A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / compiler / CharOperation.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v0.5 
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v05.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  ******************************************************************************/
11 package net.sourceforge.phpdt.core.compiler;
12
13 /**
14  * This class is a collection of helper methods to manipulate char arrays.
15  * 
16  * @since 2.1
17  */
18 public final class CharOperation {
19
20         /**
21          * Constant for an empty char array
22          */
23         public static final char[] NO_CHAR = new char[0];
24
25         /**
26          * Constant for an empty char array with two dimensions.
27          */
28         public static final char[][] NO_CHAR_CHAR = new char[0][];
29
30         /**
31          * Answers a new array with appending the suffix character at the end of the
32          * array. <br>
33          * <br>
34          * For example:<br>
35          * <ol>
36          * <li>
37          * 
38          * <pre>
39          *     array = { 'a', 'b' }
40          *     suffix = 'c'
41          *     =&gt; result = { 'a', 'b' , 'c' }
42          * </pre>
43          * 
44          * </li>
45          * <li>
46          * 
47          * <pre>
48          *     array = null
49          *     suffix = 'c'
50          *     =&gt; result = { 'c' }
51          * </pre>
52          * 
53          * </li>
54          * </ol>
55          * 
56          * @param array
57          *            the array that is concanated with the suffix character
58          * @param suffix
59          *            the suffix character
60          * @return the new array
61          */
62         public static final char[] append(char[] array, char suffix) {
63                 if (array == null)
64                         return new char[] { suffix };
65                 int length = array.length;
66                 System.arraycopy(array, 0, array = new char[length + 1], 0, length);
67                 array[length] = suffix;
68                 return array;
69         }
70
71         /**
72          * Append the given subarray to append to the target array starting at the
73          * given index in the target array. The start of the subarray is inclusive,
74          * the end is exclusive. Answers a new target array if it needs to grow,
75          * otherwise answers the same target array. <br>
76          * For example:<br>
77          * <ol>
78          * <li>
79          * 
80          * <pre>
81          *     target = { 'a', 'b', -1 }
82          *     index = 0
83          *     array = { 'c', 'd' }
84          *     start = 0
85          *     end = 1
86          *     =&gt; result = { 'a', 'b' , 'c' }
87          * </pre>
88          * 
89          * </li>
90          * <li>
91          * 
92          * <pre>
93          *     target = { 'a', 'b' }
94          *     index = 0
95          *     array = { 'c', 'd' }
96          *     start = 0
97          *     end = 1
98          *     =&gt; result = new { 'a', 'b' , 'c', -1 }
99          * </pre>
100          * 
101          * </li>
102          * <li>
103          * 
104          * <pre>
105          *     target = { 'a', 'b', 'c' }
106          *     index = 1
107          *     array = { 'c', 'd', 'e', 'f' }
108          *     start = 1
109          *     end = 4
110          *     =&gt; result = new { 'a', 'd' , 'e', 'f', -1, -1 }
111          * </pre>
112          * 
113          * </li>
114          * </ol>
115          */
116         public static final char[] append(char[] target, int index, char[] array,
117                         int start, int end) {
118                 int targetLength = target.length;
119                 int subLength = end - start;
120                 int newTargetLength = subLength + index;
121                 if (newTargetLength > targetLength) {
122                         System.arraycopy(target, 0, target = new char[newTargetLength * 2],
123                                         0, index);
124                 }
125                 System.arraycopy(array, start, target, index, subLength);
126                 return target;
127         }
128
129         /**
130          * Answers the concatenation of the two arrays. It answers null if the two
131          * arrays are null. If the first array is null, then the second array is
132          * returned. If the second array is null, then the first array is returned.
133          * <br>
134          * <br>
135          * For example:
136          * <ol>
137          * <li>
138          * 
139          * <pre>
140          *     first = null
141          *     second = null
142          *     =&gt; result = null
143          * </pre>
144          * 
145          * </li>
146          * <li>
147          * 
148          * <pre>
149          *     first = { { ' a' } }
150          *     second = null
151          *     =&gt; result = { { ' a' } }
152          * </pre>
153          * 
154          * </li>
155          * <li>
156          * 
157          * <pre>
158          *     first = null
159          *     second = { { ' a' } }
160          *     =&gt; result = { { ' a' } }
161          * </pre>
162          * 
163          * </li>
164          * <li>
165          * 
166          * <pre>
167          *     first = { { ' b' } }
168          *     second = { { ' a' } }
169          *     =&gt; result = { { ' b' }, { ' a' } }
170          * </pre>
171          * 
172          * </li>
173          * </ol>
174          * 
175          * @param first
176          *            the first array to concatenate
177          * @param second
178          *            the second array to concatenate
179          * @return the concatenation of the two arrays, or null if the two arrays
180          *         are null.
181          */
182         public static final char[][] arrayConcat(char[][] first, char[][] second) {
183                 if (first == null)
184                         return second;
185                 if (second == null)
186                         return first;
187
188                 int length1 = first.length;
189                 int length2 = second.length;
190                 char[][] result = new char[length1 + length2][];
191                 System.arraycopy(first, 0, result, 0, length1);
192                 System.arraycopy(second, 0, result, length1, length2);
193                 return result;
194         }
195
196         /**
197          * Answers a new array adding the second array at the end of first array. It
198          * answers null if the first and second are null. If the first array is
199          * null, then a new array char[][] is created with second. If the second
200          * array is null, then the first array is returned. <br>
201          * <br>
202          * For example:
203          * <ol>
204          * <li>
205          * 
206          * <pre>
207          *     first = null
208          *     second = { 'a' }
209          *     =&gt; result = { { ' a' } }
210          * </pre>
211          * 
212          * <li>
213          * 
214          * <pre>
215          *     first = { { ' a' } }
216          *     second = null
217          *     =&gt; result = { { ' a' } }
218          * </pre>
219          * 
220          * </li>
221          * <li>
222          * 
223          * <pre>
224          *     first = { { ' a' } }
225          *     second = { ' b' }
226          *     =&gt; result = { { ' a' } , { ' b' } }
227          * </pre>
228          * 
229          * </li>
230          * </ol>
231          * 
232          * @param first
233          *            the first array to concatenate
234          * @param second
235          *            the array to add at the end of the first array
236          * @return a new array adding the second array at the end of first array, or
237          *         null if the two arrays are null.
238          */
239         public static final char[][] arrayConcat(char[][] first, char[] second) {
240                 if (second == null)
241                         return first;
242                 if (first == null)
243                         return new char[][] { second };
244
245                 int length = first.length;
246                 char[][] result = new char[length + 1][];
247                 System.arraycopy(first, 0, result, 0, length);
248                 result[length] = second;
249                 return result;
250         }
251
252         /**
253          * Answers the concatenation of the two arrays. It answers null if the two
254          * arrays are null. If the first array is null, then the second array is
255          * returned. If the second array is null, then the first array is returned.
256          * <br>
257          * <br>
258          * For example:
259          * <ol>
260          * <li>
261          * 
262          * <pre>
263          *     first = null
264          *     second = { 'a' }
265          *     =&gt; result = { ' a' }
266          * </pre>
267          * 
268          * </li>
269          * <li>
270          * 
271          * <pre>
272          *     first = { ' a' }
273          *     second = null
274          *     =&gt; result = { ' a' }
275          * </pre>
276          * 
277          * </li>
278          * <li>
279          * 
280          * <pre>
281          *     first = { ' a' }
282          *     second = { ' b' }
283          *     =&gt; result = { ' a' , ' b' }
284          * </pre>
285          * 
286          * </li>
287          * </ol>
288          * 
289          * @param first
290          *            the first array to concatenate
291          * @param second
292          *            the second array to concatenate
293          * @return the concatenation of the two arrays, or null if the two arrays
294          *         are null.
295          */
296         public static final char[] concat(char[] first, char[] second) {
297                 if (first == null)
298                         return second;
299                 if (second == null)
300                         return first;
301
302                 int length1 = first.length;
303                 int length2 = second.length;
304                 char[] result = new char[length1 + length2];
305                 System.arraycopy(first, 0, result, 0, length1);
306                 System.arraycopy(second, 0, result, length1, length2);
307                 return result;
308         }
309
310         /**
311          * Answers the concatenation of the three arrays. It answers null if the
312          * three arrays are null. If first is null, it answers the concatenation of
313          * second and third. If second is null, it answers the concatenation of
314          * first and third. If third is null, it answers the concatenation of first
315          * and second. <br>
316          * <br>
317          * For example:
318          * <ol>
319          * <li>
320          * 
321          * <pre>
322          *     first = null
323          *     second = { 'a' }
324          *     third = { 'b' }
325          *     =&gt; result = { ' a', 'b' }
326          * </pre>
327          * 
328          * </li>
329          * <li>
330          * 
331          * <pre>
332          *     first = { 'a' }
333          *     second = null
334          *     third = { 'b' }
335          *     =&gt; result = { ' a', 'b' }
336          * </pre>
337          * 
338          * </li>
339          * <li>
340          * 
341          * <pre>
342          *     first = { 'a' }
343          *     second = { 'b' }
344          *     third = null
345          *     =&gt; result = { ' a', 'b' }
346          * </pre>
347          * 
348          * </li>
349          * <li>
350          * 
351          * <pre>
352          *     first = null
353          *     second = null
354          *     third = null
355          *     =&gt; result = null
356          * </pre>
357          * 
358          * </li>
359          * <li>
360          * 
361          * <pre>
362          *     first = { 'a' }
363          *     second = { 'b' }
364          *     third = { 'c' }
365          *     =&gt; result = { 'a', 'b', 'c' }
366          * </pre>
367          * 
368          * </li>
369          * </ol>
370          * 
371          * @param first
372          *            the first array to concatenate
373          * @param second
374          *            the second array to concatenate
375          * @param third
376          *            the third array to concatenate
377          * 
378          * @return the concatenation of the three arrays, or null if the three
379          *         arrays are null.
380          */
381         public static final char[] concat(char[] first, char[] second, char[] third) {
382                 if (first == null)
383                         return concat(second, third);
384                 if (second == null)
385                         return concat(first, third);
386                 if (third == null)
387                         return concat(first, second);
388
389                 int length1 = first.length;
390                 int length2 = second.length;
391                 int length3 = third.length;
392                 char[] result = new char[length1 + length2 + length3];
393                 System.arraycopy(first, 0, result, 0, length1);
394                 System.arraycopy(second, 0, result, length1, length2);
395                 System.arraycopy(third, 0, result, length1 + length2, length3);
396                 return result;
397         }
398
399         /**
400          * Answers the concatenation of the two arrays inserting the separator
401          * character between the two arrays. It answers null if the two arrays are
402          * null. If the first array is null, then the second array is returned. If
403          * the second array is null, then the first array is returned. <br>
404          * <br>
405          * For example:
406          * <ol>
407          * <li>
408          * 
409          * <pre>
410          *     first = null
411          *     second = { 'a' }
412          *     separator = '/'
413          *     =&gt; result = { ' a' }
414          * </pre>
415          * 
416          * </li>
417          * <li>
418          * 
419          * <pre>
420          *     first = { ' a' }
421          *     second = null
422          *     separator = '/'
423          *     =&gt; result = { ' a' }
424          * </pre>
425          * 
426          * </li>
427          * <li>
428          * 
429          * <pre>
430          *     first = { ' a' }
431          *     second = { ' b' }
432          *     separator = '/'
433          *     =&gt; result = { ' a' , '/', 'b' }
434          * </pre>
435          * 
436          * </li>
437          * </ol>
438          * 
439          * @param first
440          *            the first array to concatenate
441          * @param second
442          *            the second array to concatenate
443          * @param separator
444          *            the character to insert
445          * @return the concatenation of the two arrays inserting the separator
446          *         character between the two arrays , or null if the two arrays are
447          *         null.
448          */
449         public static final char[] concat(char[] first, char[] second,
450                         char separator) {
451                 if (first == null)
452                         return second;
453                 if (second == null)
454                         return first;
455
456                 int length1 = first.length;
457                 if (length1 == 0)
458                         return second;
459                 int length2 = second.length;
460                 if (length2 == 0)
461                         return first;
462
463                 char[] result = new char[length1 + length2 + 1];
464                 System.arraycopy(first, 0, result, 0, length1);
465                 result[length1] = separator;
466                 System.arraycopy(second, 0, result, length1 + 1, length2);
467                 return result;
468         }
469
470         /**
471          * Answers the concatenation of the three arrays inserting the sep1
472          * character between the two arrays and sep2 between the last two. It
473          * answers null if the three arrays are null. If the first array is null,
474          * then it answers the concatenation of second and third inserting the sep2
475          * character between them. If the second array is null, then the first array
476          * is returned. <br>
477          * <br>
478          * For example:
479          * <ol>
480          * <li>
481          * 
482          * <pre>
483          *     first = null
484          *     second = { 'a' }
485          *     separator = '/'
486          *     =&gt; result = { ' a' }
487          * </pre>
488          * 
489          * </li>
490          * <li>
491          * 
492          * <pre>
493          *     first = { ' a' }
494          *     second = null
495          *     separator = '/'
496          *     =&gt; result = { ' a' }
497          * </pre>
498          * 
499          * </li>
500          * <li>
501          * 
502          * <pre>
503          *     first = { ' a' }
504          *     second = { ' b' }
505          *     separator = '/'
506          *     =&gt; result = { ' a' , '/', 'b' }
507          * </pre>
508          * 
509          * </li>
510          * </ol>
511          * 
512          * @param first
513          *            the first array to concatenate
514          * @param second
515          *            the second array to concatenate
516          * @param separator
517          *            the character to insert
518          * @return the concatenation of the two arrays inserting the separator
519          *         character between the two arrays , or null if the two arrays are
520          *         null.
521          */
522         public static final char[] concat(char[] first, char sep1, char[] second,
523                         char sep2, char[] third) {
524                 if (first == null)
525                         return concat(second, third, sep2);
526                 if (second == null)
527                         return concat(first, third, sep1);
528                 if (third == null)
529                         return concat(first, second, sep1);
530
531                 int length1 = first.length;
532                 int length2 = second.length;
533                 int length3 = third.length;
534                 char[] result = new char[length1 + length2 + length3 + 2];
535                 System.arraycopy(first, 0, result, 0, length1);
536                 result[length1] = sep1;
537                 System.arraycopy(second, 0, result, length1 + 1, length2);
538                 result[length1 + length2 + 1] = sep2;
539                 System.arraycopy(third, 0, result, length1 + length2 + 2, length3);
540                 return result;
541         }
542
543         /**
544          * Answers a new array with prepending the prefix character and appending
545          * the suffix character at the end of the array. If array is null, it
546          * answers a new array containing the prefix and the suffix characters. <br>
547          * <br>
548          * For example:<br>
549          * <ol>
550          * <li>
551          * 
552          * <pre>
553          *     prefix = 'a'
554          *     array = { 'b' }
555          *     suffix = 'c'
556          *     =&gt; result = { 'a', 'b' , 'c' }
557          * </pre>
558          * 
559          * </li>
560          * <li>
561          * 
562          * <pre>
563          *     prefix = 'a'
564          *     array = null
565          *     suffix = 'c'
566          *     =&gt; result = { 'a', 'c' }
567          * </pre>
568          * 
569          * </li>
570          * </ol>
571          * 
572          * @param prefix
573          *            the prefix character
574          * @param array
575          *            the array that is concanated with the prefix and suffix
576          *            characters
577          * @param suffix
578          *            the suffix character
579          * @return the new array
580          */
581         public static final char[] concat(char prefix, char[] array, char suffix) {
582                 if (array == null)
583                         return new char[] { prefix, suffix };
584
585                 int length = array.length;
586                 char[] result = new char[length + 2];
587                 result[0] = prefix;
588                 System.arraycopy(array, 0, result, 1, length);
589                 result[length + 1] = suffix;
590                 return result;
591         }
592
593         /**
594          * Answers the concatenation of the given array parts using the given
595          * separator between each part and appending the given name at the end. <br>
596          * <br>
597          * For example:<br>
598          * <ol>
599          * <li>
600          * 
601          * <pre>
602          *     name = { 'c' }
603          *     array = { { 'a' }, { 'b' } }
604          *     separator = '.'
605          *     =&gt; result = { 'a', '.', 'b' , '.', 'c' }
606          * </pre>
607          * 
608          * </li>
609          * <li>
610          * 
611          * <pre>
612          *     name = null
613          *     array = { { 'a' }, { 'b' } }
614          *     separator = '.'
615          *     =&gt; result = { 'a', '.', 'b' }
616          * </pre>
617          * 
618          * </li>
619          * <li>
620          * 
621          * <pre>
622          *     name = { ' c' }
623          *     array = null
624          *     separator = '.'
625          *     =&gt; result = { 'c' }
626          * </pre>
627          * 
628          * </li>
629          * </ol>
630          * 
631          * @param name
632          *            the given name
633          * @param array
634          *            the given array
635          * @param separator
636          *            the given separator
637          * @return the concatenation of the given array parts using the given
638          *         separator between each part and appending the given name at the
639          *         end
640          */
641         public static final char[] concatWith(char[] name, char[][] array,
642                         char separator) {
643                 int nameLength = name == null ? 0 : name.length;
644                 if (nameLength == 0)
645                         return concatWith(array, separator);
646
647                 int length = array == null ? 0 : array.length;
648                 if (length == 0)
649                         return name;
650
651                 int size = nameLength;
652                 int index = length;
653                 while (--index >= 0)
654                         if (array[index].length > 0)
655                                 size += array[index].length + 1;
656                 char[] result = new char[size];
657                 index = size;
658                 for (int i = length - 1; i >= 0; i--) {
659                         int subLength = array[i].length;
660                         if (subLength > 0) {
661                                 index -= subLength;
662                                 System.arraycopy(array[i], 0, result, index, subLength);
663                                 result[--index] = separator;
664                         }
665                 }
666                 System.arraycopy(name, 0, result, 0, nameLength);
667                 return result;
668         }
669
670         /**
671          * Answers the concatenation of the given array parts using the given
672          * separator between each part and appending the given name at the end. <br>
673          * <br>
674          * For example:<br>
675          * <ol>
676          * <li>
677          * 
678          * <pre>
679          *     name = { 'c' }
680          *     array = { { 'a' }, { 'b' } }
681          *     separator = '.'
682          *     =&gt; result = { 'a', '.', 'b' , '.', 'c' }
683          * </pre>
684          * 
685          * </li>
686          * <li>
687          * 
688          * <pre>
689          *     name = null
690          *     array = { { 'a' }, { 'b' } }
691          *     separator = '.'
692          *     =&gt; result = { 'a', '.', 'b' }
693          * </pre>
694          * 
695          * </li>
696          * <li>
697          * 
698          * <pre>
699          *     name = { ' c' }
700          *     array = null
701          *     separator = '.'
702          *     =&gt; result = { 'c' }
703          * </pre>
704          * 
705          * </li>
706          * </ol>
707          * 
708          * @param array
709          *            the given array
710          * @param name
711          *            the given name
712          * @param separator
713          *            the given separator
714          * @return the concatenation of the given array parts using the given
715          *         separator between each part and appending the given name at the
716          *         end
717          */
718         public static final char[] concatWith(char[][] array, char[] name,
719                         char separator) {
720                 int nameLength = name == null ? 0 : name.length;
721                 if (nameLength == 0)
722                         return concatWith(array, separator);
723
724                 int length = array == null ? 0 : array.length;
725                 if (length == 0)
726                         return name;
727
728                 int size = nameLength;
729                 int index = length;
730                 while (--index >= 0)
731                         if (array[index].length > 0)
732                                 size += array[index].length + 1;
733                 char[] result = new char[size];
734                 index = 0;
735                 for (int i = 0; i < length; i++) {
736                         int subLength = array[i].length;
737                         if (subLength > 0) {
738                                 System.arraycopy(array[i], 0, result, index, subLength);
739                                 index += subLength;
740                                 result[index++] = separator;
741                         }
742                 }
743                 System.arraycopy(name, 0, result, index, nameLength);
744                 return result;
745         }
746
747         /**
748          * Answers the concatenation of the given array parts using the given
749          * separator between each part. <br>
750          * <br>
751          * For example:<br>
752          * <ol>
753          * <li>
754          * 
755          * <pre>
756          *     array = { { 'a' }, { 'b' } }
757          *     separator = '.'
758          *     =&gt; result = { 'a', '.', 'b' }
759          * </pre>
760          * 
761          * </li>
762          * <li>
763          * 
764          * <pre>
765          *     array = null
766          *     separator = '.'
767          *     =&gt; result = { }
768          * </pre>
769          * 
770          * </li>
771          * </ol>
772          * 
773          * @param array
774          *            the given array
775          * @param separator
776          *            the given separator
777          * @return the concatenation of the given array parts using the given
778          *         separator between each part
779          */
780         public static final char[] concatWith(char[][] array, char separator) {
781                 int length = array == null ? 0 : array.length;
782                 if (length == 0)
783                         return CharOperation.NO_CHAR;
784
785                 int size = length - 1;
786                 int index = length;
787                 while (--index >= 0) {
788                         if (array[index].length == 0)
789                                 size--;
790                         else
791                                 size += array[index].length;
792                 }
793                 if (size <= 0)
794                         return CharOperation.NO_CHAR;
795                 char[] result = new char[size];
796                 index = length;
797                 while (--index >= 0) {
798                         length = array[index].length;
799                         if (length > 0) {
800                                 System.arraycopy(array[index], 0, result, (size -= length),
801                                                 length);
802                                 if (--size >= 0)
803                                         result[size] = separator;
804                         }
805                 }
806                 return result;
807         }
808
809         /**
810          * Answers true if the array contains an occurrence of character, false
811          * otherwise.
812          * 
813          * <br>
814          * <br>
815          * For example:
816          * <ol>
817          * <li>
818          * 
819          * <pre>
820          *     character = 'c'
821          *     array = { { ' a' }, { ' b' } }
822          *     result =&gt; false
823          * </pre>
824          * 
825          * </li>
826          * <li>
827          * 
828          * <pre>
829          *     character = 'a'
830          *     array = { { ' a' }, { ' b' } }
831          *     result =&gt; true
832          * </pre>
833          * 
834          * </li>
835          * </ol>
836          * 
837          * @param character
838          *            the character to search
839          * @param array
840          *            the array in which the search is done
841          * @exception NullPointerException
842          *                if array is null.
843          * 
844          * @return true if the array contains an occurrence of character, false
845          *         otherwise.
846          */
847         public static final boolean contains(char character, char[][] array) {
848                 for (int i = array.length; --i >= 0;) {
849                         char[] subarray = array[i];
850                         for (int j = subarray.length; --j >= 0;)
851                                 if (subarray[j] == character)
852                                         return true;
853                 }
854                 return false;
855         }
856
857         /**
858          * Answers true if the array contains an occurrence of character, false
859          * otherwise.
860          * 
861          * <br>
862          * <br>
863          * For example:
864          * <ol>
865          * <li>
866          * 
867          * <pre>
868          *     character = 'c'
869          *     array = { ' b'  }
870          *     result =&gt; false
871          * </pre>
872          * 
873          * </li>
874          * <li>
875          * 
876          * <pre>
877          *     character = 'a'
878          *     array = { ' a' , ' b' }
879          *     result =&gt; true
880          * </pre>
881          * 
882          * </li>
883          * </ol>
884          * 
885          * @param character
886          *            the character to search
887          * @param array
888          *            the array in which the search is done
889          * @exception NullPointerException
890          *                if array is null.
891          * 
892          * @return true if the array contains an occurrence of character, false
893          *         otherwise.
894          */
895         public static final boolean contains(char character, char[] array) {
896                 for (int i = array.length; --i >= 0;)
897                         if (array[i] == character)
898                                 return true;
899                 return false;
900         }
901
902         /**
903          * Answers a deep copy of the toCopy array.
904          * 
905          * @param toCopy
906          *            the array to copy
907          * @return a deep copy of the toCopy array.
908          */
909         public static final char[][] deepCopy(char[][] toCopy) {
910                 int toCopyLength = toCopy.length;
911                 char[][] result = new char[toCopyLength][];
912                 for (int i = 0; i < toCopyLength; i++) {
913                         char[] toElement = toCopy[i];
914                         int toElementLength = toElement.length;
915                         char[] resultElement = new char[toElementLength];
916                         System.arraycopy(toElement, 0, resultElement, 0, toElementLength);
917                         result[i] = resultElement;
918                 }
919                 return result;
920         }
921
922         /**
923          * Return true if array ends with the sequence of characters contained in
924          * toBeFound, otherwise false. <br>
925          * <br>
926          * For example:
927          * <ol>
928          * <li>
929          * 
930          * <pre>
931          *     array = { 'a', 'b', 'c', 'd' }
932          *     toBeFound = { 'b', 'c' }
933          *     result =&gt; false
934          * </pre>
935          * 
936          * </li>
937          * <li>
938          * 
939          * <pre>
940          *     array = { 'a', 'b', 'c' }
941          *     toBeFound = { 'b', 'c' }
942          *     result =&gt; true
943          * </pre>
944          * 
945          * </li>
946          * </ol>
947          * 
948          * @param array
949          *            the array to check
950          * @param toBeFound
951          *            the array to find
952          * @exception NullPointerException
953          *                if array is null or toBeFound is null
954          * @return true if array ends with the sequence of characters contained in
955          *         toBeFound, otherwise false.
956          */
957         public static final boolean endsWith(char[] array, char[] toBeFound) {
958                 int i = toBeFound.length;
959                 int j = array.length - i;
960
961                 if (j < 0)
962                         return false;
963                 while (--i >= 0)
964                         if (toBeFound[i] != array[i + j])
965                                 return false;
966                 return true;
967         }
968
969         /**
970          * Answers true if the two arrays are identical character by character,
971          * otherwise false. The equality is case sensitive. <br>
972          * <br>
973          * For example:
974          * <ol>
975          * <li>
976          * 
977          * <pre>
978          *     first = null
979          *     second = null
980          *     result =&gt; true
981          * </pre>
982          * 
983          * </li>
984          * <li>
985          * 
986          * <pre>
987          *     first = { { } }
988          *     second = null
989          *     result =&gt; false
990          * </pre>
991          * 
992          * </li>
993          * <li>
994          * 
995          * <pre>
996          *     first = { { 'a' } }
997          *     second = { { 'a' } }
998          *     result =&gt; true
999          * </pre>
1000          * 
1001          * </li>
1002          * <li>
1003          * 
1004          * <pre>
1005          *     first = { { 'A' } }
1006          *     second = { { 'a' } }
1007          *     result =&gt; false
1008          * </pre>
1009          * 
1010          * </li>
1011          * </ol>
1012          * 
1013          * @param first
1014          *            the first array
1015          * @param second
1016          *            the second array
1017          * @return true if the two arrays are identical character by character,
1018          *         otherwise false
1019          */
1020         public static final boolean equals(char[][] first, char[][] second) {
1021                 if (first == second)
1022                         return true;
1023                 if (first == null || second == null)
1024                         return false;
1025                 if (first.length != second.length)
1026                         return false;
1027
1028                 for (int i = first.length; --i >= 0;)
1029                         if (!equals(first[i], second[i]))
1030                                 return false;
1031                 return true;
1032         }
1033
1034         /**
1035          * If isCaseSensite is true, answers true if the two arrays are identical
1036          * character by character, otherwise false. If it is false, answers true if
1037          * the two arrays are identical character by character without checking the
1038          * case, otherwise false. <br>
1039          * <br>
1040          * For example:
1041          * <ol>
1042          * <li>
1043          * 
1044          * <pre>
1045          *     first = null
1046          *     second = null
1047          *     isCaseSensitive = true
1048          *     result =&gt; true
1049          * </pre>
1050          * 
1051          * </li>
1052          * <li>
1053          * 
1054          * <pre>
1055          *     first = { { } }
1056          *     second = null
1057          *     isCaseSensitive = true
1058          *     result =&gt; false
1059          * </pre>
1060          * 
1061          * </li>
1062          * <li>
1063          * 
1064          * <pre>
1065          *     first = { { 'A' } }
1066          *     second = { { 'a' } }
1067          *     isCaseSensitive = true
1068          *     result =&gt; false
1069          * </pre>
1070          * 
1071          * </li>
1072          * <li>
1073          * 
1074          * <pre>
1075          *     first = { { 'A' } }
1076          *     second = { { 'a' } }
1077          *     isCaseSensitive = false
1078          *     result =&gt; true
1079          * </pre>
1080          * 
1081          * </li>
1082          * </ol>
1083          * 
1084          * @param first
1085          *            the first array
1086          * @param second
1087          *            the second array
1088          * @param isCaseSensitive
1089          *            check whether or not the equality should be case sensitive
1090          * @return true if the two arrays are identical character by character
1091          *         according to the value of isCaseSensitive, otherwise false
1092          */
1093         public static final boolean equals(char[][] first, char[][] second,
1094                         boolean isCaseSensitive) {
1095
1096                 if (isCaseSensitive) {
1097                         return equals(first, second);
1098                 }
1099                 if (first == second)
1100                         return true;
1101                 if (first == null || second == null)
1102                         return false;
1103                 if (first.length != second.length)
1104                         return false;
1105
1106                 for (int i = first.length; --i >= 0;)
1107                         if (!equals(first[i], second[i], false))
1108                                 return false;
1109                 return true;
1110         }
1111
1112         /**
1113          * Answers true if the two arrays are identical character by character,
1114          * otherwise false. The equality is case sensitive. <br>
1115          * <br>
1116          * For example:
1117          * <ol>
1118          * <li>
1119          * 
1120          * <pre>
1121          *     first = null
1122          *     second = null
1123          *     result =&gt; true
1124          * </pre>
1125          * 
1126          * </li>
1127          * <li>
1128          * 
1129          * <pre>
1130          *     first = { }
1131          *     second = null
1132          *     result =&gt; false
1133          * </pre>
1134          * 
1135          * </li>
1136          * <li>
1137          * 
1138          * <pre>
1139          *     first = { 'a' }
1140          *     second = { 'a' }
1141          *     result =&gt; true
1142          * </pre>
1143          * 
1144          * </li>
1145          * <li>
1146          * 
1147          * <pre>
1148          *     first = { 'a' }
1149          *     second = { 'A' }
1150          *     result =&gt; false
1151          * </pre>
1152          * 
1153          * </li>
1154          * </ol>
1155          * 
1156          * @param first
1157          *            the first array
1158          * @param second
1159          *            the second array
1160          * @return true if the two arrays are identical character by character,
1161          *         otherwise false
1162          */
1163         public static final boolean equals(char[] first, char[] second) {
1164                 if (first == second)
1165                         return true;
1166                 if (first == null || second == null)
1167                         return false;
1168                 if (first.length != second.length)
1169                         return false;
1170
1171                 for (int i = first.length; --i >= 0;)
1172                         if (first[i] != second[i])
1173                                 return false;
1174                 return true;
1175         }
1176
1177         /**
1178          * If isCaseSensite is true, answers true if the two arrays are identical
1179          * character by character, otherwise false. If it is false, answers true if
1180          * the two arrays are identical character by character without checking the
1181          * case, otherwise false. <br>
1182          * <br>
1183          * For example:
1184          * <ol>
1185          * <li>
1186          * 
1187          * <pre>
1188          *     first = null
1189          *     second = null
1190          *     isCaseSensitive = true
1191          *     result =&gt; true
1192          * </pre>
1193          * 
1194          * </li>
1195          * <li>
1196          * 
1197          * <pre>
1198          *     first = { }
1199          *     second = null
1200          *     isCaseSensitive = true
1201          *     result =&gt; false
1202          * </pre>
1203          * 
1204          * </li>
1205          * <li>
1206          * 
1207          * <pre>
1208          *     first = { 'A' }
1209          *     second = { 'a' }
1210          *     isCaseSensitive = true
1211          *     result =&gt; false
1212          * </pre>
1213          * 
1214          * </li>
1215          * <li>
1216          * 
1217          * <pre>
1218          *     first = { 'A' }
1219          *     second = { 'a' }
1220          *     isCaseSensitive = false
1221          *     result =&gt; true
1222          * </pre>
1223          * 
1224          * </li>
1225          * </ol>
1226          * 
1227          * @param first
1228          *            the first array
1229          * @param second
1230          *            the second array
1231          * @param isCaseSensitive
1232          *            check whether or not the equality should be case sensitive
1233          * @return true if the two arrays are identical character by character
1234          *         according to the value of isCaseSensitive, otherwise false
1235          */
1236         public static final boolean equals(char[] first, char[] second,
1237                         boolean isCaseSensitive) {
1238
1239                 if (isCaseSensitive) {
1240                         return equals(first, second);
1241                 }
1242                 if (first == second)
1243                         return true;
1244                 if (first == null || second == null)
1245                         return false;
1246                 if (first.length != second.length)
1247                         return false;
1248
1249                 for (int i = first.length; --i >= 0;)
1250                         if (Character.toLowerCase(first[i]) != Character
1251                                         .toLowerCase(second[i]))
1252                                 return false;
1253                 return true;
1254         }
1255
1256         /**
1257          * If isCaseSensite is true, the equality is case sensitive, otherwise it is
1258          * case insensitive.
1259          * 
1260          * Answers true if the name contains the fragment at the starting index
1261          * startIndex, otherwise false. <br>
1262          * <br>
1263          * For example:
1264          * <ol>
1265          * <li>
1266          * 
1267          * <pre>
1268          *     fragment = { 'b', 'c' , 'd' }
1269          *     name = { 'a', 'b', 'c' , 'd' }
1270          *     startIndex = 1
1271          *     isCaseSensitive = true
1272          *     result =&gt; true
1273          * </pre>
1274          * 
1275          * </li>
1276          * <li>
1277          * 
1278          * <pre>
1279          *     fragment = { 'b', 'c' , 'd' }
1280          *     name = { 'a', 'b', 'C' , 'd' }
1281          *     startIndex = 1
1282          *     isCaseSensitive = true
1283          *     result =&gt; false
1284          * </pre>
1285          * 
1286          * </li>
1287          * <li>
1288          * 
1289          * <pre>
1290          *     fragment = { 'b', 'c' , 'd' }
1291          *     name = { 'a', 'b', 'C' , 'd' }
1292          *     startIndex = 0
1293          *     isCaseSensitive = false
1294          *     result =&gt; false
1295          * </pre>
1296          * 
1297          * </li>
1298          * <li>
1299          * 
1300          * <pre>
1301          *     fragment = { 'b', 'c' , 'd' }
1302          *     name = { 'a', 'b'}
1303          *     startIndex = 0
1304          *     isCaseSensitive = true
1305          *     result =&gt; false
1306          * </pre>
1307          * 
1308          * </li>
1309          * </ol>
1310          * 
1311          * @param fragment
1312          *            the fragment to check
1313          * @param second
1314          *            the array to check
1315          * @param startIndex
1316          *            the starting index
1317          * @param isCaseSensitive
1318          *            check whether or not the equality should be case sensitive
1319          * @return true if the name contains the fragment at the starting index
1320          *         startIndex according to the value of isCaseSensitive, otherwise
1321          *         false.
1322          * @exception NullPointerException
1323          *                if fragment or name is null.
1324          */
1325         public static final boolean fragmentEquals(char[] fragment, char[] name,
1326                         int startIndex, boolean isCaseSensitive) {
1327
1328                 int max = fragment.length;
1329                 if (name.length < max + startIndex)
1330                         return false;
1331                 if (isCaseSensitive) {
1332                         for (int i = max; --i >= 0;)
1333                                 // assumes the prefix is not larger than the name
1334                                 if (fragment[i] != name[i + startIndex])
1335                                         return false;
1336                         return true;
1337                 }
1338                 for (int i = max; --i >= 0;)
1339                         // assumes the prefix is not larger than the name
1340                         if (Character.toLowerCase(fragment[i]) != Character
1341                                         .toLowerCase(name[i + startIndex]))
1342                                 return false;
1343                 return true;
1344         }
1345
1346         /**
1347          * Answers a hashcode for the array
1348          * 
1349          * @param array
1350          *            the array for which a hashcode is required
1351          * @return the hashcode
1352          * @exception NullPointerException
1353          *                if array is null
1354          */
1355         public static final int hashCode(char[] array) {
1356                 int hash = 0;
1357                 int offset = 0;
1358                 int length = array.length;
1359                 if (length < 16) {
1360                         for (int i = length; i > 0; i--)
1361                                 hash = (hash * 37) + array[offset++];
1362                 } else {
1363                         // only sample some characters
1364                         int skip = length / 8;
1365                         for (int i = length; i > 0; i -= skip, offset += skip)
1366                                 hash = (hash * 39) + array[offset];
1367                 }
1368                 return hash & 0x7FFFFFFF;
1369         }
1370
1371         /**
1372          * Answers true if c is a whitespace according to the JLS (&#92;u000a,
1373          * &#92;u000c, &#92;u000d, &#92;u0009), otherwise false. <br>
1374          * <br>
1375          * For example:
1376          * <ol>
1377          * <li>
1378          * 
1379          * <pre>
1380          *     c = ' '
1381          *     result =&gt; true
1382          * </pre>
1383          * 
1384          * </li>
1385          * <li>
1386          * 
1387          * <pre>
1388          *     c = ' \u3000'
1389          *     result =&gt; false
1390          * </pre>
1391          * 
1392          * </li>
1393          * </ol>
1394          * 
1395          * @param c
1396          *            the character to check
1397          * @return true if c is a whitespace according to the JLS, otherwise false.
1398          */
1399         public static boolean isWhitespace(char c) {
1400                 switch (c) {
1401                 case 10: /* \ u000a: LINE FEED */
1402                 case 12: /* \ u000c: FORM FEED */
1403                 case 13: /* \ u000d: CARRIAGE RETURN */
1404                 case 32: /* \ u0020: SPACE */
1405                 case 9: /* \ u0009: HORIZONTAL TABULATION */
1406                         return true;
1407                 default:
1408                         return false;
1409                 }
1410         }
1411
1412         /**
1413          * Answers the first index in the array for which the corresponding
1414          * character is equal to toBeFound. Answers -1 if no occurrence of this
1415          * character is found. <br>
1416          * <br>
1417          * For example:
1418          * <ol>
1419          * <li>
1420          * 
1421          * <pre>
1422          *     toBeFound = 'c'
1423          *     array = { ' a', 'b', 'c', 'd' }
1424          *     result =&gt; 2
1425          * </pre>
1426          * 
1427          * </li>
1428          * <li>
1429          * 
1430          * <pre>
1431          *     toBeFound = 'e'
1432          *     array = { ' a', 'b', 'c', 'd' }
1433          *     result =&gt; -1
1434          * </pre>
1435          * 
1436          * </li>
1437          * </ol>
1438          * 
1439          * @param toBeFound
1440          *            the character to search
1441          * @param array
1442          *            the array to be searched
1443          * @return the first index in the array for which the corresponding
1444          *         character is equal to toBeFound, -1 otherwise
1445          * @exception NullPointerException
1446          *                if array is null
1447          */
1448         public static final int indexOf(char toBeFound, char[] array) {
1449                 for (int i = 0; i < array.length; i++)
1450                         if (toBeFound == array[i])
1451                                 return i;
1452                 return -1;
1453         }
1454
1455         /**
1456          * Answers the first index in the array for which the corresponding
1457          * character is equal to toBeFound starting the search at index start.
1458          * Answers -1 if no occurrence of this character is found. <br>
1459          * <br>
1460          * For example:
1461          * <ol>
1462          * <li>
1463          * 
1464          * <pre>
1465          *     toBeFound = 'c'
1466          *     array = { ' a', 'b', 'c', 'd' }
1467          *     start = 2
1468          *     result =&gt; 2
1469          * </pre>
1470          * 
1471          * </li>
1472          * <li>
1473          * 
1474          * <pre>
1475          *     toBeFound = 'c'
1476          *     array = { ' a', 'b', 'c', 'd' }
1477          *     start = 3
1478          *     result =&gt; -1
1479          * </pre>
1480          * 
1481          * </li>
1482          * <li>
1483          * 
1484          * <pre>
1485          *     toBeFound = 'e'
1486          *     array = { ' a', 'b', 'c', 'd' }
1487          *     start = 1
1488          *     result =&gt; -1
1489          * </pre>
1490          * 
1491          * </li>
1492          * </ol>
1493          * 
1494          * @param toBeFound
1495          *            the character to search
1496          * @param array
1497          *            the array to be searched
1498          * @param start
1499          *            the starting index
1500          * @return the first index in the array for which the corresponding
1501          *         character is equal to toBeFound, -1 otherwise
1502          * @exception NullPointerException
1503          *                if array is null
1504          * @exception ArrayIndexOutOfBoundsException
1505          *                if start is lower than 0
1506          */
1507         public static final int indexOf(char toBeFound, char[] array, int start) {
1508                 for (int i = start; i < array.length; i++)
1509                         if (toBeFound == array[i])
1510                                 return i;
1511                 return -1;
1512         }
1513
1514         /**
1515          * Answers the last index in the array for which the corresponding character
1516          * is equal to toBeFound starting from the end of the array. Answers -1 if
1517          * no occurrence of this character is found. <br>
1518          * <br>
1519          * For example:
1520          * <ol>
1521          * <li>
1522          * 
1523          * <pre>
1524          *     toBeFound = 'c'
1525          *     array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
1526          *     result =&gt; 4
1527          * </pre>
1528          * 
1529          * </li>
1530          * <li>
1531          * 
1532          * <pre>
1533          *     toBeFound = 'e'
1534          *     array = { ' a', 'b', 'c', 'd' }
1535          *     result =&gt; -1
1536          * </pre>
1537          * 
1538          * </li>
1539          * </ol>
1540          * 
1541          * @param toBeFound
1542          *            the character to search
1543          * @param array
1544          *            the array to be searched
1545          * @return the last index in the array for which the corresponding character
1546          *         is equal to toBeFound starting from the end of the array, -1
1547          *         otherwise
1548          * @exception NullPointerException
1549          *                if array is null
1550          */
1551         public static final int lastIndexOf(char toBeFound, char[] array) {
1552                 for (int i = array.length; --i >= 0;)
1553                         if (toBeFound == array[i])
1554                                 return i;
1555                 return -1;
1556         }
1557
1558         /**
1559          * Answers the last index in the array for which the corresponding character
1560          * is equal to toBeFound stopping at the index startIndex. Answers -1 if no
1561          * occurrence of this character is found. <br>
1562          * <br>
1563          * For example:
1564          * <ol>
1565          * <li>
1566          * 
1567          * <pre>
1568          *     toBeFound = 'c'
1569          *     array = { ' a', 'b', 'c', 'd' }
1570          *     startIndex = 2
1571          *     result =&gt; 2
1572          * </pre>
1573          * 
1574          * </li>
1575          * <li>
1576          * 
1577          * <pre>
1578          *     toBeFound = 'c'
1579          *     array = { ' a', 'b', 'c', 'd', 'e' }
1580          *     startIndex = 3
1581          *     result =&gt; -1
1582          * </pre>
1583          * 
1584          * </li>
1585          * <li>
1586          * 
1587          * <pre>
1588          *     toBeFound = 'e'
1589          *     array = { ' a', 'b', 'c', 'd' }
1590          *     startIndex = 0
1591          *     result =&gt; -1
1592          * </pre>
1593          * 
1594          * </li>
1595          * </ol>
1596          * 
1597          * @param toBeFound
1598          *            the character to search
1599          * @param array
1600          *            the array to be searched
1601          * @param startIndex
1602          *            the stopping index
1603          * @return the last index in the array for which the corresponding character
1604          *         is equal to toBeFound stopping at the index startIndex, -1
1605          *         otherwise
1606          * @exception NullPointerException
1607          *                if array is null
1608          * @exception ArrayIndexOutOfBoundsException
1609          *                if startIndex is lower than 0
1610          */
1611         public static final int lastIndexOf(char toBeFound, char[] array,
1612                         int startIndex) {
1613                 for (int i = array.length; --i >= startIndex;)
1614                         if (toBeFound == array[i])
1615                                 return i;
1616                 return -1;
1617         }
1618
1619         /**
1620          * Answers the last index in the array for which the corresponding character
1621          * is equal to toBeFound starting from endIndex to startIndex. Answers -1 if
1622          * no occurrence of this character is found. <br>
1623          * <br>
1624          * For example:
1625          * <ol>
1626          * <li>
1627          * 
1628          * <pre>
1629          *     toBeFound = 'c'
1630          *     array = { ' a', 'b', 'c', 'd' }
1631          *     startIndex = 2
1632          *     endIndex = 2
1633          *     result =&gt; 2
1634          * </pre>
1635          * 
1636          * </li>
1637          * <li>
1638          * 
1639          * <pre>
1640          *     toBeFound = 'c'
1641          *     array = { ' a', 'b', 'c', 'd', 'e' }
1642          *     startIndex = 3
1643          *     endIndex = 4
1644          *     result =&gt; -1
1645          * </pre>
1646          * 
1647          * </li>
1648          * <li>
1649          * 
1650          * <pre>
1651          *     toBeFound = 'e'
1652          *     array = { ' a', 'b', 'c', 'd' }
1653          *     startIndex = 0
1654          *     endIndex = 3
1655          *     result =&gt; -1
1656          * </pre>
1657          * 
1658          * </li>
1659          * </ol>
1660          * 
1661          * @param toBeFound
1662          *            the character to search
1663          * @param array
1664          *            the array to be searched
1665          * @param startIndex
1666          *            the stopping index
1667          * @param endIndex
1668          *            the starting index
1669          * @return the last index in the array for which the corresponding character
1670          *         is equal to toBeFound starting from endIndex to startIndex, -1
1671          *         otherwise
1672          * @exception NullPointerException
1673          *                if array is null
1674          * @exception ArrayIndexOutOfBoundsException
1675          *                if endIndex is greater or equals to array length or
1676          *                starting is lower than 0
1677          */
1678         public static final int lastIndexOf(char toBeFound, char[] array,
1679                         int startIndex, int endIndex) {
1680                 for (int i = endIndex; --i >= startIndex;)
1681                         if (toBeFound == array[i])
1682                                 return i;
1683                 return -1;
1684         }
1685
1686         /**
1687          * Answers the last portion of a name given a separator. <br>
1688          * <br>
1689          * For example,
1690          * 
1691          * <pre>
1692          *      lastSegment(&quot;java.lang.Object&quot;.toCharArray(),'.') --&gt; Object
1693          * </pre>
1694          * 
1695          * @param array
1696          *            the array
1697          * @param separator
1698          *            the given separator
1699          * @return the last portion of a name given a separator
1700          * @exception NullPointerException
1701          *                if array is null
1702          */
1703         final static public char[] lastSegment(char[] array, char separator) {
1704                 int pos = lastIndexOf(separator, array);
1705                 if (pos < 0)
1706                         return array;
1707                 return subarray(array, pos + 1, array.length);
1708         }
1709
1710         /**
1711          * Answers true if the pattern matches the given name, false otherwise. This
1712          * char[] pattern matching accepts wild-cards '*' and '?'.
1713          * 
1714          * When not case sensitive, the pattern is assumed to already be lowercased,
1715          * the name will be lowercased character per character as comparing. If name
1716          * is null, the answer is false. If pattern is null, the answer is true if
1717          * name is not null. <br>
1718          * <br>
1719          * For example:
1720          * <ol>
1721          * <li>
1722          * 
1723          * <pre>
1724          *     pattern = { '?', 'b', '*' }
1725          *     name = { 'a', 'b', 'c' , 'd' }
1726          *     isCaseSensitive = true
1727          *     result =&gt; true
1728          * </pre>
1729          * 
1730          * </li>
1731          * <li>
1732          * 
1733          * <pre>
1734          *     pattern = { '?', 'b', '?' }
1735          *     name = { 'a', 'b', 'c' , 'd' }
1736          *     isCaseSensitive = true
1737          *     result =&gt; false
1738          * </pre>
1739          * 
1740          * </li>
1741          * <li>
1742          * 
1743          * <pre>
1744          *     pattern = { 'b', '*' }
1745          *     name = { 'a', 'b', 'c' , 'd' }
1746          *     isCaseSensitive = true
1747          *     result =&gt; false
1748          * </pre>
1749          * 
1750          * </li>
1751          * </ol>
1752          * 
1753          * @param pattern
1754          *            the given pattern
1755          * @param name
1756          *            the given name
1757          * @param isCaseSensitive
1758          *            flag to know whether or not the matching should be case
1759          *            sensitive
1760          * @return true if the pattern matches the given name, false otherwise
1761          */
1762         public static final boolean match(char[] pattern, char[] name,
1763                         boolean isCaseSensitive) {
1764
1765                 if (name == null)
1766                         return false; // null name cannot match
1767                 if (pattern == null)
1768                         return true; // null pattern is equivalent to '*'
1769
1770                 return match(pattern, 0, pattern.length, name, 0, name.length,
1771                                 isCaseSensitive);
1772         }
1773
1774         /**
1775          * Answers true if the a sub-pattern matches the subpart of the given name,
1776          * false otherwise. char[] pattern matching, accepting wild-cards '*' and
1777          * '?'. Can match only subset of name/pattern. end positions are
1778          * non-inclusive. The subpattern is defined by the patternStart and
1779          * pattternEnd positions. When not case sensitive, the pattern is assumed to
1780          * already be lowercased, the name will be lowercased character per
1781          * character as comparing. <br>
1782          * <br>
1783          * For example:
1784          * <ol>
1785          * <li>
1786          * 
1787          * <pre>
1788          *     pattern = { '?', 'b', '*' }
1789          *     patternStart = 1
1790          *     patternEnd = 3
1791          *     name = { 'a', 'b', 'c' , 'd' }
1792          *     nameStart = 1
1793          *     nameEnd = 4
1794          *     isCaseSensitive = true
1795          *     result =&gt; true
1796          * </pre>
1797          * 
1798          * </li>
1799          * <li>
1800          * 
1801          * <pre>
1802          *     pattern = { '?', 'b', '*' }
1803          *     patternStart = 1
1804          *     patternEnd = 2
1805          *     name = { 'a', 'b', 'c' , 'd' }
1806          *     nameStart = 1
1807          *     nameEnd = 2
1808          *     isCaseSensitive = true
1809          *     result =&gt; false
1810          * </pre>
1811          * 
1812          * </li>
1813          * </ol>
1814          * 
1815          * @param pattern
1816          *            the given pattern
1817          * @param patternStart
1818          *            the given pattern start
1819          * @param patternEnd
1820          *            the given pattern end
1821          * @param name
1822          *            the given name
1823          * @param nameStart
1824          *            the given name start
1825          * @param nameEnd
1826          *            the given name end
1827          * @param isCaseSensitive
1828          *            flag to know if the matching should be case sensitive
1829          * @return true if the a sub-pattern matches the subpart of the given name,
1830          *         false otherwise
1831          */
1832         public static final boolean match(char[] pattern, int patternStart,
1833                         int patternEnd, char[] name, int nameStart, int nameEnd,
1834                         boolean isCaseSensitive) {
1835
1836                 if (name == null)
1837                         return false; // null name cannot match
1838                 if (pattern == null)
1839                         return true; // null pattern is equivalent to '*'
1840                 int iPattern = patternStart;
1841                 int iName = nameStart;
1842
1843                 if (patternEnd < 0)
1844                         patternEnd = pattern.length;
1845                 if (nameEnd < 0)
1846                         nameEnd = name.length;
1847
1848                 /* check first segment */
1849                 char patternChar = 0;
1850                 while ((iPattern < patternEnd)
1851                                 && (patternChar = pattern[iPattern]) != '*') {
1852                         if (iName == nameEnd)
1853                                 return false;
1854                         if (patternChar != (isCaseSensitive ? name[iName] : Character
1855                                         .toLowerCase(name[iName]))
1856                                         && patternChar != '?') {
1857                                 return false;
1858                         }
1859                         iName++;
1860                         iPattern++;
1861                 }
1862                 /* check sequence of star+segment */
1863                 int segmentStart;
1864                 if (patternChar == '*') {
1865                         segmentStart = ++iPattern; // skip star
1866                 } else {
1867                         segmentStart = 0; // force iName check
1868                 }
1869                 int prefixStart = iName;
1870                 checkSegment: while (iName < nameEnd) {
1871                         if (iPattern == patternEnd) {
1872                                 iPattern = segmentStart; // mismatch - restart current
1873                                                                                         // segment
1874                                 iName = ++prefixStart;
1875                                 continue checkSegment;
1876                         }
1877                         /* segment is ending */
1878                         if ((patternChar = pattern[iPattern]) == '*') {
1879                                 segmentStart = ++iPattern; // skip start
1880                                 if (segmentStart == patternEnd) {
1881                                         return true;
1882                                 }
1883                                 prefixStart = iName;
1884                                 continue checkSegment;
1885                         }
1886                         /* check current name character */
1887                         if ((isCaseSensitive ? name[iName] : Character
1888                                         .toLowerCase(name[iName])) != patternChar
1889                                         && patternChar != '?') {
1890                                 iPattern = segmentStart; // mismatch - restart current
1891                                                                                         // segment
1892                                 iName = ++prefixStart;
1893                                 continue checkSegment;
1894                         }
1895                         iName++;
1896                         iPattern++;
1897                 }
1898
1899                 return (segmentStart == patternEnd)
1900                                 || (iName == nameEnd && iPattern == patternEnd)
1901                                 || (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
1902         }
1903
1904         /**
1905          * Answers true if the pattern matches the filepath using the pathSepatator,
1906          * false otherwise.
1907          * 
1908          * Path char[] pattern matching, accepting wild-cards '**', '*' and '?'
1909          * (using Ant directory tasks conventions, also see
1910          * "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes").
1911          * Path pattern matching is enhancing regular pattern matching in supporting
1912          * extra rule where '**' represent any folder combination. Special rules: -
1913          * foo\ is equivalent to foo\** - *.php is equivalent to **\*.php When not
1914          * case sensitive, the pattern is assumed to already be lowercased, the name
1915          * will be lowercased character per character as comparing.
1916          * 
1917          * @param pattern
1918          *            the given pattern
1919          * @param filepath
1920          *            the given path
1921          * @param isCaseSensitive
1922          *            to find out whether or not the matching should be case
1923          *            sensitive
1924          * @param pathSeparator
1925          *            the given path separator
1926          * @return true if the pattern matches the filepath using the pathSepatator,
1927          *         false otherwise
1928          */
1929         public static final boolean pathMatch(char[] pattern, char[] filepath,
1930                         boolean isCaseSensitive, char pathSeparator) {
1931
1932                 if (filepath == null)
1933                         return false; // null name cannot match
1934                 if (pattern == null)
1935                         return true; // null pattern is equivalent to '*'
1936
1937                 // special case: pattern foo is equivalent to **\foo (not absolute)
1938                 boolean freeLeadingDoubleStar;
1939
1940                 // offsets inside pattern
1941                 int pSegmentStart, pLength = pattern.length;
1942
1943                 if (freeLeadingDoubleStar = pattern[0] != pathSeparator) {
1944                         pSegmentStart = 0;
1945                 } else {
1946                         pSegmentStart = 1;
1947                 }
1948                 int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
1949                                 pSegmentStart + 1);
1950                 if (pSegmentEnd < 0)
1951                         pSegmentEnd = pLength;
1952
1953                 // special case: pattern foo\ is equivalent to foo\**
1954                 boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator;
1955
1956                 // offsets inside filepath
1957                 int fSegmentStart, fLength = filepath.length;
1958                 if (filepath[0] != pathSeparator) {
1959                         fSegmentStart = 0;
1960                 } else {
1961                         fSegmentStart = 1;
1962                 }
1963                 if (fSegmentStart != pSegmentStart) {
1964                         return false; // both must start with a separator or none.
1965                 }
1966                 int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath,
1967                                 fSegmentStart + 1);
1968                 if (fSegmentEnd < 0)
1969                         fSegmentEnd = fLength;
1970
1971                 // first segments
1972                 while (pSegmentStart < pLength
1973                                 && !freeLeadingDoubleStar
1974                                 && !(pSegmentEnd == pLength && freeTrailingDoubleStar || (pSegmentEnd == pSegmentStart + 2
1975                                                 && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*'))) {
1976
1977                         if (fSegmentStart >= fLength)
1978                                 return false;
1979                         if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd,
1980                                         filepath, fSegmentStart, fSegmentEnd, isCaseSensitive)) {
1981                                 return false;
1982                         }
1983
1984                         // jump to next segment
1985                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
1986                                         pSegmentStart = pSegmentEnd + 1);
1987                         // skip separator
1988                         if (pSegmentEnd < 0)
1989                                 pSegmentEnd = pLength;
1990
1991                         fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath,
1992                                         fSegmentStart = fSegmentEnd + 1);
1993                         // skip separator
1994                         if (fSegmentEnd < 0)
1995                                 fSegmentEnd = fLength;
1996                 }
1997
1998                 /* check sequence of doubleStar+segment */
1999                 int pSegmentRestart;
2000                 if ((pSegmentStart >= pLength && freeTrailingDoubleStar)
2001                                 || (pSegmentEnd == pSegmentStart + 2
2002                                                 && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*')) {
2003                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
2004                                         pSegmentStart = pSegmentEnd + 1);
2005                         // skip separator
2006                         if (pSegmentEnd < 0)
2007                                 pSegmentEnd = pLength;
2008                         pSegmentRestart = pSegmentStart;
2009                 } else {
2010                         pSegmentRestart = 0; // force fSegmentStart check
2011                 }
2012                 int fSegmentRestart = fSegmentStart;
2013                 checkSegment: while (fSegmentStart < fLength) {
2014
2015                         if (pSegmentStart >= pLength) {
2016                                 if (freeTrailingDoubleStar)
2017                                         return true;
2018                                 // mismatch - restart current path segment
2019                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
2020                                                 pSegmentStart = pSegmentRestart);
2021                                 if (pSegmentEnd < 0)
2022                                         pSegmentEnd = pLength;
2023
2024                                 fSegmentRestart = CharOperation.indexOf(pathSeparator,
2025                                                 filepath, fSegmentRestart + 1);
2026                                 // skip separator
2027                                 if (fSegmentRestart < 0) {
2028                                         fSegmentRestart = fLength;
2029                                 } else {
2030                                         fSegmentRestart++;
2031                                 }
2032                                 fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath,
2033                                                 fSegmentStart = fSegmentRestart);
2034                                 if (fSegmentEnd < 0)
2035                                         fSegmentEnd = fLength;
2036                                 continue checkSegment;
2037                         }
2038
2039                         /* path segment is ending */
2040                         if (pSegmentEnd == pSegmentStart + 2
2041                                         && pattern[pSegmentStart] == '*'
2042                                         && pattern[pSegmentStart + 1] == '*') {
2043                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
2044                                                 pSegmentStart = pSegmentEnd + 1);
2045                                 // skip separator
2046                                 if (pSegmentEnd < 0)
2047                                         pSegmentEnd = pLength;
2048                                 pSegmentRestart = pSegmentStart;
2049                                 fSegmentRestart = fSegmentStart;
2050                                 if (pSegmentStart >= pLength)
2051                                         return true;
2052                                 continue checkSegment;
2053                         }
2054                         /* chech current path segment */
2055                         if (!CharOperation.match(pattern, pSegmentStart, pSegmentEnd,
2056                                         filepath, fSegmentStart, fSegmentEnd, isCaseSensitive)) {
2057                                 // mismatch - restart current path segment
2058                                 pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
2059                                                 pSegmentStart = pSegmentRestart);
2060                                 if (pSegmentEnd < 0)
2061                                         pSegmentEnd = pLength;
2062
2063                                 fSegmentRestart = CharOperation.indexOf(pathSeparator,
2064                                                 filepath, fSegmentRestart + 1);
2065                                 // skip separator
2066                                 if (fSegmentRestart < 0) {
2067                                         fSegmentRestart = fLength;
2068                                 } else {
2069                                         fSegmentRestart++;
2070                                 }
2071                                 fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath,
2072                                                 fSegmentStart = fSegmentRestart);
2073                                 if (fSegmentEnd < 0)
2074                                         fSegmentEnd = fLength;
2075                                 continue checkSegment;
2076                         }
2077                         // jump to next segment
2078                         pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern,
2079                                         pSegmentStart = pSegmentEnd + 1);
2080                         // skip separator
2081                         if (pSegmentEnd < 0)
2082                                 pSegmentEnd = pLength;
2083
2084                         fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath,
2085                                         fSegmentStart = fSegmentEnd + 1);
2086                         // skip separator
2087                         if (fSegmentEnd < 0)
2088                                 fSegmentEnd = fLength;
2089                 }
2090
2091                 return (pSegmentRestart >= pSegmentEnd)
2092                                 || (fSegmentStart >= fLength && pSegmentStart >= pLength)
2093                                 || (pSegmentStart == pLength - 2
2094                                                 && pattern[pSegmentStart] == '*' && pattern[pSegmentStart + 1] == '*')
2095                                 || (pSegmentStart == pLength && freeTrailingDoubleStar);
2096         }
2097
2098         /**
2099          * Answers the number of occurrences of the given character in the given
2100          * array, 0 if any.
2101          * 
2102          * <br>
2103          * <br>
2104          * For example:
2105          * <ol>
2106          * <li>
2107          * 
2108          * <pre>
2109          *     toBeFound = 'b'
2110          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2111          *     result =&gt; 3
2112          * </pre>
2113          * 
2114          * </li>
2115          * <li>
2116          * 
2117          * <pre>
2118          *     toBeFound = 'c'
2119          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2120          *     result =&gt; 0
2121          * </pre>
2122          * 
2123          * </li>
2124          * </ol>
2125          * 
2126          * @param toBeFound
2127          *            the given character
2128          * @param array
2129          *            the given array
2130          * @return the number of occurrences of the given character in the given
2131          *         array, 0 if any
2132          * @exception NullPointerException
2133          *                if array is null
2134          */
2135         public static final int occurencesOf(char toBeFound, char[] array) {
2136                 int count = 0;
2137                 for (int i = 0; i < array.length; i++)
2138                         if (toBeFound == array[i])
2139                                 count++;
2140                 return count;
2141         }
2142
2143         /**
2144          * Answers the number of occurrences of the given character in the given
2145          * array starting at the given index, 0 if any.
2146          * 
2147          * <br>
2148          * <br>
2149          * For example:
2150          * <ol>
2151          * <li>
2152          * 
2153          * <pre>
2154          *     toBeFound = 'b'
2155          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2156          *     start = 2
2157          *     result =&gt; 2
2158          * </pre>
2159          * 
2160          * </li>
2161          * <li>
2162          * 
2163          * <pre>
2164          *     toBeFound = 'c'
2165          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2166          *     start = 0
2167          *     result =&gt; 0
2168          * </pre>
2169          * 
2170          * </li>
2171          * </ol>
2172          * 
2173          * @param toBeFound
2174          *            the given character
2175          * @param array
2176          *            the given array
2177          * @return the number of occurrences of the given character in the given
2178          *         array, 0 if any
2179          * @exception NullPointerException
2180          *                if array is null
2181          * @exception ArrayIndexOutOfBoundsException
2182          *                if start is lower than 0
2183          */
2184         public static final int occurencesOf(char toBeFound, char[] array, int start) {
2185                 int count = 0;
2186                 for (int i = start; i < array.length; i++)
2187                         if (toBeFound == array[i])
2188                                 count++;
2189                 return count;
2190         }
2191
2192         /**
2193          * Answers true if the given name starts with the given prefix, false
2194          * otherwise. The comparison is case sensitive. <br>
2195          * <br>
2196          * For example:
2197          * <ol>
2198          * <li>
2199          * 
2200          * <pre>
2201          *     prefix = { 'a' , 'b' }
2202          *     name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2203          *     result =&gt; true
2204          * </pre>
2205          * 
2206          * </li>
2207          * <li>
2208          * 
2209          * <pre>
2210          *     prefix = { 'a' , 'c' }
2211          *     name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2212          *     result =&gt; false
2213          * </pre>
2214          * 
2215          * </li>
2216          * </ol>
2217          * 
2218          * @param prefix
2219          *            the given prefix
2220          * @param name
2221          *            the given name
2222          * @return true if the given name starts with the given prefix, false
2223          *         otherwise
2224          * @exception NullPointerException
2225          *                if the given name is null or if the given prefix is null
2226          */
2227         public static final boolean prefixEquals(char[] prefix, char[] name) {
2228
2229                 int max = prefix.length;
2230                 if (name.length < max)
2231                         return false;
2232                 for (int i = max; --i >= 0;)
2233                         // assumes the prefix is not larger than the name
2234                         if (prefix[i] != name[i])
2235                                 return false;
2236                 return true;
2237         }
2238
2239         /**
2240          * Answers true if the given name starts with the given prefix, false
2241          * otherwise. isCaseSensitive is used to find out whether or not the
2242          * comparison should be case sensitive. <br>
2243          * <br>
2244          * For example:
2245          * <ol>
2246          * <li>
2247          * 
2248          * <pre>
2249          *     prefix = { 'a' , 'B' }
2250          *     name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2251          *     isCaseSensitive = false
2252          *     result =&gt; true
2253          * </pre>
2254          * 
2255          * </li>
2256          * <li>
2257          * 
2258          * <pre>
2259          *     prefix = { 'a' , 'B' }
2260          *     name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2261          *     isCaseSensitive = true
2262          *     result =&gt; false
2263          * </pre>
2264          * 
2265          * </li>
2266          * </ol>
2267          * 
2268          * @param prefix
2269          *            the given prefix
2270          * @param name
2271          *            the given name
2272          * @param isCaseSensitive
2273          *            to find out whether or not the comparison should be case
2274          *            sensitive
2275          * @return true if the given name starts with the given prefix, false
2276          *         otherwise
2277          * @exception NullPointerException
2278          *                if the given name is null or if the given prefix is null
2279          */
2280         public static final boolean prefixEquals(char[] prefix, char[] name,
2281                         boolean isCaseSensitive) {
2282
2283                 int max = prefix.length;
2284                 if (name.length < max)
2285                         return false;
2286                 if (isCaseSensitive) {
2287                         for (int i = max; --i >= 0;)
2288                                 // assumes the prefix is not larger than the name
2289                                 if (prefix[i] != name[i])
2290                                         return false;
2291                         return true;
2292                 }
2293
2294                 for (int i = max; --i >= 0;)
2295                         // assumes the prefix is not larger than the name
2296                         if (Character.toLowerCase(prefix[i]) != Character
2297                                         .toLowerCase(name[i]))
2298                                 return false;
2299                 return true;
2300         }
2301
2302         /**
2303          * Replace all occurrence of the character to be replaced with the
2304          * remplacement character in the given array. <br>
2305          * <br>
2306          * For example:
2307          * <ol>
2308          * <li>
2309          * 
2310          * <pre>
2311          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2312          *     toBeReplaced = 'b'
2313          *     replacementChar = 'a'
2314          *     result =&gt; No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
2315          * </pre>
2316          * 
2317          * </li>
2318          * <li>
2319          * 
2320          * <pre>
2321          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2322          *     toBeReplaced = 'c'
2323          *     replacementChar = 'a'
2324          *     result =&gt; No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' }
2325          * </pre>
2326          * 
2327          * </li>
2328          * </ol>
2329          * 
2330          * @param array
2331          *            the given array
2332          * @param toBeReplaced
2333          *            the character to be replaced
2334          * @param replacementChar
2335          *            the replacement character
2336          * @exception NullPointerException
2337          *                if the given array is null
2338          */
2339         public static final void replace(char[] array, char toBeReplaced,
2340                         char replacementChar) {
2341                 if (toBeReplaced != replacementChar) {
2342                         for (int i = 0, max = array.length; i < max; i++) {
2343                                 if (array[i] == toBeReplaced)
2344                                         array[i] = replacementChar;
2345                         }
2346                 }
2347         }
2348
2349         /**
2350          * Answers a new array of characters with substitutions. No side-effect is
2351          * operated on the original array, in case no substitution happened, then
2352          * the result is the same as the original one. <br>
2353          * <br>
2354          * For example:
2355          * <ol>
2356          * <li>
2357          * 
2358          * <pre>
2359          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2360          *     toBeReplaced = { 'b' }
2361          *     replacementChar = { 'a', 'a' }
2362          *     result =&gt; { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
2363          * </pre>
2364          * 
2365          * </li>
2366          * <li>
2367          * 
2368          * <pre>
2369          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2370          *     toBeReplaced = { 'c' }
2371          *     replacementChar = { 'a' }
2372          *     result =&gt; { 'a' , 'b', 'b', 'a', 'b', 'a' }
2373          * </pre>
2374          * 
2375          * </li>
2376          * </ol>
2377          * 
2378          * @param the
2379          *            given array
2380          * @param toBeReplaced
2381          *            characters to be replaced
2382          * @param the
2383          *            replacement characters
2384          * @return a new array of characters with substitutions or the given array
2385          *         if none
2386          * @exception NullPointerException
2387          *                if the given array is null
2388          */
2389         public static final char[] replace(char[] array, char[] toBeReplaced,
2390                         char[] replacementChars) {
2391
2392                 int max = array.length;
2393                 int replacedLength = toBeReplaced.length;
2394                 int replacementLength = replacementChars.length;
2395
2396                 int[] starts = new int[5];
2397                 int occurrenceCount = 0;
2398
2399                 if (!equals(toBeReplaced, replacementChars)) {
2400
2401                         next: for (int i = 0; i < max; i++) {
2402                                 int j = 0;
2403                                 while (j < replacedLength) {
2404                                         if (i + j == max)
2405                                                 continue next;
2406                                         if (array[i + j] != toBeReplaced[j++])
2407                                                 continue next;
2408                                 }
2409                                 if (occurrenceCount == starts.length) {
2410                                         System.arraycopy(starts, 0,
2411                                                         starts = new int[occurrenceCount * 2], 0,
2412                                                         occurrenceCount);
2413                                 }
2414                                 starts[occurrenceCount++] = i;
2415                         }
2416                 }
2417                 if (occurrenceCount == 0)
2418                         return array;
2419                 char[] result = new char[max + occurrenceCount
2420                                 * (replacementLength - replacedLength)];
2421                 int inStart = 0, outStart = 0;
2422                 for (int i = 0; i < occurrenceCount; i++) {
2423                         int offset = starts[i] - inStart;
2424                         System.arraycopy(array, inStart, result, outStart, offset);
2425                         inStart += offset;
2426                         outStart += offset;
2427                         System.arraycopy(replacementChars, 0, result, outStart,
2428                                         replacementLength);
2429                         inStart += replacedLength;
2430                         outStart += replacementLength;
2431                 }
2432                 System.arraycopy(array, inStart, result, outStart, max - inStart);
2433                 return result;
2434         }
2435
2436         /**
2437          * Return a new array which is the split of the given array using the given
2438          * divider and triming each subarray to remove whitespaces equals to ' '.
2439          * <br>
2440          * <br>
2441          * For example:
2442          * <ol>
2443          * <li>
2444          * 
2445          * <pre>
2446          *     divider = 'b'
2447          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2448          *     result =&gt; { { 'a' }, {  }, { 'a' }, { 'a' } }
2449          * </pre>
2450          * 
2451          * </li>
2452          * <li>
2453          * 
2454          * <pre>
2455          *     divider = 'c'
2456          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2457          *     result =&gt; { { 'a', 'b', 'b', 'a', 'b', 'a' } }
2458          * </pre>
2459          * 
2460          * </li>
2461          * <li>
2462          * 
2463          * <pre>
2464          *     divider = 'b'
2465          *     array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
2466          *     result =&gt; { { 'a' }, {  }, { 'a' }, { 'a' } }
2467          * </pre>
2468          * 
2469          * </li>
2470          * <li>
2471          * 
2472          * <pre>
2473          *     divider = 'c'
2474          *     array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
2475          *     result =&gt; { { 'a', 'b', 'b', 'a', 'b', 'a' } }
2476          * </pre>
2477          * 
2478          * </li>
2479          * </ol>
2480          * 
2481          * @param divider
2482          *            the given divider
2483          * @param array
2484          *            the given array
2485          * @return a new array which is the split of the given array using the given
2486          *         divider and triming each subarray to remove whitespaces equals to ' '
2487          */
2488         public static final char[][] splitAndTrimOn(char divider, char[] array) {
2489                 int length = array == null ? 0 : array.length;
2490                 if (length == 0)
2491                         return NO_CHAR_CHAR;
2492
2493                 int wordCount = 1;
2494                 for (int i = 0; i < length; i++)
2495                         if (array[i] == divider)
2496                                 wordCount++;
2497                 char[][] split = new char[wordCount][];
2498                 int last = 0, currentWord = 0;
2499                 for (int i = 0; i < length; i++) {
2500                         if (array[i] == divider) {
2501                                 int start = last, end = i - 1;
2502                                 while (start < i && array[start] == ' ')
2503                                         start++;
2504                                 while (end > start && array[end] == ' ')
2505                                         end--;
2506                                 split[currentWord] = new char[end - start + 1];
2507                                 System.arraycopy(array, start, split[currentWord++], 0, end
2508                                                 - start + 1);
2509                                 last = i + 1;
2510                         }
2511                 }
2512                 int start = last, end = length - 1;
2513                 while (start < length && array[start] == ' ')
2514                         start++;
2515                 while (end > start && array[end] == ' ')
2516                         end--;
2517                 split[currentWord] = new char[end - start + 1];
2518                 System
2519                                 .arraycopy(array, start, split[currentWord++], 0, end - start
2520                                                 + 1);
2521                 return split;
2522         }
2523
2524         /**
2525          * Return a new array which is the split of the given array using the given
2526          * divider. <br>
2527          * <br>
2528          * For example:
2529          * <ol>
2530          * <li>
2531          * 
2532          * <pre>
2533          *     divider = 'b'
2534          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2535          *     result =&gt; { { 'a' }, {  }, { 'a' }, { 'a' } }
2536          * </pre>
2537          * 
2538          * </li>
2539          * <li>
2540          * 
2541          * <pre>
2542          *     divider = 'c'
2543          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2544          *     result =&gt; { { 'a', 'b', 'b', 'a', 'b', 'a' } }
2545          * </pre>
2546          * 
2547          * </li>
2548          * <li>
2549          * 
2550          * <pre>
2551          *     divider = 'c'
2552          *     array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
2553          *     result =&gt; { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
2554          * </pre>
2555          * 
2556          * </li>
2557          * </ol>
2558          * 
2559          * @param divider
2560          *            the given divider
2561          * @param array
2562          *            the given array
2563          * @return a new array which is the split of the given array using the given
2564          *         divider
2565          */
2566         public static final char[][] splitOn(char divider, char[] array) {
2567                 int length = array == null ? 0 : array.length;
2568                 if (length == 0)
2569                         return NO_CHAR_CHAR;
2570
2571                 int wordCount = 1;
2572                 for (int i = 0; i < length; i++)
2573                         if (array[i] == divider)
2574                                 wordCount++;
2575                 char[][] split = new char[wordCount][];
2576                 int last = 0, currentWord = 0;
2577                 for (int i = 0; i < length; i++) {
2578                         if (array[i] == divider) {
2579                                 split[currentWord] = new char[i - last];
2580                                 System
2581                                                 .arraycopy(array, last, split[currentWord++], 0, i
2582                                                                 - last);
2583                                 last = i + 1;
2584                         }
2585                 }
2586                 split[currentWord] = new char[length - last];
2587                 System.arraycopy(array, last, split[currentWord], 0, length - last);
2588                 return split;
2589         }
2590
2591         /**
2592          * Return a new array which is the split of the given array using the given
2593          * divider. The given end is exclusive and the given start is inclusive.
2594          * <br>
2595          * <br>
2596          * For example:
2597          * <ol>
2598          * <li>
2599          * 
2600          * <pre>
2601          *     divider = 'b'
2602          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2603          *     start = 2
2604          *     end = 5
2605          *     result =&gt; { {  }, {  }, { 'a' } }
2606          * </pre>
2607          * 
2608          * </li>
2609          * </ol>
2610          * 
2611          * @param divider
2612          *            the given divider
2613          * @param array
2614          *            the given array
2615          * @param start
2616          *            the given starting index
2617          * @param end
2618          *            the given ending index
2619          * @return a new array which is the split of the given array using the given
2620          *         divider
2621          * @exception ArrayIndexOutOfBoundsException
2622          *                if start is lower than 0 or end is greater than the array
2623          *                length
2624          */
2625         public static final char[][] splitOn(char divider, char[] array, int start,
2626                         int end) {
2627                 int length = array == null ? 0 : array.length;
2628                 if (length == 0 || start > end)
2629                         return NO_CHAR_CHAR;
2630
2631                 int wordCount = 1;
2632                 for (int i = start; i < end; i++)
2633                         if (array[i] == divider)
2634                                 wordCount++;
2635                 char[][] split = new char[wordCount][];
2636                 int last = start, currentWord = 0;
2637                 for (int i = start; i < end; i++) {
2638                         if (array[i] == divider) {
2639                                 split[currentWord] = new char[i - last];
2640                                 System
2641                                                 .arraycopy(array, last, split[currentWord++], 0, i
2642                                                                 - last);
2643                                 last = i + 1;
2644                         }
2645                 }
2646                 split[currentWord] = new char[end - last];
2647                 System.arraycopy(array, last, split[currentWord], 0, end - last);
2648                 return split;
2649         }
2650
2651         /**
2652          * Answers true if the given array starts with the given characters, false
2653          * otherwise. The comparison is case sensitive. <br>
2654          * <br>
2655          * For example:
2656          * <ol>
2657          * <li>
2658          * 
2659          * <pre>
2660          *     toBeFound = { 'a' , 'b' }
2661          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2662          *     result =&gt; true
2663          * </pre>
2664          * 
2665          * </li>
2666          * <li>
2667          * 
2668          * <pre>
2669          *     toBeFound = { 'a' , 'c' }
2670          *     array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
2671          *     result =&gt; false
2672          * </pre>
2673          * 
2674          * </li>
2675          * </ol>
2676          * 
2677          * @param array
2678          *            the given array
2679          * @param toBeFound
2680          *            the given character to search
2681          * @return true if the given array starts with the given characters, false
2682          *         otherwise
2683          * @exception NullPointerException
2684          *                if the given array is null or if the given characters
2685          *                array to be found is null
2686          */
2687         public static final boolean startsWith(char[] array, char[] toBeFound) {
2688                 int i = toBeFound.length;
2689                 if (i > array.length)
2690                         return false;
2691                 while (--i >= 0)
2692                         if (toBeFound[i] != array[i])
2693                                 return false;
2694                 return true;
2695         }
2696
2697         /**
2698          * Answers a new array which is a copy of the given array starting at the
2699          * given start and ending at the given end. The given start is inclusive and
2700          * the given end is exclusive. Answers null if start is greater than end, if
2701          * start is lower than 0 or if end is greater than the length of the given
2702          * array. If end equals -1, it is converted to the array length. <br>
2703          * <br>
2704          * For example:
2705          * <ol>
2706          * <li>
2707          * 
2708          * <pre>
2709          *     array = { { 'a' } , { 'b' } }
2710          *     start = 0
2711          *     end = 1
2712          *     result =&gt; { { 'a' } }
2713          * </pre>
2714          * 
2715          * </li>
2716          * <li>
2717          * 
2718          * <pre>
2719          *     array = { { 'a' } , { 'b' } }
2720          *     start = 0
2721          *     end = -1
2722          *     result =&gt; { { 'a' }, { 'b' } }
2723          * </pre>
2724          * 
2725          * </li>
2726          * </ol>
2727          * 
2728          * @param array
2729          *            the given array
2730          * @param start
2731          *            the given starting index
2732          * @param end
2733          *            the given ending index
2734          * @return a new array which is a copy of the given array starting at the
2735          *         given start and ending at the given end
2736          * @exception NullPointerException
2737          *                if the given array is null
2738          */
2739         public static final char[][] subarray(char[][] array, int start, int end) {
2740                 if (end == -1)
2741                         end = array.length;
2742                 if (start > end)
2743                         return null;
2744                 if (start < 0)
2745                         return null;
2746                 if (end > array.length)
2747                         return null;
2748
2749                 char[][] result = new char[end - start][];
2750                 System.arraycopy(array, start, result, 0, end - start);
2751                 return result;
2752         }
2753
2754         /**
2755          * Answers a new array which is a copy of the given array starting at the
2756          * given start and ending at the given end. The given start is inclusive and
2757          * the given end is exclusive. Answers null if start is greater than end, if
2758          * start is lower than 0 or if end is greater than the length of the given
2759          * array. If end equals -1, it is converted to the array length. <br>
2760          * <br>
2761          * For example:
2762          * <ol>
2763          * <li>
2764          * 
2765          * <pre>
2766          *     array = { 'a' , 'b' }
2767          *     start = 0
2768          *     end = 1
2769          *     result =&gt; { 'a' }
2770          * </pre>
2771          * 
2772          * </li>
2773          * <li>
2774          * 
2775          * <pre>
2776          *     array = { 'a', 'b' }
2777          *     start = 0
2778          *     end = -1
2779          *     result =&gt; { 'a' , 'b' }
2780          * </pre>
2781          * 
2782          * </li>
2783          * </ol>
2784          * 
2785          * @param array
2786          *            the given array
2787          * @param start
2788          *            the given starting index
2789          * @param end
2790          *            the given ending index
2791          * @return a new array which is a copy of the given array starting at the
2792          *         given start and ending at the given end
2793          * @exception NullPointerException
2794          *                if the given array is null
2795          */
2796         public static final char[] subarray(char[] array, int start, int end) {
2797                 if (end == -1)
2798                         end = array.length;
2799                 if (start > end)
2800                         return null;
2801                 if (start < 0)
2802                         return null;
2803                 if (end > array.length)
2804                         return null;
2805
2806                 char[] result = new char[end - start];
2807                 System.arraycopy(array, start, result, 0, end - start);
2808                 return result;
2809         }
2810
2811         /**
2812          * Answers the result of a char[] conversion to lowercase. Answers null if
2813          * the given chars array is null. <br>
2814          * NOTE: if no conversion was necessary, then answers back the argument one.
2815          * <br>
2816          * <br>
2817          * For example:
2818          * <ol>
2819          * <li>
2820          * 
2821          * <pre>
2822          *     chars = { 'a' , 'b' }
2823          *     result =&gt; { 'a' , 'b' }
2824          * </pre>
2825          * 
2826          * </li>
2827          * <li>
2828          * 
2829          * <pre>
2830          *     array = { 'A', 'b' }
2831          *     result =&gt; { 'a' , 'b' }
2832          * </pre>
2833          * 
2834          * </li>
2835          * </ol>
2836          * 
2837          * @param chars
2838          *            the chars to convert
2839          * @return the result of a char[] conversion to lowercase
2840          */
2841         final static public char[] toLowerCase(char[] chars) {
2842                 if (chars == null)
2843                         return null;
2844                 int length = chars.length;
2845                 char[] lowerChars = null;
2846                 for (int i = 0; i < length; i++) {
2847                         char c = chars[i];
2848                         char lc = Character.toLowerCase(c);
2849                         if ((c != lc) || (lowerChars != null)) {
2850                                 if (lowerChars == null) {
2851                                         System.arraycopy(chars, 0, lowerChars = new char[length],
2852                                                         0, i);
2853                                 }
2854                                 lowerChars[i] = lc;
2855                         }
2856                 }
2857                 return lowerChars == null ? chars : lowerChars;
2858         }
2859
2860         /**
2861          * Answers a new array removing leading and trailing spaces (' '). Answers
2862          * the given array if there is no space characters to remove. <br>
2863          * <br>
2864          * For example:
2865          * <ol>
2866          * <li>
2867          * 
2868          * <pre>
2869          *     chars = { ' ', 'a' , 'b', ' ',  ' ' }
2870          *     result =&gt; { 'a' , 'b' }
2871          * </pre>
2872          * 
2873          * </li>
2874          * <li>
2875          * 
2876          * <pre>
2877          *     array = { 'A', 'b' }
2878          *     result =&gt; { 'A' , 'b' }
2879          * </pre>
2880          * 
2881          * </li>
2882          * </ol>
2883          * 
2884          * @param chars
2885          *            the given array
2886          * @return a new array removing leading and trailing spaces (' ')
2887          */
2888         final static public char[] trim(char[] chars) {
2889
2890                 if (chars == null)
2891                         return null;
2892
2893                 int start = 0, length = chars.length, end = length - 1;
2894                 while (start < length && chars[start] == ' ') {
2895                         start++;
2896                 }
2897                 while (end > start && chars[end] == ' ') {
2898                         end--;
2899                 }
2900                 if (start != 0 || end != length - 1) {
2901                         return subarray(chars, start, end + 1);
2902                 }
2903                 return chars;
2904         }
2905
2906         /**
2907          * Answers a string which is the concatenation of the given array using the
2908          * '.' as a separator. <br>
2909          * <br>
2910          * For example:
2911          * <ol>
2912          * <li>
2913          * 
2914          * <pre>
2915          *     array = { { 'a' } , { 'b' } }
2916          *     result =&gt; &quot;a.b&quot;
2917          * </pre>
2918          * 
2919          * </li>
2920          * <li>
2921          * 
2922          * <pre>
2923          *     array = { { ' ',  'a' } , { 'b' } }
2924          *     result =&gt; &quot; a.b&quot;
2925          * </pre>
2926          * 
2927          * </li>
2928          * </ol>
2929          * 
2930          * @param chars
2931          *            the given array
2932          * @return a string which is the concatenation of the given array using the
2933          *         '.' as a separator
2934          */
2935         final static public String toString(char[][] array) {
2936                 char[] result = concatWith(array, '.');
2937                 return new String(result);
2938         }
2939 }