code: public static String[] tokenize(final String s) {
          final List<String> result = new ArrayList<>();
          
          int start = 0;                  // start of current token
          boolean uppercaseToken = false; // if current token is all uppercase
          for (int i = 0; i < s.length(); i++) {
              char c = s.charAt(i);
              if (! Character.isJavaIdentifierPart(c) ||
                  (result.isEmpty() && start == i &&
                      !Character.isJavaIdentifierStart(c))) {
                  // This character should not appear in a Java name at all,
                  // or this would be the first character of the result, 
                  //    but it is not valid here.
                  // Treat it as a separator.
                  c = '_';
              }
              if (Character.isLowerCase(c) || Character.isDigit(c)) {
                  // the token goes on, unless it's all uppercase
                  if (uppercaseToken) {
                      // uppercase token ends here. The last uppercase
                      // character already was part of the next token.
                      add(result, start, i-1, s);
                      start = i-1;
                      // this is no uppercase token
                      uppercaseToken = false;
                  }
              } else if (Character.isUpperCase(c)) {
                  if (!uppercaseToken) {
                      // token ends here, new token starts
                      add(result, start, i, s);
                      start = i;
                  }
                  if (start == i) {
                      // first character is uppercase, this has potential for
                      // being an uppercase token, such as "HTTP"
                      uppercaseToken = true;
                  } else {
                      assert uppercaseToken : "token should be uppercase";
                  }
              } else { // c == '_'
                  // token ends here, next char is start of next token
                  add(result, start, i, s);
                  start = i+1;
                  // if this was an uppercase token, it ends now anyway
                  uppercaseToken = false;
              }
          }
          // add last token
          add(result, start, s.length(), s);
  
          return result.toArray(new String[result.size()]);
      }
docs: Splits a String into parts that can be concatenated to a valid
  Java identifier.
  <p>
  The result contains no empty strings.
  @param s string to tokenize
  @return array of strings