private static String[] splitByCharacterType(String str, boolean camelCase) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return ArrayUtils.EMPTY_STRING_ARRAY;
        }
        char[] c = str.toCharArray();
        List<String> list = new ArrayList<String>();
        int tokenStart = 0;
        int currentType = Character.getType(c[tokenStart]);
        for (int pos = tokenStart + 1; pos < c.length; pos++) {
            int type = Character.getType(c[pos]);
            if (type == currentType) {
                continue;
            }
            if (camelCase && type == Character.LOWERCASE_LETTER && currentType == Character.UPPERCASE_LETTER) {
                int newTokenStart = pos - 1;
                if (newTokenStart != tokenStart) {
                    list.add(new String(c, tokenStart, newTokenStart - tokenStart));
                    tokenStart = newTokenStart;
                }
            } else {
                list.add(new String(c, tokenStart, pos - tokenStart));
                tokenStart = pos;
            }
            currentType = type;
        }
        list.add(new String(c, tokenStart, c.length - tokenStart));
        return list.toArray(new String[list.size()]);
    }
<p>Splits a String by Character type as returned by
{@code java.lang.Character.getType(char)}. Groups of contiguous
characters of the same type are returned as complete tokens, with the
following exception: if {@code camelCase} is {@code true},
the character of type {@code Character.UPPERCASE_LETTER}, if any,
immediately preceding a token of type {@code Character.LOWERCASE_LETTER}
will belong to the following token rather than to the preceding, if any,
{@code Character.UPPERCASE_LETTER} token.
@param str the String to split, may be {@code null}
@param camelCase whether to use so-called "camel-case" for letter types
@return an array of parsed Strings, {@code null} if null String input
@since 2.4
android/android_framework/base/src/main/java/lang3/StringUtils.java