@Override
  public <T> void validateField(
      final String factType,
      final String fieldName,
      final T value,
      final Callback<Set<ConstraintViolation<T>>> callback) {
    if (factType == null || factType.isEmpty()) {
      callback.callback(Collections.emptySet());
      return;
    }
    if (fieldName == null || fieldName.isEmpty()) {
      callback.callback(Collections.emptySet());
      return;
    }
    if (callback == null) {
      return;
    }

    if (validatorInstance.isUnsatisfied()) {
      callback.callback(Collections.emptySet());
      return;

    } else if (validator == null) {
      validator = validatorInstance.get();
    }

    getTypeFieldsAnnotations(
        factType,
        (Map<String, Set<Annotation>> result) -> {
          final Set<ConstraintViolation<T>> violations = new HashSet<>();
          final Set<Annotation> fieldAnnotations = result.get(fieldName);
          if (fieldAnnotations == null || fieldAnnotations.isEmpty()) {
            callback.callback(violations);
            return;
          }

          for (Annotation fieldAnnotation : fieldAnnotations) {
            final Map<String, Object> fieldAnnotationAttributes = fieldAnnotation.getParameters();
            violations.addAll(
                validator.validate(
                    fieldAnnotation.getQualifiedTypeName(), fieldAnnotationAttributes, value));
          }
          callback.callback(violations);
        });
  }