class InstanceResourceProvider extends AbstractDRResourceProvider {

  @Override
  public Set<Resource> getResources(Request request, Predicate predicate) throws SystemException,
      UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {

    Set<String>   requestedIds = getRequestPropertyIds(request, predicate);
    Set<Resource> resources    = new HashSet<>();
    List<String>  feedNames    = new LinkedList<>();

    IvoryService service = getService();
    if (predicate == null) {
      feedNames = service.getFeedNames();
    } else {
      for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
        String feedName = (String) propertyMap.get(INSTANCE_FEED_NAME_PROPERTY_ID);
        if (feedName == null) {
          // if any part of the predicate doesn't include feed name then we have to check them all
          feedNames = service.getFeedNames();
          break;
        }
        feedNames.add(feedName);
      }
    }

    for (String feedName : feedNames) {
      List<Instance> instances = service.getInstances(feedName);
      for (Instance instance : instances) {
        Resource resource = new ResourceImpl(Resource.Type.DRInstance);
        setResourceProperty(resource, INSTANCE_FEED_NAME_PROPERTY_ID,
            instance.getFeedName(), requestedIds);
        setResourceProperty(resource, INSTANCE_ID_PROPERTY_ID,
            instance.getId(), requestedIds);
        setResourceProperty(resource, INSTANCE_STATUS_PROPERTY_ID,
            instance.getStatus(), requestedIds);
        setResourceProperty(resource, INSTANCE_START_TIME_PROPERTY_ID,
            instance.getStartTime(), requestedIds);
        setResourceProperty(resource, INSTANCE_END_TIME_PROPERTY_ID,
            instance.getEndTime(), requestedIds);
        setResourceProperty(resource, INSTANCE_DETAILS_PROPERTY_ID,
            instance.getDetails(), requestedIds);
        setResourceProperty(resource, INSTANCE_LOG_PROPERTY_ID,
            instance.getLog(), requestedIds);

        if (predicate == null || predicate.evaluate(resource)) {
          resources.add(resource);
        }
      }
    }
    return resources;
  }

  public  InstanceResourceProvider(IvoryService ivoryService);

}