docs: public void populateFromAttributes(
              @Nonnull final Template template,
              @Nonnull final Map<String, Attribute> attributes,
              @Nonnull final PObject requestJsonAttributes) {
          if (requestJsonAttributes.has(JSON_REQUEST_HEADERS) &&
                  requestJsonAttributes.getObject(JSON_REQUEST_HEADERS).has(JSON_REQUEST_HEADERS) &&
                  !attributes.containsKey(JSON_REQUEST_HEADERS)) {
              attributes.put(JSON_REQUEST_HEADERS, new HttpRequestHeadersAttribute());
          }
          for (Map.Entry<String, Attribute> attribute: attributes.entrySet()) {
              try {
                  put(attribute.getKey(),
                      attribute.getValue().getValue(template, attribute.getKey(), requestJsonAttributes));
              } catch (ObjectMissingException | IllegalArgumentException e) {
                  throw e;
              } catch (Throwable e) {
                  String templateName = "unknown";
                  for (Map.Entry<String, Template> entry: template.getConfiguration().getTemplates()
                          .entrySet()) {
                      if (entry.getValue() == template) {
                          templateName = entry.getKey();
                          break;
                      }
                  }
  
                  String defaults = "";
  
                  if (attribute instanceof ReflectiveAttribute<?>) {
                      ReflectiveAttribute<?> reflectiveAttribute = (ReflectiveAttribute<?>) attribute;
                      defaults = "\n\n The attribute defaults are: " + reflectiveAttribute.getDefaultValue();
                  }
  
                  String errorMsg = "An error occurred when creating a value from the '" + attribute.getKey() +
                          "' attribute for the '" +
                          templateName + "' template.\n\nThe JSON is: \n" + requestJsonAttributes + defaults +
                          "\n" +
                          e.toString();
  
                  throw new AttributeParsingException(errorMsg, e);
              }
          }
  
          if (template.getConfiguration().isThrowErrorOnExtraParameters()) {
              final List<String> extraProperties = new ArrayList<>();
              for (Iterator<String> it = requestJsonAttributes.keys(); it.hasNext(); ) {
                  final String attributeName = it.next();
                  if (!attributes.containsKey(attributeName)) {
                      extraProperties.add(attributeName);
                  }
              }
  
              if (!extraProperties.isEmpty()) {
                  throw new ExtraPropertyException("Extra properties found in the request attributes",
                                                   extraProperties, attributes.keySet());
              }
          }
      }