@Override
  public List<EDITOR> readAll(CONTEXT context) {
    Response response =
        context
            .getSession()
            .given()
            .contentType(getContentType())
            .header(Headers.acceptJson())
            .get(
                "/rest/applications/{variantID}/installations", context.getParent().getVariantID());

    UnexpectedResponseException.verifyResponse(response, HttpStatus.SC_OK);

    List<EDITOR> editors = new ArrayList<EDITOR>();

    JsonPath jsonPath = response.jsonPath();

    List<Map<String, ?>> items = jsonPath.getList("");

    for (int i = 0; i < items.size(); i++) {
      jsonPath.setRoot("[" + i + "]");

      EDITOR editor = demarshall(context, jsonPath);
      editors.add(editor);
    }

    return editors;
  }
  @Override
  public void deleteById(CONTEXT context, String id) {
    Response response =
        context
            .getSession()
            .given()
            .contentType(getContentType())
            .header(Headers.acceptJson())
            .delete(
                "/rest/applications/{variantID}/installations/{installationID}",
                context.getParent().getVariantID(),
                id);

    UnexpectedResponseException.verifyResponse(response, HttpStatus.SC_NO_CONTENT);
  }
  @Override
  public EDITOR read(CONTEXT context, String id) {
    Response response =
        context
            .getSession()
            .given()
            .contentType(getContentType())
            .header(Headers.acceptJson())
            .get(
                "/rest/applications/{variantID}/installations/{installationID}",
                context.getParent().getVariantID(),
                id);

    UnexpectedResponseException.verifyResponse(response, HttpStatus.SC_OK);

    return demarshall(context, response.jsonPath());
  }
  @Override
  public void update(CONTEXT context, Collection<? extends InstallationImpl> entities) {
    for (InstallationImpl entity : entities) {
      Response response =
          context
              .getSession()
              .given()
              .contentType(getContentType())
              .header(Headers.acceptJson())
              .body(marshall(entity))
              .put(
                  "/rest/applications/{variantID}/installations/{installationID}",
                  context.getParent().getVariantID(),
                  context.getEntityID(entity));

      UnexpectedResponseException.verifyResponse(response, HttpStatus.SC_NO_CONTENT);

      // FIXME do we need to demarshall?
    }
  }
  @Override
  public List<EDITOR> create(CONTEXT context, Collection<? extends BLUEPRINT> blueprints) {
    List<EDITOR> editors = new ArrayList<EDITOR>();
    for (InstallationBlueprint blueprint : blueprints) {
      Response response =
          context
              .getSession()
              .given()
              .contentType(getContentType())
              .auth()
              .basic(context.getParent().getVariantID(), context.getParent().getSecret())
              .header(Headers.acceptJson())
              .body(marshall(blueprint))
              .post("/rest/registry/device");

      UnexpectedResponseException.verifyResponse(response, HttpStatus.SC_OK);

      editors.add(demarshall(context, response.jsonPath()));
    }
    return editors;
  }