/**
  * Validates a list of dimension names
  *
  * @param names
  */
 public static void validateNames(List<String> names) {
   if (names != null) {
     for (String name : names) {
       if (Strings.isNullOrEmpty(name)) {
         throw Exceptions.unprocessableEntity("Dimension name cannot be empty");
       }
       if (name.length() > 255) {
         throw Exceptions.unprocessableEntity(
             "Dimension name '%s' must be 255 characters or less", name);
       }
       // Dimension names that start with underscores are reserved for internal use only.
       if (name.startsWith("_")) {
         throw Exceptions.unprocessableEntity(
             "Dimension name '%s' cannot start with underscore (_)", name);
       }
       if (!VALID_DIMENSION_NAME.matcher(name).matches())
         throw Exceptions.unprocessableEntity(
             "Dimension name '%s' may not contain: %s", name, INVALID_CHAR_STRING);
     }
   }
 }
  /**
   * Validates that the given {@code dimensions} are valid.
   *
   * @throws WebApplicationException if validation fails
   */
  public static void validate(Map<String, String> dimensions, @Nullable String service) {
    // Validate dimension names and values
    for (Map.Entry<String, String> dimension : dimensions.entrySet()) {
      String name = dimension.getKey();
      String value = dimension.getValue();

      // General validations
      if (Strings.isNullOrEmpty(name))
        throw Exceptions.unprocessableEntity("Dimension name cannot be empty");
      if (Strings.isNullOrEmpty(value))
        throw Exceptions.unprocessableEntity("Dimension %s cannot have an empty value", name);
      if (name.length() > 255)
        throw Exceptions.unprocessableEntity(
            "Dimension name %s must be 255 characters or less", name);
      if (value.length() > 255)
        throw Exceptions.unprocessableEntity(
            "Dimension value %s must be 255 characters or less", value);
      // Dimension names that start with underscores are reserved for internal use only.
      if (name.startsWith("_")) {
        throw Exceptions.unprocessableEntity(
            "Dimension name cannot start with underscore (_)", name);
      }
      if (!VALID_DIMENSION_NAME.matcher(name).matches())
        throw Exceptions.unprocessableEntity(
            "Dimension name %s may not contain: %s", name, INVALID_CHAR_STRING);

      // Service specific validations
      if (service != null) {
        if (!name.equals(Services.SERVICE_DIMENSION)
            && !Services.isValidDimensionName(service, name))
          throw Exceptions.unprocessableEntity(
              "%s is not a valid dimension name for service %s", name, service);
        DimensionValidator validator = VALIDATORS.get(service);
        if (validator != null && !validator.isValidDimension(name, value))
          throw Exceptions.unprocessableEntity(
              "%s is not a valid dimension value for service %s", value, service);
      }
    }
  }