class PoliciesAclMigrations {

    public static Policy accessControlListToPolicyEntries(final AccessControlList accessControlList,
            final PolicyId policyId, final List<SubjectIssuer> subjectIssuers) {
        final PolicyBuilder policyBuilder = PoliciesModelFactory.newPolicyBuilder(policyId);
        accessControlList.getEntriesSet().forEach(aclEntry -> {
            final String sid = getSubjectWithoutIssuer(aclEntry);
            final PolicyBuilder.LabelScoped labelScoped = policyBuilder.forLabel(ACL_LABEL_PREFIX + sid);

            subjectIssuers.forEach(
                    subjectIssuer -> labelScoped.setSubject(subjectIssuer, sid));

            if (aclEntry.getPermissions().contains(org.eclipse.ditto.model.things.Permission.READ) &&
                    aclEntry.getPermissions()
                            .contains(org.eclipse.ditto.model.things.Permission.WRITE)) {
                labelScoped.setGrantedPermissions(PoliciesResourceType.policyResource(ROOT_PATH), Permission.READ);
                labelScoped.setGrantedPermissions(PoliciesResourceType.thingResource(ROOT_PATH), Permission.READ,
                        Permission.WRITE);
                labelScoped.setGrantedPermissions(PoliciesResourceType.messageResource(ROOT_PATH), Permission.READ,
                        Permission.WRITE);
            } else if (aclEntry.getPermissions().contains(org.eclipse.ditto.model.things.Permission.READ)) {
                labelScoped.setGrantedPermissions(PoliciesResourceType.policyResource(ROOT_PATH), Permission.READ);
                labelScoped.setGrantedPermissions(PoliciesResourceType.thingResource(ROOT_PATH), Permission.READ);
                labelScoped.setGrantedPermissions(PoliciesResourceType.messageResource(ROOT_PATH), Permission.READ);
            } else if (aclEntry.getPermissions().contains(org.eclipse.ditto.model.things.Permission.WRITE)) {
                labelScoped.setGrantedPermissions(PoliciesResourceType.thingResource(ROOT_PATH), Permission.WRITE);
                labelScoped.setGrantedPermissions(PoliciesResourceType.messageResource(ROOT_PATH), Permission.WRITE);
            }

            if (aclEntry.getPermissions().contains(org.eclipse.ditto.model.things.Permission.ADMINISTRATE)) {
                // allow reading+writing policy:/ if the ACL entry has Administrate permission
                labelScoped.setGrantedPermissions(PoliciesResourceType.policyResource(ROOT_PATH),
                        Permission.READ, Permission.WRITE);
                // allow writing thing:/acl if the ACL entry has Administrate permission
                labelScoped.setGrantedPermissions(PoliciesResourceType.thingResource(Thing.JsonFields.ACL.getPointer()),
                        Permission.READ, Permission.WRITE);
            } else {
                // forbid writing thing:/acl if the ACL entry was missing Administrate permission
                labelScoped.setRevokedPermissions(PoliciesResourceType.thingResource(Thing.JsonFields.ACL.getPointer()),
                        Permission.WRITE);
            }
        });
        return policyBuilder.build();
    }

    private  PoliciesAclMigrations();

}