class ImmutablePolicy implements Policy {

    @Override
    public Policy removeSubjectFor(final CharSequence label, final SubjectId subjectId) {
        final Label lbl = Label.of(label);

        Policy result = this;
        final PolicyEntry existingPolicyEntry = entries.get(lbl);
        if (null != existingPolicyEntry) {
            final Subjects existingSubjects = existingPolicyEntry.getSubjects();
            final Subjects newSubjects = existingSubjects.removeSubject(subjectId);
            if (!Objects.equals(existingSubjects, newSubjects)) {
                final Map<Label, PolicyEntry> entriesCopy = copyEntries();
                entriesCopy.put(lbl, newPolicyEntry(lbl, newSubjects, existingPolicyEntry.getResources()));
                result = new ImmutablePolicy(policyId, entriesCopy, lifecycle, revision, modified, created);
            }
        }

        return result;
    }

    private  ImmutablePolicy(@Nullable final PolicyId policyId,
            final Map<Label, PolicyEntry> theEntries,
            @Nullable final PolicyLifecycle lifecycle,
            @Nullable final PolicyRevision revision,
            @Nullable final Instant modified,
            @Nullable final Instant created);

}