@Override
  public Set<Resource> getResources(Request request, Predicate predicate)
      throws SystemException, UnsupportedPropertyException, NoSuchResourceException,
          NoSuchParentResourceException {
    final Set<StackServiceComponentRequest> requests = new HashSet<StackServiceComponentRequest>();

    if (predicate == null) {
      requests.add(getRequest(Collections.<String, Object>emptyMap()));
    } else {
      for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
        requests.add(getRequest(propertyMap));
      }
    }

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

    Set<StackServiceComponentResponse> responses =
        getResources(
            new Command<Set<StackServiceComponentResponse>>() {
              @Override
              public Set<StackServiceComponentResponse> invoke() throws AmbariException {
                return getManagementController().getStackComponents(requests);
              }
            });

    Set<Resource> resources = new HashSet<Resource>();

    for (StackServiceComponentResponse response : responses) {
      Resource resource = new ResourceImpl(Resource.Type.StackServiceComponent);

      setResourceProperty(resource, STACK_NAME_PROPERTY_ID, response.getStackName(), requestedIds);

      setResourceProperty(
          resource, STACK_VERSION_PROPERTY_ID, response.getStackVersion(), requestedIds);

      setResourceProperty(
          resource, SERVICE_NAME_PROPERTY_ID, response.getServiceName(), requestedIds);

      setResourceProperty(
          resource, COMPONENT_NAME_PROPERTY_ID, response.getComponentName(), requestedIds);

      setResourceProperty(
          resource,
          COMPONENT_DISPLAY_NAME_PROPERTY_ID,
          response.getComponentDisplayName(),
          requestedIds);

      setResourceProperty(
          resource, COMPONENT_CATEGORY_PROPERTY_ID, response.getComponentCategory(), requestedIds);

      setResourceProperty(resource, IS_CLIENT_PROPERTY_ID, response.isClient(), requestedIds);

      setResourceProperty(resource, IS_MASTER_PROPERTY_ID, response.isMaster(), requestedIds);

      setResourceProperty(resource, CARDINALITY_ID, response.getCardinality(), requestedIds);

      setResourceProperty(
          resource, ADVERTISE_VERSION_ID, response.isVersionAdvertised(), requestedIds);

      setResourceProperty(
          resource, CUSTOM_COMMANDS_PROPERTY_ID, response.getCustomCommands(), requestedIds);

      AutoDeployInfo autoDeployInfo = response.getAutoDeploy();
      if (autoDeployInfo != null) {
        setResourceProperty(
            resource, AUTO_DEPLOY_ENABLED_ID, autoDeployInfo.isEnabled(), requestedIds);

        if (autoDeployInfo.getCoLocate() != null) {
          setResourceProperty(
              resource, AUTO_DEPLOY_LOCATION_ID, autoDeployInfo.getCoLocate(), requestedIds);
        }
      }
      try {
        StackInfo stackInfo =
            getManagementController()
                .getAmbariMetaInfo()
                .getStack(response.getStackName(), response.getStackVersion());
        if (stackInfo != null && stackInfo.getServicePort() != null) {
          List<String> usedPorts =
              stackInfo
                  .getServicePort()
                  .getComponentPort(response.getServiceName(), response.getComponentName());
          setResourceProperty(resource, USED_PORTS_ID, usedPorts, requestedIds);
        }
      } catch (AmbariException e) {
        throw new SystemException(
            "Stack "
                + response.getStackName()
                + " "
                + response.getStackVersion()
                + " is not found in Ambari metainfo");
      }

      resources.add(resource);
    }

    return resources;
  }