class ComponentsInstallationCheck extends AbstractCheckDescriptor {

  @Override
  public void perform(PrerequisiteCheck prerequisiteCheck, PrereqCheckRequest request) throws AmbariException {
    final String clusterName = request.getClusterName();
    final Cluster cluster = clustersProvider.get().getCluster(clusterName);
    Set<String> failedServiceNames = new HashSet<>();

    // Preq-req check should fail if any service component is in INSTALL_FAILED state
    Set<String> installFailedHostComponents = new HashSet<>();

    Set<String> servicesInUpgrade = getServicesInUpgrade(request);
    for (String serviceName : servicesInUpgrade) {
      final Service service = cluster.getService(serviceName);
      // Skip service if it is in maintenance mode
      if (service.getMaintenanceState() == MaintenanceState.ON) {
        continue;
      }

      Map<String, ServiceComponent> serviceComponents = service.getServiceComponents();
      for (Map.Entry<String, ServiceComponent> component : serviceComponents.entrySet()) {
        ServiceComponent serviceComponent = component.getValue();
        if (serviceComponent.isVersionAdvertised()) {
          List<HostComponentSummary> hostComponentSummaries = HostComponentSummary.getHostComponentSummaries(
              service.getName(), serviceComponent.getName());

          for (HostComponentSummary hcs : hostComponentSummaries) {
            // Skip host if it is in maintenance mode
            Host host = clustersProvider.get().getHost(hcs.getHostName());
            if (host.getMaintenanceState(cluster.getClusterId()) != MaintenanceState.ON) {
              if (hcs.getCurrentState() == State.INSTALL_FAILED) {

                prerequisiteCheck.getFailedDetail().add(hcs);

                failedServiceNames.add(service.getName());
                installFailedHostComponents.add(MessageFormat.format("[{0}:{1} on {2}]",
                    service.getName(), serviceComponent.getName(), hcs.getHostName()));
              }
            }
          }
        }
      }
    }

    if(!installFailedHostComponents.isEmpty()) {
      String message = MessageFormat.format("Service components in INSTALL_FAILED state: {0}.",
          StringUtils.join(installFailedHostComponents, ", "));

      prerequisiteCheck.setFailedOn(new LinkedHashSet<>(failedServiceNames));
      prerequisiteCheck.setStatus(PrereqCheckStatus.FAIL);
      prerequisiteCheck.setFailReason(
          "Found service components in INSTALL_FAILED state. Please re-install these components. " + message);
    }
  }

  public  ComponentsInstallationCheck();

}