docs: public FluentValidator doValidate(ValidateCallback cb) {
          Preconditions.checkNotNull(cb, "ValidateCallback should not be NULL");
          if (validatorElementList.isEmpty()) {
              LOGGER.debug("Nothing to validate");
              return this;
          }
          context.setResult(result);
  
          LOGGER.debug("Start to validate through " + validatorElementList);
          long start = System.currentTimeMillis();
          try {
              GroupingHolder.setGrouping(groups);
              for (ValidatorElement element : validatorElementList.getAllValidatorElements()) {
                  Object target = element.getTarget();
                  Validator v = element.getValidator();
                  try {
                      if (v.accept(context, target)) {
                          if (!v.validate(context, target)) {
                              result.setIsSuccess(false);
                              if (isFailFast) {
                                  break;
                              }
                          }
                      }
                  } catch (Exception e) {
                      try {
                          v.onException(e, context, target);
                          cb.onUncaughtException(v, e, target);
                      } catch (Exception e1) {
                          if (LOGGER.isDebugEnabled()) {
                              LOGGER.error(v + " onException or onUncaughtException throws exception due to " + e1
                                      .getMessage(), e1);
                          }
                          throw new RuntimeValidateException(e1);
                      }
                      if (LOGGER.isDebugEnabled()) {
                          LOGGER.error(v + " failed due to " + e.getMessage(), e);
                      }
                      throw new RuntimeValidateException(e);
                  }
              }
  
              if (result.isSuccess()) {
                  cb.onSuccess(validatorElementList);
              } else {
                  cb.onFail(validatorElementList, result.getErrors());
              }
          } finally {
              GroupingHolder.clean();
              int timeElapsed = (int) (System.currentTimeMillis() - start);
              LOGGER.debug("End to validate through" + validatorElementList + " costing " + timeElapsed + "ms with "
                      + "isSuccess=" + result.isSuccess());
              result.setTimeElapsed(timeElapsed);
          }
          return this;
      }