/**
   * This method returns an HTTP response with content body appropriate to the following arguments.
   *
   * @param rangeValue starting and ending byte offsets, see {@link Range}
   * @param limit is the number of child resources returned in the response, -1 for all
   * @param rdfStream to which response RDF will be concatenated
   * @return HTTP response
   * @throws IOException
   */
  protected Response getContent(final String rangeValue, final int limit, final RdfStream rdfStream)
      throws IOException {
    if (resource() instanceof FedoraBinary) {

      final String contentTypeString = ((FedoraBinary) resource()).getMimeType();

      final Lang lang = contentTypeToLang(contentTypeString);

      if (!contentTypeString.equals("text/plain") && lang != null) {

        final String format = lang.getName().toUpperCase();

        final InputStream content = ((FedoraBinary) resource()).getContent();

        final Model inputModel =
            createDefaultModel().read(content, (resource()).toString(), format);

        rdfStream.concat(Iterators.transform(inputModel.listStatements(), Statement::asTriple));
      } else {

        final MediaType mediaType = MediaType.valueOf(contentTypeString);
        if (MESSAGE_EXTERNAL_BODY.isCompatible(mediaType)
            && mediaType.getParameters().containsKey("access-type")
            && mediaType.getParameters().get("access-type").equals("URL")
            && mediaType.getParameters().containsKey("URL")) {
          try {
            return temporaryRedirect(new URI(mediaType.getParameters().get("URL"))).build();
          } catch (final URISyntaxException e) {
            throw new RepositoryRuntimeException(e);
          }
        }
        return getBinaryContent(rangeValue);
      }

    } else {
      rdfStream.concat(getResourceTriples(limit));
      if (prefer != null) {
        prefer.getReturn().addResponseHeaders(servletResponse);
      }
    }
    servletResponse.addHeader("Vary", "Accept, Range, Accept-Encoding, Accept-Language");

    return ok(rdfStream).build();
  }
  /**
   * This method returns a stream of RDF triples associated with this target resource
   *
   * @param limit is the number of child resources returned in the response, -1 for all
   * @return {@link RdfStream}
   */
  protected RdfStream getResourceTriples(final int limit) {
    // use the thing described, not the description, for the subject of descriptive triples
    if (resource() instanceof NonRdfSourceDescription) {
      resource = ((NonRdfSourceDescription) resource()).getDescribedResource();
    }
    final PreferTag returnPreference;

    if (prefer != null && prefer.hasReturn()) {
      returnPreference = prefer.getReturn();
    } else if (prefer != null && prefer.hasHandling()) {
      returnPreference = prefer.getHandling();
    } else {
      returnPreference = PreferTag.emptyTag();
    }

    final LdpPreferTag ldpPreferences = new LdpPreferTag(returnPreference);

    final RdfStream rdfStream = new RdfStream();

    final Predicate<Triple> tripleFilter =
        ldpPreferences.prefersServerManaged() ? x -> true : IS_MANAGED_TRIPLE.negate();

    if (ldpPreferences.prefersServerManaged()) {
      rdfStream.concat(getTriples(LdpRdfContext.class));
    }

    rdfStream.concat(filter(getTriples(TypeRdfContext.class), tripleFilter::test));

    rdfStream.concat(filter(getTriples(PropertiesRdfContext.class), tripleFilter::test));

    if (!returnPreference.getValue().equals("minimal")) {

      // Additional server-managed triples about this resource
      if (ldpPreferences.prefersServerManaged()) {
        rdfStream.concat(getTriples(AclRdfContext.class));
        rdfStream.concat(getTriples(RootRdfContext.class));
        rdfStream.concat(getTriples(ContentRdfContext.class));
        rdfStream.concat(getTriples(ParentRdfContext.class));
      }

      // containment triples about this resource
      if (ldpPreferences.prefersContainment()) {
        rdfStream.concat(getTriples(ChildrenRdfContext.class).limit(limit));
      }

      // LDP container membership triples for this resource
      if (ldpPreferences.prefersMembership()) {
        rdfStream.concat(getTriples(LdpContainerRdfContext.class));
        rdfStream.concat(getTriples(LdpIsMemberOfRdfContext.class));
      }

      // Embed all hash and blank nodes
      // using IS_MANAGED_TRIPLE directly to avoid Prefer header logic (we never want them for hash
      // fragments)
      rdfStream.concat(filter(getTriples(HashRdfContext.class), IS_MANAGED_TRIPLE.negate()::test));
      rdfStream.concat(filter(getTriples(SkolemNodeRdfContext.class), tripleFilter::test));

      // Include inbound references to this object
      if (ldpPreferences.prefersReferences()) {
        rdfStream.concat(getTriples(ReferencesRdfContext.class));
      }

      // Embed the children of this object
      if (ldpPreferences.prefersEmbed()) {

        final Iterator<FedoraResource> children = resource().getChildren();

        rdfStream.concat(
            filter(
                concat(
                    transform(
                        children,
                        child ->
                            child.getTriples(
                                translator(),
                                ImmutableList.of(
                                    TypeRdfContext.class,
                                    PropertiesRdfContext.class,
                                    SkolemNodeRdfContext.class)))),
                tripleFilter::test));
      }
    }

    if (httpTripleUtil != null && ldpPreferences.prefersServerManaged()) {
      httpTripleUtil.addHttpComponentModelsForResourceToStream(
          rdfStream, resource(), uriInfo, translator());
    }

    return rdfStream;
  }