@SuppressWarnings("nls")
    private static String replaceQMark(String query, Object[] sanitisedArgs) {
        StringBuilder sb = new StringBuilder(query.length() + (sanitisedArgs.length * 10));
        int argIdx = 0;
        char pChar = ' ';
        for (int i = 0; i < query.length(); i++) {
            char cChar = query.charAt(i);
            if (cChar == '?' && pChar != '\\') {
                Object arg = sanitisedArgs[argIdx];
                if (arg instanceof Number) {
                    sb.append(arg);
                } else {
                    sb.append("\"");
                    sb.append(arg.toString());
                    sb.append("\"");
                }
                argIdx++;
            } else {
                sb.append(cChar);
            }
            pChar = cChar;
        }
        return sb.toString();
    }
An ES query with escaped arguments:
<p>
Use the SQL convention of ? (e.g. "foo": ?, "bar": ?).
<p>
A {@link Number} instance will be unquoted, all other types will be quoted.

@param query ES query
@param args the corresponding positional arguments {0} ... {n-1}
@return query with escaped variables substituted in
common/es/src/main/java/io/apiman/common/es/util/EsUtils.java