removed Makefile; lifted repo/org.ibex.tool/src/ to src/
[org.ibex.tool.git] / src / org / eclipse / jdt / core / compiler / CharOperation.java
diff --git a/src/org/eclipse/jdt/core/compiler/CharOperation.java b/src/org/eclipse/jdt/core/compiler/CharOperation.java
new file mode 100644 (file)
index 0000000..07d23e3
--- /dev/null
@@ -0,0 +1,2686 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2004 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.jdt.core.compiler;
+
+/**
+ * This class is a collection of helper methods to manipulate char arrays.
+ * 
+ * @since 2.1
+ */
+public final class CharOperation {
+
+       /**
+        * Constant for an empty char array
+        */
+       public static final char[] NO_CHAR = new char[0];
+
+       /**
+        * Constant for an empty char array with two dimensions.
+        */
+       public static final char[][] NO_CHAR_CHAR = new char[0][];
+       
+       /**
+        * Answers a new array with appending the suffix character at the end of the array.
+        * <br>
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    array = { 'a', 'b' }
+        *    suffix = 'c'
+        *    => result = { 'a', 'b' , 'c' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = null
+        *    suffix = 'c'
+        *    => result = { 'c' }
+        * </pre></li>
+        * </ol>
+        * 
+        * @param array the array that is concanated with the suffix character
+        * @param suffix the suffix character
+        * @return the new array
+        */
+       public static final char[] append(char[] array, char suffix) {
+               if (array == null)
+                       return new char[] { suffix };
+               int length = array.length;
+               System.arraycopy(array, 0, array = new char[length + 1], 0, length);
+               array[length] = suffix;
+               return array;
+       }
+       /**
+        * Append the given subarray to the target array starting at the given index in the target array.
+        * The start of the subarray is inclusive, the end is exclusive.
+        * Answers a new target array if it needs to grow, otherwise answers the same target array.
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    target = { 'a', 'b', '0' }
+        *    index = 2
+        *    array = { 'c', 'd' }
+        *    start = 0
+        *    end = 1
+        *    => result = { 'a', 'b' , 'c' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    target = { 'a', 'b' }
+        *    index = 2
+        *    array = { 'c', 'd' }
+        *    start = 0
+        *    end = 1
+        *    => result = { 'a', 'b' , 'c', '0', '0' , '0' } (new array)
+        * </pre></li>
+        * <li><pre>
+        *    target = { 'a', 'b', 'c' }
+        *    index = 1
+        *    array = { 'c', 'd', 'e', 'f' }
+        *    start = 1
+        *    end = 4
+        *    => result = { 'a', 'd' , 'e', 'f', '0', '0', '0', '0' } (new array)
+        * </pre></li>
+        * </ol>
+        * 
+        * @param target the given target
+        * @param index the given index
+        * @param array the given array
+        * @param start the given start index
+        * @param end the given end index
+        * 
+        * @return the new array
+        * @throws NullPointerException if the target array is null
+        */
+       public static final char[] append(char[] target, int index, char[] array, int start, int end) {
+               int targetLength = target.length;
+               int subLength = end-start;
+               int newTargetLength = subLength+index;
+               if (newTargetLength > targetLength) {
+                       System.arraycopy(target, 0, target = new char[newTargetLength*2], 0, index);
+               }
+               System.arraycopy(array, start, target, index, subLength);
+               return target;
+       }
+
+       /**
+        * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
+        * If the first array is null, then the second array is returned.
+        * If the second array is null, then the first array is returned.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    => result = null
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { ' a' } }
+        *    second = null
+        *    => result = { { ' a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = null
+        *    second = { { ' a' } }
+        *    => result = { { ' a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { ' b' } }
+        *    second = { { ' a' } }
+        *    => result = { { ' b' }, { ' a' } }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param second the second array to concatenate
+        * @return the concatenation of the two arrays, or null if the two arrays are null.
+        */
+       public static final char[][] arrayConcat(char[][] first, char[][] second) {
+               if (first == null)
+                       return second;
+               if (second == null)
+                       return first;
+
+               int length1 = first.length;
+               int length2 = second.length;
+               char[][] result = new char[length1 + length2][];
+               System.arraycopy(first, 0, result, 0, length1);
+               System.arraycopy(second, 0, result, length1, length2);
+               return result;
+       }
+       /**
+        * Returns the char arrays as an array of Strings
+        * 
+        * @param charArrays the char array to convert
+        * @return the char arrays as an array of Strings or null if the given char arrays is null.
+        * @since 3.0
+        */
+       public static String[] charArrayToStringArray(char[][] charArrays) {
+               if (charArrays == null) {
+                       return null;
+               }
+               String[] strings= new String[charArrays.length];
+               for (int i= 0; i < charArrays.length; i++) {
+                       strings[i]= new String(charArrays[i]);
+               }
+               return strings;
+       }
+       /**
+        * Returns the char array as a String
+
+        * @param charArray the char array to convert
+        * @return the char array as a String or null if the given char array is null.
+        * @since 3.0
+        */
+       public static String charToString(char[] charArray) {
+               if (charArray == null) return null;
+               return new String(charArray);
+       }
+
+       /**
+        * Answers a new array adding the second array at the end of first array.
+        * It answers null if the first and second are null.
+        * If the first array is null, then a new array char[][] is created with second.
+        * If the second array is null, then the first array is returned.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = { 'a' }
+        *    => result = { { ' a' } }
+        * </pre>
+        * <li><pre>
+        *    first = { { ' a' } }
+        *    second = null
+        *    => result = { { ' a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { ' a' } }
+        *    second = { ' b' }
+        *    => result = { { ' a' } , { ' b' } }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param second the array to add at the end of the first array
+        * @return a new array adding the second array at the end of first array, or null if the two arrays are null.
+        */
+       public static final char[][] arrayConcat(char[][] first, char[] second) {
+               if (second == null)
+                       return first;
+               if (first == null)
+                       return new char[][] { second };
+
+               int length = first.length;
+               char[][] result = new char[length + 1][];
+               System.arraycopy(first, 0, result, 0, length);
+               result[length] = second;
+               return result;
+       }
+
+       /**
+        * Compares the contents of the two arrays array and prefix. Returns
+        * <ul>
+        * <li>zero if the array starts with the prefix contents</li>
+        * <li>the difference between the first two characters that are not equal </li>
+        * <li>one if array length is lower than the prefix length and that the prefix starts with the 
+        * array contents.</li>
+        * </ul>
+        * <p>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = null
+        *    prefix = null
+        *    => result = NullPointerException
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'b', 'c', 'd', 'e' }
+        *    prefix = { 'a', 'b', 'c'}
+        *    => result = 0
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'b', 'c', 'd', 'e' }
+        *    prefix = { 'a', 'B', 'c'}
+        *    => result = 32
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'd', 'b', 'c', 'd', 'e' }
+        *    prefix = { 'a', 'b', 'c'}
+        *    => result = 3
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'b', 'c', 'd', 'e' }
+        *    prefix = { 'd', 'b', 'c'}
+        *    => result = -3
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'a', 'c', 'd', 'e' }
+        *    prefix = { 'a', 'e', 'c'}
+        *    => result = -4
+        * </pre>
+        * </li>
+        * </ol>
+        * </p>
+        * 
+        * @param array the given array
+        * @param prefix the given prefix
+        * @return the result of the comparison (>=0 if array>prefix)
+        * @throws NullPointerException if either array or prefix is null
+        */
+       public static final int compareWith(char[] array, char[] prefix) {
+               int arrayLength = array.length;
+               int prefixLength = prefix.length;
+               int min = Math.min(arrayLength, prefixLength);
+               int i = 0;
+               while (min-- != 0) {
+                       char c1 = array[i];
+                       char c2 = prefix[i++];
+                       if (c1 != c2)
+                               return c1 - c2;
+               }
+               if (prefixLength == i)
+                       return 0;
+               return -1;      // array is shorter than prefix (e.g. array:'ab' < prefix:'abc').
+       }
+
+       /**
+        * Answers the concatenation of the two arrays. It answers null if the two arrays are null.
+        * If the first array is null, then the second array is returned.
+        * If the second array is null, then the first array is returned.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = { 'a' }
+        *    => result = { ' a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { ' a' }
+        *    second = null
+        *    => result = { ' a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { ' a' }
+        *    second = { ' b' }
+        *    => result = { ' a' , ' b' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param second the second array to concatenate
+        * @return the concatenation of the two arrays, or null if the two arrays are null.
+        */
+       public static final char[] concat(char[] first, char[] second) {
+               if (first == null)
+                       return second;
+               if (second == null)
+                       return first;
+
+               int length1 = first.length;
+               int length2 = second.length;
+               char[] result = new char[length1 + length2];
+               System.arraycopy(first, 0, result, 0, length1);
+               System.arraycopy(second, 0, result, length1, length2);
+               return result;
+       }
+
+       /**
+        * Answers the concatenation of the three arrays. It answers null if the three arrays are null.
+        * If first is null, it answers the concatenation of second and third.
+        * If second is null, it answers the concatenation of first and third.
+        * If third is null, it answers the concatenation of first and second.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = { 'a' }
+        *    third = { 'b' }
+        *    => result = { ' a', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = null
+        *    third = { 'b' }
+        *    => result = { ' a', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'b' }
+        *    third = null
+        *    => result = { ' a', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    third = null
+        *    => result = null
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'b' }
+        *    third = { 'c' }
+        *    => result = { 'a', 'b', 'c' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param second the second array to concatenate
+        * @param third the third array to concatenate
+        * 
+        * @return the concatenation of the three arrays, or null if the three arrays are null.
+        */
+       public static final char[] concat(
+               char[] first,
+               char[] second,
+               char[] third) {
+               if (first == null)
+                       return concat(second, third);
+               if (second == null)
+                       return concat(first, third);
+               if (third == null)
+                       return concat(first, second);
+
+               int length1 = first.length;
+               int length2 = second.length;
+               int length3 = third.length;
+               char[] result = new char[length1 + length2 + length3];
+               System.arraycopy(first, 0, result, 0, length1);
+               System.arraycopy(second, 0, result, length1, length2);
+               System.arraycopy(third, 0, result, length1 + length2, length3);
+               return result;
+       }
+
+       /**
+        * Answers the concatenation of the two arrays inserting the separator character between the two arrays.
+        * It answers null if the two arrays are null.
+        * If the first array is null, then the second array is returned.
+        * If the second array is null, then the first array is returned.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = { 'a' }
+        *    separator = '/'
+        *    => result = { ' a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { ' a' }
+        *    second = null
+        *    separator = '/'
+        *    => result = { ' a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { ' a' }
+        *    second = { ' b' }
+        *    separator = '/'
+        *    => result = { ' a' , '/', 'b' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param second the second array to concatenate
+        * @param separator the character to insert
+        * @return the concatenation of the two arrays inserting the separator character 
+        * between the two arrays , or null if the two arrays are null.
+        */
+       public static final char[] concat(
+               char[] first,
+               char[] second,
+               char separator) {
+               if (first == null)
+                       return second;
+               if (second == null)
+                       return first;
+
+               int length1 = first.length;
+               if (length1 == 0)
+                       return second;
+               int length2 = second.length;
+               if (length2 == 0)
+                       return first;
+
+               char[] result = new char[length1 + length2 + 1];
+               System.arraycopy(first, 0, result, 0, length1);
+               result[length1] = separator;
+               System.arraycopy(second, 0, result, length1 + 1, length2);
+               return result;
+       }
+
+       /**
+        * Answers the concatenation of the three arrays inserting the sep1 character between the 
+        * two arrays and sep2 between the last two.
+        * It answers null if the three arrays are null.
+        * If the first array is null, then it answers the concatenation of second and third inserting
+        * the sep2 character between them.
+        * If the second array is null, then it answers the concatenation of first and third inserting
+        * the sep1 character between them.
+        * If the third array is null, then it answers the concatenation of first and second inserting
+        * the sep1 character between them.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    sep1 = '/'
+        *    second = { 'a' }
+        *    sep2 = ':'
+        *    third = { 'b' }
+        *    => result = { ' a' , ':', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    sep1 = '/'
+        *    second = null
+        *    sep2 = ':'
+        *    third = { 'b' }
+        *    => result = { ' a' , '/', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    sep1 = '/'
+        *    second = { 'b' }
+        *    sep2 = ':'
+        *    third = null
+        *    => result = { ' a' , '/', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    sep1 = '/'
+        *    second = { 'b' }
+        *    sep2 = ':'
+        *    third = { 'c' }
+        *    => result = { ' a' , '/', 'b' , ':', 'c' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array to concatenate
+        * @param sep1 the character to insert
+        * @param second the second array to concatenate
+        * @param sep2 the character to insert
+        * @param third the second array to concatenate
+        * @return the concatenation of the three arrays inserting the sep1 character between the 
+        * two arrays and sep2 between the last two.
+        */
+       public static final char[] concat(
+               char[] first,
+               char sep1,
+               char[] second,
+               char sep2,
+               char[] third) {
+               if (first == null)
+                       return concat(second, third, sep2);
+               if (second == null)
+                       return concat(first, third, sep1);
+               if (third == null)
+                       return concat(first, second, sep1);
+
+               int length1 = first.length;
+               int length2 = second.length;
+               int length3 = third.length;
+               char[] result = new char[length1 + length2 + length3 + 2];
+               System.arraycopy(first, 0, result, 0, length1);
+               result[length1] = sep1;
+               System.arraycopy(second, 0, result, length1 + 1, length2);
+               result[length1 + length2 + 1] = sep2;
+               System.arraycopy(third, 0, result, length1 + length2 + 2, length3);
+               return result;
+       }
+
+       /**
+        * Answers a new array with prepending the prefix character and appending the suffix 
+        * character at the end of the array. If array is null, it answers a new array containing the 
+        * prefix and the suffix characters.
+        * <br>
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    prefix = 'a'
+        *    array = { 'b' }
+        *    suffix = 'c'
+        *    => result = { 'a', 'b' , 'c' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    prefix = 'a'
+        *    array = null
+        *    suffix = 'c'
+        *    => result = { 'a', 'c' }
+        * </pre></li>
+        * </ol>
+        * 
+        * @param prefix the prefix character
+        * @param array the array that is concanated with the prefix and suffix characters
+        * @param suffix the suffix character
+        * @return the new array
+        */
+       public static final char[] concat(char prefix, char[] array, char suffix) {
+               if (array == null)
+                       return new char[] { prefix, suffix };
+
+               int length = array.length;
+               char[] result = new char[length + 2];
+               result[0] = prefix;
+               System.arraycopy(array, 0, result, 1, length);
+               result[length + 1] = suffix;
+               return result;
+       }
+       
+       /**
+        * Answers the concatenation of the given array parts using the given separator between each
+        * part and appending the given name at the end.
+        * <br>
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    name = { 'c' }
+        *    array = { { 'a' }, { 'b' } }
+        *    separator = '.'
+        *    => result = { 'a', '.', 'b' , '.', 'c' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    name = null
+        *    array = { { 'a' }, { 'b' } }
+        *    separator = '.'
+        *    => result = { 'a', '.', 'b' }
+        * </pre></li>
+        * <li><pre>
+        *    name = { ' c' }
+        *    array = null
+        *    separator = '.'
+        *    => result = { 'c' }
+        * </pre></li>
+        * </ol>
+        * 
+        * @param name the given name
+        * @param array the given array
+        * @param separator the given separator
+        * @return the concatenation of the given array parts using the given separator between each
+        * part and appending the given name at the end
+        */
+       public static final char[] concatWith(
+               char[] name,
+               char[][] array,
+               char separator) {
+               int nameLength = name == null ? 0 : name.length;
+               if (nameLength == 0)
+                       return concatWith(array, separator);
+
+               int length = array == null ? 0 : array.length;
+               if (length == 0)
+                       return name;
+
+               int size = nameLength;
+               int index = length;
+               while (--index >= 0)
+                       if (array[index].length > 0)
+                               size += array[index].length + 1;
+               char[] result = new char[size];
+               index = size;
+               for (int i = length - 1; i >= 0; i--) {
+                       int subLength = array[i].length;
+                       if (subLength > 0) {
+                               index -= subLength;
+                               System.arraycopy(array[i], 0, result, index, subLength);
+                               result[--index] = separator;
+                       }
+               }
+               System.arraycopy(name, 0, result, 0, nameLength);
+               return result;
+       }
+
+       /**
+        * Answers the concatenation of the given array parts using the given separator between each
+        * part and appending the given name at the end.
+        * <br>
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    name = { 'c' }
+        *    array = { { 'a' }, { 'b' } }
+        *    separator = '.'
+        *    => result = { 'a', '.', 'b' , '.', 'c' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    name = null
+        *    array = { { 'a' }, { 'b' } }
+        *    separator = '.'
+        *    => result = { 'a', '.', 'b' }
+        * </pre></li>
+        * <li><pre>
+        *    name = { ' c' }
+        *    array = null
+        *    separator = '.'
+        *    => result = { 'c' }
+        * </pre></li>
+        * </ol>
+        * 
+        * @param array the given array
+        * @param name the given name
+        * @param separator the given separator
+        * @return the concatenation of the given array parts using the given separator between each
+        * part and appending the given name at the end
+        */
+       public static final char[] concatWith(
+               char[][] array,
+               char[] name,
+               char separator) {
+               int nameLength = name == null ? 0 : name.length;
+               if (nameLength == 0)
+                       return concatWith(array, separator);
+
+               int length = array == null ? 0 : array.length;
+               if (length == 0)
+                       return name;
+
+               int size = nameLength;
+               int index = length;
+               while (--index >= 0)
+                       if (array[index].length > 0)
+                               size += array[index].length + 1;
+               char[] result = new char[size];
+               index = 0;
+               for (int i = 0; i < length; i++) {
+                       int subLength = array[i].length;
+                       if (subLength > 0) {
+                               System.arraycopy(array[i], 0, result, index, subLength);
+                               index += subLength;
+                               result[index++] = separator;
+                       }
+               }
+               System.arraycopy(name, 0, result, index, nameLength);
+               return result;
+       }
+
+       /**
+        * Answers the concatenation of the given array parts using the given separator between each part.
+        * <br>
+        * <br>
+        * For example:<br>
+        * <ol>
+        * <li><pre>
+        *    array = { { 'a' }, { 'b' } }
+        *    separator = '.'
+        *    => result = { 'a', '.', 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = null
+        *    separator = '.'
+        *    => result = { }
+        * </pre></li>
+        * </ol>
+        * 
+        * @param array the given array
+        * @param separator the given separator
+        * @return the concatenation of the given array parts using the given separator between each part
+        */
+       public static final char[] concatWith(char[][] array, char separator) {
+               int length = array == null ? 0 : array.length;
+               if (length == 0)
+                       return CharOperation.NO_CHAR;
+
+               int size = length - 1;
+               int index = length;
+               while (--index >= 0) {
+                       if (array[index].length == 0)
+                               size--;
+                       else
+                               size += array[index].length;
+               }
+               if (size <= 0)
+                       return CharOperation.NO_CHAR;
+               char[] result = new char[size];
+               index = length;
+               while (--index >= 0) {
+                       length = array[index].length;
+                       if (length > 0) {
+                               System.arraycopy(
+                                       array[index],
+                                       0,
+                                       result,
+                                       (size -= length),
+                                       length);
+                               if (--size >= 0)
+                                       result[size] = separator;
+                       }
+               }
+               return result;
+       }
+       
+       /**
+        * Answers true if the array contains an occurrence of character, false otherwise.
+        * 
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    character = 'c'
+        *    array = { { ' a' }, { ' b' } }
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    character = 'a'
+        *    array = { { ' a' }, { ' b' } }
+        *    result => true
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param character the character to search
+        * @param array the array in which the search is done
+        * @return true if the array contains an occurrence of character, false otherwise.
+        * @throws NullPointerException if array is null.
+        */
+       public static final boolean contains(char character, char[][] array) {
+               for (int i = array.length; --i >= 0;) {
+                       char[] subarray = array[i];
+                       for (int j = subarray.length; --j >= 0;)
+                               if (subarray[j] == character)
+                                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Answers true if the array contains an occurrence of character, false otherwise.
+        * 
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    character = 'c'
+        *    array = { ' b'  }
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    character = 'a'
+        *    array = { ' a' , ' b' }
+        *    result => true
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param character the character to search
+        * @param array the array in which the search is done
+        * @return true if the array contains an occurrence of character, false otherwise.
+        * @throws NullPointerException if array is null.
+        */
+       public static final boolean contains(char character, char[] array) {
+               for (int i = array.length; --i >= 0;)
+                       if (array[i] == character)
+                               return true;
+               return false;
+       }
+       
+       /**
+        * Answers a deep copy of the toCopy array.
+        * 
+        * @param toCopy the array to copy
+        * @return a deep copy of the toCopy array.
+        */
+       public static final char[][] deepCopy(char[][] toCopy) {
+               int toCopyLength = toCopy.length;
+               char[][] result = new char[toCopyLength][];
+               for (int i = 0; i < toCopyLength; i++) {
+                       char[] toElement = toCopy[i];
+                       int toElementLength = toElement.length;
+                       char[] resultElement = new char[toElementLength];
+                       System.arraycopy(toElement, 0, resultElement, 0, toElementLength);
+                       result[i] = resultElement;
+               }
+               return result;
+       }
+
+       /**
+        * Return true if array ends with the sequence of characters contained in toBeFound, 
+        * otherwise false.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { 'a', 'b', 'c', 'd' }
+        *    toBeFound = { 'b', 'c' }
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'b', 'c' }
+        *    toBeFound = { 'b', 'c' }
+        *    result => true
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param array the array to check
+        * @param toBeFound the array to find
+        * @return true if array ends with the sequence of characters contained in toBeFound, 
+        * otherwise false.
+        * @throws NullPointerException if array is null or toBeFound is null
+        */
+       public static final boolean endsWith(char[] array, char[] toBeFound) {
+               int i = toBeFound.length;
+               int j = array.length - i;
+
+               if (j < 0)
+                       return false;
+               while (--i >= 0)
+                       if (toBeFound[i] != array[i + j])
+                               return false;
+               return true;
+       }
+
+       /**
+        * Answers true if the two arrays are identical character by character, otherwise false.
+        * The equality is case sensitive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { } }
+        *    second = null
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { 'a' } }
+        *    second = { { 'a' } }
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { 'A' } }
+        *    second = { { 'a' } }
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * @param first the first array
+        * @param second the second array
+        * @return true if the two arrays are identical character by character, otherwise false
+        */
+       public static final boolean equals(char[][] first, char[][] second) {
+               if (first == second)
+                       return true;
+               if (first == null || second == null)
+                       return false;
+               if (first.length != second.length)
+                       return false;
+
+               for (int i = first.length; --i >= 0;)
+                       if (!equals(first[i], second[i]))
+                               return false;
+               return true;
+       }
+
+       /**
+        * If isCaseSensite is true, answers true if the two arrays are identical character
+        * by character, otherwise false.
+        * If it is false, answers true if the two arrays are identical character by 
+        * character without checking the case, otherwise false.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    isCaseSensitive = true
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { } }
+        *    second = null
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { 'A' } }
+        *    second = { { 'a' } }
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { { 'A' } }
+        *    second = { { 'a' } }
+        *    isCaseSensitive = false
+        *    result => true
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array
+        * @param second the second array
+        * @param isCaseSensitive check whether or not the equality should be case sensitive
+        * @return true if the two arrays are identical character by character according to the value
+        * of isCaseSensitive, otherwise false
+        */
+       public static final boolean equals(
+               char[][] first,
+               char[][] second,
+               boolean isCaseSensitive) {
+
+               if (isCaseSensitive) {
+                       return equals(first, second);
+               }
+               if (first == second)
+                       return true;
+               if (first == null || second == null)
+                       return false;
+               if (first.length != second.length)
+                       return false;
+
+               for (int i = first.length; --i >= 0;)
+                       if (!equals(first[i], second[i], false))
+                               return false;
+               return true;
+       }
+
+       /**
+        * Answers true if the two arrays are identical character by character, otherwise false.
+        * The equality is case sensitive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { }
+        *    second = null
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'a' }
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'A' }
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * @param first the first array
+        * @param second the second array
+        * @return true if the two arrays are identical character by character, otherwise false
+        */
+       public static final boolean equals(char[] first, char[] second) {
+               if (first == second)
+                       return true;
+               if (first == null || second == null)
+                       return false;
+               if (first.length != second.length)
+                       return false;
+
+               for (int i = first.length; --i >= 0;)
+                       if (first[i] != second[i])
+                               return false;
+               return true;
+       }
+       
+       /**
+        * Answers true if the first array is identical character by character to a portion of the second array
+        * delimited from position secondStart (inclusive) to secondEnd(exclusive), otherwise false.
+        * The equality is case sensitive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    secondStart = 0
+        *    secondEnd = 0
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { }
+        *    second = null
+        *    secondStart = 0
+        *    secondEnd = 0
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'a' }
+        *    secondStart = 0
+        *    secondEnd = 1
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'a' }
+        *    second = { 'A' }
+        *    secondStart = 0
+        *    secondEnd = 1
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * @param first the first array
+        * @param second the second array
+        * @param secondStart inclusive start position in the second array to compare
+        * @param secondEnd exclusive end position in the second array to compare
+        * @return true if the first array is identical character by character to fragment of second array ranging from secondStart to secondEnd-1, otherwise false
+        * @since 3.0
+        */
+       public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd) {
+               if (first == second)
+                       return true;
+               if (first == null || second == null)
+                       return false;
+               if (first.length != secondEnd - secondStart)
+                       return false;
+
+               for (int i = first.length; --i >= 0;)
+                       if (first[i] != second[i+secondStart])
+                               return false;
+               return true;
+       }
+
+       /**
+        * If isCaseSensite is true, answers true if the two arrays are identical character
+        * by character, otherwise false.
+        * If it is false, answers true if the two arrays are identical character by 
+        * character without checking the case, otherwise false.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    first = null
+        *    second = null
+        *    isCaseSensitive = true
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { }
+        *    second = null
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'A' }
+        *    second = { 'a' }
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    first = { 'A' }
+        *    second = { 'a' }
+        *    isCaseSensitive = false
+        *    result => true
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param first the first array
+        * @param second the second array
+        * @param isCaseSensitive check whether or not the equality should be case sensitive
+        * @return true if the two arrays are identical character by character according to the value
+        * of isCaseSensitive, otherwise false
+        */
+       public static final boolean equals(
+               char[] first,
+               char[] second,
+               boolean isCaseSensitive) {
+
+               if (isCaseSensitive) {
+                       return equals(first, second);
+               }
+               if (first == second)
+                       return true;
+               if (first == null || second == null)
+                       return false;
+               if (first.length != second.length)
+                       return false;
+
+               for (int i = first.length; --i >= 0;)
+                       if (Character.toLowerCase(first[i])
+                               != Character.toLowerCase(second[i]))
+                               return false;
+               return true;
+       }
+       /**
+        * If isCaseSensite is true, the equality is case sensitive, otherwise it is case insensitive.
+        * 
+        * Answers true if the name contains the fragment at the starting index startIndex, otherwise false.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    fragment = { 'b', 'c' , 'd' }
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    startIndex = 1
+        *    isCaseSensitive = true
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    fragment = { 'b', 'c' , 'd' }
+        *    name = { 'a', 'b', 'C' , 'd' }
+        *    startIndex = 1
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    fragment = { 'b', 'c' , 'd' }
+        *    name = { 'a', 'b', 'C' , 'd' }
+        *    startIndex = 0
+        *    isCaseSensitive = false
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    fragment = { 'b', 'c' , 'd' }
+        *    name = { 'a', 'b'}
+        *    startIndex = 0
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param fragment the fragment to check
+        * @param name the array to check
+        * @param startIndex the starting index
+        * @param isCaseSensitive check whether or not the equality should be case sensitive
+        * @return true if the name contains the fragment at the starting index startIndex according to the 
+        * value of isCaseSensitive, otherwise false.
+        * @throws NullPointerException if fragment or name is null.
+        */
+       public static final boolean fragmentEquals(
+               char[] fragment,
+               char[] name,
+               int startIndex,
+               boolean isCaseSensitive) {
+
+               int max = fragment.length;
+               if (name.length < max + startIndex)
+                       return false;
+               if (isCaseSensitive) {
+                       for (int i = max;
+                               --i >= 0;
+                               ) // assumes the prefix is not larger than the name
+                               if (fragment[i] != name[i + startIndex])
+                                       return false;
+                       return true;
+               }
+               for (int i = max;
+                       --i >= 0;
+                       ) // assumes the prefix is not larger than the name
+                       if (Character.toLowerCase(fragment[i])
+                               != Character.toLowerCase(name[i + startIndex]))
+                               return false;
+               return true;
+       }
+
+       /**
+        * Answers a hashcode for the array
+        * 
+        * @param array the array for which a hashcode is required
+        * @return the hashcode
+        * @throws NullPointerException if array is null
+        */
+       public static final int hashCode(char[] array) {
+               int hash = 0;
+               int offset = 0;
+               int length = array.length;
+               if (length < 16) {
+                       for (int i = length; i > 0; i--)
+                               hash = (hash * 37) + array[offset++];
+               } else {
+                       // only sample some characters
+                       int skip = length / 8;
+                       for (int i = length; i > 0; i -= skip, offset += skip)
+                               hash = (hash * 39) + array[offset];
+               }
+               return hash & 0x7FFFFFFF;
+       }
+       /**
+        * Answers true if c is a whitespace according to the JLS (&#92;u000a, &#92;u000c, &#92;u000d, &#92;u0009), otherwise false.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    c = ' '
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    c = '&#92;u3000'
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param c the character to check
+        * @return true if c is a whitespace according to the JLS, otherwise false.
+        */
+       public static boolean isWhitespace(char c) {
+               switch (c) {
+                       case 10 : /* \ u000a: LINE FEED               */
+                       case 12 : /* \ u000c: FORM FEED               */
+                       case 13 : /* \ u000d: CARRIAGE RETURN         */
+                       case 32 : /* \ u0020: SPACE                   */
+                       case 9 : /* \ u0009: HORIZONTAL TABULATION   */
+                               return true;
+                       default :
+                               return false;
+               }
+       }
+       
+       /**
+        * Answers the first index in the array for which the corresponding character is
+        * equal to toBeFound. Answers -1 if no occurrence of this character is found.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    result => 2
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'e'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    result => -1
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param toBeFound the character to search
+        * @param array the array to be searched
+        * @return the first index in the array for which the corresponding character is
+        * equal to toBeFound, -1 otherwise
+        * @throws NullPointerException if array is null
+        */
+       public static final int indexOf(char toBeFound, char[] array) {
+               for (int i = 0; i < array.length; i++)
+                       if (toBeFound == array[i])
+                               return i;
+               return -1;
+       }
+
+       /**
+        * Answers the first index in the array for which the corresponding character is
+        * equal to toBeFound starting the search at index start.
+        * Answers -1 if no occurrence of this character is found.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    start = 2
+        *    result => 2
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    start = 3
+        *    result => -1
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'e'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    start = 1
+        *    result => -1
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param toBeFound the character to search
+        * @param array the array to be searched
+        * @param start the starting index
+        * @return the first index in the array for which the corresponding character is
+        * equal to toBeFound, -1 otherwise
+        * @throws NullPointerException if array is null
+        * @throws ArrayIndexOutOfBoundsException if  start is lower than 0
+        */
+       public static final int indexOf(char toBeFound, char[] array, int start) {
+               for (int i = start; i < array.length; i++)
+                       if (toBeFound == array[i])
+                               return i;
+               return -1;
+       }
+
+       /**
+        * Answers the last index in the array for which the corresponding character is
+        * equal to toBeFound starting from the end of the array.
+        * Answers -1 if no occurrence of this character is found.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' , 'c', 'e' }
+        *    result => 4
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'e'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    result => -1
+        * </pre>
+        * </li>
+        * </ol>
+        *
+        * @param toBeFound the character to search
+        * @param array the array to be searched
+        * @return the last index in the array for which the corresponding character is
+        * equal to toBeFound starting from the end of the array, -1 otherwise
+        * @throws NullPointerException if array is null
+        */
+       public static final int lastIndexOf(char toBeFound, char[] array) {
+               for (int i = array.length; --i >= 0;)
+                       if (toBeFound == array[i])
+                               return i;
+               return -1;
+       }
+
+       /**
+        * Answers the last index in the array for which the corresponding character is
+        * equal to toBeFound stopping at the index startIndex.
+        * Answers -1 if no occurrence of this character is found.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    startIndex = 2
+        *    result => 2
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd', 'e' }
+        *    startIndex = 3
+        *    result => -1
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'e'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    startIndex = 0
+        *    result => -1
+        * </pre>
+        * </li>
+        * </ol>
+        *
+        * @param toBeFound the character to search
+        * @param array the array to be searched
+        * @param startIndex the stopping index
+        * @return the last index in the array for which the corresponding character is
+        * equal to toBeFound stopping at the index startIndex, -1 otherwise
+        * @throws NullPointerException if array is null
+        * @throws ArrayIndexOutOfBoundsException if startIndex is lower than 0
+        */
+       public static final int lastIndexOf(
+               char toBeFound,
+               char[] array,
+               int startIndex) {
+               for (int i = array.length; --i >= startIndex;)
+                       if (toBeFound == array[i])
+                               return i;
+               return -1;
+       }
+
+       /**
+        * Answers the last index in the array for which the corresponding character is
+        * equal to toBeFound starting from endIndex to startIndex.
+        * Answers -1 if no occurrence of this character is found.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    startIndex = 2
+        *    endIndex = 2
+        *    result => 2
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { ' a', 'b', 'c', 'd', 'e' }
+        *    startIndex = 3
+        *    endIndex = 4
+        *    result => -1
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'e'
+        *    array = { ' a', 'b', 'c', 'd' }
+        *    startIndex = 0
+        *    endIndex = 3
+        *    result => -1
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param toBeFound the character to search
+        * @param array the array to be searched
+        * @param startIndex the stopping index
+        * @param endIndex the starting index
+        * @return the last index in the array for which the corresponding character is
+        * equal to toBeFound starting from endIndex to startIndex, -1 otherwise
+        * @throws NullPointerException if array is null
+        * @throws ArrayIndexOutOfBoundsException if endIndex is greater or equals to array length or starting is lower than 0
+        */
+       public static final int lastIndexOf(
+               char toBeFound,
+               char[] array,
+               int startIndex,
+               int endIndex) {
+               for (int i = endIndex; --i >= startIndex;)
+                       if (toBeFound == array[i])
+                               return i;
+               return -1;
+       }
+       
+       /**
+        * Answers the last portion of a name given a separator.
+        * <br>
+        * <br>
+        * For example,
+        * <pre>
+        *      lastSegment("java.lang.Object".toCharArray(),'.') --> Object
+        * </pre>
+        * 
+        * @param array the array
+        * @param separator the given separator
+        * @return the last portion of a name given a separator
+        * @throws NullPointerException if array is null
+        */
+       final static public char[] lastSegment(char[] array, char separator) {
+               int pos = lastIndexOf(separator, array);
+               if (pos < 0)
+                       return array;
+               return subarray(array, pos + 1, array.length);
+       }
+
+       /**
+        * Answers true if the pattern matches the given name, false otherwise. This char[] pattern matching
+        * accepts wild-cards '*' and '?'.
+        *
+        * When not case sensitive, the pattern is assumed to already be lowercased, the
+        * name will be lowercased character per character as comparing.
+        * If name is null, the answer is false.
+        * If pattern is null, the answer is true if name is not null.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    pattern = { '?', 'b', '*' }
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    isCaseSensitive = true
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    pattern = { '?', 'b', '?' }
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    pattern = { 'b', '*' }
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param pattern the given pattern
+        * @param name the given name
+        * @param isCaseSensitive flag to know whether or not the matching should be case sensitive
+        * @return true if the pattern matches the given name, false otherwise
+        */
+       public static final boolean match(
+               char[] pattern,
+               char[] name,
+               boolean isCaseSensitive) {
+
+               if (name == null)
+                       return false; // null name cannot match
+               if (pattern == null)
+                       return true; // null pattern is equivalent to '*'
+
+               return match(
+                       pattern,
+                       0,
+                       pattern.length,
+                       name,
+                       0,
+                       name.length,
+                       isCaseSensitive);
+       }
+
+       /**
+        * Answers true if the a sub-pattern matches the subpart of the given name, false otherwise.
+        * char[] pattern matching, accepting wild-cards '*' and '?'. Can match only subset of name/pattern.
+        * end positions are non-inclusive.
+        * The subpattern is defined by the patternStart and pattternEnd positions.
+        * When not case sensitive, the pattern is assumed to already be lowercased, the
+        * name will be lowercased character per character as comparing.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    pattern = { '?', 'b', '*' }
+        *    patternStart = 1
+        *    patternEnd = 3
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    nameStart = 1
+        *    nameEnd = 4
+        *    isCaseSensitive = true
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    pattern = { '?', 'b', '*' }
+        *    patternStart = 1
+        *    patternEnd = 2
+        *    name = { 'a', 'b', 'c' , 'd' }
+        *    nameStart = 1
+        *    nameEnd = 2
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param pattern the given pattern
+        * @param patternStart the given pattern start
+        * @param patternEnd the given pattern end
+        * @param name the given name
+        * @param nameStart the given name start
+        * @param nameEnd the given name end
+        * @param isCaseSensitive flag to know if the matching should be case sensitive
+        * @return true if the a sub-pattern matches the subpart of the given name, false otherwise
+        */
+       public static final boolean match(
+               char[] pattern,
+               int patternStart,
+               int patternEnd,
+               char[] name,
+               int nameStart,
+               int nameEnd,
+               boolean isCaseSensitive) {
+
+               if (name == null)
+                       return false; // null name cannot match
+               if (pattern == null)
+                       return true; // null pattern is equivalent to '*'
+               int iPattern = patternStart;
+               int iName = nameStart;
+
+               if (patternEnd < 0)
+                       patternEnd = pattern.length;
+               if (nameEnd < 0)
+                       nameEnd = name.length;
+
+               /* check first segment */
+               char patternChar = 0;
+               while ((iPattern < patternEnd)
+                       && (patternChar = pattern[iPattern]) != '*') {
+                       if (iName == nameEnd)
+                               return false;
+                       if (patternChar
+                               != (isCaseSensitive
+                                       ? name[iName]
+                                       : Character.toLowerCase(name[iName]))
+                               && patternChar != '?') {
+                               return false;
+                       }
+                       iName++;
+                       iPattern++;
+               }
+               /* check sequence of star+segment */
+               int segmentStart;
+               if (patternChar == '*') {
+                       segmentStart = ++iPattern; // skip star
+               } else {
+                       segmentStart = 0; // force iName check
+               }
+               int prefixStart = iName;
+               checkSegment : while (iName < nameEnd) {
+                       if (iPattern == patternEnd) {
+                               iPattern = segmentStart; // mismatch - restart current segment
+                               iName = ++prefixStart;
+                               continue checkSegment;
+                       }
+                       /* segment is ending */
+                       if ((patternChar = pattern[iPattern]) == '*') {
+                               segmentStart = ++iPattern; // skip start
+                               if (segmentStart == patternEnd) {
+                                       return true;
+                               }
+                               prefixStart = iName;
+                               continue checkSegment;
+                       }
+                       /* check current name character */
+                       if ((isCaseSensitive ? name[iName] : Character.toLowerCase(name[iName]))
+                                               != patternChar
+                                       && patternChar != '?') {
+                               iPattern = segmentStart; // mismatch - restart current segment
+                               iName = ++prefixStart;
+                               continue checkSegment;
+                       }
+                       iName++;
+                       iPattern++;
+               }
+
+               return (segmentStart == patternEnd)
+                       || (iName == nameEnd && iPattern == patternEnd)
+                       || (iPattern == patternEnd - 1 && pattern[iPattern] == '*');
+       }
+
+       /**
+        * Answers true if the pattern matches the filepath using the pathSepatator, false otherwise.
+        * 
+        * Path char[] pattern matching, accepting wild-cards '**', '*' and '?' (using Ant directory tasks
+        * conventions, also see "http://jakarta.apache.org/ant/manual/dirtasks.html#defaultexcludes").
+        * Path pattern matching is enhancing regular pattern matching in supporting extra rule where '**' represent
+        * any folder combination.
+        * Special rule: 
+        * - foo\  is equivalent to foo\**   
+        * When not case sensitive, the pattern is assumed to already be lowercased, the
+        * name will be lowercased character per character as comparing.
+        * 
+        * @param pattern the given pattern
+        * @param filepath the given path 
+        * @param isCaseSensitive to find out whether or not the matching should be case sensitive
+        * @param pathSeparator the given path separator
+        * @return true if the pattern matches the filepath using the pathSepatator, false otherwise
+        */
+       public static final boolean pathMatch(
+               char[] pattern,
+               char[] filepath,
+               boolean isCaseSensitive,
+               char pathSeparator) {
+
+               if (filepath == null)
+                       return false; // null name cannot match
+               if (pattern == null)
+                       return true; // null pattern is equivalent to '*'
+
+               // offsets inside pattern
+               int pSegmentStart = pattern[0] == pathSeparator ? 1 : 0;
+               int pLength = pattern.length;
+               int pSegmentEnd = CharOperation.indexOf(pathSeparator, pattern, pSegmentStart+1);
+               if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+               // special case: pattern foo\ is equivalent to foo\**
+               boolean freeTrailingDoubleStar = pattern[pLength - 1] == pathSeparator;
+
+               // offsets inside filepath
+               int fSegmentStart, fLength = filepath.length;
+               if (filepath[0] != pathSeparator){
+                       fSegmentStart = 0;
+               } else {
+                       fSegmentStart = 1;
+               }
+               if (fSegmentStart != pSegmentStart) {
+                       return false; // both must start with a separator or none.
+               }
+               int fSegmentEnd = CharOperation.indexOf(pathSeparator, filepath, fSegmentStart+1);
+               if (fSegmentEnd < 0) fSegmentEnd = fLength;
+
+               // first segments
+               while (pSegmentStart < pLength
+                       && !(pSegmentEnd == pLength && freeTrailingDoubleStar
+                                       || (pSegmentEnd == pSegmentStart + 2
+                                                       && pattern[pSegmentStart] == '*'
+                                                       && pattern[pSegmentStart + 1] == '*'))) {
+
+                       if (fSegmentStart >= fLength)
+                               return false;
+                       if (!CharOperation
+                               .match(
+                                       pattern,
+                                       pSegmentStart,
+                                       pSegmentEnd,
+                                       filepath,
+                                       fSegmentStart,
+                                       fSegmentEnd,
+                                       isCaseSensitive)) {
+                               return false;
+                       }
+
+                       // jump to next segment         
+                       pSegmentEnd =
+                               CharOperation.indexOf(
+                                       pathSeparator,
+                                       pattern,
+                                       pSegmentStart = pSegmentEnd + 1);
+                       // skip separator
+                       if (pSegmentEnd < 0)
+                               pSegmentEnd = pLength;
+
+                       fSegmentEnd =
+                               CharOperation.indexOf(
+                                       pathSeparator,
+                                       filepath,
+                                       fSegmentStart = fSegmentEnd + 1);
+                       // skip separator
+                       if (fSegmentEnd < 0) fSegmentEnd = fLength;
+               }
+
+               /* check sequence of doubleStar+segment */
+               int pSegmentRestart;
+               if ((pSegmentStart >= pLength && freeTrailingDoubleStar)
+                               || (pSegmentEnd == pSegmentStart + 2
+                                       && pattern[pSegmentStart] == '*'
+                                       && pattern[pSegmentStart + 1] == '*')) {
+                       pSegmentEnd =
+                               CharOperation.indexOf(
+                                       pathSeparator,
+                                       pattern,
+                                       pSegmentStart = pSegmentEnd + 1);
+                       // skip separator
+                       if (pSegmentEnd < 0) pSegmentEnd = pLength;
+                       pSegmentRestart = pSegmentStart;
+               } else {
+                       if (pSegmentStart >= pLength) return fSegmentStart >= fLength; // true if filepath is done too.
+                       pSegmentRestart = 0; // force fSegmentStart check
+               }
+               int fSegmentRestart = fSegmentStart;
+               checkSegment : while (fSegmentStart < fLength) {
+                               
+                       if (pSegmentStart >= pLength) {
+                               if (freeTrailingDoubleStar) return true;
+                               // mismatch - restart current path segment
+                               pSegmentEnd =
+                                       CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
+                               if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+                               fSegmentRestart = 
+                                       CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
+                               // skip separator
+                               if (fSegmentRestart < 0) {
+                                       fSegmentRestart = fLength;
+                               } else {
+                                       fSegmentRestart++;
+                               }
+                               fSegmentEnd =
+                                       CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
+                               if (fSegmentEnd < 0) fSegmentEnd = fLength;
+                               continue checkSegment;
+                       }
+                       
+                       /* path segment is ending */
+                       if (pSegmentEnd == pSegmentStart + 2
+                               && pattern[pSegmentStart] == '*'
+                               && pattern[pSegmentStart + 1] == '*') {
+                               pSegmentEnd =
+                                       CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentEnd + 1);
+                               // skip separator
+                               if (pSegmentEnd < 0) pSegmentEnd = pLength;
+                               pSegmentRestart = pSegmentStart;
+                               fSegmentRestart = fSegmentStart;
+                               if (pSegmentStart >= pLength) return true;
+                               continue checkSegment;
+                       }
+                       /* chech current path segment */
+                       if (!CharOperation.match(
+                                                               pattern,
+                                                               pSegmentStart,
+                                                               pSegmentEnd,
+                                                               filepath,
+                                                               fSegmentStart,
+                                                               fSegmentEnd,
+                                                               isCaseSensitive)) {
+                               // mismatch - restart current path segment
+                               pSegmentEnd =
+                                       CharOperation.indexOf(pathSeparator, pattern, pSegmentStart = pSegmentRestart);
+                               if (pSegmentEnd < 0) pSegmentEnd = pLength;
+
+                               fSegmentRestart = 
+                                       CharOperation.indexOf(pathSeparator, filepath, fSegmentRestart + 1);
+                               // skip separator
+                               if (fSegmentRestart < 0) {
+                                       fSegmentRestart = fLength;
+                               } else {
+                                       fSegmentRestart++;
+                               }
+                               fSegmentEnd =
+                                       CharOperation.indexOf(pathSeparator, filepath, fSegmentStart = fSegmentRestart);
+                               if (fSegmentEnd < 0) fSegmentEnd = fLength;
+                               continue checkSegment;
+                       }
+                       // jump to next segment         
+                       pSegmentEnd =
+                               CharOperation.indexOf(
+                                       pathSeparator,
+                                       pattern,
+                                       pSegmentStart = pSegmentEnd + 1);
+                       // skip separator
+                       if (pSegmentEnd < 0)
+                               pSegmentEnd = pLength;
+
+                       fSegmentEnd =
+                               CharOperation.indexOf(
+                                       pathSeparator,
+                                       filepath,
+                                       fSegmentStart = fSegmentEnd + 1);
+                       // skip separator
+                       if (fSegmentEnd < 0)
+                               fSegmentEnd = fLength;
+               }
+
+               return (pSegmentRestart >= pSegmentEnd)
+                       || (fSegmentStart >= fLength && pSegmentStart >= pLength)
+                       || (pSegmentStart == pLength - 2
+                               && pattern[pSegmentStart] == '*'
+                               && pattern[pSegmentStart + 1] == '*')
+                       || (pSegmentStart == pLength && freeTrailingDoubleStar);
+       }
+
+       /**
+        * Answers the number of occurrences of the given character in the given array, 0 if any.
+        * 
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'b'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => 3
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => 0
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param toBeFound the given character
+        * @param array the given array
+        * @return the number of occurrences of the given character in the given array, 0 if any
+        * @throws NullPointerException if array is null
+        */
+       public static final int occurencesOf(char toBeFound, char[] array) {
+               int count = 0;
+               for (int i = 0; i < array.length; i++)
+                       if (toBeFound == array[i])
+                               count++;
+               return count;
+       }
+
+       /**
+        * Answers the number of occurrences of the given character in the given array starting
+        * at the given index, 0 if any.
+        * 
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    toBeFound = 'b'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    start = 2
+        *    result => 2
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    toBeFound = 'c'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    start = 0
+        *    result => 0
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param toBeFound the given character
+        * @param array the given array
+        * @param start the given index
+        * @return the number of occurrences of the given character in the given array, 0 if any
+        * @throws NullPointerException if array is null
+        * @throws ArrayIndexOutOfBoundsException if start is lower than 0
+        */
+       public static final int occurencesOf(
+               char toBeFound,
+               char[] array,
+               int start) {
+               int count = 0;
+               for (int i = start; i < array.length; i++)
+                       if (toBeFound == array[i])
+                               count++;
+               return count;
+       }
+
+       /**
+        * Answers true if the given name starts with the given prefix, false otherwise.
+        * The comparison is case sensitive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    prefix = { 'a' , 'b' }
+        *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    prefix = { 'a' , 'c' }
+        *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param prefix the given prefix
+        * @param name the given name
+        * @return true if the given name starts with the given prefix, false otherwise
+        * @throws NullPointerException if the given name is null or if the given prefix is null
+        */
+       public static final boolean prefixEquals(char[] prefix, char[] name) {
+
+               int max = prefix.length;
+               if (name.length < max)
+                       return false;
+               for (int i = max;
+                       --i >= 0;
+                       ) // assumes the prefix is not larger than the name
+                       if (prefix[i] != name[i])
+                               return false;
+               return true;
+       }
+
+       /**
+        * Answers true if the given name starts with the given prefix, false otherwise.
+        * isCaseSensitive is used to find out whether or not the comparison should be case sensitive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    prefix = { 'a' , 'B' }
+        *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    isCaseSensitive = false
+        *    result => true
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    prefix = { 'a' , 'B' }
+        *    name = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    isCaseSensitive = true
+        *    result => false
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param prefix the given prefix
+        * @param name the given name
+        * @param isCaseSensitive to find out whether or not the comparison should be case sensitive
+        * @return true if the given name starts with the given prefix, false otherwise
+        * @throws NullPointerException if the given name is null or if the given prefix is null
+        */
+       public static final boolean prefixEquals(
+               char[] prefix,
+               char[] name,
+               boolean isCaseSensitive) {
+
+               int max = prefix.length;
+               if (name.length < max)
+                       return false;
+               if (isCaseSensitive) {
+                       for (int i = max;
+                               --i >= 0;
+                               ) // assumes the prefix is not larger than the name
+                               if (prefix[i] != name[i])
+                                       return false;
+                       return true;
+               }
+
+               for (int i = max;
+                       --i >= 0;
+                       ) // assumes the prefix is not larger than the name
+                       if (Character.toLowerCase(prefix[i])
+                               != Character.toLowerCase(name[i]))
+                               return false;
+               return true;
+       }
+
+       /**
+        * Replace all occurrence of the character to be replaced with the remplacement character in the
+        * given array.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    toBeReplaced = 'b'
+        *    replacementChar = 'a'
+        *    result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    toBeReplaced = 'c'
+        *    replacementChar = 'a'
+        *    result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param array the given array
+        * @param toBeReplaced the character to be replaced
+        * @param replacementChar the replacement character
+        * @throws NullPointerException if the given array is null
+        */
+       public static final void replace(
+               char[] array,
+               char toBeReplaced,
+               char replacementChar) {
+               if (toBeReplaced != replacementChar) {
+                       for (int i = 0, max = array.length; i < max; i++) {
+                               if (array[i] == toBeReplaced)
+                                       array[i] = replacementChar;
+                       }
+               }
+       }
+
+       /**
+        * Answers a new array of characters with substitutions. No side-effect is operated on the original
+        * array, in case no substitution happened, then the result is the same as the
+        * original one.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    toBeReplaced = { 'b' }
+        *    replacementChar = { 'a', 'a' }
+        *    result => { 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    toBeReplaced = { 'c' }
+        *    replacementChar = { 'a' }
+        *    result => { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param array the given array
+        * @param toBeReplaced characters to be replaced
+        * @param replacementChars the replacement characters
+        * @return a new array of characters with substitutions or the given array if none
+        * @throws NullPointerException if the given array is null
+        */
+       public static final char[] replace(
+               char[] array,
+               char[] toBeReplaced,
+               char[] replacementChars) {
+
+               int max = array.length;
+               int replacedLength = toBeReplaced.length;
+               int replacementLength = replacementChars.length;
+
+               int[] starts = new int[5];
+               int occurrenceCount = 0;
+
+               if (!equals(toBeReplaced, replacementChars)) {
+
+                       next : for (int i = 0; i < max; i++) {
+                               int j = 0;
+                               while (j < replacedLength) {
+                                       if (i + j == max)
+                                               continue next;
+                                       if (array[i + j] != toBeReplaced[j++])
+                                               continue next;
+                               }
+                               if (occurrenceCount == starts.length) {
+                                       System.arraycopy(
+                                               starts,
+                                               0,
+                                               starts = new int[occurrenceCount * 2],
+                                               0,
+                                               occurrenceCount);
+                               }
+                               starts[occurrenceCount++] = i;
+                       }
+               }
+               if (occurrenceCount == 0)
+                       return array;
+               char[] result =
+                       new char[max
+                               + occurrenceCount * (replacementLength - replacedLength)];
+               int inStart = 0, outStart = 0;
+               for (int i = 0; i < occurrenceCount; i++) {
+                       int offset = starts[i] - inStart;
+                       System.arraycopy(array, inStart, result, outStart, offset);
+                       inStart += offset;
+                       outStart += offset;
+                       System.arraycopy(
+                               replacementChars,
+                               0,
+                               result,
+                               outStart,
+                               replacementLength);
+                       inStart += replacedLength;
+                       outStart += replacementLength;
+               }
+               System.arraycopy(array, inStart, result, outStart, max - inStart);
+               return result;
+       }
+
+       /**
+        * Return a new array which is the split of the given array using the given divider and triming each subarray to remove
+        * whitespaces equals to ' '.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    divider = 'b'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    divider = 'c'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    divider = 'b'
+        *    array = { 'a' , ' ', 'b', 'b', 'a', 'b', 'a' }
+        *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    divider = 'c'
+        *    array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
+        *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param divider the given divider
+        * @param array the given array
+        * @return a new array which is the split of the given array using the given divider and triming each subarray to remove
+        * whitespaces equals to ' '
+        */
+       public static final char[][] splitAndTrimOn(char divider, char[] array) {
+               int length = array == null ? 0 : array.length;
+               if (length == 0)
+                       return NO_CHAR_CHAR;
+
+               int wordCount = 1;
+               for (int i = 0; i < length; i++)
+                       if (array[i] == divider)
+                               wordCount++;
+               char[][] split = new char[wordCount][];
+               int last = 0, currentWord = 0;
+               for (int i = 0; i < length; i++) {
+                       if (array[i] == divider) {
+                               int start = last, end = i - 1;
+                               while (start < i && array[start] == ' ')
+                                       start++;
+                               while (end > start && array[end] == ' ')
+                                       end--;
+                               split[currentWord] = new char[end - start + 1];
+                               System.arraycopy(
+                                       array,
+                                       start,
+                                       split[currentWord++],
+                                       0,
+                                       end - start + 1);
+                               last = i + 1;
+                       }
+               }
+               int start = last, end = length - 1;
+               while (start < length && array[start] == ' ')
+                       start++;
+               while (end > start && array[end] == ' ')
+                       end--;
+               split[currentWord] = new char[end - start + 1];
+               System.arraycopy(
+                       array,
+                       start,
+                       split[currentWord++],
+                       0,
+                       end - start + 1);
+               return split;
+       }
+
+       /**
+        * Return a new array which is the split of the given array using the given divider.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    divider = 'b'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => { { 'a' }, {  }, { 'a' }, { 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    divider = 'c'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    result => { { 'a', 'b', 'b', 'a', 'b', 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    divider = 'c'
+        *    array = { ' ', ' ', 'a' , 'b', 'b', 'a', 'b', 'a', ' ' }
+        *    result => { { ' ', 'a', 'b', 'b', 'a', 'b', 'a', ' ' } }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param divider the given divider
+        * @param array the given array
+        * @return a new array which is the split of the given array using the given divider
+        */
+       public static final char[][] splitOn(char divider, char[] array) {
+               int length = array == null ? 0 : array.length;
+               if (length == 0)
+                       return NO_CHAR_CHAR;
+
+               int wordCount = 1;
+               for (int i = 0; i < length; i++)
+                       if (array[i] == divider)
+                               wordCount++;
+               char[][] split = new char[wordCount][];
+               int last = 0, currentWord = 0;
+               for (int i = 0; i < length; i++) {
+                       if (array[i] == divider) {
+                               split[currentWord] = new char[i - last];
+                               System.arraycopy(
+                                       array,
+                                       last,
+                                       split[currentWord++],
+                                       0,
+                                       i - last);
+                               last = i + 1;
+                       }
+               }
+               split[currentWord] = new char[length - last];
+               System.arraycopy(array, last, split[currentWord], 0, length - last);
+               return split;
+       }
+
+       /**
+        * Return a new array which is the split of the given array using the given divider. The given end 
+        * is exclusive and the given start is inclusive.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    divider = 'b'
+        *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
+        *    start = 2
+        *    end = 5
+        *    result => { {  }, { 'a' }, {  } }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param divider the given divider
+        * @param array the given array
+        * @param start the given starting index
+        * @param end the given ending index
+        * @return a new array which is the split of the given array using the given divider
+        * @throws ArrayIndexOutOfBoundsException if start is lower than 0 or end is greater than the array length
+        */
+       public static final char[][] splitOn(
+               char divider,
+               char[] array,
+               int start,
+               int end) {
+               int length = array == null ? 0 : array.length;
+               if (length == 0 || start > end)
+                       return NO_CHAR_CHAR;
+
+               int wordCount = 1;
+               for (int i = start; i < end; i++)
+                       if (array[i] == divider)
+                               wordCount++;
+               char[][] split = new char[wordCount][];
+               int last = start, currentWord = 0;
+               for (int i = start; i < end; i++) {
+                       if (array[i] == divider) {
+                               split[currentWord] = new char[i - last];
+                               System.arraycopy(
+                                       array,
+                                       last,
+                                       split[currentWord++],
+                                       0,
+                                       i - last);
+                               last = i + 1;
+                       }
+               }
+               split[currentWord] = new char[end - last];
+               System.arraycopy(array, last, split[currentWord], 0, end - last);
+               return split;
+       }
+
+       /**
+        * Answers a new array which is a copy of the given array starting at the given start and 
+        * ending at the given end. The given start is inclusive and the given end is exclusive.
+        * Answers null if start is greater than end, if start is lower than 0 or if end is greater 
+        * than the length of the given array. If end  equals -1, it is converted to the array length.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { { 'a' } , { 'b' } }
+        *    start = 0
+        *    end = 1
+        *    result => { { 'a' } }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { { 'a' } , { 'b' } }
+        *    start = 0
+        *    end = -1
+        *    result => { { 'a' }, { 'b' } }
+        * </pre>
+        * </li>
+        * </ol>
+        *  
+        * @param array the given array
+        * @param start the given starting index
+        * @param end the given ending index
+        * @return a new array which is a copy of the given array starting at the given start and 
+        * ending at the given end
+        * @throws NullPointerException if the given array is null
+        */
+       public static final char[][] subarray(char[][] array, int start, int end) {
+               if (end == -1)
+                       end = array.length;
+               if (start > end)
+                       return null;
+               if (start < 0)
+                       return null;
+               if (end > array.length)
+                       return null;
+
+               char[][] result = new char[end - start][];
+               System.arraycopy(array, start, result, 0, end - start);
+               return result;
+       }
+
+       /**
+        * Answers a new array which is a copy of the given array starting at the given start and 
+        * ending at the given end. The given start is inclusive and the given end is exclusive.
+        * Answers null if start is greater than end, if start is lower than 0 or if end is greater 
+        * than the length of the given array. If end  equals -1, it is converted to the array length.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { 'a' , 'b' }
+        *    start = 0
+        *    end = 1
+        *    result => { 'a' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'a', 'b' }
+        *    start = 0
+        *    end = -1
+        *    result => { 'a' , 'b' }
+        * </pre>
+        * </li>
+        * </ol>
+        *  
+        * @param array the given array
+        * @param start the given starting index
+        * @param end the given ending index
+        * @return a new array which is a copy of the given array starting at the given start and 
+        * ending at the given end
+        * @throws NullPointerException if the given array is null
+        */
+       public static final char[] subarray(char[] array, int start, int end) {
+               if (end == -1)
+                       end = array.length;
+               if (start > end)
+                       return null;
+               if (start < 0)
+                       return null;
+               if (end > array.length)
+                       return null;
+
+               char[] result = new char[end - start];
+               System.arraycopy(array, start, result, 0, end - start);
+               return result;
+       }
+       /**
+        * Answers the result of a char[] conversion to lowercase. Answers null if the given chars array is null.
+        * <br>
+        * NOTE: If no conversion was necessary, then answers back the argument one.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    chars = { 'a' , 'b' }
+        *    result => { 'a' , 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'A', 'b' }
+        *    result => { 'a' , 'b' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param chars the chars to convert
+        * @return the result of a char[] conversion to lowercase
+        */
+       final static public char[] toLowerCase(char[] chars) {
+               if (chars == null)
+                       return null;
+               int length = chars.length;
+               char[] lowerChars = null;
+               for (int i = 0; i < length; i++) {
+                       char c = chars[i];
+                       char lc = Character.toLowerCase(c);
+                       if ((c != lc) || (lowerChars != null)) {
+                               if (lowerChars == null) {
+                                       System.arraycopy(
+                                               chars,
+                                               0,
+                                               lowerChars = new char[length],
+                                               0,
+                                               i);
+                               }
+                               lowerChars[i] = lc;
+                       }
+               }
+               return lowerChars == null ? chars : lowerChars;
+       }
+
+       /**
+        * Answers a new array removing leading and trailing spaces (' '). Answers the given array if there is no
+        * space characters to remove.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    chars = { ' ', 'a' , 'b', ' ',  ' ' }
+        *    result => { 'a' , 'b' }
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { 'A', 'b' }
+        *    result => { 'A' , 'b' }
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param chars the given array
+        * @return a new array removing leading and trailing spaces (' ')
+        */
+       final static public char[] trim(char[] chars) {
+
+               if (chars == null)
+                       return null;
+
+               int start = 0, length = chars.length, end = length - 1;
+               while (start < length && chars[start] == ' ') {
+                       start++;
+               }
+               while (end > start && chars[end] == ' ') {
+                       end--;
+               }
+               if (start != 0 || end != length - 1) {
+                       return subarray(chars, start, end + 1);
+               }
+               return chars;
+       }
+
+       /**
+        * Answers a string which is the concatenation of the given array using the '.' as a separator.
+        * <br>
+        * <br>
+        * For example:
+        * <ol>
+        * <li><pre>
+        *    array = { { 'a' } , { 'b' } }
+        *    result => "a.b"
+        * </pre>
+        * </li>
+        * <li><pre>
+        *    array = { { ' ',  'a' } , { 'b' } }
+        *    result => " a.b"
+        * </pre>
+        * </li>
+        * </ol>
+        * 
+        * @param array the given array
+        * @return a string which is the concatenation of the given array using the '.' as a separator
+        */
+       final static public String toString(char[][] array) {
+               char[] result = concatWith(array, '.');
+               return new String(result);
+       }
+       /**
+        * Answers an array of strings from the given array of char array.
+        * 
+        * @param array the given array
+        * @return an array of strings
+        * @since 3.0
+        */
+       final static public String[] toStrings(char[][] array) {
+               int length = array.length;
+               String[] result = new String[length];
+               for (int i = 0; i < length; i++)
+                       result[i] = new String(array[i]);
+               return result;
+       }
+}