class CompatibleRepositoryVersionResourceProvider extends ReadOnlyResourceProvider {

  @Override
  public Set<Resource> getResources(Request request, Predicate predicate)
    throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
    final Set<Resource> resources = new HashSet<>();
    final Set<String> requestedIds = getRequestPropertyIds(request, predicate);
    final Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);

    Long currentStackUniqueId = null;
    Map<Long, CompatibleRepositoryVersion> compatibleRepositoryVersionsMap = new HashMap<>();

    StackId stackId = null;
    // !!! this is the case where the predicate was altered to include all stacks
    for (Map<String, Object> propertyMap : propertyMaps) {
      if (propertyMap.containsKey(REPOSITORY_STACK_VALUE)) {
        stackId = new StackId(propertyMap.get(REPOSITORY_STACK_VALUE).toString());
        break;
      }
    }

    if (null == stackId) {
      if (propertyMaps.size() == 1) {
        Map<String, Object> propertyMap = propertyMaps.iterator().next();
        stackId = getStackInformationFromUrl(propertyMap);
      } else {
        LOG.error("Property Maps size is NOT equal to 1. Current 'propertyMaps' size = {}", propertyMaps.size());
      }
    }

    if (null == stackId) {
      LOG.error("Could not determine stack to process.  Returning empty set.");
      return resources;
    }

    for (RepositoryVersionEntity repositoryVersionEntity : s_repositoryVersionDAO.findByStack(stackId)) {
      currentStackUniqueId = repositoryVersionEntity.getId();
      compatibleRepositoryVersionsMap.put(repositoryVersionEntity.getId(),
          new CompatibleRepositoryVersion(repositoryVersionEntity));
      if (LOG.isDebugEnabled()) {
        LOG.debug("Added current stack id: {} to map", repositoryVersionEntity.getId());
      }
    }

    Map<String, UpgradePack> packs = s_ambariMetaInfo.get().getUpgradePacks(
      stackId.getStackName(), stackId.getStackVersion());

    for (UpgradePack up : packs.values()) {
      if (null != up.getTargetStack()) {
        StackId targetStackId = new StackId(up.getTargetStack());
        List<RepositoryVersionEntity> repositoryVersionEntities = s_repositoryVersionDAO.findByStack(targetStackId);

        for (RepositoryVersionEntity repositoryVersionEntity : repositoryVersionEntities) {
          if (compatibleRepositoryVersionsMap.containsKey(repositoryVersionEntity.getId())) {
            compatibleRepositoryVersionsMap.get(repositoryVersionEntity.getId()).addUpgradePackType(up.getType());
            if (LOG.isDebugEnabled()) {
              LOG.debug("Stack id: {} exists in map.  Appended new upgrade type {}{}", up.getType(), repositoryVersionEntity.getId());
            }
          } else {
            CompatibleRepositoryVersion compatibleRepositoryVersionEntity = new CompatibleRepositoryVersion(repositoryVersionEntity);
            compatibleRepositoryVersionEntity.addUpgradePackType(up.getType());
            compatibleRepositoryVersionsMap.put(repositoryVersionEntity.getId(), compatibleRepositoryVersionEntity);
            if (LOG.isDebugEnabled()) {
              LOG.debug("Added Stack id: {} to map with upgrade type {}", repositoryVersionEntity.getId(), up.getType());
            }
          }
        }
      } else {
        if (currentStackUniqueId != null) {
          compatibleRepositoryVersionsMap.get(currentStackUniqueId).addUpgradePackType(up.getType());
          if (LOG.isDebugEnabled()) {
            LOG.debug("Current Stack id: {} retrieved from map. Added upgrade type {}", currentStackUniqueId, up.getType());
          }
        } else {
          LOG.error("Couldn't retrieve Current stack entry from Map.");
        }
      }
    }

    for (CompatibleRepositoryVersion entity : compatibleRepositoryVersionsMap.values()) {

      RepositoryVersionEntity repositoryVersionEntity = entity.getRepositoryVersionEntity();
      final Resource resource = new ResourceImpl(Resource.Type.CompatibleRepositoryVersion);
      setResourceProperty(resource, REPOSITORY_VERSION_ID_PROPERTY_ID, repositoryVersionEntity.getId(), requestedIds);

      setResourceProperty(resource, REPOSITORY_VERSION_STACK_NAME_PROPERTY_ID, repositoryVersionEntity.getStackName(), requestedIds);
      setResourceProperty(resource, REPOSITORY_VERSION_STACK_VERSION_PROPERTY_ID, repositoryVersionEntity.getStackVersion(), requestedIds);

      setResourceProperty(resource, REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, repositoryVersionEntity.getDisplayName(), requestedIds);
      setResourceProperty(resource, REPOSITORY_VERSION_REPOSITORY_VERSION_PROPERTY_ID, repositoryVersionEntity.getVersion(), requestedIds);
      setResourceProperty(resource, REPOSITORY_UPGRADES_SUPPORTED_TYPES_ID, entity.getSupportedTypes(), requestedIds);

      final VersionDefinitionXml xml;
      try {
        xml = repositoryVersionEntity.getRepositoryXml();
      } catch (Exception e) {
        throw new SystemException(String.format("Could not load xml for Repository %s", repositoryVersionEntity.getId()), e);
      }

      final StackInfo stack;
      try {
        stack = s_ambariMetaInfo.get().getStack(repositoryVersionEntity.getStackName(), repositoryVersionEntity.getStackVersion());
      } catch (AmbariException e) {
        throw new SystemException(String.format("Could not load stack %s for Repository %s",
            repositoryVersionEntity.getStackId().toString(), repositoryVersionEntity.getId()));
      }

      final List<ManifestServiceInfo> stackServices;

      if (null != xml) {
        setResourceProperty(resource, REPOSITORY_VERSION_SERVICES, xml.getAvailableServices(stack), requestedIds);
        stackServices = xml.getStackServices(stack);
      } else {
        stackServices = new ArrayList<>();

        for (ServiceInfo si : stack.getServices()) {
          stackServices.add(new ManifestServiceInfo(si.getName(), si.getDisplayName(), si.getComment(),
              Collections.singleton(si.getVersion())));
        }
      }

      setResourceProperty(resource, REPOSITORY_VERSION_STACK_SERVICES, stackServices, requestedIds);

      resources.add(resource);
    }
    return resources;
  }

  public  CompatibleRepositoryVersionResourceProvider(AmbariManagementController amc);

}