class CheckHelper {

  public List<PrerequisiteCheck> performChecks(PrereqCheckRequest request,
                                               List<AbstractCheckDescriptor> checksRegistry, Configuration config) {

    final String clusterName = request.getClusterName();
    final List<PrerequisiteCheck> prerequisiteCheckResults = new ArrayList<>();
    final boolean canBypassPreChecks = config.isUpgradePrecheckBypass();

    List<DescriptorPreCheck> applicablePreChecks = getApplicablePrerequisiteChecks(request, checksRegistry);

    for (DescriptorPreCheck descriptorPreCheck : applicablePreChecks) {
      AbstractCheckDescriptor checkDescriptor = descriptorPreCheck.descriptor;
      PrerequisiteCheck prerequisiteCheck = descriptorPreCheck.check;
      try {
        checkDescriptor.perform(prerequisiteCheck, request);
      } catch (ClusterNotFoundException ex) {
        prerequisiteCheck.setFailReason("Cluster with name " + clusterName + " doesn't exists");
        prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
      } catch (Exception ex) {
        LOG.error("Check " + checkDescriptor.getDescription().name() + " failed", ex);
        prerequisiteCheck.setFailReason("Unexpected server error happened");
        prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
      }

      if (prerequisiteCheck.getStatus() == PrereqCheckStatus.FAIL && canBypassPreChecks) {
        LOG.error("Check {} failed but stack upgrade is allowed to bypass failures. Error to bypass: {}. Failed on: {}",
          checkDescriptor.getDescription().name(),
          prerequisiteCheck.getFailReason(),
          StringUtils.join(prerequisiteCheck.getFailedOn(), ", "));
        prerequisiteCheck.setStatus(PrereqCheckStatus.BYPASS);
      }

      prerequisiteCheckResults.add(prerequisiteCheck);
      request.addResult(checkDescriptor.getDescription(), prerequisiteCheck.getStatus());
    }

    return prerequisiteCheckResults;
  }

}