code: public String url(Map<String, ?> parametersMap)
      {
          StringBuilder queryStringBuilder = new StringBuilder();
          for (Map.Entry<String, ?> entry : parametersMap.entrySet()) {
              if (entry.getKey() == null) {
                  // Skip the parameter if its name is null.
                  continue;
              }
              String cleanKey = this.url(entry.getKey());
              Object mapValues = entry.getValue();
              if (mapValues != null && mapValues.getClass().isArray()) {
                  // A parameter with multiple values.
                  Object[] values = (Object[]) mapValues;
                  for (Object value : values) {
                      addQueryStringPair(cleanKey, value, queryStringBuilder);
                  }
              } else if (mapValues != null && Collection.class.isAssignableFrom(mapValues.getClass())) {
                  // A parameter with multiple values.
                  Collection<?> values = (Collection<?>) mapValues;
                  for (Object value : values) {
                      addQueryStringPair(cleanKey, value, queryStringBuilder);
                  }
              } else {
                  addQueryStringPair(cleanKey, mapValues, queryStringBuilder);
              }
          }
          return queryStringBuilder.toString();
      }
docs: Properly escape a parameter map representing a query string, so that it can be safely used in an URL. Parameters
  can have multiple values in which case the value in the map is either an array or a {@link Collection}. If the
  parameter name is {@code null} (the key is {@code null}) then the parameter is ignored. {@code null} values are
  serialized as an empty string.
  
  @param parametersMap Map representing the query string.
  @return the safe query string representing the passed parameters
  @since 5.2M1