docs: @Override
      public void validate(final FacesContext context, final UIComponent component, final Object value)
      {
          if (context == null)
          {
              throw new NullPointerException("context");
          }
          if (component == null)
          {
              throw new NullPointerException("component");
          }
  
          ValueExpression valueExpression = component.getValueExpression("value");
          if (valueExpression == null)
          {
              log.warning("cannot validate component with empty value: " 
                      + component.getClientId(context));
              return;
          }
  
          // Obtain a reference to the to-be-validated object and the property name.
          ValueReference reference = getValueReference(valueExpression, context);
          if (reference == null)
          {
              return;
          }
          Object base = reference.getBase();
          if (base == null)
          {
              return;
          }
          
          Class<?> valueBaseClass = base.getClass();
          if (valueBaseClass == null)
          {
              return;
          }
          
          Object referenceProperty = reference.getProperty();
          if (!(referenceProperty instanceof String))
          {
              // if the property is not a String, the ValueReference does not
              // point to a bean method, but e.g. to a value in a Map, thus we 
              // can exit bean validation here
              return;
          }
          String valueProperty = (String) referenceProperty;
  
          // Initialize Bean Validation.
          ValidatorFactory validatorFactory = createValidatorFactory(context);
          javax.validation.Validator validator = createValidator(validatorFactory, context);
          BeanDescriptor beanDescriptor = validator.getConstraintsForClass(valueBaseClass);
          if (!beanDescriptor.isBeanConstrained())
          {
              return;
          }
          
          // Note that validationGroupsArray was initialized when createValidator was called
          Class[] validationGroupsArray = this.validationGroupsArray;
  
          // JSF 2.3: If the ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME application parameter is enabled and this Validator 
          // instance has validation groups other than or in addition to the Default group
          boolean containsOtherValidationGroup = false;
          if (validationGroupsArray != null && validationGroupsArray.length > 0)
          {
              for (Class<?> clazz : validationGroupsArray)
              {
                  if (!Default.class.equals(clazz))
                  {
                      containsOtherValidationGroup = true;
                      break;
                  }
              }
          }
          
          // Delegate to Bean Validation.
          Set constraintViolations = validator.validateValue(valueBaseClass, valueProperty, value, validationGroupsArray);
          if (!constraintViolations.isEmpty())
          {
              Set<FacesMessage> messages = new LinkedHashSet<FacesMessage>(constraintViolations.size());
              for (Object violation: constraintViolations)
              {
                  ConstraintViolation constraintViolation = (ConstraintViolation) violation;
                  String message = constraintViolation.getMessage();
                  Object[] args = new Object[]{ message, _MessageUtils.getLabel(context, component) };
                  FacesMessage msg = _MessageUtils.getErrorMessage(context, MESSAGE_ID, args);
                  messages.add(msg);
              }
              
              if (isValidateWholeBeanEnabled(context) && containsOtherValidationGroup)
              {
                  // JSF 2.3: record the fact that this field failed validation so that any <f:validateWholeBean /> 
                  // component later in the tree is able to skip class-level validation for the bean for which this 
                  // particular field is a property. Regardless of whether or not 
                  // ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME is set, throw the new exception.            
                  context.getViewRoot().getTransientStateHelper().putTransient(BEAN_VALIDATION_FAILED, Boolean.TRUE);
              }
              
              throw new ValidatorException(messages);
          }
          else
          {
              
              // JSF 2.3: If the returned Set is empty, the ENABLE_VALIDATE_WHOLE_BEAN_PARAM_NAME application parameter
              // is enabled and this Validator instance has validation groups other than or in addition to the 
              // Default group
              if (isValidateWholeBeanEnabled(context) && containsOtherValidationGroup)
              {
                  // record the fact that this field passed validation so that any <f:validateWholeBean /> component 
                  // later in the tree is able to allow class-level validation for the bean for which this particular 
                  // field is a property.
                  
                  Map<String, Object> candidatesMap = (Map<String, Object>) context.getViewRoot()
                          .getTransientStateHelper().getTransient(CANDIDATE_COMPONENT_VALUES_MAP);
                  if (candidatesMap == null)
                  {
                      candidatesMap = new LinkedHashMap<String, Object>();
                      context.getViewRoot().getTransientStateHelper().putTransient(
                              CANDIDATE_COMPONENT_VALUES_MAP, candidatesMap);
                  }
                  candidatesMap.put(component.getClientId(context), value);
              }
          }
      }