docs: public static void parse(
              final boolean errorOnExtraProperties, final PObject requestData, final Object objectToPopulate,
              final String... extraPropertyToIgnore) {
          checkForExtraProperties(errorOnExtraProperties, objectToPopulate.getClass(), requestData,
                                  extraPropertyToIgnore);
  
          final Collection<Field> allAttributes =
                  ParserUtils.getAttributes(objectToPopulate.getClass(), FILTER_NON_FINAL_FIELDS);
          Map<String, Class<?>> missingProperties = new HashMap<>();
  
          final OneOfTracker oneOfTracker = new OneOfTracker();
          final RequiresTracker requiresTracker = new RequiresTracker();
          final String paramClassName = objectToPopulate.getClass().getName();
          for (Field attribute: allAttributes) {
              oneOfTracker.register(attribute);
              requiresTracker.register(attribute);
          }
  
          for (Field property: allAttributes) {
              try {
                  Object value;
                  try {
                      value = parseValue(errorOnExtraProperties, extraPropertyToIgnore, property.getType(),
                                         property.getName(),
                                         requestData);
                  } catch (UnsupportedTypeException e) {
                      String type = e.type.getName();
                      if (e.type.isArray()) {
                          type = e.type.getComponentType().getName() + "[]";
                      }
                      throw new RuntimeException(
                              "The type '" + type + "' is not a supported type when parsing json.  " +
                                      "See documentation for supported types.\n\nUnsupported type found in " +
                                      paramClassName
                                      + " " +
                                      "under the property: " + property.getName() +
                                      "\n\nTo support more types add the type to" +
                                      " " +
                                      "parseValue and parseArrayValue in this class and add a test to the " +
                                      "test class",
                              e);
                  }
                  try {
                      oneOfTracker.markAsVisited(property);
                      requiresTracker.markAsVisited(property);
                      property.set(objectToPopulate, value);
                  } catch (IllegalAccessException e) {
                      throw ExceptionUtils.getRuntimeException(e);
                  }
              } catch (ObjectMissingException e) {
                  final HasDefaultValue hasDefaultValue = property.getAnnotation(HasDefaultValue.class);
                  final OneOf oneOf = property.getAnnotation(OneOf.class);
                  final CanSatisfyOneOf canSatisfyOneOf = property.getAnnotation(CanSatisfyOneOf.class);
                  if (hasDefaultValue == null && oneOf == null && canSatisfyOneOf == null) {
                      missingProperties.put(property.getName(), property.getType());
                  }
              }
          }
  
          oneOfTracker.checkAllGroupsSatisfied(requestData.getCurrentPath());
          requiresTracker.checkAllRequirementsSatisfied(requestData.getCurrentPath());
  
          if (!missingProperties.isEmpty()) {
              String message =
                      "Request Json is missing some required attributes at: '" + requestData.getCurrentPath() +
                              "': ";
              throw new MissingPropertyException(message, missingProperties,
                                                 getAllAttributeNames(objectToPopulate.getClass()));
          }
  
          try {
              final Method method = objectToPopulate.getClass().getMethod(POST_CONSTRUCT_METHOD_NAME);
              method.invoke(objectToPopulate);
          } catch (NoSuchMethodException e) {
              LOGGER.debug("No {} method on parameter object of class {}", POST_CONSTRUCT_METHOD_NAME,
                           paramClassName);
          } catch (InvocationTargetException e) {
              final Throwable targetException = e.getTargetException();
              if (targetException instanceof RuntimeException) {
                  throw (RuntimeException) targetException;
              } else if (targetException instanceof Error) {
                  throw (Error) targetException;
              }
              throw new RuntimeException(e);
          } catch (IllegalAccessException e) {
              throw new RuntimeException(e);
          }
      }