List<String> (@NotNull String parameterString, boolean keepQuotes, boolean supportSingleQuotes, boolean keepEmptyParameters) { if (!keepEmptyParameters) { parameterString = parameterString.trim(); } final List<String> params = new ArrayList<>(); if (parameterString.isEmpty()) { return params; } final StringBuilder token = new StringBuilder(128); boolean inQuotes = false; boolean escapedQuote = false; IntSet possibleQuoteChars = new IntOpenHashSet(); possibleQuoteChars.add('"'); if (supportSingleQuotes) { possibleQuoteChars.add('\''); } char currentQuote = 0; boolean nonEmpty = false; for (int i = 0; i < parameterString.length(); i++) { final char ch = parameterString.charAt(i); if ((inQuotes ? currentQuote == ch : possibleQuoteChars.contains(ch))) { if (!escapedQuote) { inQuotes = !inQuotes; currentQuote = ch; nonEmpty = true; if (!keepQuotes) { continue; } } escapedQuote = false; } else if (Character.isWhitespace(ch)) { if (!inQuotes) { if (keepEmptyParameters || token.length() > 0 || nonEmpty) { params.add(token.toString()); token.setLength(0); nonEmpty = false; } continue; } } else if (ch == '\\' && i < parameterString.length() - 1) { final char nextchar = parameterString.charAt(i + 1); if (inQuotes ? currentQuote == nextchar : possibleQuoteChars.contains(nextchar)) { escapedQuote = true; if (!keepQuotes) { continue; } } } token.append(ch); } if (keepEmptyParameters || token.length() > 0 || nonEmpty) { params.add(token.toString()); } return params; }