public MultiValueMap<String, Connection<?>> findConnectionsToUsers(
     MultiValueMap<String, String> providerUsers) {
   if (providerUsers == null || providerUsers.isEmpty()) {
     throw new IllegalArgumentException("Unable to execute find: no providerUsers provided");
   }
   StringBuilder providerUsersCriteriaSql = new StringBuilder();
   MapSqlParameterSource parameters = new MapSqlParameterSource();
   parameters.addValue("userId", userId);
   for (Iterator<Entry<String, List<String>>> it = providerUsers.entrySet().iterator();
       it.hasNext(); ) {
     Entry<String, List<String>> entry = it.next();
     String providerId = entry.getKey();
     providerUsersCriteriaSql
         .append("providerId = :providerId_")
         .append(providerId)
         .append(" and providerUserId in (:providerUserIds_")
         .append(providerId)
         .append(")");
     parameters.addValue("providerId_" + providerId, providerId);
     parameters.addValue("providerUserIds_" + providerId, entry.getValue());
     if (it.hasNext()) {
       providerUsersCriteriaSql.append(" or ");
     }
   }
   List<Connection<?>> resultList =
       new NamedParameterJdbcTemplate(jdbcTemplate)
           .query(
               selectFromUserConnection()
                   + " where userId = :userId and "
                   + providerUsersCriteriaSql
                   + " order by providerId, rank",
               parameters,
               connectionMapper);
   MultiValueMap<String, Connection<?>> connectionsForUsers =
       new LinkedMultiValueMap<String, Connection<?>>();
   for (Connection<?> connection : resultList) {
     String providerId = connection.getKey().getProviderId();
     List<String> userIds = providerUsers.get(providerId);
     List<Connection<?>> connections = connectionsForUsers.get(providerId);
     if (connections == null) {
       connections = new ArrayList<Connection<?>>(userIds.size());
       for (int i = 0; i < userIds.size(); i++) {
         connections.add(null);
       }
       connectionsForUsers.put(providerId, connections);
     }
     String providerUserId = connection.getKey().getProviderUserId();
     int connectionIndex = userIds.indexOf(providerUserId);
     connections.set(connectionIndex, connection);
   }
   return connectionsForUsers;
 }
 private String normalizeParameters(MultiValueMap<String, String> collectedParameters) {
   // Normalizes the collected parameters for baseString calculation, per
   // http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2
   MultiValueMap<String, String> sortedEncodedParameters = new TreeMultiValueMap<String, String>();
   for (Iterator<Entry<String, List<String>>> entryIt = collectedParameters.entrySet().iterator();
       entryIt.hasNext(); ) {
     Entry<String, List<String>> entry = entryIt.next();
     String collectedName = entry.getKey();
     List<String> collectedValues = entry.getValue();
     List<String> encodedValues = new ArrayList<String>(collectedValues.size());
     sortedEncodedParameters.put(oauthEncode(collectedName), encodedValues);
     for (Iterator<String> valueIt = collectedValues.iterator(); valueIt.hasNext(); ) {
       String value = valueIt.next();
       encodedValues.add(value != null ? oauthEncode(value) : "");
     }
     Collections.sort(encodedValues);
   }
   StringBuilder paramsBuilder = new StringBuilder();
   for (Iterator<Entry<String, List<String>>> entryIt =
           sortedEncodedParameters.entrySet().iterator();
       entryIt.hasNext(); ) {
     Entry<String, List<String>> entry = entryIt.next();
     String name = entry.getKey();
     List<String> values = entry.getValue();
     for (Iterator<String> valueIt = values.iterator(); valueIt.hasNext(); ) {
       String value = valueIt.next();
       paramsBuilder.append(name).append('=').append(value);
       if (valueIt.hasNext()) {
         paramsBuilder.append("&");
       }
     }
     if (entryIt.hasNext()) {
       paramsBuilder.append("&");
     }
   }
   return paramsBuilder.toString();
 }
 private String getQueryString() throws UnsupportedEncodingException {
   HttpServletRequest request = RequestContext.getCurrentContext().getRequest();
   MultiValueMap<String, String> params = helper.buildZuulRequestQueryParams(request);
   StringBuilder query = new StringBuilder();
   for (Map.Entry<String, List<String>> entry : params.entrySet()) {
     String key = URLEncoder.encode(entry.getKey(), "UTF-8");
     for (String value : entry.getValue()) {
       query.append("&");
       query.append(key);
       query.append("=");
       query.append(URLEncoder.encode(value, "UTF-8"));
     }
   }
   return (query.length() > 0) ? "?" + query.substring(1) : "";
 }
 // can't use putAll here because it will overwrite anything that has the same key in both maps
 private MultiValueMap<String, String> union(
     MultiValueMap<String, String> map1, MultiValueMap<String, String> map2) {
   MultiValueMap<String, String> union = new LinkedMultiValueMap<String, String>(map1);
   Set<Entry<String, List<String>>> map2Entries = map2.entrySet();
   for (Iterator<Entry<String, List<String>>> entryIt = map2Entries.iterator();
       entryIt.hasNext(); ) {
     Entry<String, List<String>> entry = entryIt.next();
     String key = entry.getKey();
     List<String> values = entry.getValue();
     for (String value : values) {
       union.add(key, value);
     }
   }
   return union;
 }
  @Override
  public MultiValueMap<String, Connection<?>> findConnectionsToUsers(
      MultiValueMap<String, String> providerUsers) {
    if (providerUsers == null || providerUsers.isEmpty()) {
      throw new IllegalArgumentException("Unable to execute find: no providerUsers provided");
    }

    List<Connection<?>> allConnections =
        providerUsers
            .entrySet()
            .stream()
            .flatMap(
                entry ->
                    entry
                        .getValue()
                        .stream()
                        .map(u -> LdoD.getInstance().getUserConnection(userId, entry.getKey(), u)))
            .sorted((uc1, uc2) -> compareByProviderIdAndRank(uc1, uc2))
            .map(uc -> mapUserConnection(uc))
            .collect(Collectors.toList());

    MultiValueMap<String, Connection<?>> connectionsForUsers =
        new LinkedMultiValueMap<String, Connection<?>>();
    for (Connection<?> connection : allConnections) {
      String providerId = connection.getKey().getProviderId();
      List<String> userIds = providerUsers.get(providerId);
      List<Connection<?>> connections = connectionsForUsers.get(providerId);
      if (connections == null) {
        connections = new ArrayList<Connection<?>>(userIds.size());
        for (int i = 0; i < userIds.size(); i++) {
          connections.add(null);
        }
        connectionsForUsers.put(providerId, connections);
      }
      String providerUserId = connection.getKey().getProviderUserId();
      int connectionIndex = userIds.indexOf(providerUserId);
      connections.set(connectionIndex, connection);
    }
    return connectionsForUsers;
  }