code: public static Map<String, String> cleanupProperties(
              final Map<String, String> rawProperties, final String[] blackList) {
          final Map<String, String> newProp = new HashMap<String, String>(
                  rawProperties.size()); // roughly the same size
          for (String okey : rawProperties.keySet()) {
              final String key = okey.trim();
              if (blackList != null) {
                  boolean blackListed = false;
                  for (String blackKey : blackList) {
                      if (blackKey.equals(key)) {
                          blackListed = true;
                          break;
                      }
                  }
                  if (blackListed) {
                      continue;
                  }
              }
              final String value = rawProperties.get(key);
              if (value == null || "".equals(value)) {
                  // remove null or empty values
                  continue;
              }
              if (isSpecifiedPropertyName(key)) {
                  // a well known property name
                  newProp.put(key, value);
              } else {
                  // convert to a custom property name
                  newProp.put(adaptToCustomPropertyName(key), value);
              }
          }
          return newProp;
      }
docs: Any properties which are not well known (i.e. in
  {@link BasicLTIConstants#validPropertyNames}) will be mapped to custom
  properties per the specified semantics.
  
  @param rawProperties A set of properties that will be cleaned.
  @param blackList An array of {@link String}s which are considered unsafe
  to be included in launch data. Any matches will be removed from the
  return.
  @return A cleansed version of rawProperties.