class ViewSubResourceProvider extends AbstractResourceProvider {

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

    Set<String> requestedIds = getRequestPropertyIds(request, predicate);

    Set<ViewInstanceEntity> instanceDefinitions = new HashSet<>();

    try {

      Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate);
      int size = propertyMaps.size();

      Collection<ViewInstanceEntity> viewInstanceDefinitions = viewDefinition.getInstances();
      if (size == 0) {
        instanceDefinitions.addAll(viewInstanceDefinitions);
      } else {
        for (Map<String, Object> propertyMap : propertyMaps) {
          String instanceName = (String) propertyMap.get(INSTANCE_NAME_PROPERTY_ID);
          if (size == 1 && instanceName != null) {
            String resourceId = (String) propertyMap.get(pkField);
            if (resourceId != null) {
              Object bean = getResourceProvider(instanceName).getResource(resourceId, requestedIds);
              return Collections.singleton(getResource(bean, viewDefinition.getCommonName(),
                  viewDefinition.getVersion(), instanceName, requestedIds));
            }
          }
          if (instanceName == null) {
            instanceDefinitions.addAll(viewInstanceDefinitions);
            break;
          } else {
            ViewInstanceEntity instanceDefinition = viewDefinition.getInstanceDefinition(instanceName);
            if (instanceDefinition != null) {
              instanceDefinitions.add(instanceDefinition);
            }
          }
        }
      }

      Set<Resource> results = new HashSet<>();
      ReadRequest readRequest = new ViewReadRequest(request, requestedIds, predicate == null ? "" : predicate.toString());
      for (ViewInstanceEntity instanceDefinition : instanceDefinitions) {

        Set<?> beans = instanceDefinition.getResourceProvider(type).getResources(readRequest);

        for (Object bean : beans) {
          Resource resource = getResource(bean, viewDefinition.getCommonName(),
              viewDefinition.getVersion(), instanceDefinition.getName(), requestedIds);
          if (predicate.evaluate(resource)) {
            results.add(resource);
          }
        }
      }
      return results;
    } catch (org.apache.ambari.view.NoSuchResourceException e) {
      throw new NoSuchParentResourceException(e.getMessage(), e);
    } catch (org.apache.ambari.view.UnsupportedPropertyException e) {
      throw new UnsupportedPropertyException(getResourceType(e), e.getPropertyIds());
    } catch (Exception e) {
      LOG.error("Caught exception getting view sub resources.", e);
      throw new SystemException(e.getMessage(), e);
    }
  }

  public  ViewSubResourceProvider(Resource.Type type, Class<?> clazz, String pkField, ViewEntity viewDefinition);

}