@Override
 public void respondMethodNotAllowed(Resource res, Response response, Request request) {
   log.debug(
       "method not allowed. handler: "
           + this.getClass().getName()
           + " resource: "
           + res.getClass().getName());
   response.setStatus(Response.Status.SC_METHOD_NOT_ALLOWED);
   contentGenerator.generate(res, request, response, Status.SC_METHOD_NOT_ALLOWED);
 }
  @Override
  public void respondContent(
      Resource resource, Response response, Request request, Map<String, String> params)
      throws NotAuthorizedException, BadRequestException, NotFoundException {
    log.debug("respondContent: " + resource.getClass());
    Auth auth = request.getAuthorization();
    setRespondContentCommonHeaders(response, resource, auth);
    if (resource instanceof GetableResource) {
      GetableResource gr = (GetableResource) resource;
      String acc = request.getAcceptHeader();
      String ct = gr.getContentType(acc);
      if (ct != null) {
        ct = pickBestContentType(ct);
        response.setContentTypeHeader(ct);
      }
      cacheControlHelper.setCacheControl(gr, response, request.getAuthorization());

      Long contentLength = gr.getContentLength();
      Boolean doBuffering = null;
      if (resource instanceof BufferingControlResource) {
        BufferingControlResource bcr = (BufferingControlResource) resource;
        doBuffering = bcr.isBufferingRequired();
      }
      if (doBuffering == null) {
        if (buffering == null || buffering == BUFFERING.whenNeeded) {
          doBuffering =
              (contentLength
                  == null); // if no content length then we buffer content to find content length
        } else {
          doBuffering =
              (buffering
                  == BUFFERING
                      .always); // if not null or whenNeeded then buffering is explicitly enabled or
                                // disabled
        }
      }
      if (!doBuffering) {
        log.trace("sending content with known content length: " + contentLength);
        if (contentLength != null) {
          response.setContentLengthHeader(contentLength);
        }
        response.setEntity(new GetableResourceEntity(gr, params, ct));
      } else {
        BufferingGetableResourceEntity e =
            new BufferingGetableResourceEntity(gr, params, ct, contentLength, getMaxMemorySize());
        response.setEntity(e);
      }
    }
  }
  @Override
  public List<QName> getResourceTypes(Resource r) {
    if (log.isTraceEnabled()) {
      log.trace("getResourceTypes:" + r.getClass().getCanonicalName());
    }
    QName qn, qn2;
    List<QName> list = wrapped.getResourceTypes(r);

    if (r instanceof AddressBookResource) {
      log.trace("getResourceTypes: is a AddressBookResource");
      qn = new QName(CardDavProtocol.CARDDAV_NS, "addressbook");
      qn2 = new QName(CardDavProtocol.CARDDAV_NS, "directory");
      if (list == null) {
        list = new ArrayList<QName>();
      }
      if (r instanceof AddressBookDirectoryResource) {
        list.add(qn2);
      }
      list.add(qn);
    }
    return list;
  }