package org.apache.maven.shared.utils;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */


import java.util.Arrays;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.StringTokenizer;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * <p>Common <code>String</code> manipulation routines.</p>
 * <p/>
 * <p>Originally from
 * <a href="http://jakarta.apache.org/turbine/">Turbine</a>, the
 * GenerationJavaCore library and Velocity.
 * Later a lots methods from commons-lang StringUtils
 * got added too. Gradually smaller additions and fixes have been made
 * over the time by various ASF committers.</p>
 *
 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a>
 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
 * @author <a href="mailto:gcoladonato@yahoo.com">Greg Coladonato</a>
 * @author <a href="mailto:bayard@generationjava.com">Henri Yandell</a>
 * @author <a href="mailto:ed@apache.org">Ed Korthof</a>
 * @author <a href="mailto:rand_mcneely@yahoo.com">Rand McNeely</a>
 * @author Stephen Colebourne
 * @author <a href="mailto:fredrik@westermarck.com">Fredrik Westermarck</a>
 * @author Holger Krauth
 * @author <a href="mailto:alex@purpletech.com">Alexander Day Chaffee</a>
 * @version $Id$
 * 
 */
public class StringUtils
{
    /**
     * <p><code>StringUtils</code> instances should NOT be constructed in
     * standard programming. Instead, the class should be used as
     * <code>StringUtils.trim(" foo ");</code>.</p>
     * <p/>
     * <p>This constructor is public to permit tools that require a JavaBean
     * manager to operate.</p>
     */
    public StringUtils()
    {
    }

    // Empty
    //--------------------------------------------------------------------------

    /**
     * <p>Removes control characters, including whitespace, from both
     * ends of this String, handling <code>null</code> by returning
     * an empty String.</p>
     *
     * @param str the String to check
     * @return the trimmed text (never <code>null</code>)
     * @see java.lang.String#trim()
     */
    @Nonnull public static String clean( String str )
    {
        return ( str == null ? "" : str.trim() );
    }

    /**
     * <p>Removes control characters, including whitespace, from both
     * ends of this String, handling <code>null</code> by returning
     * <code>null</code>.</p>
     *
     * @param str the String to check
     * @return the trimmed text (or <code>null</code>)
     * @see java.lang.String#trim()
     */
    public static String trim( String str )
    {
        return ( str == null ? null : str.trim() );
    }

    /**
     * <p>Deletes all whitespaces from a String.</p>
     * <p/>
     * <p>Whitespace is defined by
     * {@link Character#isWhitespace(char)}.</p>
     *
     * @param str String target to delete whitespace from
     * @return the String without whitespaces
     * @throws NullPointerException
     */
    @Nonnull public static String deleteWhitespace( @Nonnull String str )
    {
        StringBuilder buffer = new StringBuilder();
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( !Character.isWhitespace( str.charAt( i ) ) )
            {
                buffer.append( str.charAt( i ) );
            }
        }
        return buffer.toString();
    }

    /**
     * <p>Checks if a String is non <code>null</code> and is
     * not empty (<code>length > 0</code>).</p>
     *
     * @param str the String to check
     * @return true if the String is non-null, and not length zero
     */
    public static boolean isNotEmpty( @Nullable String str )
    {
        return ( ( str != null ) && ( str.length() > 0 ) );
    }

    /**
     * <p>Checks if a (trimmed) String is <code>null</code> or empty.</p>
     * <p/>
     * <p><strong>Note:</strong> In future releases, this method will no longer trim the input string such that it works
     * complementary to {@link #isNotEmpty(String)}. Code that wants to test for whitespace-only strings should be
     * migrated to use {@link #isBlank(String)} instead.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if the String is <code>null</code>, or
     *         length zero once trimmed
     */
    public static boolean isEmpty( @Nullable String str )
    {
        return ( ( str == null ) || ( str.trim().length() == 0 ) );
    }

    /**
     * <p>
     * Checks if a String is whitespace, empty ("") or null.
     * </p>
     * <p/>
     * <pre>
     * StringUtils.isBlank(null)      = true
     * StringUtils.isBlank("")        = true
     * StringUtils.isBlank(" ")       = true
     * StringUtils.isBlank("bob")     = false
     * StringUtils.isBlank("  bob  ") = false
     * </pre>
     *
     * @param str the String to check, may be null
     * @return <code>true</code> if the String is null, empty or whitespace
     * 
     */
    public static boolean isBlank( @Nullable String str )
    {
        int strLen;
        // CHECKSTYLE_OFF: InnerAssignment
        if ( str == null || ( strLen = str.length() ) == 0 )
        // CHECKSTYLE_ON: InnerAssignment
        {
            return true;
        }
        for ( int i = 0; i < strLen; i++ )
        {
            if ( !Character.isWhitespace( str.charAt( i ) ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>
     * Checks if a String is not empty (""), not null and not whitespace only.
     * </p>
     * <p/>
     * <pre>
     * StringUtils.isNotBlank(null)      = false
     * StringUtils.isNotBlank("")        = false
     * StringUtils.isNotBlank(" ")       = false
     * StringUtils.isNotBlank("bob")     = true
     * StringUtils.isNotBlank("  bob  ") = true
     * </pre>
     *
     * @param str the String to check, may be null
     * @return <code>true</code> if the String is not empty and not null and not whitespace
     * 
     */
    public static boolean isNotBlank( @Nullable String str )
    {
        return !isBlank( str );
    }

    // Equals and IndexOf
    //--------------------------------------------------------------------------

    /**
     * <p>Compares two Strings, returning <code>true</code> if they are equal.</p>
     * <p/>
     * <p><code>null</code>s are handled without exceptions. Two <code>null</code>
     * references are considered to be equal. The comparison is case sensitive.</p>
     *
     * @param str1 the first string
     * @param str2 the second string
     * @return <code>true</code> if the Strings are equal, case sensitive, or
     *         both <code>null</code>
     * @see java.lang.String#equals(Object)
     */
    public static boolean equals( @Nullable String str1, @Nullable String str2 )
    {
        return ( str1 == null ? str2 == null : str1.equals( str2 ) );
    }

    /**
     * <p>Compares two Strings, returning <code>true</code> if they are equal ignoring
     * the case.</p>
     * <p/>
     * <p><code>Nulls</code> are handled without exceptions. Two <code>null</code>
     * references are considered equal. Comparison is case insensitive.</p>
     *
     * @param str1 the first string
     * @param str2 the second string
     * @return <code>true</code> if the Strings are equal, case insensitive, or
     *         both <code>null</code>
     * @see java.lang.String#equalsIgnoreCase(String)
     */
    public static boolean equalsIgnoreCase( String str1, String str2 )
    {
        return ( str1 == null ? str2 == null : str1.equalsIgnoreCase( str2 ) );
    }

    /**
     * <p>Find the first index of any of a set of potential substrings.</p>
     * <p/>
     * <p><code>null</code> String will return <code>-1</code>.</p>
     *
     * @param str        the String to check
     * @param searchStrs the Strings to search for
     * @return the first index of any of the searchStrs in str
     * @throws NullPointerException if any of searchStrs[i] is <code>null</code>
     */
    public static int indexOfAny( String str, String... searchStrs )
    {
        if ( ( str == null ) || ( searchStrs == null ) )
        {
            return -1;
        }
        // String's can't have a MAX_VALUEth index.
        int ret = Integer.MAX_VALUE;

        int tmp;
        for ( String searchStr : searchStrs )
        {
            tmp = str.indexOf( searchStr );
            if ( tmp == -1 )
            {
                continue;
            }

            if ( tmp < ret )
            {
                ret = tmp;
            }
        }

        return ( ret == Integer.MAX_VALUE ) ? -1 : ret;
    }

    /**
     * <p>Find the latest index of any of a set of potential substrings.</p>
     * <p/>
     * <p><code>null</code> string will return <code>-1</code>.</p>
     *
     * @param str        the String to check
     * @param searchStrs the Strings to search for
     * @return the last index of any of the Strings
     * @throws NullPointerException if any of searchStrs[i] is <code>null</code>
     */
    public static int lastIndexOfAny( String str, String... searchStrs )
    {
        if ( ( str == null ) || ( searchStrs == null ) )
        {
            return -1;
        }
        int ret = -1;
        int tmp;
        for ( String searchStr : searchStrs )
        {
            tmp = str.lastIndexOf( searchStr );
            if ( tmp > ret )
            {
                ret = tmp;
            }
        }
        return ret;
    }

    // Substring
    //--------------------------------------------------------------------------

    /**
     * <p>Gets a substring from the specified string avoiding exceptions.</p>
     * <p/>
     * <p>A negative start position can be used to start <code>n</code>
     * characters from the end of the String.</p>
     *
     * @param str   the String to get the substring from
     * @param start the position to start from, negative means
     *              count back from the end of the String by this many characters
     * @return substring from start position
     */
    public static String substring( String str, int start )
    {
        if ( str == null )
        {
            return null;
        }

        // handle negatives, which means last n characters
        if ( start < 0 )
        {
            start = str.length() + start; // remember start is negative
        }

        if ( start < 0 )
        {
            start = 0;
        }
        if ( start > str.length() )
        {
            return "";
        }

        return str.substring( start );
    }

    /**
     * <p>Gets a substring from the specified String avoiding exceptions.</p>
     * <p/>
     * <p>A negative start position can be used to start/end <code>n</code>
     * characters from the end of the String.</p>
     *
     * @param str   the String to get the substring from
     * @param start the position to start from, negative means
     *              count back from the end of the string by this many characters
     * @param end   the position to end at (exclusive), negative means
     *              count back from the end of the String by this many characters
     * @return substring from start position to end positon
     */
    public static String substring( String str, int start, int end )
    {
        if ( str == null )
        {
            return null;
        }

        // handle negatives
        if ( end < 0 )
        {
            end = str.length() + end; // remember end is negative
        }
        if ( start < 0 )
        {
            start = str.length() + start; // remember start is negative
        }

        // check length next
        if ( end > str.length() )
        {
            // check this works.
            end = str.length();
        }

        // if start is greater than end, return ""
        if ( start > end )
        {
            return "";
        }

        if ( start < 0 )
        {
            start = 0;
        }
        if ( end < 0 )
        {
            end = 0;
        }

        return str.substring( start, end );
    }

    /**
     * <p>Gets the leftmost <code>n</code> characters of a String.</p>
     * <p/>
     * <p>If <code>n</code> characters are not available, or the
     * String is <code>null</code>, the String will be returned without
     * an exception.</p>
     *
     * @param str the String to get the leftmost characters from
     * @param len the length of the required String
     * @return the leftmost characters
     * @throws IllegalArgumentException if len is less than zero
     */
    public static String left( String str, int len )
    {
        if ( len < 0 )
        {
            throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
        }
        if ( ( str == null ) || ( str.length() <= len ) )
        {
            return str;
        }
        else
        {
            return str.substring( 0, len );
        }
    }

    /**
     * <p>Gets the rightmost <code>n</code> characters of a String.</p>
     * <p/>
     * <p>If <code>n</code> characters are not available, or the String
     * is <code>null</code>, the String will be returned without an
     * exception.</p>
     *
     * @param str the String to get the rightmost characters from
     * @param len the length of the required String
     * @return the leftmost characters
     * @throws IllegalArgumentException if len is less than zero
     */
    public static String right( String str, int len )
    {
        if ( len < 0 )
        {
            throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
        }
        if ( ( str == null ) || ( str.length() <= len ) )
        {
            return str;
        }
        else
        {
            return str.substring( str.length() - len );
        }
    }

    /**
     * <p>Gets <code>n</code> characters from the middle of a String.</p>
     * <p/>
     * <p>If <code>n</code> characters are not available, the remainder
     * of the String will be returned without an exception. If the
     * String is <code>null</code>, <code>null</code> will be returned.</p>
     *
     * @param str the String to get the characters from
     * @param pos the position to start from
     * @param len the length of the required String
     * @return the leftmost characters
     * @throws IndexOutOfBoundsException if pos is out of bounds
     * @throws IllegalArgumentException  if len is less than zero
     */
    public static String mid( String str, int pos, int len )
    {
        if ( ( pos < 0 ) || ( ( str != null ) && ( pos > str.length() ) ) )
        {
            throw new StringIndexOutOfBoundsException( "String index " + pos + " is out of bounds" );
        }
        if ( len < 0 )
        {
            throw new IllegalArgumentException( "Requested String length " + len + " is less than zero" );
        }
        if ( str == null )
        {
            return null;
        }
        if ( str.length() <= ( pos + len ) )
        {
            return str.substring( pos );
        }
        else
        {
            return str.substring( pos, pos + len );
        }
    }

    // Splitting
    //--------------------------------------------------------------------------

    /**
     * <p>Splits the provided text into a array, using whitespace as the
     * separator.</p>
     * <p/>
     * <p>The separator is not included in the returned String array.</p>
     *
     * @param str the String to parse
     * @return an array of parsed Strings
     */
    @Nonnull public static String[] split( @Nonnull String str )
    {
        return split( str, null, -1 );
    }

    /**
     * @param text The text to be split.
     * @param separator The separator at which the text will be split.
     * @return The resulting array.
     * @see #split(String, String, int)
     */
    @Nonnull public static String[] split( @Nonnull String text, @Nullable String separator )
    {
        return split( text, separator, -1 );
    }

    /**
     * <p>Splits the provided text into a array, based on a given separator.</p>
     * <p/>
     * <p>The separator is not included in the returned String array. The
     * maximum number of splits to perfom can be controlled. A <code>null</code>
     * separator will cause parsing to be on whitespace.</p>
     * <p/>
     * <p>This is useful for quickly splitting a String directly into
     * an array of tokens, instead of an enumeration of tokens (as
     * <code>StringTokenizer</code> does).</p>
     *
     * @param str       The string to parse.
     * @param separator Characters used as the delimiters. If
     *                  <code>null</code>, splits on whitespace.
     * @param max       The maximum number of elements to include in the
     *                  array.  A zero or negative value implies no limit.
     * @return an array of parsed Strings
     */
    @Nonnull public static String[] split( @Nonnull String str, @Nullable String separator, int max )
    {
        StringTokenizer tok;
        if ( separator == null )
        {
            // Null separator means we're using StringTokenizer's default
            // delimiter, which comprises all whitespace characters.
            tok = new StringTokenizer( str );
        }
        else
        {
            tok = new StringTokenizer( str, separator );
        }

        int listSize = tok.countTokens();
        if ( ( max > 0 ) && ( listSize > max ) )
        {
            listSize = max;
        }

        String[] list = new String[listSize];
        int i = 0;
        int lastTokenBegin;
        int lastTokenEnd = 0;
        while ( tok.hasMoreTokens() )
        {
            if ( ( max > 0 ) && ( i == listSize - 1 ) )
            {
                // In the situation where we hit the max yet have
                // tokens left over in our input, the last list
                // element gets all remaining text.
                String endToken = tok.nextToken();
                lastTokenBegin = str.indexOf( endToken, lastTokenEnd );
                list[i] = str.substring( lastTokenBegin );
                break;
            }
            else
            {
                list[i] = tok.nextToken();
                lastTokenBegin = str.indexOf( list[i], lastTokenEnd );
                lastTokenEnd = lastTokenBegin + list[i].length();
            }
            i++;
        }
        return list;
    }

    // Joining
    //--------------------------------------------------------------------------

    /**
     * <p>Concatenates elements of an array into a single String.</p>
     * <p/>
     * <p>The difference from join is that concatenate has no delimiter.</p>
     *
     * @param array the array of values to concatenate.
     * @return the concatenated string.
     */
    @Nonnull public static String concatenate( @Nonnull Object... array )
    {
        return join( array, "" );
    }

    /**
     * <p>Joins the elements of the provided array into a single String
     * containing the provided list of elements.</p>
     * <p/>
     * <p>No delimiter is added before or after the list. A
     * <code>null</code> separator is the same as a blank String.</p>
     *
     * @param array     the array of values to join together
     * @param separator the separator character to use
     * @return the joined String
     */
    @Nonnull public static String join( @Nonnull Object[] array, @Nullable String separator )
    {
        if ( separator == null )
        {
            separator = "";
        }
        int arraySize = array.length;
        int bufSize = ( arraySize == 0 ? 0 : ( array[0].toString().length() + separator.length() ) * arraySize );
        StringBuilder buf = new StringBuilder( bufSize );

        for ( int i = 0; i < arraySize; i++ )
        {
            if ( i > 0 )
            {
                buf.append( separator );
            }
            buf.append( array[i] );
        }
        return buf.toString();
    }

    /**
     * <p>Joins the elements of the provided <code>Iterator</code> into
     * a single String containing the provided elements.</p>
     * <p/>
     * <p>No delimiter is added before or after the list. A
     * <code>null</code> separator is the same as a blank String.</p>
     *
     * @param iterator  the <code>Iterator</code> of values to join together
     * @param separator the separator character to use
     * @return the joined String
     */
    @Nonnull public static String join( @Nonnull Iterator<?> iterator, String separator )
    {
        if ( separator == null )
        {
            separator = "";
        }
        StringBuilder buf = new StringBuilder( 256 );  // Java default is 16, probably too small
        while ( iterator.hasNext() )
        {
            buf.append( iterator.next() );
            if ( iterator.hasNext() )
            {
                buf.append( separator );
            }
        }
        return buf.toString();
    }

    // Replacing
    //--------------------------------------------------------------------------

    /**
     * <p>Replace a char with another char inside a larger String, once.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl char to search for
     * @param with char to replace with
     * @return the text with any replacements processed
     * @see #replace(String text, char repl, char with, int max)
     */
    public static String replaceOnce( @Nullable String text, char repl, char with )
    {
        return replace( text, repl, with, 1 );
    }

    /**
     * <p>Replace all occurances of a char within another char.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl char to search for
     * @param with char to replace with
     * @return the text with any replacements processed
     * @see #replace(String text, char repl, char with, int max)
     */
    public static String replace( @Nullable String text, char repl, char with )
    {
        return replace( text, repl, with, -1 );
    }

    /**
     * <p>Replace a char with another char inside a larger String,
     * for the first <code>max</code> values of the search char.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl char to search for
     * @param with char to replace with
     * @param max  maximum number of values to replace, or <code>-1</code> if no maximum
     * @return the text with any replacements processed
     */
    public static String replace( @Nullable String text, char repl, char with, int max )
    {
        return replace( text, String.valueOf( repl ), String.valueOf( with ), max );
    }

    /**
     * <p>Replace a String with another String inside a larger String, once.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl String to search for
     * @param with String to replace with
     * @return the text with any replacements processed
     * @see #replace(String text, String repl, String with, int max)
     */
    public static String replaceOnce( @Nullable String text, @Nullable String repl, @Nullable String with )
    {
        return replace( text, repl, with, 1 );
    }

    /**
     * <p>Replace all occurances of a String within another String.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl String to search for
     * @param with String to replace with
     * @return the text with any replacements processed
     * @see #replace(String text, String repl, String with, int max)
     */
    public static String replace( @Nullable String text, @Nullable  String repl, @Nullable String with )
    {
        return replace( text, repl, with, -1 );
    }

    /**
     * <p>Replace a String with another String inside a larger String,
     * for the first <code>max</code> values of the search String.</p>
     * <p/>
     * <p>A <code>null</code> reference passed to this method is a no-op.</p>
     *
     * @param text text to search and replace in
     * @param repl String to search for
     * @param with String to replace with
     * @param max  maximum number of values to replace, or <code>-1</code> if no maximum
     * @return the text with any replacements processed
     */
    public static String replace( @Nullable String text, @Nullable String repl, @Nullable String with, int max )
    {
        if ( ( text == null ) || ( repl == null ) || ( with == null ) || ( repl.length() == 0 ) )
        {
            return text;
        }

        StringBuilder buf = new StringBuilder( text.length() );
        int start = 0, end;
        while ( ( end = text.indexOf( repl, start ) ) != -1 )
        {
            buf.append( text, start, end ).append( with );
            start = end + repl.length();

            if ( --max == 0 )
            {
                break;
            }
        }
        buf.append( text, start, text.length() );
        return buf.toString();
    }

    /**
     * <p>Overlay a part of a String with another String.</p>
     *
     * @param text    String to do overlaying in
     * @param overlay String to overlay
     * @param start   int to start overlaying at
     * @param end     int to stop overlaying before
     * @return String with overlayed text
     * @throws NullPointerException if text or overlay is <code>null</code>
     */
    @Nonnull public static String overlayString( @Nonnull String text, @Nonnull String overlay, int start, int end )
    {
        if ( overlay == null )
        {
            throw new NullPointerException( "overlay is null" );
        }
        return new StringBuilder( start + overlay.length() + text.length() - end + 1 )
            .append( text, 0, start  )
            .append( overlay )
            .append( text, end, text.length() )
            .toString();
    }

    // Centering
    //--------------------------------------------------------------------------

    /**
     * <p>Center a String in a larger String of size <code>n</code>.<p>
     * <p/>
     * <p>Uses spaces as the value to buffer the String with.
     * Equivalent to <code>center(str, size, " ")</code>.</p>
     *
     * @param str  String to center
     * @param size int size of new String
     * @return String containing centered String
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String center( @Nonnull String str, int size )
    {
        return center( str, size, " " );
    }

    /**
     * <p>Center a String in a larger String of size <code>n</code>.</p>
     * <p/>
     * <p>Uses a supplied String as the value to buffer the String with.</p>
     *
     * @param str   String to center
     * @param size  int size of new String
     * @param delim String to buffer the new String with
     * @return String containing centered String
     * @throws NullPointerException if str or delim is <code>null</code>
     * @throws ArithmeticException  if delim is the empty String
     */
    @Nonnull public static String center( @Nonnull String str, int size, @Nonnull String delim )
    {
        int sz = str.length();
        int p = size - sz;
        if ( p < 1 )
        {
            return str;
        }
        str = leftPad( str, sz + p / 2, delim );
        str = rightPad( str, size, delim );
        return str;
    }

    // Chomping
    //--------------------------------------------------------------------------

    /**
     * <p>Remove the last newline, and everything after it from a String.</p>
     *
     * @param str String to chomp the newline from
     * @return String without chomped newline
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String chomp( @Nonnull String str )
    {
        return chomp( str, "\n" );
    }

    /**
     * <p>Remove the last value of a supplied String, and everything after
     * it from a String.</p>
     *
     * @param str String to chomp from
     * @param sep String to chomp
     * @return String without chomped ending
     * @throws NullPointerException if str or sep is <code>null</code>
     */
    @Nonnull public static String chomp( @Nonnull String str, @Nonnull String sep )
    {
        int idx = str.lastIndexOf( sep );
        if ( idx != -1 )
        {
            return str.substring( 0, idx );
        }
        else
        {
            return str;
        }
    }

    /**
     * <p>Remove a newline if and only if it is at the end
     * of the supplied String.</p>
     *
     * @param str String to chomp from
     * @return String without chomped ending
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String chompLast( @Nonnull String str )
    {
        return chompLast( str, "\n" );
    }

    /**
     * <p>Remove a value if and only if the String ends with that value.</p>
     *
     * @param str String to chomp from
     * @param sep String to chomp
     * @return String without chomped ending
     * @throws NullPointerException if str or sep is <code>null</code>
     */
    @Nonnull public static String chompLast( @Nonnull String str, @Nonnull String sep )
    {
        if ( str.length() == 0 )
        {
            return str;
        }
        String sub = str.substring( str.length() - sep.length() );
        if ( sep.equals( sub ) )
        {
            return str.substring( 0, str.length() - sep.length() );
        }
        else
        {
            return str;
        }
    }

    /**
     * <p>Remove everything and return the last value of a supplied String, and
     * everything after it from a String.</p>
     *
     * @param str String to chomp from
     * @param sep String to chomp
     * @return String chomped
     * @throws NullPointerException if str or sep is <code>null</code>
     */
    @Nonnull public static String getChomp( @Nonnull String str, @Nonnull String sep )
    {
        int idx = str.lastIndexOf( sep );
        if ( idx == str.length() - sep.length() )
        {
            return sep;
        }
        else if ( idx != -1 )
        {
            return str.substring( idx );
        }
        else
        {
            return "";
        }
    }

    /**
     * <p>Remove the first value of a supplied String, and everything before it
     * from a String.</p>
     *
     * @param str String to chomp from
     * @param sep String to chomp
     * @return String without chomped beginning
     * @throws NullPointerException if str or sep is <code>null</code>
     */
    @Nonnull public static String prechomp( @Nonnull String str, @Nonnull String sep )
    {
        int idx = str.indexOf( sep );
        if ( idx != -1 )
        {
            return str.substring( idx + sep.length() );
        }
        else
        {
            return str;
        }
    }

    /**
     * <p>Remove and return everything before the first value of a
     * supplied String from another String.</p>
     *
     * @param str String to chomp from
     * @param sep String to chomp
     * @return String prechomped
     * @throws NullPointerException if str or sep is <code>null</code>
     */
    @Nonnull public static String getPrechomp( @Nonnull String str, @Nonnull String sep )
    {
        int idx = str.indexOf( sep );
        if ( idx != -1 )
        {
            return str.substring( 0, idx + sep.length() );
        }
        else
        {
            return "";
        }
    }

    // Chopping
    //--------------------------------------------------------------------------

    /**
     * <p>Remove the last character from a String.</p>
     * <p/>
     * <p>If the String ends in <code>\r\n</code>, then remove both
     * of them.</p>
     *
     * @param str String to chop last character from
     * @return String without last character
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String chop( @Nonnull String str )
    {
        if ( "".equals( str ) )
        {
            return "";
        }
        if ( str.length() == 1 )
        {
            return "";
        }
        int lastIdx = str.length() - 1;
        String ret = str.substring( 0, lastIdx );
        char last = str.charAt( lastIdx );
        if ( last == '\n' )
        {
            if ( ret.charAt( lastIdx - 1 ) == '\r' )
            {
                return ret.substring( 0, lastIdx - 1 );
            }
        }
        return ret;
    }

    /**
     * <p>Remove <code>\n</code> from end of a String if it's there.
     * If a <code>\r</code> precedes it, then remove that too.</p>
     *
     * @param str String to chop a newline from
     * @return String without newline
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String chopNewline( @Nonnull String str )
    {
        int lastIdx = str.length() - 1;
        char last = str.charAt( lastIdx );
        if ( last == '\n' )
        {
            if ( str.charAt( lastIdx - 1 ) == '\r' )
            {
                lastIdx--;
            }
        }
        else
        {
            lastIdx++;
        }
        return str.substring( 0, lastIdx );
    }

    // Conversion
    //--------------------------------------------------------------------------

    // spec 3.10.6

    /**
     * <p>Escapes any values it finds into their String form.</p>
     * <p/>
     * <p>So a tab becomes the characters <code>'\\'</code> and
     * <code>'t'</code>.</p>
     *
     * @param str String to escape values in
     * @return String with escaped values
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String escape( @Nonnull String str )
    {
        // improved with code from  cybertiger@cyberiantiger.org
        // unicode from him, and defaul for < 32's.
        int sz = str.length();
        StringBuilder buffer = new StringBuilder( 2 * sz );
        for ( int i = 0; i < sz; i++ )
        {
            char ch = str.charAt( i );

            // handle unicode
            // CHECKSTYLE_OFF: MagicNumber
            if ( ch > 0xfff )
            {
                buffer.append( "\\u" ).append( Integer.toHexString( ch ) );
            }
            else if ( ch > 0xff )
            {
                buffer.append( "\\u0" ).append( Integer.toHexString( ch ) );
            }
            else if ( ch > 0x7f )
            {
                buffer.append( "\\u00" ).append( Integer.toHexString( ch ) );
            }
            // CHECKSTYLE_ON: MagicNumber
            else if ( ch < 32 )
            {
                switch ( ch )
                {
                    case '\b':
                        buffer.append( '\\' );
                        buffer.append( 'b' );
                        break;
                    case '\n':
                        buffer.append( '\\' );
                        buffer.append( 'n' );
                        break;
                    case '\t':
                        buffer.append( '\\' );
                        buffer.append( 't' );
                        break;
                    case '\f':
                        buffer.append( '\\' );
                        buffer.append( 'f' );
                        break;
                    case '\r':
                        buffer.append( '\\' );
                        buffer.append( 'r' );
                        break;
                    default:
                        if ( ch > 0xf )
                        {
                            buffer.append( "\\u00" ).append( Integer.toHexString( ch ) );
                        }
                        else
                        {
                            buffer.append( "\\u000" ).append( Integer.toHexString( ch ) );
                        }
                        break;
                }
            }
            else
            {
                switch ( ch )
                {
                    case '\'':
                        buffer.append( '\\' );
                        buffer.append( '\'' );
                        break;
                    case '"':
                        buffer.append( '\\' );
                        buffer.append( '"' );
                        break;
                    case '\\':
                        buffer.append( '\\' );
                        buffer.append( '\\' );
                        break;
                    default:
                        buffer.append( ch );
                        break;
                }
            }
        }
        return buffer.toString();
    }

    // Padding
    //--------------------------------------------------------------------------

    /**
     * <p>Repeat a String <code>n</code> times to form a
     * new string.</p>
     *
     * @param str    String to repeat
     * @param repeat number of times to repeat str
     * @return String with repeated String
     * @throws NegativeArraySizeException if <code>repeat < 0</code>
     * @throws NullPointerException       if str is <code>null</code>
     */
    @Nonnull public static String repeat( @Nonnull String str, int repeat )
    {
        StringBuilder buffer = new StringBuilder( repeat * str.length() );
        for ( int i = 0; i < repeat; i++ )
        {
            buffer.append( str );
        }
        return buffer.toString();
    }

    /**
     * <p>Right pad a String with spaces.</p>
     * <p/>
     * <p>The String is padded to the size of <code>n</code>.</p>
     *
     * @param str  String to repeat
     * @param size number of times to repeat str
     * @return right padded String
     * @throws NullPointerException if str is <code>null</code>
     */
    @Nonnull public static String rightPad( @Nonnull String str, int size )
    {
        return rightPad( str, size, " " );
    }

    /**
     * <p>Right pad a String with a specified string.</p>
     * <p/>
     * <p>The String is padded to the size of <code>n</code>.</p>
     *
     * @param str   String to pad out
     * @param size  size to pad to
     * @param delim String to pad with
     * @return right padded String
     * @throws NullPointerException if str or delim is <code>null</code>
     * @throws ArithmeticException  if delim is the empty String
     */
    @Nonnull public static String rightPad( @Nonnull String str, int size, @Nonnull String delim )
    {
        size = ( size - str.length() ) / delim.length();
        if ( size > 0 )
        {
            str += repeat( delim, size );
        }
        return str;
    }

    /**
     * <p>Left pad a String with spaces.</p>
     * <p/>
     * <p>The String is padded to the size of <code>n</code>.</p>
     *
     * @param str  String to pad out
     * @param size size to pad to
     * @return left padded String
     * @throws NullPointerException if str or delim is <code>null</code>
     */
    @Nonnull public static String leftPad( @Nonnull String str, int size )
    {
        return leftPad( str, size, " " );
    }

    /**
     * Left pad a String with a specified string. Pad to a size of n.
     *
     * @param str   String to pad out
     * @param size  size to pad to
     * @param delim String to pad with
     * @return left padded String
     * @throws NullPointerException if str or delim is null
     * @throws ArithmeticException  if delim is the empty string
     */
    @Nonnull public static String leftPad( @Nonnull String str, int size, @Nonnull String delim )
    {
        size = ( size - str.length() ) / delim.length();
        if ( size > 0 )
        {
            str = repeat( delim, size ) + str;
        }
        return str;
    }

    // Stripping
    //--------------------------------------------------------------------------

    /**
     * <p>Remove whitespace from the front and back of a String.</p>
     *
     * @param str the String to remove whitespace from
     * @return the stripped String
     */
    public static String strip( String str )
    {
        return strip( str, null );
    }

    /**
     * <p>Remove a specified String from the front and back of a
     * String.</p>
     * <p/>
     * <p>If whitespace is wanted to be removed, used the
     * {@link #strip(java.lang.String)} method.</p>
     *
     * @param str   the String to remove a string from
     * @param delim the String to remove at start and end
     * @return the stripped String
     */
    public static String strip( String str, @Nullable String delim )
    {
        str = stripStart( str, delim );
        return stripEnd( str, delim );
    }

    /**
     * <p>Strip whitespace from the front and back of every String
     * in the array.</p>
     *
     * @param strs the Strings to remove whitespace from
     * @return the stripped Strings
     */
    public static String[] stripAll( String... strs )
    {
        return stripAll( strs, null );
    }

    /**
     * <p>Strip the specified delimiter from the front and back of
     * every String in the array.</p>
     *
     * @param strs      the Strings to remove a String from
     * @param delimiter the String to remove at start and end
     * @return the stripped Strings
     */
    public static String[] stripAll( String[] strs, @Nullable String delimiter )
    {
        if ( ( strs == null ) || ( strs.length == 0 ) )
        {
            return strs;
        }
        int sz = strs.length;
        String[] newArr = new String[sz];
        for ( int i = 0; i < sz; i++ )
        {
            newArr[i] = strip( strs[i], delimiter );
        }
        return newArr;
    }

    /**
     * <p>Strip any of a supplied String from the end of a String.</p>
     * <p/>
     * <p>If the strip String is <code>null</code>, whitespace is
     * stripped.</p>
     *
     * @param str   the String to remove characters from
     * @param strip the String to remove
     * @return the stripped String
     */
    public static String stripEnd( String str, @Nullable String strip )
    {
        if ( str == null )
        {
            return null;
        }
        int end = str.length();

        if ( strip == null )
        {
            while ( ( end != 0 ) && Character.isWhitespace( str.charAt( end - 1 ) ) )
            {
                end--;
            }
        }
        else
        {
            while ( ( end != 0 ) && ( strip.indexOf( str.charAt( end - 1 ) ) != -1 ) )
            {
                end--;
            }
        }
        return str.substring( 0, end );
    }

    /**
     * <p>Strip any of a supplied String from the start of a String.</p>
     * <p/>
     * <p>If the strip String is <code>null</code>, whitespace is
     * stripped.</p>
     *
     * @param str   the String to remove characters from
     * @param strip the String to remove
     * @return the stripped String
     */
    public static String stripStart( String str, @Nullable String strip )
    {
        if ( str == null )
        {
            return null;
        }

        int start = 0;

        int sz = str.length();

        if ( strip == null )
        {
            while ( ( start != sz ) && Character.isWhitespace( str.charAt( start ) ) )
            {
                start++;
            }
        }
        else
        {
            while ( ( start != sz ) && ( strip.indexOf( str.charAt( start ) ) != -1 ) )
            {
                start++;
            }
        }
        return str.substring( start );
    }

    // Case conversion
    //--------------------------------------------------------------------------

    /**
     * <p>Convert a String to upper case, <code>null</code> String
     * returns <code>null</code>.</p>
     *
     * @param str the String to uppercase
     * @return the upper cased String
     */
    public static String upperCase( String str )
    {
        if ( str == null )
        {
            return null;
        }
        return str.toUpperCase();
    }

    /**
     * <p>Convert a String to lower case, <code>null</code> String
     * returns <code>null</code>.</p>
     *
     * @param str the string to lowercase
     * @return the lower cased String
     */
    public static String lowerCase( String str )
    {
        if ( str == null )
        {
            return null;
        }
        return str.toLowerCase();
    }

    /**
     * <p>Uncapitalise a String.</p>
     * <p/>
     * <p>That is, convert the first character into lower-case.
     * <code>null</code> is returned as <code>null</code>.</p>
     *
     * @param str the String to uncapitalise
     * @return uncapitalised String
     */
    public static String uncapitalise( String str )
    {
        if ( str == null )
        {
            return null;
        }
        else
        {
            int length = str.length();
            if ( length == 0 )
            {
                return "";
            }
            else
            {
                return new StringBuffer( length )
                    .append( Character.toLowerCase( str.charAt( 0 ) ) )
                    .append( str, 1, length )
                    .toString();
            }
        }
    }

    /**
     * <p>Capitalise a String.</p>
     * <p/>
     * <p>That is, convert the first character into title-case.
     * <code>null</code> is returned as <code>null</code>.</p>
     *
     * @param str the String to capitalise
     * @return capitalised String
     */
    public static String capitalise( String str )
    {
        if ( str == null )
        {
            return null;
        }
        else
        {
            int length = str.length();
            if ( length == 0 )
            {
                return "";
            }
            else
            {
                return new StringBuilder( length )
                    .append( Character.toTitleCase( str.charAt( 0 ) ) )
                    .append( str, 1, length )
                    .toString();
            }
        }
    }

    /**
     * <p>Swaps the case of String.</p>
     * <p/>
     * <p>Properly looks after making sure the start of words
     * are Titlecase and not Uppercase.</p>
     * <p/>
     * <p><code>null</code> is returned as <code>null</code>.</p>
     *
     * @param str the String to swap the case of
     * @return the modified String
     */
    public static String swapCase( String str )
    {
        if ( str == null )
        {
            return null;
        }
        int sz = str.length();
        StringBuilder buffer = new StringBuilder( sz );

        boolean whitespace = false;
        char ch;
        char tmp;

        for ( int i = 0; i < sz; i++ )
        {
            ch = str.charAt( i );
            if ( Character.isUpperCase( ch ) )
            {
                tmp = Character.toLowerCase( ch );
            }
            else if ( Character.isTitleCase( ch ) )
            {
                tmp = Character.toLowerCase( ch );
            }
            else if ( Character.isLowerCase( ch ) )
            {
                if ( whitespace )
                {
                    tmp = Character.toTitleCase( ch );
                }
                else
                {
                    tmp = Character.toUpperCase( ch );
                }
            }
            else
            {
                tmp = ch;
            }
            buffer.append( tmp );
            whitespace = Character.isWhitespace( ch );
        }
        return buffer.toString();
    }


    /**
     * <p>Capitalise all the words in a String.</p>
     * <p/>
     * <p>Uses {@link Character#isWhitespace(char)} as a
     * separator between words.</p>
     * <p/>
     * <p><code>null</code> will return <code>null</code>.</p>
     *
     * @param str the String to capitalise
     * @return capitalised String
     */
    public static String capitaliseAllWords( String str )
    {
        if ( str == null )
        {
            return null;
        }
        int sz = str.length();
        StringBuilder buffer = new StringBuilder( sz );
        boolean space = true;
        for ( int i = 0; i < sz; i++ )
        {
            char ch = str.charAt( i );
            if ( Character.isWhitespace( ch ) )
            {
                buffer.append( ch );
                space = true;
            }
            else if ( space )
            {
                buffer.append( Character.toTitleCase( ch ) );
                space = false;
            }
            else
            {
                buffer.append( ch );
            }
        }
        return buffer.toString();
    }

    /**
     * <p>Uncapitalise all the words in a string.</p>
     * <p/>
     * <p>Uses {@link Character#isWhitespace(char)} as a
     * separator between words.</p>
     * <p/>
     * <p><code>null</code> will return <code>null</code>.</p>
     *
     * @param str the string to uncapitalise
     * @return uncapitalised string
     */
    public static String uncapitaliseAllWords( String str )
    {
        if ( str == null )
        {
            return null;
        }
        int sz = str.length();
        StringBuilder buffer = new StringBuilder( sz );
        boolean space = true;
        for ( int i = 0; i < sz; i++ )
        {
            char ch = str.charAt( i );
            if ( Character.isWhitespace( ch ) )
            {
                buffer.append( ch );
                space = true;
            }
            else if ( space )
            {
                buffer.append( Character.toLowerCase( ch ) );
                space = false;
            }
            else
            {
                buffer.append( ch );
            }
        }
        return buffer.toString();
    }

    // Nested extraction
    //--------------------------------------------------------------------------

    /**
     * <p>Get the String that is nested in between two instances of the
     * same String.</p>
     * <p/>
     * <p>If <code>str</code> is <code>null</code>, will
     * return <code>null</code>.</p>
     *
     * @param str the String containing nested-string
     * @param tag the String before and after nested-string
     * @return the String that was nested, or <code>null</code>
     * @throws NullPointerException if tag is <code>null</code>
     */
    public static String getNestedString( String str, @Nonnull String tag )
    {
        return getNestedString( str, tag, tag );
    }

    /**
     * <p>Get the String that is nested in between two Strings.</p>
     *
     * @param str   the String containing nested-string
     * @param open  the String before nested-string
     * @param close the String after nested-string
     * @return the String that was nested, or <code>null</code>
     * @throws NullPointerException if open or close is <code>null</code>
     */
    public static String getNestedString( String str, @Nonnull String open, @Nonnull String close )
    {
        if ( str == null )
        {
            return null;
        }
        int start = str.indexOf( open );
        if ( start != -1 )
        {
            int end = str.indexOf( close, start + open.length() );
            if ( end != -1 )
            {
                return str.substring( start + open.length(), end );
            }
        }
        return null;
    }

    /**
     * <p>How many times is the substring in the larger String.</p>
     * <p/>
     * <p><code>null</code> returns <code>0</code>.</p>
     *
     * @param str the String to check
     * @param sub the substring to count
     * @return the number of occurances, 0 if the String is <code>null</code>
     * @throws NullPointerException if sub is <code>null</code>
     */
    public static int countMatches( @Nullable String str, @Nonnull String sub )
    {
        if ( sub.equals( "" ) )
        {
            return 0;
        }
        if ( str == null )
        {
            return 0;
        }
        int count = 0;
        int idx = 0;
        while ( ( idx = str.indexOf( sub, idx ) ) != -1 )
        {
            count++;
            idx += sub.length();
        }
        return count;
    }

    // Character Tests
    //--------------------------------------------------------------------------

    /**
     * <p>Checks if the String contains only unicode letters.</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>.
     * An empty String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains letters, and is non-null
     */
    public static boolean isAlpha( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( !Character.isLetter( str.charAt( i ) ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if the String contains only whitespace.</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>. An
     * empty String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains whitespace, and is non-null
     */
    public static boolean isWhitespace( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( ( !Character.isWhitespace( str.charAt( i ) ) ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if the String contains only unicode letters and
     * space (<code>' '</code>).</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>. An
     * empty String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains letters and space,
     *         and is non-null
     */
    public static boolean isAlphaSpace( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( ( !Character.isLetter( str.charAt( i ) ) ) && ( str.charAt( i ) != ' ' ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if the String contains only unicode letters or digits.</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>. An empty
     * String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains letters or digits,
     *         and is non-null
     */
    public static boolean isAlphanumeric( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( !Character.isLetterOrDigit( str.charAt( i ) ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if the String contains only unicode letters, digits
     * or space (<code>' '</code>).</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>. An empty
     * String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains letters, digits or space,
     *         and is non-null
     */
    public static boolean isAlphanumericSpace( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( ( !Character.isLetterOrDigit( str.charAt( i ) ) ) && ( str.charAt( i ) != ' ' ) )
            {
                return false;
            }
        }
        return true;
    }

    /**
     * <p>Checks if the String contains only unicode digits.</p>
     * <p/>
     * <p><code>null</code> will return <code>false</code>.
     * An empty String will return <code>true</code>.</p>
     *
     * @param str the String to check
     * @return <code>true</code> if only contains digits, and is non-null
     */
    public static boolean isNumeric( String str )
    {
        if ( str == null )
        {
            return false;
        }
        int sz = str.length();
        for ( int i = 0; i < sz; i++ )
        {
            if ( !Character.isDigit( str.charAt( i ) ) )
            {
                return false;
            }
        }
        return true;
    }

    // Defaults
    //--------------------------------------------------------------------------

    /**
     * <p>Returns either the passed in <code>Object</code> as a String,
     * or, if the <code>Object</code> is <code>null</code>, an empty
     * String.</p>
     *
     * @param obj the Object to check
     * @return the passed in Object's toString, or blank if it was
     *         <code>null</code>
     */
    @Nonnull public static String defaultString( Object obj )
    {
        return defaultString( obj, "" );
    }

    /**
     * <p>Returns either the passed in <code>Object</code> as a String,
     * or, if the <code>Object</code> is <code>null</code>, a passed
     * in default String.</p>
     *
     * @param obj           the Object to check
     * @param defaultString the default String to return if str is
     *                      <code>null</code>
     * @return the passed in string, or the default if it was
     *         <code>null</code>
     */
    @Nonnull public static String defaultString( Object obj, @Nonnull String defaultString )
    {
        return ( obj == null ) ? defaultString : obj.toString();
    }

    // Reversing
    //--------------------------------------------------------------------------

    /**
     * <p>Reverse a String.</p>
     * <p/>
     * <p><code>null</code> String returns <code>null</code>.</p>
     *
     * @param str the String to reverse
     * @return the reversed String
     */
    public static String reverse( String str )
    {
        if ( str == null )
        {
            return null;
        }
        return new StringBuffer( str ).reverse().toString();
    }

    /**
     * <p>Reverses a String that is delimited by a specific character.</p>
     * <p/>
     * <p>The Strings between the delimiters are not reversed.
     * Thus java.lang.String becomes String.lang.java (if the delimiter
     * is <code>'.'</code>).</p>
     *
     * @param str       the String to reverse
     * @param delimiter the delimiter to use
     * @return the reversed String
     */
    @Nonnull public static String reverseDelimitedString( @Nonnull String str, String delimiter )
    {
        // could implement manually, but simple way is to reuse other,
        // probably slower, methods.
        String[] strs = split( str, delimiter );
        reverseArray( strs );
        return join( strs, delimiter );
    }

    /**
     * <p>Reverses an array.</p>
     * <p/>
     * <p>TAKEN FROM CollectionsUtils.</p>
     *
     * @param array the array to reverse
     */
    private static void reverseArray( @Nonnull String... array )
    {
        int i = 0;
        int j = array.length - 1;
        String tmp;

        while ( j > i )
        {
            tmp = array[j];
            array[j] = array[i];
            array[i] = tmp;
            j--;
            i++;
        }
    }

    // Abbreviating
    //--------------------------------------------------------------------------

    /**
     * Turn "Now is the time for all good men" into "Now is the time for..."
     * <p/>
     * Specifically:
     * <p/>
     * If str is less than max characters long, return it.
     * Else abbreviate it to (substring(str, 0, max-3) + "...").
     * If maxWidth is less than 3, throw an IllegalArgumentException.
     * In no case will it return a string of length greater than maxWidth.
     * 
     * @param s The string to be abbreviated.
     * @param maxWidth maximum length of result string
     * @return The abbreviated string.
     */
    @Nonnull public static String abbreviate( @Nonnull String s, int maxWidth )
    {
        return abbreviate( s, 0, maxWidth );
    }

    /**
     * Turn "Now is the time for all good men" into "...is the time for..."
     * <p/>
     * Works like abbreviate(String, int), but allows you to specify a "left edge"
     * offset.  Note that this left edge is not necessarily going to be the leftmost
     * character in the result, or the first
     * character following the ellipses, but it will appear somewhere in the result.
     * In no case will it return a string of length greater than maxWidth.
     * 
     * @param s        String to abbreviate.
     * @param offset   left edge of source string
     * @param maxWidth maximum length of result string
     * @return The abbreviated string.
     */
    @Nonnull public static String abbreviate( @Nonnull String s, int offset, int maxWidth )
    {
        if ( maxWidth < 4 )
        {
            throw new IllegalArgumentException( "Minimum abbreviation width is 4" );
        }
        if ( s.length() <= maxWidth )
        {
            return s;
        }
        if ( offset > s.length() )
        {
            offset = s.length();
        }
        if ( ( s.length() - offset ) < ( maxWidth - 3 ) )
        {
            offset = s.length() - ( maxWidth - 3 );
        }
        if ( offset <= 4 )
        {
            return s.substring( 0, maxWidth - 3 ) + "...";
        }
        if ( maxWidth < 7 )
        {
            throw new IllegalArgumentException( "Minimum abbreviation width with offset is 7" );
        }
        if ( ( offset + ( maxWidth - 3 ) ) < s.length() )
        {
            return "..." + abbreviate( s.substring( offset ), maxWidth - 3 );
        }
        return "..." + s.substring( s.length() - ( maxWidth - 3 ) );
    }

    // Difference
    //--------------------------------------------------------------------------

    /**
     * Compare two strings, and return the portion where they differ.
     * (More precisely, return the remainder of the second string,
     * starting from where it's different from the first.)
     * <p/>
     * E.g. strdiff("i am a machine", "i am a robot") -> "robot"
     *
     * @param s1 The first string.
     * @param s2 The second string.
     * @return the portion of s2 where it differs from s1; returns the empty string ("") if they are equal
     */
    public static String difference( @Nonnull String s1, @Nonnull String s2 )
    {
        int at = differenceAt( s1, s2 );
        if ( at == -1 )
        {
            return "";
        }
        return s2.substring( at );
    }

    /**
     * Compare two strings, and return the index at which the strings begin to differ.
     * <p>
     * E.g. strdiff("i am a machine", "i am a robot") -> 7
     * </p>
     *
     * @param s1 The first string.
     * @param s2 The second string.
     * @return the index where s2 and s1 begin to differ; -1 if they are equal
     */
    public static int differenceAt( @Nonnull String s1, @Nonnull String s2 )
    {
        int i;
        for ( i = 0; ( i < s1.length() ) && ( i < s2.length() ); ++i )
        {
            if ( s1.charAt( i ) != s2.charAt( i ) )
            {
                break;
            }
        }
        if ( ( i < s2.length() ) || ( i < s1.length() ) )
        {
            return i;
        }
        return -1;
    }

    /**
     * Fill all 'variables' in the given text with the values from the map.
     * Any text looking like '${key}' will get replaced by the value stored
     * in the namespace map under the 'key'.
     *
     * @param text The text where replacements will be searched for.
     * @param namespace The namespace which contains the replacements.
     * @return the interpolated text.
     */
    public static String interpolate( String text, @Nonnull Map<?, ?> namespace )
    {
        for ( Map.Entry<?, ?> entry : namespace.entrySet() )
        {
            String key = entry.getKey().toString();

            Object obj = entry.getValue();

            if ( obj == null )
            {
                throw new NullPointerException( "The value of the key '" + key + "' is null." );
            }

            String value = obj.toString();

            text = replace( text, "${" + key + "}", value );

            if ( !key.contains( " " ) )
            {
                text = replace( text, "$" + key, value );
            }
        }
        return text;
    }

    /**
     * This is basically the inverse of {@link #addAndDeHump(String)}.
     * It will remove the 'replaceThis' parameter and uppercase the next
     * character afterwards.
     * <pre>
     * removeAndHump( &quot;this-is-it&quot;, %quot;-&quot; );
     * </pre>
     * will become 'ThisIsIt'.
     *
     * @param data The data.
     * @param replaceThis The things which should be replaced.
     * @return humped String
     */
    @Nonnull public static String removeAndHump( @Nonnull String data, @Nonnull String replaceThis )
    {
        String temp;

        StringBuilder out = new StringBuilder();

        temp = data;

        StringTokenizer st = new StringTokenizer( temp, replaceThis );

        while ( st.hasMoreTokens() )
        {
            String element = st.nextToken();

            out.append( capitalizeFirstLetter( element ) );
        }

        return out.toString();
    }

    /**
     * Convert the first character of the given String to uppercase.
     * This method will <i>not</i> trim of spaces!
     * <p/>
     * <p>
     * <b>Attention:</b> this method will currently throw a
     * <code>IndexOutOfBoundsException</code> for empty strings!
     * </p>
     *
     * @param data the String to get capitalized
     * @return data string with the first character transformed to uppercase
     * @throws NullPointerException if data is <code>null</code>
     */
    @Nonnull public static String capitalizeFirstLetter( @Nonnull String data )
    {
        char firstChar = data.charAt( 0 );
        char titleCase = Character.toTitleCase( firstChar );
        if ( firstChar == titleCase )
        {
            return data;
        }
        StringBuilder result = new StringBuilder( data.length() );
        result.append( titleCase );
        result.append(  data, 1, data.length() );
        return result.toString();
    }

    /**
     * Convert the first character of the given String to lowercase.
     * This method will <i>not</i> trim of spaces!
     * <p/>
     * <p>
     * <b>Attention:</b> this method will currently throw a
     * <code>IndexOutOfBoundsException</code> for empty strings!
     * </p>
     *
     * @param data the String to get it's first character lower-cased.
     * @return data string with the first character transformed to lowercase
     * @throws NullPointerException if data is <code>null</code>
     */
    @Nonnull public static String lowercaseFirstLetter( @Nonnull String data )
    {
        char firstLetter = Character.toLowerCase( data.substring( 0, 1 ).charAt( 0 ) );

        String restLetters = data.substring( 1 );

        return firstLetter + restLetters;
    }

    /**
     * Take the input string and un-camel-case it.
     * <p/>
     * 'ThisIsIt' will become 'this-is-it'.
     *
     * @param view The view.
     * @return deHumped String
     */
    @Nonnull public static String addAndDeHump( @Nonnull String view )
    {
        StringBuilder sb = new StringBuilder();

        for ( int i = 0; i < view.length(); i++ )
        {
            if ( ( i != 0 ) && Character.isUpperCase( view.charAt( i ) ) )
            {
                sb.append( '-' );
            }

            sb.append( view.charAt( i ) );
        }

        return sb.toString().trim().toLowerCase( Locale.ENGLISH );
    }

    /**
     * <p>Quote and escape a String with the given character, handling <code>null</code>.</p>
     * <p/>
     * <pre>
     * StringUtils.quoteAndEscape(null, *)    = null
     * StringUtils.quoteAndEscape("", *)      = ""
     * StringUtils.quoteAndEscape("abc", '"') = abc
     * StringUtils.quoteAndEscape("a\"bc", '"') = "a\"bc"
     * StringUtils.quoteAndEscape("a\"bc", '\'') = 'a\"bc'
     * </pre>
     *
     * @param source The source.
     * @param quoteChar The quote character.
     * @return the String quoted and escaped
     * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
     * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
     * 
     */
    public static String quoteAndEscape( @Nullable String source, char quoteChar )
    {
        return quoteAndEscape( source, quoteChar, new char[]{ quoteChar }, new char[]{ ' ' }, '\\', false );
    }

    /**
     * <p>Quote and escape a String with the given character, handling <code>null</code>.</p>
     *
     * @param source The source.
     * @param quoteChar The quote character.
     * @param quotingTriggers The quoting trigger.
     * @return the String quoted and escaped
     * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
     * 
     */
    public static String quoteAndEscape( @Nullable String source, char quoteChar, @Nonnull char[] quotingTriggers )
    {
        return quoteAndEscape( source, quoteChar, new char[]{ quoteChar }, quotingTriggers, '\\', false );
    }

    /**
     * @param source The source.
     * @param quoteChar The quote character.
     * @param escapedChars The escaped characters.
     * @param escapeChar The escape character.
     * @param force true/false.
     * @return the String quoted and escaped
     * @see #quoteAndEscape(String, char, char[], char[], char, boolean)
     * 
     */
    public static String quoteAndEscape( @Nullable String source, char quoteChar,
                                         @Nonnull final char[] escapedChars, char escapeChar, boolean force )
    {
        return quoteAndEscape( source, quoteChar, escapedChars, new char[]{ ' ' }, escapeChar, force );
    }

    /**
     * @param source The source.
     * @param quoteChar The quote character.
     * @param escapedChars set of characters to escape.
     * @param quotingTriggers The quoting trigger.
     * @param escapeChar prefix for escaping a character.
     * @param force true/false.
     * @return the String quoted and escaped
     */
    public static String quoteAndEscape( @Nullable String source, char quoteChar, @Nonnull final char[] escapedChars,
                                         @Nonnull final char[] quotingTriggers, char escapeChar, boolean force )
    {
        if ( source == null )
        {
            return null;
        }

        if ( !force && source.startsWith( Character.toString( quoteChar ) ) && source.endsWith(
            Character.toString( quoteChar ) ) )
        {
            return source;
        }

        String escaped = escape( source, escapedChars, escapeChar );

        boolean quote = false;
        if ( force )
        {
            quote = true;
        }
        else if ( !escaped.equals( source ) )
        {
            quote = true;
        }
        else
        {
            for ( char quotingTrigger : quotingTriggers )
            {
                if ( escaped.indexOf( quotingTrigger ) > -1 )
                {
                    quote = true;
                    break;
                }
            }
        }

        if ( quote )
        {
            return quoteChar + escaped + quoteChar;
        }

        return escaped;
    }

    /**
     * @param source The source.
     * @param escapedChars set of characters to escape.
     * @param escapeChar prefix for escaping a character.
     * @return the String escaped
     */
    public static String escape( @Nullable String source, @Nonnull final char[] escapedChars, char escapeChar )
    {
        if ( source == null )
        {
            return null;
        }

        char[] eqc = new char[escapedChars.length];
        System.arraycopy( escapedChars, 0, eqc, 0, escapedChars.length );
        Arrays.sort( eqc );

        StringBuilder buffer = new StringBuilder( source.length() );

        for ( int i = 0; i < source.length(); i++ )
        {
            final char c = source.charAt( i );
            int result = Arrays.binarySearch( eqc, c );

            if ( result > -1 )
            {
                buffer.append( escapeChar );
            }
            buffer.append( c );
        }

        return buffer.toString();
    }

    /**
     * Remove all duplicate whitespace characters and line terminators are replaced with a single
     * space.
     *
     * @param s a not null String
     * @return a string with unique whitespace.
     * 
     */
    @Nonnull public static String removeDuplicateWhitespace( @Nonnull String s )
    {
        StringBuilder result = new StringBuilder();
        int length = s.length();
        boolean isPreviousWhiteSpace = false;
        for ( int i = 0; i < length; i++ )
        {
            char c = s.charAt( i );
            boolean thisCharWhiteSpace = Character.isWhitespace( c );
            if ( !( isPreviousWhiteSpace && thisCharWhiteSpace ) )
            {
                result.append( c );
            }
            isPreviousWhiteSpace = thisCharWhiteSpace;
        }
        return result.toString();
    }

    /**
     * Parses the given String and replaces all occurrences of
     * '\n', '\r' and '\r\n' with the system line separator.
     *
     * @param s a not null String
     * @return a String that contains only System line separators.
     * @see #unifyLineSeparators(String, String)
     * 
     */
    public static String unifyLineSeparators( @Nullable String s )
    {
        return unifyLineSeparators( s, System.getProperty( "line.separator" ) );
    }

    /**
     * Parses the given String and replaces all occurrences of
     * '\n', '\r' and '\r\n' with the system line separator.
     *
     * @param s  a not null String
     * @param ls the wanted line separator ("\n" on UNIX), if null using the System line separator.
     * @return a String that contains only System line separators.
     * @throws IllegalArgumentException if ls is not '\n', '\r' and '\r\n' characters.
     * 
     */
    public static String unifyLineSeparators( @Nullable String s, @Nullable String ls )
    {
        if ( s == null )
        {
            return null;
        }

        if ( ls == null )
        {
            ls = System.getProperty( "line.separator" );
        }

        if ( !( ls.equals( "\n" ) || ls.equals( "\r" ) || ls.equals( "\r\n" ) ) )
        {
            throw new IllegalArgumentException( "Requested line separator is invalid." );
        }

        int length = s.length();

        StringBuilder buffer = new StringBuilder( length );
        for ( int i = 0; i < length; i++ )
        {
            if ( s.charAt( i ) == '\r' )
            {
                if ( ( i + 1 ) < length && s.charAt( i + 1 ) == '\n' )
                {
                    i++;
                }

                buffer.append( ls );
            }
            else if ( s.charAt( i ) == '\n' )
            {
                buffer.append( ls );
            }
            else
            {
                buffer.append( s.charAt( i ) );
            }
        }

        return buffer.toString();
    }

    /**
     * <p>Checks if String contains a search character, handling <code>null</code>.
     * This method uses {@link String#indexOf(int)}.</p>
     * <p/>
     * <p>A <code>null</code> or empty ("") String will return <code>false</code>.</p>
     * <p/>
     * <pre>
     * StringUtils.contains(null, *)    = false
     * StringUtils.contains("", *)      = false
     * StringUtils.contains("abc", 'a') = true
     * StringUtils.contains("abc", 'z') = false
     * </pre>
     *
     * @param str        the String to check, may be null
     * @param searchChar the character to find
     * @return true if the String contains the search character,
     *         false if not or <code>null</code> string input
     * 
     */
    public static boolean contains( @Nullable String str, char searchChar )
    {
        return !isEmpty( str ) && str.indexOf( searchChar ) >= 0;
    }

    /**
     * <p>Checks if String contains a search String, handling <code>null</code>.
     * This method uses {@link String#indexOf(int)}.</p>
     * <p/>
     * <p>A <code>null</code> String will return <code>false</code>.</p>
     * <p/>
     * <pre>
     * StringUtils.contains(null, *)     = false
     * StringUtils.contains(*, null)     = false
     * StringUtils.contains("", "")      = true
     * StringUtils.contains("abc", "")   = true
     * StringUtils.contains("abc", "a")  = true
     * StringUtils.contains("abc", "z")  = false
     * </pre>
     *
     * @param str       the String to check, may be null
     * @param searchStr the String to find, may be null
     * @return true if the String contains the search String,
     *         false if not or <code>null</code> string input
     */
    public static boolean contains( @Nullable String str, @Nullable String searchStr )
    {
        return !( str == null || searchStr == null ) && str.contains( searchStr );
    }

    /**
     * <p>Checks if String ends with a search String, handling <code>null</code>.</p>
     * <p/>
     * <p>A <code>null</code> String will return <code>false</code>.</p>
     * <p/>
     * <pre>
     * StringUtils.endsWithIgnoreCase(null, *)     = false
     * StringUtils.endsWithIgnoreCase(*, null)     = false
     * StringUtils.endsWithIgnoreCase("", "")      = true
     * StringUtils.endsWithIgnoreCase("abc", "")   = true
     * StringUtils.endsWithIgnoreCase("abc", "C")  = true
     * StringUtils.endsWithIgnoreCase("abc", "a")  = false
     * </pre>
     *
     * @param str       the String to check, may be null
     * @param searchStr the String to find at end, may be null
     * @return true if the String ends with the search String,
     *         false if not or <code>null</code> string input
     * 
     */
    public static boolean endsWithIgnoreCase( @Nullable String str, @Nullable String searchStr )
    {
        if ( str == null || searchStr == null )
        {
            // for consistency with contains
            return false;
        }

        if ( str.length() < searchStr.length() )
        {
            return false;
        }

        return str.regionMatches( true, str.length() - searchStr.length(), searchStr, 0, searchStr.length() );
    }
}
