class RecordPermissionsRest {

    @PUT
    @Path("{recordId}")
    @Consumes(MediaType.APPLICATION_JSON)
    @ApiOperation("Updates an existing record security policy using the provided JSON body.")
    @ResourceId(type = ValueType.PATH, value = "recordId")
    public Response updateRecordPolicy(@PathParam("recordId") String recordId, String policyJson) {
        try (RepositoryConnection conn = repo.getConnection()) {
            // Record Policy
            Optional<String> recordPolicyIdOpt = getRelatedResourceId(recordId, conn);
            String recordPolicyId = recordPolicyIdOpt.orElseThrow(() -> ErrorUtils.sendError("Policy for record "
                    + recordId + " does not exist in repository", Response.Status.BAD_REQUEST));
            IRI recordPolicyIRI = vf.createIRI(recordPolicyId);
            Optional<XACMLPolicy> recordPolicy = policyManager.getPolicy(recordPolicyIRI);
            if (!recordPolicy.isPresent()) {
                throw ErrorUtils.sendError("Record policy to update could not be found", Response.Status.BAD_REQUEST);
            }

            XACMLPolicy updatedRecordPolicy = recordJsonToPolicy(policyJson, recordPolicy.get().getJaxbPolicy());
            if (!updatedRecordPolicy.getId().equals(recordPolicyIRI)) {
                throw ErrorUtils.sendError("Policy Id does not match provided record policy",
                        Response.Status.BAD_REQUEST);
            }

            // Policy Policy
            Optional<String> policyPolicyIdOpt = getRelatedResourceId(recordPolicyId, conn);
            String policyPolicyId = policyPolicyIdOpt.orElseThrow(() -> ErrorUtils.sendError("Policy for record "
                    + "policy " + recordId + " does not exist in repository", Response.Status.BAD_REQUEST));
            if (StringUtils.isEmpty(policyPolicyId)) {
                throw ErrorUtils.sendError("Policy for policy " + recordPolicyId + "does not exist in repository",
                        Response.Status.BAD_REQUEST);
            }
            IRI policyPolicyIRI = vf.createIRI(policyPolicyId);
            Optional<XACMLPolicy> policyPolicy = policyManager.getPolicy(policyPolicyIRI);
            if (!policyPolicy.isPresent()) {
                throw ErrorUtils.sendError("Policy policy to update could not be found", Response.Status.BAD_REQUEST);
            }

            XACMLPolicy updatedPolicyPolicy = updatePolicyPolicy(policyJson, policyPolicy.get().getJaxbPolicy());
            if (!updatedPolicyPolicy.getId().equals(vf.createIRI(policyPolicyId))) {
                throw ErrorUtils.sendError("Policy policy Id does not match provided policy",
                        Response.Status.BAD_REQUEST);
            }

            policyManager.updatePolicy(updatedRecordPolicy);
            policyManager.updatePolicy(updatedPolicyPolicy);
            return Response.ok().build();
        } catch (IllegalArgumentException | PolicySyntaxException ex) {
            throw ErrorUtils.sendError(ex, ex.getMessage(), Response.Status.BAD_REQUEST);
        } catch (IllegalStateException | MobiException ex) {
            throw ErrorUtils.sendError(ex, "Policy could not be updated", Response.Status.INTERNAL_SERVER_ERROR);
        }
    }

}