public ParseResult parseAll(Map<String, String> values) throws FormValidationException {
    Map<Field, Object> results = new HashMap<>(fields.size());
    Map<Field, ValidationException> failures = new HashMap<>(fields.size());
    for (Field field : fields) {
      String value = values.get(field.getName());
      Object result = null;
      try {
        result = field.validate(value);
      } catch (ValidationException e) {
        failures.put(field, e);
      }
      if (result != null) {
        results.put(field, result);
      }
    }
    if (!failures.isEmpty()) {
      throw new FormValidationException(failures);
    }
    return new ParseResult(results);
  }