@Test
public void testBeforeSlingInstallAndAfterScanPackage() throws Exception {

    ExpectAces.Check check = checkFor(obj()
            .key(ExpectAces.keys().principal(), "nouser")
            .key(ExpectAces.keys().expectedAces(), arr()
                    .val("type=allow;path=/foo1;privileges=jcr:read")
                    .val("type=allow;path=/foo1;privileges=rep:write")
            )
            .key(ExpectAces.keys().notExpectedAces(), arr()
                    .val("type=allow;path=/foo2;privileges=jcr:read")
                    .val("type=allow;path=/foo2;privileges=rep:write")
                    // foo3 is not created. a non-existent path should satisfy not-expected aces
                    .val("type=allow;path=/foo3;privileges=rep:write")
            )
            .get());
    final Principal principal = new PrincipalImpl("nouser");
    new OakMachine.Builder().build().adminInitAndInspect(session -> {
        final JackrabbitAccessControlManager accessControlManager =
                (JackrabbitAccessControlManager) session.getAccessControlManager();
        final PrivilegeManager privilegeManager = ((JackrabbitWorkspace) session.getWorkspace()).getPrivilegeManager();
        final Privilege jcrRead = privilegeManager.getPrivilege("jcr:read");
        final Node foo1 = session.getRootNode().addNode("foo1", resolver.getJCRName(NameConstants.NT_FOLDER));
        foo1.addMixin("rep:AccessControllable");
        final Node foo2 = session.getRootNode().addNode("foo2", resolver.getJCRName(NameConstants.NT_FOLDER));
        foo2.addMixin("rep:AccessControllable");
        session.save();
        for (String path : new String[]{"/foo1", "/foo2"}) {
            for (AccessControlPolicyIterator policyIt = accessControlManager.getApplicablePolicies(path); policyIt.hasNext(); ) {
                AccessControlPolicy policy = policyIt.nextAccessControlPolicy();
                if (policy instanceof JackrabbitAccessControlList) {
                    JackrabbitAccessControlList acl = (JackrabbitAccessControlList) policy;
                    acl.addEntry(principal, new Privilege[]{jcrRead}, true);
                    accessControlManager.setPolicy(path, acl);
                }
            }
        }
        check.afterExtract(PackageId.fromString("foo"), session);
        check.startedScan();
        check.afterExtract(PackageId.fromString("foo"), session);
        check.afterExtract(PackageId.fromString("foo"), session);
        check.finishedScan();
    });
    Assert.assertEquals("expected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("expected: ")).count());
    Assert.assertEquals("expected violated spec ends with rep:write", 1,
            check.getReportedViolations().stream()
                    .filter(viol -> viol.getDescription().startsWith("expected: ")
                            && viol.getDescription().endsWith("rep:write")).count());
    Assert.assertEquals("unexpected violation count", 1, check.getReportedViolations().stream().filter(viol -> viol.getDescription().startsWith("unexpected: ")).count());
    Assert.assertEquals("unexpected violated spec ends with jcr:read", 1,
            check.getReportedViolations().stream()
                    .filter(viol -> viol.getDescription().startsWith("unexpected: ")
                            && viol.getDescription().endsWith("jcr:read")).count());
}