/*******************************************************************************
 * Copyright (c) 2001, 2004 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.core.internal.util;



import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.wst.sse.core.internal.Logger;


public class StringUtils {
	protected static final String AMPERSTAND = "&"; //$NON-NLS-1$
	protected static final String AMPERSTAND_ENTITY = "&&;"; //$NON-NLS-1$
	protected static final String CARRIAGE_RETURN = "\r"; //$NON-NLS-1$
	protected static final String CARRIAGE_RETURN_ENTITY = "\\r"; //$NON-NLS-1$
	protected static final String CR = "\r"; //$NON-NLS-1$
	protected static final String CRLF = "\r\n"; //$NON-NLS-1$
	protected static final String DELIMITERS = " \t\n\r\f"; //$NON-NLS-1$
	protected static final String DOUBLE_QUOTE = "\""; //$NON-NLS-1$
	protected static final char DOUBLE_QUOTE_CHAR = '\"'; //$NON-NLS-1$
	protected static final String DOUBLE_QUOTE_ENTITY = "&quot;"; //$NON-NLS-1$

	protected static final String EQUAL_SIGN = "="; //$NON-NLS-1$
	protected static final String EQUAL_SIGN_ENTITY = "&#61;"; //$NON-NLS-1$
	private static final String FALSE = "false"; //$NON-NLS-1$
	protected static final String GREATER_THAN = ">"; //$NON-NLS-1$
	protected static final String GREATER_THAN_ENTITY = "&gt;"; //$NON-NLS-1$
	protected static final String LESS_THAN = "<"; //$NON-NLS-1$
	protected static final String LESS_THAN_ENTITY = "&lt;"; //$NON-NLS-1$
	protected static final String LF = "\n"; //$NON-NLS-1$
	protected static final String LINE_FEED = "\n"; //$NON-NLS-1$
	protected static final String LINE_FEED_ENTITY = "\\n"; //$NON-NLS-1$
	protected static final String LINE_FEED_TAG = "<dl>"; //$NON-NLS-1$
	protected static final String LINE_TAB = "\t"; //$NON-NLS-1$
	protected static final String LINE_TAB_ENTITY = "\\t"; //$NON-NLS-1$
	protected static final String LINE_TAB_TAG = "<dd>"; //$NON-NLS-1$
	protected static final String SINGLE_QUOTE = "'"; //$NON-NLS-1$
	protected static final char SINGLE_QUOTE_CHAR = '\''; //$NON-NLS-1$
	protected static final String SINGLE_QUOTE_ENTITY = "&#039;"; //$NON-NLS-1$
	protected static final String SPACE = " "; //$NON-NLS-1$
	protected static final String SPACE_ENTITY = "&nbsp;"; //$NON-NLS-1$
	private static final String TRUE = "true"; //$NON-NLS-1$

	/**
	 * Append appendString to the end of aString only if aString does not end
	 * with the insertString.
	 */
	public static String appendIfNotEndWith(String aString, String appendString) {
		if ((aString != null) && (appendString != null))
			if (aString.endsWith(appendString))
				return aString;
			else
				return aString + appendString;
		else
			return aString;
	}

	/**
	 * Breaks out space-separated words into an array of words. For example:
	 * <code>"no comment"</code> into an array <code>a[0]="no"</code> and
	 * <code>a[1]= "comment"</code>.
	 * 
	 * @param value
	 *            the string to be converted
	 * @return the list of words
	 */
	public static String[] asArray(String value) {
		ArrayList list = new ArrayList();
		StringTokenizer stok = new StringTokenizer(value);
		while (stok.hasMoreTokens()) {
			list.add(stok.nextToken());
		}
		String result[] = new String[list.size()];
		list.toArray(result);
		return result;
	}

	/**
	 * Breaks out delim-separated words into an array of words. For example:
	 * <code>"no comment"</code> into an array <code>a[0]="no"</code> and
	 * <code>a[1]= "comment"</code>.
	 * 
	 * @param value
	 *            the string to be converted
	 * @return the list of words
	 */
	public static String[] asArray(String value, String delim) {
		return asArray(value, delim, false);
	}

	/**
	 * Breaks out delim-separated words into an array of words. For example:
	 * <code>"no comment"</code> into an array <code>a[0]="no"</code> and
	 * <code>a[1]= "comment"</code>.
	 * 
	 * @param value
	 *            the string to be converted
	 * @return the list of words
	 */
	public static String[] asArray(String value, String delim, boolean returnTokens) {
		ArrayList list = new ArrayList();
		StringTokenizer stok = new StringTokenizer(value, delim, returnTokens);
		while (stok.hasMoreTokens()) {
			list.add(stok.nextToken());
		}
		String result[] = new String[list.size()];
		list.toArray(result);
		return result;
	}

	/**
	 * Breaks out delim-separated words into an array of words. For example:
	 * <code>"abc,,def"</code> into an array <code>a[0]="abc"</code>,
	 * <code>a[1]=null</code>, and <code>a[2]= "def"</code> where "," is
	 * the delim.
	 * 
	 * @param value
	 *            the string to be converted
	 * @return the list of words
	 */
	public static String[] asFixedArray(String value, String delim) {
		String array[] = asArray(value, delim, true);
		int arrayLength = array.length;
		boolean stringFound = false;
		ArrayList list = new ArrayList();

		for (int i = 0; i < arrayLength; i++) {
			String token = array[i];
			if (token.compareTo(delim) == 0) {
				if (!stringFound)
					list.add(null);
				stringFound = false;
			}
			else {
				list.add(token);
				stringFound = true;
			}
		}
		// add one more null if last token is the delim
		if (!stringFound)
			list.add(null);

		String result[] = new String[list.size()];
		list.toArray(result);
		return result;
	}

	public static String chop(String source) {
		return chop(source, "/"); //$NON-NLS-1$
	}

	public static String chop(String source, String delimiter) {
		return source.substring(0, source.lastIndexOf(delimiter));
	}

	public static boolean contains(String[] arrayOfStrings, String needle, boolean caseSensitive) {
		boolean result = false;
		if (needle == null)
			return false;
		if (arrayOfStrings == null)
			return false;

		if (caseSensitive) {
			for (int i = 0; i < arrayOfStrings.length; i++) {
				if (needle.equals(arrayOfStrings[i])) {
					result = true;
					break;
				}
			}
		}
		else {
			for (int i = 0; i < arrayOfStrings.length; i++) {
				if (needle.equalsIgnoreCase(arrayOfStrings[i])) {
					result = true;
					break;
				}
			}
		}
		return result;
	}

	public static boolean containsLetters(String fullValue) {

		if (fullValue == null || fullValue.length() == 0)
			return false;

		char[] chars = fullValue.toCharArray();
		for (int i = 0; i < fullValue.length(); i++)
			if (Character.isLetter(chars[i]))
				return true;

		return false;
	}

	public static boolean containsLineDelimiter(String aString) {
		return indexOfLineDelimiter(aString) != -1;
	}

	public static String convertLineDelimiters(String allText, String lineDelimiterToUse) {
		IDocument tempDoc = new Document(allText);

		if (lineDelimiterToUse == null)
			lineDelimiterToUse = System.getProperty("line.separator"); //$NON-NLS-1$

		String newText = ""; //$NON-NLS-1$
		int lineCount = tempDoc.getNumberOfLines();
		for (int i = 0; i < lineCount; i++) {
			try {
				org.eclipse.jface.text.IRegion lineInfo = tempDoc.getLineInformation(i);
				int lineStartOffset = lineInfo.getOffset();
				int lineLength = lineInfo.getLength();
				int lineEndOffset = lineStartOffset + lineLength;
				newText += allText.substring(lineStartOffset, lineEndOffset);

				if ((i < lineCount - 1) && (tempDoc.getLineDelimiter(i) != null))
					newText += lineDelimiterToUse;
			}
			catch (BadLocationException e) {
				// log for now, unless we find reason not to
				Logger.log(Logger.INFO, e.getMessage());
			}
		}

		return newText;
	}

	/**
	 * Replaces all instances of special HTML characters with the appropriate
	 * HTML entity equivalent. WARNING only use this method for strings that
	 * dont already have HTML-specific items such as tags and entities.
	 * 
	 * @param String
	 *            content String to convert
	 * 
	 * @return String the converted string
	 * @see HTMLPrinter#convertToHTMLContent(String content)
	 */
	public static String convertToHTMLContent(String content) {
		content = replace(content, AMPERSTAND, AMPERSTAND_ENTITY);
		content = replace(content, LESS_THAN, LESS_THAN_ENTITY);
		content = replace(content, GREATER_THAN, GREATER_THAN_ENTITY);
		content = replace(content, LINE_FEED, LINE_FEED_TAG);
		content = replace(content, LINE_TAB, LINE_TAB_TAG);
		content = replace(content, SINGLE_QUOTE, SINGLE_QUOTE_ENTITY);
		content = replace(content, DOUBLE_QUOTE, DOUBLE_QUOTE_ENTITY);
		content = replace(content, SPACE + SPACE, SPACE_ENTITY + SPACE_ENTITY); // replacing
		// every
		// space
		// would
		// be
		// too
		// much
		return content;
	}

	/**
	 * Converts a string into a form that will not conflict with saving it
	 * into an INI file
	 */
	public static String escape(String normalString) {
		if (normalString == null)
			return null;
		StringBuffer escapedBuffer = new StringBuffer();
		StringTokenizer toker = new StringTokenizer(normalString, EQUAL_SIGN + LINE_FEED + CARRIAGE_RETURN + LINE_TAB, true);
		String chunk = null;
		while (toker.hasMoreTokens()) {
			chunk = toker.nextToken();
			if (chunk.equals(EQUAL_SIGN)) {
				escapedBuffer.append(EQUAL_SIGN_ENTITY);
			}
			else if (chunk.equals(LINE_FEED)) {
				escapedBuffer.append(LINE_FEED_ENTITY);
			}
			else if (chunk.equals(CARRIAGE_RETURN)) {
				escapedBuffer.append(CARRIAGE_RETURN_ENTITY);
			}
			else if (chunk.equals(LINE_TAB)) {
				escapedBuffer.append(LINE_TAB_ENTITY);
			}
			else {
				escapedBuffer.append(chunk);
			}
		}
		return escapedBuffer.toString();
	}

	/**
	 * Returns the first line of the given text without a trailing delimiter
	 * 
	 * @param text
	 * @return
	 */
	public static String firstLineOf(String text) {
		if (text == null || text.length() < 1) {
			return text;
		}
		IDocument doc = new Document(text);
		try {
			int lineNumber = doc.getLineOfOffset(0);
			IRegion line = doc.getLineInformation(lineNumber);
			return doc.get(line.getOffset(), line.getLength());
		}
		catch (BadLocationException e) {
			// do nothing
		}
		return text;
	}

	public static int indexOfLastLineDelimiter(String aString) {
		return indexOfLastLineDelimiter(aString, aString.length());
	}

	public static int indexOfLastLineDelimiter(String aString, int offset) {
		int index = -1;

		if (aString != null && aString.length() > 0) {
			index = aString.lastIndexOf(CRLF, offset);
			if (index == -1) {
				index = aString.lastIndexOf(CR, offset);
				if (index == -1)
					index = aString.lastIndexOf(LF, offset);
			}
		}

		return index;
	}

	public static int indexOfLineDelimiter(String aString) {
		return indexOfLineDelimiter(aString, 0);
	}

	public static int indexOfLineDelimiter(String aString, int offset) {
		int index = -1;

		if (aString != null && aString.length() > 0) {
			index = aString.indexOf(CRLF, offset);
			if (index == -1) {
				index = aString.indexOf(CR, offset);
				if (index == -1)
					index = aString.indexOf(LF, offset);
			}
		}

		return index;
	}

	public static int indexOfNonblank(String aString) {
		return indexOfNonblank(aString, 0);
	}

	public static int indexOfNonblank(String aString, int offset) {
		int index = -1;

		if (aString != null && aString.length() > 0) {
			for (int i = offset; i < aString.length(); i++) {
				if (DELIMITERS.indexOf(aString.substring(i, i + 1)) == -1) {
					index = i;
					break;
				}
			}
		}

		return index;
	}

	/**
	 * Insert insertString to the beginning of aString only if aString does
	 * not start with the insertString.
	 */
	public static String insertIfNotStartWith(String aString, String insertString) {
		if ((aString != null) && (insertString != null))
			if (aString.startsWith(insertString))
				return aString;
			else
				return insertString + aString;
		else
			return aString;
	}

	public static boolean isQuoted(String string) {
		if ((string == null) || (string.length() < 2))
			return false;

		int lastIndex = string.length() - 1;
		char firstChar = string.charAt(0);
		char lastChar = string.charAt(lastIndex);

		return (((firstChar == SINGLE_QUOTE_CHAR) && (lastChar == SINGLE_QUOTE_CHAR)) || ((firstChar == DOUBLE_QUOTE_CHAR) && (lastChar == DOUBLE_QUOTE_CHAR)));
	}

	/**
	 * Unit tests.
	 * 
	 * @param args
	 *            java.lang.String[]
	 */
	public static void main(String[] args) {
		// testPaste();
		testStripNonLetterDigits();
	}

	/*
	 * Returns the merged form of both strings
	 */
	public static String merge(String newStart, String newEnd) {
		String[] regions = overlapRegions(newStart, newEnd);
		return regions[0] + regions[1] + regions[2];
	}

	public static int occurrencesOf(String searchString, char targetChar) {
		int result = 0;
		int len = searchString.length();
		for (int i = 0; i < len; i++) {
			if (targetChar == searchString.charAt(i))
				result++;
		}
		return result;
	}

	/**
	 * 
	 * @return java.lang.String[]
	 * @param start
	 *            java.lang.String
	 * @param end
	 *            java.lang.String
	 * 
	 * Returns a 3 String array containing unique text from the start,
	 * duplicated text that overlaps the start and end, and the unique text
	 * from the end.
	 */
	private static String[] overlapRegions(String start, String end) {
		String[] results = null;
		if (start != null && end == null) {
			results = new String[]{start, "", ""}; //$NON-NLS-2$//$NON-NLS-1$
		}
		else if (start == null && end != null) {
			results = new String[]{"", "", end}; //$NON-NLS-2$//$NON-NLS-1$
		}
		else if (start == null && end == null) {
			results = new String[]{"", "", ""}; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
		}
		else if (start != null && end != null) {

			int startLength = start.length();
			int endLength = end.length();

			if (startLength == 0 || endLength == 0) {
				results = new String[]{"", "", ""}; //$NON-NLS-3$//$NON-NLS-2$//$NON-NLS-1$
			}
			else {
				results = new String[3];
				String testStart = ""; //$NON-NLS-1$
				String testEnd = ""; //$NON-NLS-1$
				int mergeLength = Math.min(startLength, endLength);
				boolean finished = false;
				while (mergeLength > 0 && !finished) {
					testStart = start.substring(startLength - mergeLength);
					testEnd = end.substring(0, mergeLength);
					// case sensitive
					if (testStart.equals(testEnd)) {
						finished = true;
						results[0] = start.substring(0, startLength - mergeLength);
						results[1] = start.substring(startLength - mergeLength);
						results[2] = end.substring(mergeLength);
					}
					mergeLength--;
				}
				if (!finished) {
					results[0] = start;
					results[1] = ""; //$NON-NLS-1$
					results[2] = end;
				}
			}
		}
		return results;
	}

	/**
	 * Packs an array of Strings into a single comma delimited String.
	 * 
	 * @param strings
	 * @return
	 * @todo Generated comment
	 */
	public static String pack(String[] strings) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < strings.length; i++) {
			buf.append(StringUtils.replace(strings[i], ",", "&comma;")); //$NON-NLS-1$ //$NON-NLS-2$
			if (i < strings.length - 1)
				buf.append(","); //$NON-NLS-1$
		}
		return buf.toString();
	}

	/*
	 * Pastes the new text into the old at the start position, replacing text
	 * implied by length.
	 */
	public static String paste(String oldText, String newText, int start, int length) {
		String result = null;
		StringBuffer sb = new StringBuffer();
		int startIndex = start;
		int endIndex = start + length;
		if (startIndex > oldText.length()) {
			startIndex = oldText.length();
		}
		sb.append(oldText.substring(0, startIndex));
		// null or empty new text accompliches a delete
		if (newText != null) {
			sb.append(newText);
		}
		if (endIndex < oldText.length()) {

			sb.append(oldText.substring(endIndex));
		}
		result = sb.toString();
		return result;
	}

	/**
	 * Replace matching literal portions of a string with another string
	 */
	public static String replace(String aString, String source, String target) {
		if (aString == null)
			return null;
		String normalString = ""; //$NON-NLS-1$
		int length = aString.length();
		int position = 0;
		int previous = 0;
		int spacer = source.length();
		while (position + spacer - 1 < length && aString.indexOf(source, position) > -1) {
			position = aString.indexOf(source, previous);
			normalString = normalString + aString.substring(previous, position) + target;
			position += spacer;
			previous = position;
		}
		normalString = normalString + aString.substring(position, aString.length());

		return normalString;
	}

	/**
	 * Restore the entity references for markup delimiters in text where they
	 * have been replaced by the proper Unicode values through a DOM text
	 * parser.
	 */
	public static String restoreMarkers(String text) {
		String content = text;
		content = replace(content, AMPERSTAND, AMPERSTAND_ENTITY);
		content = replace(content, LESS_THAN, LESS_THAN_ENTITY);
		content = replace(content, GREATER_THAN, GREATER_THAN_ENTITY);
		return content;
	}

	/**
	 * Removes extra whitespace characters and quotes
	 */
	public static String strip(String quotedString) {
		if (quotedString == null || quotedString.length() == 0)
			return quotedString;
		String trimmed = quotedString.trim();
		if (trimmed.length() < 2)
			return quotedString;

		char first = trimmed.charAt(0);
		char nextToLast = trimmed.charAt(trimmed.length() - 2);
		char last = trimmed.charAt(trimmed.length() - 1);

		if ((first == '\"' && last == '\"' && nextToLast != '\\') || (first == '\'' && last == '\'' && nextToLast != '\\')) {
			return trimmed.substring(1, trimmed.length() - 1);
		}
		return trimmed;
	}

	/**
	 * This method strips anything from the beginning and end of a string that
	 * is not a letter or digit. It is used by some encoding detectors to come
	 * up with the encoding name from illformed input (e.g in <?xml
	 * encoding="abc?> -- where final quote is left off, the '>' is returned
	 * with the rest of the attribute value 'abc').
	 */
	public static String stripNonLetterDigits(String fullValue) {
		if (fullValue == null || fullValue.length() == 0)
			return fullValue;
		int fullValueLength = fullValue.length();
		int firstPos = 0;
		while (firstPos < fullValueLength && !Character.isLetterOrDigit(fullValue.charAt(firstPos))) {
			firstPos++;
		}
		int lastPos = fullValueLength - 1;
		while (lastPos > firstPos && !Character.isLetterOrDigit(fullValue.charAt(lastPos))) {
			lastPos--;
		}
		String result = fullValue;
		if (firstPos != 0 || lastPos != fullValueLength) {
			result = fullValue.substring(firstPos, lastPos + 1);
		}
		return result;
	}

	/**
	 * Similar to strip, except quotes don't need to match such as "UTF' is
	 * still stripped of both quotes. (Plus, this one does not detect escaped
	 * quotes)
	 */
	public static String stripQuotes(String quotedValue) {
		if (quotedValue == null)
			return null;
		// normally will never have leading or trailing blanks,
		// but if it does, we'll do lenient interpretation
		return stripQuotesLeaveInsideSpace(quotedValue).trim();
	}

	/**
	 * Like strip quotes, except leaves the start and end space inside the
	 * quotes
	 * 
	 * @param quotedValue
	 * @return
	 */
	public static String stripQuotesLeaveInsideSpace(String quotedValue) {
		if (quotedValue == null)
			return null;
		// nomally will never have leading or trailing blanks ... but just in
		// case.
		String result = quotedValue.trim();
		int len = result.length();
		if (len > 0) {
			char firstChar = result.charAt(0);
			if ((firstChar == SINGLE_QUOTE_CHAR) || (firstChar == DOUBLE_QUOTE_CHAR)) {
				result = result.substring(1, len);
			}
			len = result.length();
			if (len > 0) {
				char lastChar = result.charAt(len - 1);
				if ((lastChar == SINGLE_QUOTE_CHAR) || (lastChar == DOUBLE_QUOTE_CHAR)) {
					result = result.substring(0, len - 1);
				}
			}
		}
		return result;
	}

	public static void testPaste() {
		String testString = "The quick brown fox ..."; //$NON-NLS-1$
		System.out.println(paste(testString, null, 4, 5));
		System.out.println(paste(testString, null, 4, 6));
		System.out.println(paste(testString, "", 4, 6)); //$NON-NLS-1$
		System.out.println(paste(testString, "fast", 4, 6)); //$NON-NLS-1$
		System.out.println(paste(testString, "fast ", 4, 6)); //$NON-NLS-1$
		System.out.println(paste(testString, "But ", 0, 0)); //$NON-NLS-1$
		System.out.println(paste("", "burp", 4, 6)); //$NON-NLS-2$//$NON-NLS-1$
	}

	public static void testStripNonLetterDigits() {
		String testString = "abc"; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = ""; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = "\"abc\""; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = "\"ab-c1?"; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = "+++"; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = "abc="; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$
		testString = "abc "; //$NON-NLS-1$
		System.out.println(testString + " -->" + stripNonLetterDigits(testString) + "<--"); //$NON-NLS-1$ //$NON-NLS-2$

	}

	public static String toString(boolean booleanValue) {
		if (booleanValue)
			return TRUE;
		else
			return FALSE;
	}

	/**
	 * Remove "escaped" chars from a string.
	 */
	public static String unescape(String aString) {
		if (aString == null)
			return null;
		String normalString = replace(aString, EQUAL_SIGN_ENTITY, EQUAL_SIGN);
		normalString = replace(normalString, LINE_FEED_ENTITY, LINE_FEED);
		normalString = replace(normalString, CARRIAGE_RETURN_ENTITY, CARRIAGE_RETURN);
		normalString = replace(normalString, LINE_TAB_ENTITY, LINE_TAB);
		return normalString;
	}

	public static String uniqueEndOf(String newStart, String newEnd) {
		String[] regions = overlapRegions(newStart, newEnd);
		return regions[2];
	}

	/**
	 * Unpacks a comma delimited String into an array of Strings
	 * 
	 * @param s
	 * @return
	 * @todo Generated comment
	 */
	public static String[] unpack(String s) {
		if (s == null)
			return new String[0];
		StringTokenizer toker = new StringTokenizer(s, ","); //$NON-NLS-1$
		List list = new ArrayList();
		while (toker.hasMoreTokens()) {
			// since we're separating the values with ',', escape ',' in the
			// values
			list.add(StringUtils.replace(toker.nextToken(), "&comma;", ",").trim()); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return (String[]) list.toArray(new String[0]);
	}

	/**
	 * StringUtils constructor comment.
	 */
	private StringUtils() {
		super();
	}

}
