/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Luiz-Otavio Zorzella <zorzella at gmail dot com> - Improve CamelCase algorithm
 *******************************************************************************/
package org.eclipse.jdt.core.compiler;

import org.eclipse.jdt.internal.compiler.parser.ScannerHelper;

/**
 * This class is a collection of helper methods to manipulate char arrays.
 *
 * @since 2.1
 * @noinstantiate This class is not intended to be instantiated by clients.
 */
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][];

	/**
	 * Constant for an empty String array.
	 * @since 3.1
	 */
	public static final String[] NO_STRINGS = new String[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 concatenated 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 sub-array to the target array starting at the given index in the target array.
 * The start of the sub-array 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;
}

/**
 * Answers true if the pattern matches the given name using CamelCase rules, or
 * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
 * '*' and '?' and is inherently case sensitive.
 * <p>
 * CamelCase denotes the convention of writing compound names without spaces,
 * and capitalizing every term. This function recognizes both upper and lower
 * CamelCase, depending whether the leading character is capitalized or not.
 * The leading part of an upper CamelCase pattern is assumed to contain a
 * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
 * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
 * uses a lowercase first character. In Java, type names follow the upper
 * CamelCase convention, whereas method or field names follow the lower
 * CamelCase convention.
 * <p>
 * The pattern may contain lowercase characters, which will be matched in a case
 * sensitive way. These characters must appear in sequence in the name.
 * For instance, 'NPExcep' will match 'NullPointerException', but not
 * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
 * 'NoPointerException'.
 * <p>
 * Digit characters are treated in a special way. They can be used in the pattern
 * but are not always considered as leading character. For instance, both
 * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
 * <p>
 * Using this method allows matching names to have more parts than the specified
 * pattern (see {@link #camelCaseMatch(char[], char[], boolean)}).<br>
 * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
 * 'HatMapper' <b>and also</b> 'HashMapEntry'.
 * <p>
 * <pre>
 * Examples:<ol>
 * <li> pattern = "NPE".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => true</li>
 * <li> pattern = "NPE".toCharArray()
 * name = "NoPermissionException".toCharArray()
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * name = "NoPermissionException".toCharArray()
 * result => false</li>
 * <li> pattern = "npe".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => false</li>
 * <li> pattern = "IPL3".toCharArray()
 * name = "IPerspectiveListener3".toCharArray()
 * result => true</li>
 * <li> pattern = "HM".toCharArray()
 * name = "HashMapEntry".toCharArray()
 * result => true</li>
 * </ol></pre>
 *
 * @param pattern the given pattern
 * @param name the given name
 * @return true if the pattern matches the given name, false otherwise
 * @since 3.2
 */
public static final boolean camelCaseMatch(char[] pattern, char[] name) {
	if (pattern == null)
		return true; // null pattern is equivalent to '*'
	if (name == null)
		return false; // null name cannot match

	return camelCaseMatch(pattern, 0, pattern.length, name, 0, name.length, false/*not the same count of parts*/);
}

/**
 * Answers true if the pattern matches the given name using CamelCase rules, or
 * false otherwise. char[] CamelCase matching does NOT accept explicit wild-cards
 * '*' and '?' and is inherently case sensitive.
 * <p>
 * CamelCase denotes the convention of writing compound names without spaces,
 * and capitalizing every term. This function recognizes both upper and lower
 * CamelCase, depending whether the leading character is capitalized or not.
 * The leading part of an upper CamelCase pattern is assumed to contain a
 * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
 * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
 * uses a lowercase first character. In Java, type names follow the upper
 * CamelCase convention, whereas method or field names follow the lower
 * CamelCase convention.
 * <p>
 * The pattern may contain lowercase characters, which will be matched in a case
 * sensitive way. These characters must appear in sequence in the name.
 * For instance, 'NPExcep' will match 'NullPointerException', but not
 * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
 * 'NoPointerException'.
 * <p>
 * Digit characters are treated in a special way. They can be used in the pattern
 * but are not always considered as leading character. For instance, both
 * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
 * <p>
 * CamelCase can be restricted to match only the same count of parts. When this
 * restriction is specified the given pattern and the given name must have <b>exactly</b>
 * the same number of parts (i.e. the same number of uppercase characters).<br>
 * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
 * 'HatMapper' <b>but not</b> 'HashMapEntry'.
 * <p>
 * <pre>
 * Examples:<ol>
 * <li> pattern = "NPE".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => true</li>
 * <li> pattern = "NPE".toCharArray()
 * name = "NoPermissionException".toCharArray()
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * name = "NoPermissionException".toCharArray()
 * result => false</li>
 * <li> pattern = "npe".toCharArray()
 * name = "NullPointerException".toCharArray()
 * result => false</li>
 * <li> pattern = "IPL3".toCharArray()
 * name = "IPerspectiveListener3".toCharArray()
 * result => true</li>
 * <li> pattern = "HM".toCharArray()
 * name = "HashMapEntry".toCharArray()
 * result => (samePartCount == false)</li>
 * </ol></pre>
 *
 * @param pattern the given pattern
 * @param name the given name
 * @param samePartCount flag telling whether the pattern and the name should
 * 	have the same count of parts or not.<br>
 * 	&nbsp;&nbsp;For example:
 * 	<ul>
 * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
 * 				but not 'HashMapEntry'</li>
 * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
 * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
 * 	</ul>
 * @return true if the pattern matches the given name, false otherwise
 * @since 3.4
 */
public static final boolean camelCaseMatch(char[] pattern, char[] name, boolean samePartCount) {
	if (pattern == null)
		return true; // null pattern is equivalent to '*'
	if (name == null)
		return false; // null name cannot match

	return camelCaseMatch(pattern, 0, pattern.length, name, 0, name.length, samePartCount);
}

/**
 * Answers true if a sub-pattern matches the sub-part of the given name using
 * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
 * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
 * Can match only subset of name/pattern, considering end positions as non-inclusive.
 * The sub-pattern is defined by the patternStart and patternEnd positions.
 * <p>
 * CamelCase denotes the convention of writing compound names without spaces,
 * and capitalizing every term. This function recognizes both upper and lower
 * CamelCase, depending whether the leading character is capitalized or not.
 * The leading part of an upper CamelCase pattern is assumed to contain a
 * sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
 * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
 * uses a lowercase first character. In Java, type names follow the upper
 * CamelCase convention, whereas method or field names follow the lower
 * CamelCase convention.
 * <p>
 * The pattern may contain lowercase characters, which will be matched in a case
 * sensitive way. These characters must appear in sequence in the name.
 * For instance, 'NPExcep' will match 'NullPointerException', but not
 * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
 * 'NoPointerException'.
 * <p>
 * Digit characters are treated in a special way. They can be used in the pattern
 * but are not always considered as leading character. For instance, both
 * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
 * <p>
 * Digit characters are treated in a special way. They can be used in the pattern
 * but are not always considered as leading character. For instance, both
 * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
 * <p>
 * Using this method allows matching names to have more parts than the specified
 * pattern (see {@link #camelCaseMatch(char[], int, int, char[], int, int, boolean)}).<br>
 * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap',
 * 'HatMapper' <b>and also</b> 'HashMapEntry'.
 * <p>
 * Examples:
 * <ol>
 * <li> pattern = "NPE".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => true</li>
 * <li> pattern = "NPE".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NoPermissionException".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * patternStart = 0
 * patternEnd = 6
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * patternStart = 0
 * patternEnd = 6
 * name = "NoPermissionException".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => false</li>
 * <li> pattern = "npe".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => false</li>
 * <li> pattern = "IPL3".toCharArray()
 * patternStart = 0
 * patternEnd = 4
 * name = "IPerspectiveListener3".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => true</li>
 * <li> pattern = "HM".toCharArray()
 * patternStart = 0
 * patternEnd = 2
 * name = "HashMapEntry".toCharArray()
 * nameStart = 0
 * nameEnd = 12
 * result => true</li>
 * </ol>
 *
 * @param pattern the given pattern
 * @param patternStart the start index of the pattern, inclusive
 * @param patternEnd the end index of the pattern, exclusive
 * @param name the given name
 * @param nameStart the start index of the name, inclusive
 * @param nameEnd the end index of the name, exclusive
 * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
 * @since 3.2
 */
public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd) {
	return camelCaseMatch(pattern, patternStart, patternEnd, name, nameStart, nameEnd, false/*not the same count of parts*/);
}

/**
 * Answers true if a sub-pattern matches the sub-part of the given name using
 * CamelCase rules, or false otherwise.  char[] CamelCase matching does NOT
 * accept explicit wild-cards '*' and '?' and is inherently case sensitive.
 * Can match only subset of name/pattern, considering end positions as
 * non-inclusive. The sub-pattern is defined by the patternStart and patternEnd
 * positions.
 * <p>
 * CamelCase denotes the convention of writing compound names without spaces,
 * and capitalizing every term. This function recognizes both upper and lower
 * CamelCase, depending whether the leading character is capitalized or not.
 * The leading part of an upper CamelCase pattern is assumed to contain
 * a sequence of capitals which are appearing in the matching name; e.g. 'NPE' will
 * match 'NullPointerException', but not 'NewPerfData'. A lower CamelCase pattern
 * uses a lowercase first character. In Java, type names follow the upper
 * CamelCase convention, whereas method or field names follow the lower
 * CamelCase convention.
 * <p>
 * The pattern may contain lowercase characters, which will be matched in a case
 * sensitive way. These characters must appear in sequence in the name.
 * For instance, 'NPExcep' will match 'NullPointerException', but not
 * 'NullPointerExCEPTION' or 'NuPoEx' will match 'NullPointerException', but not
 * 'NoPointerException'.
 * <p>
 * Digit characters are treated in a special way. They can be used in the pattern
 * but are not always considered as leading character. For instance, both
 * 'UTF16DSS' and 'UTFDSS' patterns will match 'UTF16DocumentScannerSupport'.
 * <p>
 * CamelCase can be restricted to match only the same count of parts. When this
 * restriction is specified the given pattern and the given name must have <b>exactly</b>
 * the same number of parts (i.e. the same number of uppercase characters).<br>
 * For instance, 'HM' , 'HaMa' and  'HMap' patterns will match 'HashMap' and
 * 'HatMapper' <b>but not</b> 'HashMapEntry'.
 * <p>
 * <pre>
 * Examples:
 * <ol>
 * <li> pattern = "NPE".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => true</li>
 * <li> pattern = "NPE".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NoPermissionException".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * patternStart = 0
 * patternEnd = 6
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => true</li>
 * <li> pattern = "NuPoEx".toCharArray()
 * patternStart = 0
 * patternEnd = 6
 * name = "NoPermissionException".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => false</li>
 * <li> pattern = "npe".toCharArray()
 * patternStart = 0
 * patternEnd = 3
 * name = "NullPointerException".toCharArray()
 * nameStart = 0
 * nameEnd = 20
 * result => false</li>
 * <li> pattern = "IPL3".toCharArray()
 * patternStart = 0
 * patternEnd = 4
 * name = "IPerspectiveListener3".toCharArray()
 * nameStart = 0
 * nameEnd = 21
 * result => true</li>
 * <li> pattern = "HM".toCharArray()
 * patternStart = 0
 * patternEnd = 2
 * name = "HashMapEntry".toCharArray()
 * nameStart = 0
 * nameEnd = 12
 * result => (samePartCount == false)</li>
 * </ol>
 * </pre>
 *
 * @param pattern the given pattern
 * @param patternStart the start index of the pattern, inclusive
 * @param patternEnd the end index of the pattern, exclusive
 * @param name the given name
 * @param nameStart the start index of the name, inclusive
 * @param nameEnd the end index of the name, exclusive
 * @param samePartCount flag telling whether the pattern and the name should
 * 	have the same count of parts or not.<br>
 * 	&nbsp;&nbsp;For example:
 * 	<ul>
 * 		<li>'HM' type string pattern will match 'HashMap' and 'HtmlMapper' types,
 * 				but not 'HashMapEntry'</li>
 * 		<li>'HMap' type string pattern will still match previous 'HashMap' and
 * 				'HtmlMapper' types, but not 'HighMagnitude'</li>
 * 	</ul>
 * @return true if a sub-pattern matches the sub-part of the given name, false otherwise
 * @since 3.4
 */
public static final boolean camelCaseMatch(char[] pattern, int patternStart, int patternEnd, char[] name, int nameStart, int nameEnd, boolean samePartCount) {

	/* !!!!!!!!!! WARNING !!!!!!!!!!
	 * The algorithm implemented in this method has been heavily used in
	 * StringOperation#getCamelCaseMatchingRegions(String, int, int, String, int, int, boolean)
	 * method.
	 *
	 * So, if any change needs to be applied in the current algorithm,
	 * do NOT forget to also apply the same change in the StringOperation method!
	 */

	if (name == null)
		return false; // null name cannot match
	if (pattern == null)
		return true; // null pattern is equivalent to '*'
	if (patternEnd < 0) 	patternEnd = pattern.length;
	if (nameEnd < 0) nameEnd = name.length;

	if (patternEnd <= patternStart) return nameEnd <= nameStart;
	if (nameEnd <= nameStart) return false;
	// check first pattern char
	if (name[nameStart] != pattern[patternStart]) {
		// first char must strictly match (upper/lower)
		return false;
	}

	char patternChar, nameChar;
	int iPattern = patternStart;
	int iName = nameStart;

	// Main loop is on pattern characters
	while (true) {

		iPattern++;
		iName++;

		if (iPattern == patternEnd) { // we have exhausted pattern...
			// it's a match if the name can have additional parts (i.e. uppercase characters) or is also exhausted
			if (!samePartCount || iName == nameEnd) return true;

			// otherwise it's a match only if the name has no more uppercase characters
			while (true) {
				if (iName == nameEnd) {
					// we have exhausted the name, so it's a match
					return true;
				}
				nameChar = name[iName];
				// test if the name character is uppercase
				if (nameChar < ScannerHelper.MAX_OBVIOUS) {
					if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar] & ScannerHelper.C_UPPER_LETTER) != 0) {
						return false;
					}
				}
				else if (!Character.isJavaIdentifierPart(nameChar) || Character.isUpperCase(nameChar)) {
					return false;
				}
				iName++;
			}
		}

		if (iName == nameEnd){
			// We have exhausted the name (and not the pattern), so it's not a match
			return false;
		}

		// For as long as we're exactly matching, bring it on (even if it's a lower case character)
		if ((patternChar = pattern[iPattern]) == name[iName]) {
			continue;
		}

		// If characters are not equals, then it's not a match if patternChar is lowercase
		if (patternChar < ScannerHelper.MAX_OBVIOUS) {
			if ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[patternChar] & (ScannerHelper.C_UPPER_LETTER | ScannerHelper.C_DIGIT)) == 0) {
				return false;
			}
		}
		else if (Character.isJavaIdentifierPart(patternChar) && !Character.isUpperCase(patternChar) && !Character.isDigit(patternChar)) {
			return false;
		}

		// patternChar is uppercase, so let's find the next uppercase in name
		while (true) {
			if (iName == nameEnd){
	            //	We have exhausted name (and not pattern), so it's not a match
				return false;
			}

			nameChar = name[iName];
			if (nameChar < ScannerHelper.MAX_OBVIOUS) {
				int charNature = ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[nameChar];
				if ((charNature & (ScannerHelper.C_LOWER_LETTER | ScannerHelper.C_SPECIAL)) != 0) {
					// nameChar is lowercase
					iName++;
				} else if ((charNature & ScannerHelper.C_DIGIT) != 0) {
					// nameChar is digit => break if the digit is current pattern character otherwise consume it
					if (patternChar == nameChar) break;
					iName++;
				// nameChar is uppercase...
				} else  if (patternChar != nameChar) {
					//.. and it does not match patternChar, so it's not a match
					return false;
				} else {
					//.. and it matched patternChar. Back to the big loop
					break;
				}
			}
			// Same tests for non-obvious characters
			else if (Character.isJavaIdentifierPart(nameChar) && !Character.isUpperCase(nameChar)) {
				iName++;
			} else if (Character.isDigit(nameChar)) {
				if (patternChar == nameChar) break;
				iName++;
			} else  if (patternChar != nameChar) {
				return false;
			} else {
				break;
			}
		}
		// At this point, either name has been exhausted, or it is at an uppercase letter.
		// Since pattern is also at an uppercase letter
	}
}

/**
 * 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;
	int length = charArrays.length;
	if (length == 0)
		return NO_STRINGS;
	String[] strings= new String[length];
	for (int i= 0; i < 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 two char arrays lexicographically.
 *
 * Returns a negative integer if array1 lexicographically precedes the array2,
 * a positive integer if this array1 lexicographically follows the array2, or
 * zero if both arrays are equal.
 *
 * @param array1 the first given array
 * @param array2 the second given array
 * @return the returned value of the comparison between array1 and array2
 * @throws NullPointerException if one of the arrays is null
 * @since 3.3
 */
public static final int compareTo(char[] array1, char[] array2) {
	int length1 = array1.length;
	int length2 = array2.length;
	int min = Math.min(length1, length2);
	for (int i = 0; i < min; i++) {
		if (array1[i] != array2[i]) {
			return array1[i] - array2[i];
		}
	}
	return length1 - length2;
}
/**
 * Compares the two char arrays lexicographically between the given start and end positions.
 *
 * Returns a negative integer if array1 lexicographically precedes the array2,
 * a positive integer if this array1 lexicographically follows the array2, or
 * zero if both arrays are equal.
 * <p>The comparison is done between start and end positions.</p>
 *
 * @param array1 the first given array
 * @param array2 the second given array
 * @param start the starting position to compare (inclusive)
 * @param end the ending position to compare (exclusive)
 * 
 * @return the returned value of the comparison between array1 and array2
 * @throws NullPointerException if one of the arrays is null
 * @since 3.7.1
 */
public static final int compareTo(char[] array1, char[] array2, int start, int end) {
	int length1 = array1.length;
	int length2 = array2.length;
	int min = Math.min(length1, length2);
	min = Math.min(min, end);
	for (int i = start; i < min; i++) {
		if (array1[i] != array2[i]) {
			return array1[i] - array2[i];
		}
	}
	return length1 - length2;
}
/**
 * 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
 * first 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 concatenated 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 prepending the given name at the beginning.
 * <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 prepending the given name at the beginning
 */
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 true if the array contains an occurrence of one of the characters, false otherwise.
 *
 * <br>
 * <br>
 * For example:
 * <ol>
 * <li><pre>
 *    characters = { 'c', 'd' }
 *    array = { 'a', ' b'  }
 *    result => false
 * </pre>
 * </li>
 * <li><pre>
 *    characters = { 'c', 'd' }
 *    array = { 'a', ' b', 'c'  }
 *    result => true
 * </pre>
 * </li>
 * </ol>
 *
 * @param characters the characters to search
 * @param array the array in which the search is done
 * @return true if the array contains an occurrence of one of the characters, false otherwise.
 * @throws NullPointerException if array is null.
 * @since 3.1
 */
public static final boolean contains(char[] characters, char[] array) {
	for (int i = array.length; --i >= 0;)
		for (int j = characters.length; --j >= 0;)
			if (array[i] == characters[j])
				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) {
	return equals(first, second, secondStart, secondEnd, true);
}
/**
 * <p>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 could be either
 * case sensitive or case insensitive according to the value of the <code>isCaseSensitive</code> parameter.
 * </p>
 * <p>For example:</p>
 * <ol>
 * <li><pre>
 *    first = null
 *    second = null
 *    secondStart = 0
 *    secondEnd = 0
 *    isCaseSensitive = false
 *    result => true
 * </pre>
 * </li>
 * <li><pre>
 *    first = { }
 *    second = null
 *    secondStart = 0
 *    secondEnd = 0
 *    isCaseSensitive = false
 *    result => false
 * </pre>
 * </li>
 * <li><pre>
 *    first = { 'a' }
 *    second = { 'a' }
 *    secondStart = 0
 *    secondEnd = 1
 *    isCaseSensitive = true
 *    result => true
 * </pre>
 * </li>
 * <li><pre>
 *    first = { 'a' }
 *    second = { 'A' }
 *    secondStart = 0
 *    secondEnd = 1
 *    isCaseSensitive = true
 *    result => false
 * </pre>
 * </li>
 * <li><pre>
 *    first = { 'a' }
 *    second = { 'A' }
 *    secondStart = 0
 *    secondEnd = 1
 *    isCaseSensitive = false
 *    result => true
 * </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
 * @param isCaseSensitive check whether or not the equality should be case sensitive
 * @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.2
 */
public static final boolean equals(char[] first, char[] second, int secondStart, int secondEnd, boolean isCaseSensitive) {
	if (first == second)
		return true;
	if (first == null || second == null)
		return false;
	if (first.length != secondEnd - secondStart)
		return false;
	if (isCaseSensitive) {
		for (int i = first.length; --i >= 0;)
			if (first[i] != second[i+secondStart])
				return false;
	} else {
		for (int i = first.length; --i >= 0;)
			if (ScannerHelper.toLowerCase(first[i]) != ScannerHelper.toLowerCase(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 (ScannerHelper.toLowerCase(first[i])
			!= ScannerHelper.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 (ScannerHelper.toLowerCase(fragment[i])
			!= ScannerHelper.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 length = array.length;
	int hash = length == 0 ? 31 : array[0];
	if (length < 8) {
		for (int i = length; --i > 0;)
			hash = (hash * 31) + array[i];
	} else {
		// 8 characters is enough to compute a decent hash code, don't waste time examining every character
		for (int i = length - 1, last = i > 16 ? i - 16 : 0; i > last; i -= 2)
			hash = (hash * 31) + array[i];
	}
	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) {
	return c < ScannerHelper.MAX_OBVIOUS && ((ScannerHelper.OBVIOUS_IDENT_CHAR_NATURES[c] & ScannerHelper.C_JLS_SPACE) != 0);
}

/**
 * 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) {
	return indexOf(toBeFound, array, 0);
}

/**
 * Answers the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule. Answers -1 if no match 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 subarray to search
 * @param array the array to be searched
 * @param isCaseSensitive flag to know if the matching should be case sensitive
 * @return the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule, -1 otherwise
 * @throws NullPointerException if array is null or toBeFound is null
 * @since 3.2
 */
public static final int indexOf(char[] toBeFound, char[] array, boolean isCaseSensitive) {
	return indexOf(toBeFound, array, isCaseSensitive, 0);
}

/**
 * Answers the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule starting at the index start. Answers -1 if no match 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 subarray to search
 * @param array the array to be searched
 * @param isCaseSensitive flag to know if the matching should be case sensitive
 * @param start the starting index
 * @return the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule starting at the index start, -1 otherwise
 * @throws NullPointerException if array is null or toBeFound is null
 * @since 3.2
 */
public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start) {
	return indexOf(toBeFound, array, isCaseSensitive, start, array.length);
}

/**
 * Answers the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule starting at the index start. Answers -1 if no match 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 subarray to search
 * @param array the array to be searched
 * @param isCaseSensitive flag to know if the matching should be case sensitive
 * @param start the starting index (inclusive)
 * @param end the end index (exclusive)
 * @return the first index in the array for which the toBeFound array is a matching
 * subarray following the case rule starting at the index start, -1 otherwise
 * @throws NullPointerException if array is null or toBeFound is null
 * @since 3.2
 */
public static final int indexOf(final char[] toBeFound, final char[] array, final boolean isCaseSensitive, final int start, final int end) {
	final int arrayLength = end;
	final int toBeFoundLength = toBeFound.length;
	if (toBeFoundLength > arrayLength || start < 0) return -1;
	if (toBeFoundLength == 0) return 0;
	if (toBeFoundLength == arrayLength) {
		if (isCaseSensitive) {
			for (int i = start; i < arrayLength; i++) {
				if (array[i] != toBeFound[i]) return -1;
			}
			return 0;
		} else {
			for (int i = start; i < arrayLength; i++) {
				if (ScannerHelper.toLowerCase(array[i]) != ScannerHelper.toLowerCase(toBeFound[i])) return -1;
			}
			return 0;
		}
	}
	if (isCaseSensitive) {
		arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
			if (array[i] == toBeFound[0]) {
				for (int j = 1; j < toBeFoundLength; j++) {
					if (array[i + j] != toBeFound[j]) continue arrayLoop;
				}
				return i;
			}
		}
	} else {
		arrayLoop: for (int i = start, max = arrayLength - toBeFoundLength + 1; i < max; i++) {
			if (ScannerHelper.toLowerCase(array[i]) == ScannerHelper.toLowerCase(toBeFound[0])) {
				for (int j = 1; j < toBeFoundLength; j++) {
					if (ScannerHelper.toLowerCase(array[i + j]) != ScannerHelper.toLowerCase(toBeFound[j])) continue arrayLoop;
				}
				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 first index in the array for which the corresponding character is
 * equal to toBeFound starting the search at index start and before the ending index.
 * 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 (inclusive)
 * @param end the ending index (exclusive)
 * @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 or ending greater than array length
 * @since 3.2
 */
public static final int indexOf(char toBeFound, char[] array, int start, int end) {
	for (int i = start; i < end; 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 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 = 4
 *    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 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 (true) {
		if (iPattern == patternEnd) {
			if (iName == nameEnd) return true; // the chars match
			return false; // pattern has ended but not the name, no match
		} 
		if ((patternChar = pattern[iPattern]) == '*') {
			break;
		}
		if (iName == nameEnd) {
			return false; // name has ended but not the pattern
		}
		if (patternChar
			!= (isCaseSensitive
				? name[iName]
				: ScannerHelper.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] : ScannerHelper.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;
}
/**
 * Return the int value represented by the designated subpart of array. The
 * calculation of the result for single-digit positive integers is optimized in
 * time.
 * @param array the array within which the int value is to be parsed
 * @param start first character of the int value in array
 * @param length length of the int value in array
 * @return the int value of a subpart of array
 * @throws NumberFormatException if the designated subpart of array does not
 *         parse to an int
 * @since 3.4
 */
public static final int parseInt(char[] array, int start, int length) throws NumberFormatException {
	if (length == 1) {
		int result = array[start] - '0';
		if (result < 0 || result > 9) {
			throw new NumberFormatException("invalid digit"); //$NON-NLS-1$
		}
		return result;
	} else {
		return Integer.parseInt(new String(array, start, length));
	}
}
/**
 * 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) {
	return prefixEquals(prefix, name, isCaseSensitive, 0);
}

/**
 * Answers true if the given name, starting from the given index, 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 = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
 *    startIndex = 2
 *    isCaseSensitive = false
 *    result => true
 * </pre>
 * </li>
 * <li><pre>
 *    prefix = { 'a' , 'B' }
 *    name = { 'c', 'd', 'a' , 'b', 'b', 'a', 'b', 'a' }
 *    startIndex = 2
 *    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
 * @param startIndex index from which the prefix should be searched in the 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
 * @since 3.7
 */
public static final boolean prefixEquals(
	char[] prefix,
	char[] name,
	boolean isCaseSensitive,
	int startIndex) {

	int max = prefix.length;
	if (name.length - startIndex < max)
		return false;
	if (isCaseSensitive) {
		for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
			if (prefix[i] != name[startIndex + i])
				return false;
		return true;
	}

	for (int i = max; --i >= 0;) // assumes the prefix is not larger than the name
		if (ScannerHelper.toLowerCase(prefix[i])
			!= ScannerHelper.toLowerCase(name[startIndex + i]))
			return false;
	return true;
}

/**
 * Answers a new array removing a given character. Answers the given array if there is
 * no occurrence of the character to remove.
 * <br>
 * <br>
 * For example:
 * <ol>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'c', 'b', 'a' }
 *    toBeRemoved = 'b'
 *    return { 'a' , 'c', 'a' }
 * </pre>
 * </li>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
 *    toBeRemoved = 'c'
 *    return array
 * </pre>
 * </li>
 * </ol>
 *
 * @param array the given array
 * @param toBeRemoved the character to be removed
 * @return a new array removing given character
 * @since 3.2
 */
public static final char[] remove(char[] array, char toBeRemoved) {

	if (array == null) return null;
	int length = array.length;
	if (length == 0) return array;
	char[] result = null;
	int count = 0;
	for (int i = 0; i < length; i++) {
		char c = array[i];
		if (c == toBeRemoved) {
			if (result == null) {
				result = new char[length];
				System.arraycopy(array, 0, result, 0, i);
				count = i;
			}
		} else if (result != null) {
			result[count++] = c;
		}
	}
	if (result == null) return array;
	System.arraycopy(result, 0, result = new char[count], 0, count);
	return result;
}

/**
 * Replace all occurrence of the character to be replaced with the replacement 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;
		}
	}
}

/**
 * Replace all occurrences of characters to be replaced with the replacement character in the
 * given array.
 * <br>
 * <br>
 * For example:
 * <ol>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
 *    toBeReplaced = { 'b', 'c' }
 *    replacementChar = 'a'
 *    result => No returned value, but array is now equals to { 'a' , 'a', 'a', 'a', 'a', 'a', 'a', 'a' }
 * </pre>
 * </li>
 * </ol>
 *
 * @param array the given array
 * @param toBeReplaced characters to be replaced
 * @param replacementChar the replacement character
 * @throws NullPointerException if arrays are null.
 * @since 3.1
 */
public static final void replace(char[] array, char[] toBeReplaced, char replacementChar) {
	replace(array, toBeReplaced, replacementChar, 0, array.length);
}

/**
 * Replace all occurrences of characters to be replaced with the replacement character in the
 * given array from the start position (inclusive) to the end position (exclusive).
 * <br>
 * <br>
 * For example:
 * <ol>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'c', 'a', 'b', 'c', 'a' }
 *    toBeReplaced = { 'b', 'c' }
 *    replacementChar = 'a'
 *    start = 4
 *    end = 8
 *    result => No returned value, but array is now equals to { 'a' , 'b', 'b', 'c', 'a', 'a', 'a', 'a' }
 * </pre>
 * </li>
 * </ol>
 *
 * @param array the given array
 * @param toBeReplaced characters to be replaced
 * @param replacementChar the replacement character
 * @param start the given start position (inclusive)
 * @param end  the given end position (exclusive)
 * @throws NullPointerException if arrays are null.
 * @since 3.2
 */
public static final void replace(char[] array, char[] toBeReplaced, char replacementChar, int start, int end) {
	for (int i = end; --i >= start;)
		for (int j = toBeReplaced.length; --j >= 0;)
			if (array[i] == toBeReplaced[j])
				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;) {
			int index = indexOf(toBeReplaced, array, true, i);
			if (index == -1) {
				i++;
				continue next;
			}
			if (occurrenceCount == starts.length) {
				System.arraycopy(
					starts,
					0,
					starts = new int[occurrenceCount * 2],
					0,
					occurrenceCount);
			}
			starts[occurrenceCount++] = index;
			i = index + replacedLength;
		}
	}
	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;
}

/**
 * Replace all occurrence of the character to be replaced with the replacement character
 * in a copy of the given array. Returns the given array if no occurrences of the character
 * to be replaced are found.
 * <br>
 * <br>
 * For example:
 * <ol>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
 *    toBeReplaced = 'b'
 *    replacementChar = 'a'
 *    result => A new array that is equals to { 'a' , 'a', 'a', 'a', 'a', 'a' }
 * </pre>
 * </li>
 * <li><pre>
 *    array = { 'a' , 'b', 'b', 'a', 'b', 'a' }
 *    toBeReplaced = 'c'
 *    replacementChar = 'a'
 *    result => The original array that remains unchanged.
 * </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
 * @since 3.1
 */
public static final char[] replaceOnCopy(
	char[] array,
	char toBeReplaced,
	char replacementChar) {

	char[] result = null;
	for (int i = 0, length = array.length; i < length; i++) {
		char c = array[i];
		if (c == toBeReplaced) {
			if (result == null) {
				result = new char[length];
				System.arraycopy(array, 0, result, 0, i);
			}
			result[i] = replacementChar;
		} else if (result != null) {
			result[i] = c;
		}
	}
	if (result == null) return array;
	return result;
}

/**
 * Return a new array which is the split of the given array using the given divider and trimming 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 trimming 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 = ScannerHelper.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 the result of a char[] conversion to uppercase. 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 uppercase
 * 
 * @since 3.5
 */
final static public char[] toUpperCase(char[] chars) {
	if (chars == null)
		return null;
	int length = chars.length;
	char[] upperChars = null;
	for (int i = 0; i < length; i++) {
		char c = chars[i];
		char lc = ScannerHelper.toUpperCase(c);
		if ((c != lc) || (upperChars != null)) {
			if (upperChars == null) {
				System.arraycopy(
					chars,
					0,
					upperChars = new char[length],
					0,
					i);
			}
			upperChars[i] = lc;
		}
	}
	return upperChars == null ? chars : upperChars;
}

/**
 * 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) {
	if (array == null) return NO_STRINGS;
	int length = array.length;
	if (length == 0) return NO_STRINGS;
	String[] result = new String[length];
	for (int i = 0; i < length; i++)
		result[i] = new String(array[i]);
	return result;
}
}
