Merge branch 'master' into SLING-8569
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
index 80ac1be..79b2f0d 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/AclManager.java
@@ -28,7 +28,7 @@
 
     boolean addSystemUser(SystemUser systemUser);
 
-    Acl addAcl(String systemUser, Acl acl);
+    boolean addAcl(String systemUser, Acl acl);
 
     void addRepoinitExtension(List<VaultPackageAssembler> packageAssemblers, Feature feature);
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
index 4db3d54..cebc5c2 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/DefaultAclManager.java
@@ -62,9 +62,12 @@
         return false;
     }
 
-    public Acl addAcl(String systemUser, Acl acl) {
-        acls.computeIfAbsent(systemUser, k -> new LinkedList<>()).add(acl);
-        return acl;
+    public boolean addAcl(String systemUser, Acl acl) {
+        if (isKnownSystemUser(systemUser)) {
+            acls.computeIfAbsent(systemUser, k -> new LinkedList<>()).add(acl);
+            return true;
+        }
+        return false;
     }
 
     private void addPath(Path path, Set<Path> paths) {
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java b/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
index 0c3c3c6..097fad7 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/acl/SystemUser.java
@@ -61,6 +61,9 @@
         return Objects.equals(id, other.getId()) && Objects.equals(path, other.getPath());
     }
 
-    
+    @Override
+    public String toString() {
+        return "SystemUser [id=" + id + ", path=" + path + "]";
+    }
 
 }
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java b/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
index f805eef..1a16252 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/features/DefaultFeaturesManager.java
@@ -110,6 +110,10 @@
     }
 
     public void addArtifact(String runMode, ArtifactId id) {
+        addArtifact(runMode, id, null);
+    }
+
+    public void addArtifact(String runMode, ArtifactId id, Integer startOrder) {
         requireNonNull(id, "Artifact can not be attached to a feature without specifying a valid ArtifactId.");
 
         Artifact artifact = new Artifact(id);
@@ -128,7 +132,8 @@
 
             artifacts = extension.getArtifacts();
         } else {
-            artifact.setStartOrder(bundlesStartOrder);
+            int startOrderForBundle = startOrder != null ? startOrder.intValue() : bundlesStartOrder;
+            artifact.setStartOrder(startOrderForBundle);
             artifacts = targetFeature.getBundles();
         }
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java b/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
index 30851be..9319d26 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/features/FeaturesManager.java
@@ -31,6 +31,8 @@
 
     void addArtifact(String runMode, ArtifactId id);
 
+    void addArtifact(String runMode, ArtifactId id, Integer startOrder);
+
     void addConfiguration(String runMode, String pid, Dictionary<String, Object> configurationProperties);
 
     void serialize() throws Exception;
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
index e757de0..c5eee53 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandler.java
@@ -33,6 +33,7 @@
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
 import org.apache.sling.feature.cpconverter.artifacts.InputStreamArtifactWriter;
+import org.codehaus.plexus.util.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -57,7 +58,7 @@
     private final Pattern pomPropertiesPattern = Pattern.compile("META-INF/maven/[^/]+/[^/]+/pom.properties");
 
     public BundleEntryHandler() {
-        super("/jcr_root/(?:apps|libs)/.+/install(\\.([^/]+))?/.+\\.jar");
+        super("/jcr_root/(?:apps|libs)/.+/install(?:\\.([^/]+))?/(?:([0-9]+)/)?.+\\.jar");
     }
 
     @Override
@@ -87,11 +88,9 @@
 
         Matcher matcher = getPattern().matcher(path);
         String runMode = null;
+        Integer startLevel = null;
         // we are pretty sure it matches, here
-        if (matcher.matches()) {
-            // there is a specified RunMode
-            runMode = matcher.group(2);
-        } else {
+        if (!matcher.matches()) {
             throw new IllegalStateException("Something went terribly wrong: pattern '"
                                             + getPattern().pattern()
                                             + "' should have matched already with path '"
@@ -99,12 +98,24 @@
                                             + "' but it does not, currently");
         }
 
+        if (StringUtils.isNotBlank(matcher.group(1))) {
+            // there is a specified RunMode
+            runMode = matcher.group(1);
+            logger.debug("Runmode {} was extracted from path {}", runMode, path);
+        }
+
+        if (StringUtils.isNotBlank(matcher.group(2))) {
+            // there is a specified Start Level
+            startLevel = Integer.parseInt(matcher.group(2)); // NumberFormatException impossible due to RegEx
+            logger.debug("Start level {} was extracted from path {}", startLevel, path);
+        }
+
         try (InputStream input = archive.openInputStream(entry)) {
             ArtifactId id = new ArtifactId(groupId, artifactId, version, classifier, JAR_TYPE);
 
             converter.getArtifactsDeployer().deploy(new InputStreamArtifactWriter(input), id);
 
-            converter.getFeaturesManager().addArtifact(runMode, id);
+            converter.getFeaturesManager().addArtifact(runMode, id, startLevel);
         }
     }
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
index dfe8126..79995f4 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandler.java
@@ -19,13 +19,25 @@
 import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 
 import java.io.InputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Stack;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXTransformerFactory;
+import javax.xml.transform.sax.TransformerHandler;
+import javax.xml.transform.stream.StreamResult;
+
+import org.apache.commons.io.IOUtils;
 import org.apache.jackrabbit.vault.fs.io.Archive;
 import org.apache.jackrabbit.vault.fs.io.Archive.Entry;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
@@ -37,6 +49,8 @@
 
 public final class RepPolicyEntryHandler extends AbstractRegexEntryHandler {
 
+    private final SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) TransformerFactory.newInstance();
+
     public RepPolicyEntryHandler() {
         super("/jcr_root(.*/)_rep_policy.xml");
     }
@@ -44,10 +58,11 @@
     @Override
     public void handle(String path, Archive archive, Entry entry, ContentPackage2FeatureModelConverter converter)
             throws Exception {
+        String resourcePath;
         Matcher matcher = getPattern().matcher(path);
         // we are pretty sure it matches, here
         if (matcher.matches()) {
-            path = matcher.group(1);
+            resourcePath = matcher.group(1);
         } else {
             throw new IllegalStateException("Something went terribly wrong: pattern '"
                                             + getPattern().pattern()
@@ -56,13 +71,31 @@
                                             + "' but it does not, currently");
         }
 
-        RepPolicyParser systemUserParser = new RepPolicyParser(path, converter.getAclManager());
+        Properties format = new Properties();
+        format.put(OutputKeys.INDENT, "yes");
+        format.put(OutputKeys.ENCODING, "utf-8");
+
+        TransformerHandler handler = saxTransformerFactory.newTransformerHandler();
+        handler.getTransformer().setOutputProperties(format);
+        StringWriter stringWriter = new StringWriter();
+        handler.setResult(new StreamResult(stringWriter));
+
+        RepPolicyParser systemUserParser = new RepPolicyParser(resourcePath, converter.getAclManager(), handler);
+        boolean hasRejectedAcls;
+
         try (InputStream input = archive.openInputStream(entry)) {
-            systemUserParser.parse(input);
+            hasRejectedAcls = systemUserParser.parse(input);
+        }
+
+        if (hasRejectedAcls) {
+            try (Reader reader = new StringReader(stringWriter.toString());
+                    OutputStreamWriter writer = new OutputStreamWriter(converter.getMainPackageAssembler().createEntry(path))) {
+                IOUtils.copy(reader, writer);
+            }
         }
     }
 
-    private static final class RepPolicyParser extends AbstractJcrNodeParser<Void> {
+    private static final class RepPolicyParser extends AbstractJcrNodeParser<Boolean> {
 
         private static final String REP_ACL = "rep:ACL";
 
@@ -76,8 +109,6 @@
 
         private static final String REP_PRIVILEGES = "rep:privileges";
 
-        private static final String[] RESTRICTIONS = new String[] { "rep:glob", "rep:ntNames", "rep:prefixes", "rep:itemNames" };
-
         private static final Map<String, String> operations = new HashMap<>();
 
         static {
@@ -85,6 +116,8 @@
             operations.put(REP_DENY_ACE, "deny");
         }
 
+        private static final String[] RESTRICTIONS = new String[] { "rep:glob", "rep:ntNames", "rep:prefixes", "rep:itemNames" };
+
         private static final Pattern typeIndicatorPattern = Pattern.compile("\\{[^\\}]+\\}\\[(.+)\\]");
 
         private final Stack<Acl> acls = new Stack<>();
@@ -93,12 +126,26 @@
 
         private final AclManager aclManager;
 
+        private final TransformerHandler handler;
+
         private boolean onRepAclNode = false;
 
-        public RepPolicyParser(String path, AclManager aclManager) {
+        // ACL processing result
+        private boolean hasRejectedNodes = false;
+
+        // just internal pointer for every iteration
+        private boolean processCurrentAcl = false;
+
+        public RepPolicyParser(String path, AclManager aclManager, TransformerHandler handler) {
             super(REP_ACL);
             this.path = path;
             this.aclManager = aclManager;
+            this.handler = handler;
+        }
+
+        @Override
+        public void startDocument() throws SAXException {
+            handler.startDocument();
         }
 
         @Override
@@ -115,36 +162,55 @@
 
                     Acl acl = new Acl(operation, privileges, Paths.get(path));
 
-                    acls.add(aclManager.addAcl(principalName, acl));
+                    processCurrentAcl = aclManager.addAcl(principalName, acl);
+                    if (processCurrentAcl) {
+                        acls.add(acl);
+                    } else {
+                        hasRejectedNodes = true;
+                    }
                 } else if (REP_RESTRICTIONS.equals(primaryType) && !acls.isEmpty()) {
-                    for (String restriction : RESTRICTIONS) {
-                        String path = extractValue(attributes.getValue(restriction));
+                    if (processCurrentAcl) {
+                        for (String restriction : RESTRICTIONS) {
+                            String path = extractValue(attributes.getValue(restriction));
 
-                        if (path != null && !path.isEmpty()) {
-                            acls.peek().addRestriction(restriction + ',' + path);
+                            if (path != null && !path.isEmpty()) {
+                                acls.peek().addRestriction(restriction + ',' + path);
+                            }
                         }
                     }
                 }
             } else {
                 super.startElement(uri, localName, qName, attributes);
             }
+
+            if (!onRepAclNode || !processCurrentAcl) {
+                handler.startElement(uri, localName, qName, attributes);
+            }
         }
 
         @Override
         public void endElement(String uri, String localName, String qName) throws SAXException {
-            if (onRepAclNode && !acls.isEmpty()) {
+            if (onRepAclNode && processCurrentAcl && !acls.isEmpty()) {
                 acls.pop();
+            } else {
+                processCurrentAcl = false;
+                handler.endElement(uri, localName, qName);
             }
         }
 
         @Override
+        public void endDocument() throws SAXException {
+            handler.endDocument();
+        }
+
+        @Override
         protected void onJcrRootElement(String uri, String localName, String qName, Attributes attributes) {
             onRepAclNode = true;
         }
 
         @Override
-        protected Void getParsingResult() {
-            return null;
+        protected Boolean getParsingResult() {
+            return hasRejectedNodes;
         }
 
         private static String extractValue(String expression) {
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/RecollectorVaultPackageScanner.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/RecollectorVaultPackageScanner.java
index 79925dd..4284e1b 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/RecollectorVaultPackageScanner.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/RecollectorVaultPackageScanner.java
@@ -23,13 +23,15 @@
 import org.apache.jackrabbit.vault.packaging.PackageId;
 import org.apache.jackrabbit.vault.packaging.PackageManager;
 import org.apache.sling.feature.cpconverter.ContentPackage2FeatureModelConverter;
+import org.apache.sling.feature.cpconverter.handlers.EntryHandler;
+import org.apache.sling.feature.cpconverter.handlers.SystemUsersEntryHandler;
 import org.apache.sling.feature.cpconverter.handlers.VersionResolverContentPackageEntryHandler;
 
 public final class RecollectorVaultPackageScanner extends BaseVaultPackageScanner {
 
     private final ContentPackage2FeatureModelConverter converter;
 
-    private final VersionResolverContentPackageEntryHandler handler;
+    private final EntryHandler[] handlers;
 
     public RecollectorVaultPackageScanner(ContentPackage2FeatureModelConverter converter,
                                           PackageManager packageManager,
@@ -37,13 +39,18 @@
                                           Map<PackageId, String> subContentPackages) {
         super(packageManager, strictValidation);
         this.converter = converter;
-        handler = new VersionResolverContentPackageEntryHandler(this, subContentPackages);
+        handlers = new EntryHandler[] {
+                new SystemUsersEntryHandler(),
+                new VersionResolverContentPackageEntryHandler(this, subContentPackages)
+        };
     }
 
     @Override
     protected void onFile(String path, Archive archive, Entry entry) throws Exception {
-        if (handler.matches(path)) {
-            handler.handle(path, archive, entry, converter);
+        for (EntryHandler handler : handlers) {
+            if (handler.matches(path)) {
+                handler.handle(path, archive, entry, converter);
+            }
         }
     }
 
diff --git a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
index 51d2107..7ec08de 100644
--- a/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
+++ b/src/main/java/org/apache/sling/feature/cpconverter/vltpkg/VaultPackageAssembler.java
@@ -155,15 +155,17 @@
     }
 
     public void addEntry(String path, InputStream input) throws IOException {
-        File target = new File(storingDirectory, path);
-
-        target.getParentFile().mkdirs();
-
-        try (OutputStream output = new FileOutputStream(target)) {
+        try (OutputStream output = createEntry(path)) {
             IOUtils.copy(input, output);
         }
     }
 
+    public OutputStream createEntry(String path) throws IOException {
+        File target = new File(storingDirectory, path);
+        target.getParentFile().mkdirs();
+        return new FileOutputStream(target);
+    }
+
     public File getEntry(String path) {
         if (!path.startsWith(ROOT_DIR)) {
             path = ROOT_DIR + path;
diff --git a/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.handlers.EntryHandler b/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.handlers.EntryHandler
index b63a5d8..f75b920 100644
--- a/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.handlers.EntryHandler
+++ b/src/main/resources/META-INF/services/org.apache.sling.feature.cpconverter.handlers.EntryHandler
@@ -6,5 +6,4 @@
 org.apache.sling.feature.cpconverter.handlers.PrivilegesHandler
 org.apache.sling.feature.cpconverter.handlers.PropertiesConfigurationEntryHandler
 org.apache.sling.feature.cpconverter.handlers.RepPolicyEntryHandler
-org.apache.sling.feature.cpconverter.handlers.SystemUsersEntryHandler
 org.apache.sling.feature.cpconverter.handlers.XmlConfigurationEntryHandler
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerTest.java
index 23c9edf..ae2031d 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/BundleEntryHandlerTest.java
@@ -53,9 +53,12 @@
 
     private final EntryHandler bundleEntryHandler;
 
-    public BundleEntryHandlerTest(String bundleLocation, EntryHandler bundleEntryHandler) {
+    private final int startOrder;
+
+    public BundleEntryHandlerTest(String bundleLocation, EntryHandler bundleEntryHandler, int startOrder) {
         this.bundleLocation = bundleLocation;
         this.bundleEntryHandler = bundleEntryHandler;
+        this.startOrder = startOrder;
     }
 
     @Test
@@ -108,6 +111,7 @@
         assertFalse(featuresManager.getTargetFeature().getBundles().isEmpty());
         assertEquals(1, feature.getBundles().size());
         assertEquals("org.apache.felix:org.apache.felix.framework:6.0.1", feature.getBundles().get(0).getId().toMvnId());
+        assertEquals(startOrder, feature.getBundles().get(0).getStartOrder());
     }
 
     @Parameters
@@ -115,10 +119,12 @@
         final BundleEntryHandler bundleEntryHandler = new BundleEntryHandler();
 
         return Arrays.asList(new Object[][] {
-            { "/jcr_root/apps/asd/install/test-framework-no-pom.jar", bundleEntryHandler },
-            { "/jcr_root/apps/asd/install/test-framework.jar", bundleEntryHandler },
-            { "/jcr_root/apps/asd/install.author/test-framework.jar", bundleEntryHandler },
-            { "/jcr_root/apps/asd/install.publish/test-framework.jar", bundleEntryHandler }
+                { "/jcr_root/apps/asd/install/test-framework-no-pom.jar", bundleEntryHandler, 20 },
+                { "/jcr_root/apps/asd/install/test-framework.jar", bundleEntryHandler, 20 },
+                { "/jcr_root/apps/asd/install/9/test-framework.jar", bundleEntryHandler, 9 },
+                { "/jcr_root/apps/asd/install.author/test-framework.jar", bundleEntryHandler, 20 },
+                { "/jcr_root/apps/asd/install.author/9/test-framework.jar", bundleEntryHandler, 9 },
+                { "/jcr_root/apps/asd/install.publish/test-framework.jar", bundleEntryHandler, 20 }
         });
     }
 
diff --git a/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
index 7bd8fc6..5545bb4 100644
--- a/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
+++ b/src/test/java/org/apache/sling/feature/cpconverter/handlers/RepPolicyEntryHandlerTest.java
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.StringReader;
 import java.nio.file.Path;
@@ -89,7 +90,7 @@
                                                           "acs-commons-package-replication-status-event-service",
                                                           "acs-commons-ensure-service-user-service",
                                                           "acs-commons-automatic-package-replicator-service",
-                                                          "acs-commons-on-deploy-scripts-service");
+                                                          "acs-commons-on-deploy-scripts-service").getRepoinitExtension();
         assertNotNull(repoinitExtension);
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
@@ -130,10 +131,12 @@
 
     @Test
     public void notDeclaredSystemUsersWillNotHaveAclSettings() throws Exception {
-        Extension repoinitExtension = parseAndSetRepoinit("acs-commons-package-replication-status-event-service",
-                                                          "acs-commons-ensure-service-user-service",
-                                                          "acs-commons-automatic-package-replicator-service",
-                                                          "acs-commons-on-deploy-scripts-service");
+        ParseResult result = parseAndSetRepoinit("acs-commons-package-replication-status-event-service",
+                                                 "acs-commons-ensure-service-user-service",
+                                                 "acs-commons-automatic-package-replicator-service",
+                                                 "acs-commons-on-deploy-scripts-service");
+        Extension repoinitExtension = result.getRepoinitExtension();
+
         assertNotNull(repoinitExtension);
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
@@ -162,11 +165,22 @@
         RepoInitParser repoInitParser = new RepoInitParserService();
         List<Operation> operations = repoInitParser.parse(new StringReader(actual));
         assertFalse(operations.isEmpty());
+
+        // acs-commons-ensure-oak-index-service and acs-commons-dispatcher-flush-service not recognized as system users
+        expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">\n" + 
+                "<allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">\n" + 
+                "<rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>\n" + 
+                "</allow0>\n" + 
+                "<allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>\n" + 
+                "</jcr:root>\n";
+        actual = result.getExcludedAcls();
+        assertEquals(expected, actual);
     }
 
     @Test
     public void systemUserAclSetNotForUserPath() throws Exception {
-        Extension repoinitExtension = parseAndSetRepoinit(new SystemUser("acs-commons-package-replication-status-event-service", Paths.get("/this/is/a/completely/different/path")));
+        ParseResult result = parseAndSetRepoinit(new SystemUser("acs-commons-package-replication-status-event-service", Paths.get("/this/is/a/completely/different/path")));
+        Extension repoinitExtension = result.getRepoinitExtension();
         assertNotNull(repoinitExtension);
         assertEquals(ExtensionType.TEXT, repoinitExtension.getType());
 
@@ -182,15 +196,28 @@
         RepoInitParser repoInitParser = new RepoInitParserService();
         List<Operation> operations = repoInitParser.parse(new StringReader(actual));
         assertFalse(operations.isEmpty());
+
+        // acs-commons-package-replication-status-event-service only recognised as system user - ACLs in allow2
+        expected = "<?xml version=\"1.0\" encoding=\"utf-8\"?><jcr:root xmlns:jcr=\"http://www.jcp.org/jcr/1.0\" xmlns:rep=\"internal\" jcr:primaryType=\"rep:ACL\">\n" + 
+                "<allow0 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-oak-index-service\" rep:privileges=\"{Name}[jcr:read,rep:write,rep:indexDefinitionManagement]\">\n" + 
+                "<rep:restrictions jcr:primaryType=\"rep:Restrictions\" rep:glob=\"{Name}[*/oak:index/*]\"/>\n" + 
+                "</allow0>\n" + 
+                "<allow1 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-dispatcher-flush-service\" rep:privileges=\"{Name}[jcr:read,crx:replicate,jcr:removeNode]\"/>\n" + 
+                "<allow3 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-ensure-service-user-service\" rep:privileges=\"{Name}[jcr:read,rep:write,jcr:readAccessControl,jcr:modifyAccessControl]\"/>\n" + 
+                "<allow4 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-automatic-package-replicator-service\" rep:privileges=\"{Name}[jcr:read]\"/>\n" + 
+                "<allow5 jcr:primaryType=\"rep:GrantACE\" rep:principalName=\"acs-commons-on-deploy-scripts-service\" rep:privileges=\"{Name}[jcr:read]\"/>\n" + 
+                "</jcr:root>\n";
+        actual = result.getExcludedAcls();
+        assertEquals(expected, actual);
     }
 
     @Test
     public void parseEmptyAcl() throws Exception {
-        Extension repoinitExtension = parseAndSetRepoinit(new String[] {});
+        Extension repoinitExtension = parseAndSetRepoinit(new String[] {}).getRepoinitExtension();
         assertNull(repoinitExtension);
     }
 
-    private Extension parseAndSetRepoinit(String...systemUsersNames) throws Exception {
+    private ParseResult parseAndSetRepoinit(String...systemUsersNames) throws Exception {
         Path alwaysTheSamePath = Paths.get("/asd/public");
 
         SystemUser[] systemUsers = new SystemUser[systemUsersNames.length];
@@ -201,11 +228,13 @@
         return parseAndSetRepoinit(systemUsers);
     }
 
-    private Extension parseAndSetRepoinit(SystemUser...systemUsers) throws Exception {
+    private ParseResult parseAndSetRepoinit(SystemUser...systemUsers) throws Exception {
         String path = "/jcr_root/asd/public/_rep_policy.xml";
         Archive archive = mock(Archive.class);
         Entry entry = mock(Entry.class);
         VaultPackageAssembler packageAssembler = mock(VaultPackageAssembler.class);
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        when(packageAssembler.createEntry(anyString())).thenReturn(baos);
 
         when(archive.openInputStream(entry)).thenReturn(getClass().getResourceAsStream(path.substring(1)));
 
@@ -215,8 +244,7 @@
         ContentPackage2FeatureModelConverter converter = spy(ContentPackage2FeatureModelConverter.class);
         when(converter.getFeaturesManager()).thenReturn(featuresManager);
         when(converter.getAclManager()).thenReturn(new DefaultAclManager());
-
-        handler.handle(path, archive, entry, converter);
+        when(converter.getMainPackageAssembler()).thenReturn(packageAssembler);
 
         if (systemUsers != null) {
             for (SystemUser systemUser : systemUsers) {
@@ -224,10 +252,33 @@
             }
         }
 
+        handler.handle(path, archive, entry, converter);
+
         when(packageAssembler.getEntry(anyString())).thenReturn(new File("itdoesnotexist"));
 
         converter.getAclManager().addRepoinitExtension(Arrays.asList(packageAssembler), feature);
-        return feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT);
+        return new ParseResult(feature.getExtensions().getByName(Extension.EXTENSION_NAME_REPOINIT), new String(baos.toByteArray()));
+    }
+
+    private static final class ParseResult {
+
+        private final Extension repoinitExtension;
+
+        private final String excludedAcls;
+
+        public ParseResult(Extension repoinitExtension, String excludedAcls) {
+            this.repoinitExtension = repoinitExtension;
+            this.excludedAcls = excludedAcls;
+        }
+
+        public Extension getRepoinitExtension() {
+            return repoinitExtension;
+        }
+
+        public String getExcludedAcls() {
+            return excludedAcls;
+        }
+
     }
 
 }
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install.author/9/test-framework.jar b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install.author/9/test-framework.jar
new file mode 100644
index 0000000..9ce022d
--- /dev/null
+++ b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install.author/9/test-framework.jar
Binary files differ
diff --git a/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install/9/test-framework.jar b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install/9/test-framework.jar
new file mode 100644
index 0000000..9ce022d
--- /dev/null
+++ b/src/test/resources/org/apache/sling/feature/cpconverter/handlers/jcr_root/apps/asd/install/9/test-framework.jar
Binary files differ