You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ss...@apache.org on 2021/08/25 14:44:57 UTC

[sling-org-apache-sling-testing-sling-mock] branch feature/SLING-5922-SLING-10753-load-folder-and-filevault created (now d7c97d6)

This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a change to branch feature/SLING-5922-SLING-10753-load-folder-and-filevault
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git.


      at d7c97d6  SLING-10753/SLING-5922 support mounting folders with JSON (Sling-Initial-Content) and FileValue XML (extracted content package) content support loading individual FileVault XML files

This branch includes the following new commits:

     new d7c97d6  SLING-10753/SLING-5922 support mounting folders with JSON (Sling-Initial-Content) and FileValue XML (extracted content package) content support loading individual FileVault XML files

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


[sling-org-apache-sling-testing-sling-mock] 01/01: SLING-10753/SLING-5922 support mounting folders with JSON (Sling-Initial-Content) and FileValue XML (extracted content package) content support loading individual FileVault XML files

Posted by ss...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

sseifert pushed a commit to branch feature/SLING-5922-SLING-10753-load-folder-and-filevault
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-sling-mock.git

commit d7c97d6978721afb6c609d306e439bfd753ba02e
Author: Stefan Seifert <st...@users.noreply.github.com>
AuthorDate: Wed Aug 25 16:44:39 2021 +0200

    SLING-10753/SLING-5922 support mounting folders with JSON (Sling-Initial-Content) and FileValue XML (extracted content package) content
    support loading individual FileVault XML files
---
 core/pom.xml                                       |  18 +-
 .../apache/sling/testing/mock/sling/MockSling.java |  32 ++--
 .../sling/RRMockMockResourceResolverAdapter.java   |  14 +-
 .../RRMockResourceResolverFactoryWrapper.java      | 113 ++++++++++++
 .../mock/sling/RRMockResourceResolverWrapper.java  | 121 ++++++++++++
 .../testing/mock/sling/loader/ContentLoader.java   | 205 ++++++++++++++++++---
 .../testing/mock/sling/loader/package-info.java    |   2 +-
 .../sling/spi/ResourceResolverTypeAdapter.java     |   5 +
 .../loader/ContentLoaderFileVaultXmlTest.java}     |  17 +-
 .../ContentLoaderFolderFileVaultXmlTest.java}      |  18 +-
 .../loader/ContentLoaderFolderJsonTest.java}       |  18 +-
 .../loader/AbstractContentLoaderBinaryTest.java    |  13 +-
 .../AbstractContentLoaderFileVaultXmlTest.java     | 116 ++++++++++++
 ...bstractContentLoaderFolderFileVaultXmlTest.java |  92 +++++++++
 .../AbstractContentLoaderFolderJsonTest.java       |  85 +++++++++
 .../loader/ContentLoaderFileVaultXmlTest.java}     |  18 +-
 .../ContentLoaderFolderFileVaultXmlTest.java}      |  18 +-
 .../loader/ContentLoaderFolderJsonTest.java}       |  18 +-
 .../json-import-samples/binary/sample-image.gif    | Bin 0 -> 62 bytes
 .../resources/xml-jcr-import-samples/.content.xml  |  24 +++
 .../xml-jcr-import-samples/content/.content.xml    |  28 +++
 .../content/dam/.content.xml                       |  24 +++
 .../content/dam/talk.png/.content.xml              |  44 +++++
 .../dam/talk.png/_jcr_content/renditions/original  | Bin 0 -> 8668 bytes
 .../renditions/original.dir/.content.xml           |  25 +++
 .../_jcr_content/renditions/web.1280.1280.png      | Bin 0 -> 5252 bytes
 .../content/samples/.content.xml                   |  23 +++
 .../content/samples/en/.content.xml                | 195 ++++++++++++++++++++
 .../mock/sling/junit5/SlingContextMemberTest.java  |   5 +-
 .../mock/sling/junit5/SlingContextTest.java        |   5 +-
 parent/pom.xml                                     |  31 ++++
 31 files changed, 1235 insertions(+), 92 deletions(-)

diff --git a/core/pom.xml b/core/pom.xml
index fd2e111..7226a24 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -195,19 +195,31 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.contentparser.api</artifactId>
-            <version>2.0.0</version>
             <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.contentparser.json</artifactId>
-            <version>2.0.0</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.contentparser.xml-jcr</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit.vault</groupId>
+            <artifactId>org.apache.jackrabbit.vault</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.fsresource</artifactId>
             <scope>compile</scope>
         </dependency>
         <dependency>
             <groupId>commons-beanutils</groupId>
             <artifactId>commons-beanutils</artifactId>
-            <version>1.8.3</version>
             <scope>compile</scope>
         </dependency>
 
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java b/core/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java
index 35489ab..31a7162 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/MockSling.java
@@ -18,6 +18,9 @@
  */
 package org.apache.sling.testing.mock.sling;
 
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.adapter.SlingAdaptable;
@@ -69,7 +72,7 @@ public final class MockSling {
      */
     public static @NotNull ResourceResolverFactory newResourceResolverFactory(@NotNull final ResourceResolverType type,
             @NotNull final BundleContext bundleContext) {
-        ResourceResolverTypeAdapter adapter = getResourceResolverTypeAdapter(type);
+        ResourceResolverTypeAdapter adapter = getResourceResolverTypeAdapter(type, bundleContext);
         ResourceResolverFactory factory = adapter.newResourceResolverFactory();
         if (factory == null) {
             SlingRepository repository = adapter.newSlingRepository();
@@ -81,24 +84,21 @@ public final class MockSling {
         return factory;
     }
 
-    private static ResourceResolverTypeAdapter getResourceResolverTypeAdapter(final ResourceResolverType type) {
+    private static ResourceResolverTypeAdapter getResourceResolverTypeAdapter(final ResourceResolverType type,
+            @NotNull final BundleContext bundleContext) {
         try {
             Class clazz = Class.forName(type.getResourceResolverTypeAdapterClass());
-            return (ResourceResolverTypeAdapter) clazz.newInstance();
-        }
-        catch (ClassNotFoundException ex) {
-            throw new RuntimeException("Unable to instantiate resourcer resolver: "
-                    + type.getResourceResolverTypeAdapterClass()
-                    + (type.getArtifactCoordinates() != null ? ". Make sure this maven dependency is included: "
-                            + type.getArtifactCoordinates() : ""), ex);
-        }
-        catch (InstantiationException ex) {
-            throw new RuntimeException("Unable to instantiate resourcer resolver: "
-                    + type.getResourceResolverTypeAdapterClass()
-                    + (type.getArtifactCoordinates() != null ? ". Make sure this maven dependency is included: "
-                            + type.getArtifactCoordinates() : ""), ex);
+            try {
+                Constructor<ResourceResolverTypeAdapter> bundleContextConstructor = clazz.getConstructor(BundleContext.class);
+                // use constructor with bundle context
+                return bundleContextConstructor.newInstance(bundleContext);
+            }
+            catch (NoSuchMethodException ex) {
+                // fallback to default constructor
+                return (ResourceResolverTypeAdapter)clazz.newInstance();
+            }
         }
-        catch (IllegalAccessException ex) {
+        catch (ClassNotFoundException | InstantiationException | IllegalAccessException | InvocationTargetException ex) {
             throw new RuntimeException("Unable to instantiate resourcer resolver: "
                     + type.getResourceResolverTypeAdapterClass()
                     + (type.getArtifactCoordinates() != null ? ". Make sure this maven dependency is included: "
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
index 84f9248..ccb2c2e 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockMockResourceResolverAdapter.java
@@ -23,26 +23,28 @@ import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.testing.mock.sling.spi.ResourceResolverTypeAdapter;
 import org.apache.sling.testing.resourceresolver.MockResourceResolverFactory;
 import org.apache.sling.testing.resourceresolver.MockResourceResolverFactoryOptions;
-import org.jetbrains.annotations.NotNull;
+import org.osgi.framework.BundleContext;
 
 /**
  * Resource resolver type adapter for Sling Resource Resolver Mock implementation.
  */
 class RRMockMockResourceResolverAdapter implements ResourceResolverTypeAdapter {
 
-    private final @NotNull MockResourceResolverFactoryOptions options;
+    private final MockResourceResolverFactoryOptions options;
+    private final BundleContext bundleContext;
 
     /**
      * Constructor
      */
-    public RRMockMockResourceResolverAdapter() {
-        options = new MockResourceResolverFactoryOptions();
-        options.setMangleNamespacePrefixes(true);
+    public RRMockMockResourceResolverAdapter(BundleContext bundleContext) {
+        this.options = new MockResourceResolverFactoryOptions();
+        this.options.setMangleNamespacePrefixes(true);
+        this.bundleContext = bundleContext;
     }
 
     @Override
     public ResourceResolverFactory newResourceResolverFactory() {
-        return new MockResourceResolverFactory(options);
+        return new RRMockResourceResolverFactoryWrapper(new MockResourceResolverFactory(options), bundleContext);
     }
 
     @Override
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
new file mode 100644
index 0000000..f72ff91
--- /dev/null
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+/**
+ * Wraps the ResourceResolverFactory from ResourceResolverMock to add a service tracker
+ * for ResourceProvider (e.g. injected by ContentLoader for mounting filesystem folders).
+ */
+class RRMockResourceResolverFactoryWrapper implements ResourceResolverFactory,
+        ServiceTrackerCustomizer<ResourceProvider, ResourceProvider> {
+
+    private final ResourceResolverFactory delegate;
+    private final BundleContext bundleContext;
+    private final ServiceTracker<ResourceProvider, ResourceProvider> serviceTracker;
+    private final ConcurrentMap<String, ResourceProvider> resourceProviders = new ConcurrentHashMap<>();
+
+    @SuppressWarnings("null")
+    RRMockResourceResolverFactoryWrapper(ResourceResolverFactory delegate, BundleContext bundleContext) {
+        this.delegate = delegate;
+        this.bundleContext = bundleContext;
+        // track registered resource provider implementations
+        this.serviceTracker = new ServiceTracker<ResourceProvider, ResourceProvider>(bundleContext, ResourceProvider.class, this);
+        this.serviceTracker.open();
+    }
+
+    @Override
+    public @NotNull ResourceResolver getResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
+        return wrap(delegate.getResourceResolver(authenticationInfo));
+    }
+
+    @Override
+    @Deprecated
+    public @NotNull ResourceResolver getAdministrativeResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
+        return wrap(delegate.getAdministrativeResourceResolver(authenticationInfo));
+    }
+
+    @Override
+    public @NotNull ResourceResolver getServiceResourceResolver(Map<String, Object> authenticationInfo) throws LoginException {
+        return wrap(delegate.getServiceResourceResolver(authenticationInfo));
+    }
+
+    @Override
+    public @Nullable ResourceResolver getThreadResourceResolver() {
+        return wrap(delegate.getThreadResourceResolver());
+    }
+
+    private ResourceResolver wrap(ResourceResolver resourceResolver) {
+        return new RRMockResourceResolverWrapper(resourceResolver, resourceProviders);
+    }
+
+    @Override
+    public ResourceProvider addingService(ServiceReference<ResourceProvider> reference) {
+        String rootPath = getRootPath(reference);
+        ResourceProvider service = bundleContext.getService(reference);
+        if (rootPath != null) {
+            resourceProviders.put(rootPath, service);
+        }
+        return service;
+    }
+
+    @Override
+    public void modifiedService(ServiceReference<ResourceProvider> reference, ResourceProvider service) {
+        // ignore
+    }
+
+    @Override
+    public void removedService(ServiceReference<ResourceProvider> reference, ResourceProvider service) {
+        String rootPath = getRootPath(reference);
+        if (rootPath != null) {
+            resourceProviders.remove(rootPath);
+        }
+    }
+
+    private String getRootPath(ServiceReference<ResourceProvider> reference) {
+        Object value = reference.getProperty(ResourceProvider.PROPERTY_ROOT);
+        if (value instanceof String) {
+            return (String)value;
+        }
+        return null;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
new file mode 100644
index 0000000..6689e5d
--- /dev/null
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
@@ -0,0 +1,121 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.wrappers.ResourceResolverWrapper;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Wraps resource resolver form ResourceResolverMock to check for resource provider implementations
+ * registered to specific path. This is a very simplified implementation to overlay the mocked
+ * resource tree with resource providers, but should be sufficient for unit tests.
+ */
+class RRMockResourceResolverWrapper extends ResourceResolverWrapper implements ResolveContext {
+
+    private final ConcurrentMap<String, ResourceProvider> resourceProviders;
+
+    RRMockResourceResolverWrapper(ResourceResolver delegate, ConcurrentMap<String, ResourceProvider> resourceProviders) {
+        super(delegate);
+        this.resourceProviders = resourceProviders;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Resource getResource(@NotNull String path) {
+        ResourceProvider resourceProvider = getMatchingResourceProvider(path);
+        if (resourceProvider != null) {
+            return resourceProvider.getResource(this, path, ResourceContext.EMPTY_CONTEXT, null);
+        }
+        return super.getResource(path);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public @NotNull Iterator<Resource> listChildren(@NotNull Resource parent) {
+        ResourceProvider resourceProvider = getMatchingResourceProvider(parent.getPath());
+        if (resourceProvider != null) {
+            Iterator<Resource> result = resourceProvider.listChildren(this,  parent);
+            if (result == null) {
+                return Collections.emptyIterator();
+            }
+            else {
+                return result;
+            }
+        }
+        return super.listChildren(parent);
+    }
+
+    private ResourceProvider getMatchingResourceProvider(String path) {
+        if (resourceProviders.isEmpty()) {
+            return null;
+        }
+        String normalizedPath = ResourceUtil.normalize(path);
+        if (!StringUtils.startsWith(normalizedPath, "/")) {
+            return null;
+        }
+        return getMatchingResourceProviderRecursively(normalizedPath);
+    }
+
+    private ResourceProvider getMatchingResourceProviderRecursively(String path) {
+        ResourceProvider provider = resourceProviders.get(path);
+        if (provider != null) {
+            return provider;
+        }
+        String parentPath = ResourceUtil.getParent(path);
+        if (parentPath != null) {
+            return getMatchingResourceProviderRecursively(parentPath);
+        }
+        else {
+            return null;
+        }
+    }
+
+    @Override
+    public @NotNull ResourceResolver getResourceResolver() {
+        return this;
+    }
+
+    @Override
+    public @Nullable Object getProviderState() {
+        return null;
+    }
+
+    @Override
+    public @Nullable ResolveContext getParentResolveContext() {
+        return null;
+    }
+
+    @Override
+    public @Nullable ResourceProvider getParentResourceProvider() {
+        return null;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
index d0f0c6a..c79a883 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/ContentLoader.java
@@ -18,8 +18,10 @@
  */
 package org.apache.sling.testing.mock.sling.loader;
 
+import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.Dictionary;
 import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.Map;
@@ -27,6 +29,7 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.PersistenceException;
@@ -39,6 +42,11 @@ import org.apache.sling.contentparser.api.ParserOptions;
 import org.apache.sling.contentparser.json.JSONParserFeature;
 import org.apache.sling.contentparser.json.JSONParserOptions;
 import org.apache.sling.contentparser.json.internal.JSONContentParser;
+import org.apache.sling.contentparser.xml.jcr.internal.JCRXMLContentParser;
+import org.apache.sling.fsprovider.internal.FsResourceProvider;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.apache.sling.testing.mock.osgi.MapUtil;
+import org.apache.sling.testing.mock.osgi.MockOsgi;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.builder.ImmutableValueMap;
 import org.jetbrains.annotations.NotNull;
@@ -84,6 +92,8 @@ public final class ContentLoader {
     private final Set<String> ignoredNames;
     private final ContentParser jsonParser;
     private final ParserOptions jsonParserOptions;
+    private final ContentParser fileVaultXmlParser;
+    private final ParserOptions fileVaultXmlParserOptions;
 
     /**
      * @param resourceResolver Resource resolver
@@ -121,13 +131,19 @@ public final class ContentLoader {
         this.bundleContext = bundleContext;
         this.autoCommit = autoCommit;
         this.ignoredNames = getIgnoredNamesForResourceResolverType(resourceResolverType);
+
         this.jsonParserOptions = new JSONParserOptions()
             .withFeatures(EnumSet.of(JSONParserFeature.COMMENTS, JSONParserFeature.QUOTE_TICK))
             .detectCalendarValues(true)
             .ignorePropertyNames(this.ignoredNames)
             .ignoreResourceNames(this.ignoredNames);
-        // JSONContentParser is an OSGi service - for sake of simplicity in this mock environment instantiate it directly
         this.jsonParser = new JSONContentParser();
+
+        this.fileVaultXmlParserOptions = new ParserOptions()
+                .detectCalendarValues(true)
+                .ignorePropertyNames(this.ignoredNames)
+                .ignoreResourceNames(this.ignoredNames);
+        this.fileVaultXmlParser = new JCRXMLContentParser();
     }
 
     private final Set<String> getIgnoredNamesForResourceResolverType(ResourceResolverType resourceResolverType) {
@@ -147,19 +163,7 @@ public final class ContentLoader {
      * @return Resource
      */
     public @NotNull Resource json(@NotNull String classpathResource, @NotNull Resource parentResource, @NotNull String childName) {
-        InputStream is = ContentLoader.class.getResourceAsStream(classpathResource);
-        if (is == null) {
-            throw new IllegalArgumentException("Classpath resource not found: " + classpathResource);
-        }
-        try {
-            return json(is, parentResource, childName);
-        } finally {
-            try {
-                is.close();
-            } catch (IOException ex) {
-                // ignore
-            }
-        }
+        return json(classpathResource, parentResource.getPath() + "/" + childName);
     }
 
     /**
@@ -176,12 +180,9 @@ public final class ContentLoader {
         }
         try {
             return json(is, destPath);
-        } finally {
-            try {
-                is.close();
-            } catch (IOException ex) {
-                // ignore
-            }
+        }
+        finally {
+            IOUtils.closeQuietly(is);
         }
     }
 
@@ -203,8 +204,66 @@ public final class ContentLoader {
      * @param destPath Path to import the JSON content to
      * @return Resource
      */
-    @SuppressWarnings("null")
     public @NotNull Resource json(@NotNull InputStream inputStream, @NotNull String destPath) {
+        return mountParsedFile(inputStream, destPath, jsonParser, jsonParserOptions);
+    }
+
+    /**
+     * Import content of FileVault XML file into repository.
+     * @param classpathResource Classpath resource URL for Filevault content
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to create with Filevault content
+     * @return Resource
+     */
+    public @NotNull Resource fileVaultXml(@NotNull String classpathResource, @NotNull Resource parentResource, @NotNull String childName) {
+        return fileVaultXml(classpathResource, parentResource.getPath() + "/" + childName);
+    }
+
+    /**
+     * Import content of FileVault XML file into repository. Auto-creates parent
+     * hierarchies as nt:unstrucured nodes if missing.
+     * @param classpathResource Classpath resource URL for Filevault content
+     * @param destPath Path to import the Filevault content to
+     * @return Resource
+     */
+    public @NotNull Resource fileVaultXml(@NotNull String classpathResource, @NotNull String destPath) {
+        InputStream is = ContentLoader.class.getResourceAsStream(classpathResource);
+        if (is == null) {
+            throw new IllegalArgumentException("Classpath resource not found: " + classpathResource);
+        }
+        try {
+            return fileVaultXml(is, destPath);
+        }
+        finally {
+            IOUtils.closeQuietly(is);
+        }
+    }
+
+    /**
+     * Import content of FileVault XML file into repository.
+     * @param inputStream Input stream with Filevault content
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to create with Filevault content
+     * @return Resource
+     */
+    public @NotNull Resource fileVaultXml(@NotNull InputStream inputStream, @NotNull Resource parentResource, @NotNull String childName) {
+        return fileVaultXml(inputStream, parentResource.getPath() + "/" + childName);
+    }
+
+    /**
+     * Import content of FileVault XML file into repository. Auto-creates parent
+     * hierarchies as nt:unstrucured nodes if missing.
+     * @param inputStream Input stream with Filevault content
+     * @param destPath Path to import the Filevault content to
+     * @return Resource
+     */
+    public @NotNull Resource fileVaultXml(@NotNull InputStream inputStream, @NotNull String destPath) {
+        return mountParsedFile(inputStream, destPath, fileVaultXmlParser, fileVaultXmlParserOptions);
+    }
+
+    @SuppressWarnings("null")
+    private @NotNull Resource mountParsedFile(@NotNull InputStream inputStream, @NotNull String destPath,
+            @NotNull ContentParser contentParser, @NotNull ParserOptions parserOptions) {
         try {
             String parentPath = ResourceUtil.getParent(destPath);
             String childName = ResourceUtil.getName(destPath);
@@ -222,12 +281,13 @@ public final class ContentLoader {
             }
 
             LoaderContentHandler contentHandler = new LoaderContentHandler(destPath, resourceResolver);
-            jsonParser.parse(contentHandler, inputStream, jsonParserOptions);
+            contentParser.parse(contentHandler, inputStream, parserOptions);
             if (autoCommit) {
                 resourceResolver.commit();
             }
             return resourceResolver.getResource(destPath);
-        } catch (IOException ex) {
+        }
+        catch (IOException ex) {
             throw new RuntimeException(ex);
         }
     }
@@ -510,7 +570,7 @@ public final class ContentLoader {
             if (bundleContext != null && StringUtils.isNotEmpty(fileExtension)) {
                 ServiceReference<MimeTypeService> ref = bundleContext.getServiceReference(MimeTypeService.class);
                 if (ref != null) {
-                    MimeTypeService mimeTypeService = (MimeTypeService)bundleContext.getService(ref);
+                    MimeTypeService mimeTypeService = bundleContext.getService(ref);
                     mimeType = mimeTypeService.getMimeType(fileExtension);
                     break;
                 }
@@ -519,4 +579,101 @@ public final class ContentLoader {
         return StringUtils.defaultString(mimeType, CONTENTTYPE_OCTET_STREAM);
     }
 
+    /**
+     * Mount a folder containing content in JSON (Sling-Inital-Content) format in repository.
+     * @param mountFolderPath Root folder path to mount
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to mount folder into
+     */
+    public void folderJson(@NotNull String mountFolderPath, @NotNull Resource parentResource, @NotNull String childName) {
+        folderJson(new File(mountFolderPath), parentResource, childName);
+    }
+
+    /**
+     * Mount a folder containing content in JSON (Sling-Inital-Content) format in repository.
+     * @param mountFolder Root folder path to mount
+     * @param destPath Path to mount folder into
+     */
+    public void folderJson(@NotNull String mountFolderPath, @NotNull String destPath) {
+        folderJson(new File(mountFolderPath), destPath);
+    }
+
+    /**
+     * Mount a folder containing content in JSON (Sling-Inital-Content) format in repository.
+     * @param mountFolderPath Root folder to mount
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to mount folder into
+     */
+    public void folderJson(@NotNull File mountFolder, @NotNull Resource parentResource, @NotNull String childName) {
+        folderJson(mountFolder, parentResource.getPath() + "/" + childName);
+    }
+
+    /**
+     * Mount a folder containing content in JSON (Sling-Inital-Content) format in repository.
+     * @param mountFolder Root folder to mount
+     * @param destPath Path to mount folder into
+     */
+    @SuppressWarnings("null")
+    public void folderJson(@NotNull File mountFolder, @NotNull String destPath) {
+        if (bundleContext == null) {
+            throw new IllegalArgumentException("No bundle context given for content loader.");
+        }
+        Dictionary<String, Object> serviceProperties = MapUtil.toDictionary(
+                "provider.file", mountFolder.getAbsolutePath(),
+                "provider.root", destPath,
+                "provider.fs.mode", "INITIAL_CONTENT",
+                "provider.initial.content.import.options", "overwrite:=true;ignoreImportProviders:=\"xml\"",
+                "provider.checkinterval", 0);
+        FsResourceProvider service = MockOsgi.activateInjectServices(FsResourceProvider.class, bundleContext, serviceProperties);
+        bundleContext.registerService(ResourceProvider.class, service, serviceProperties);
+    }
+
+    /**
+     * Mount a folder containing content in FileVault XML format in repository.
+     * @param mountFolderPath Root folder path to mount. Path needs to point to the root folder of the content package structure.
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to mount folder into
+     */
+    public void folderFileVaultXml(@NotNull String mountFolderPath, @NotNull Resource parentResource, @NotNull String childName) {
+        folderFileVaultXml(new File(mountFolderPath), parentResource, childName);
+    }
+
+    /**
+     * Mount a folder containing content in FileVault XML format in repository.
+     * @param mountFolder Root folder path to mount. Path needs to point to the root folder of the content package structure.
+     * @param destPath Path to mount folder into
+     */
+    public void folderFileVaultXml(@NotNull String mountFolderPath, @NotNull String destPath) {
+        folderFileVaultXml(new File(mountFolderPath), destPath);
+    }
+
+    /**
+     * Mount a folder containing content in FileVault XML format in repository.
+     * @param mountFolderPath Root folder to mount. Path needs to point to the root folder of the content package structure.
+     * @param parentResource Parent resource
+     * @param childName Name of child resource to mount folder into
+     */
+    public void folderFileVaultXml(@NotNull File mountFolder, @NotNull Resource parentResource, @NotNull String childName) {
+        folderFileVaultXml(mountFolder, parentResource.getPath() + "/" + childName);
+    }
+
+    /**
+     * Mount a folder containing content in FileVault XML format in repository.
+     * @param mountFolder Root folder to mount. Path needs to point to the root folder of the content package structure.
+     * @param destPath Path to mount folder into
+     */
+    @SuppressWarnings("null")
+    public void folderFileVaultXml(@NotNull File mountFolder, @NotNull String destPath) {
+        if (bundleContext == null) {
+            throw new IllegalArgumentException("No bundle context given for content loader.");
+        }
+        Dictionary<String, Object> serviceProperties = MapUtil.toDictionary(
+                "provider.file", mountFolder.getAbsolutePath(),
+                "provider.root", destPath,
+                "provider.fs.mode", "FILEVAULT_XML",
+                "provider.checkinterval", 0);
+        FsResourceProvider service = MockOsgi.activateInjectServices(FsResourceProvider.class, bundleContext, serviceProperties);
+        bundleContext.registerService(ResourceProvider.class, service, serviceProperties);
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
index 39c717a..59b9a8b 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Helpers for importing test content into the mocked repositories / resource hierarchies.
  */
-@org.osgi.annotation.versioning.Version("1.2.0")
+@org.osgi.annotation.versioning.Version("1.3.0")
 package org.apache.sling.testing.mock.sling.loader;
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java b/core/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java
index 66bde79..55bf8cf 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/spi/ResourceResolverTypeAdapter.java
@@ -25,6 +25,11 @@ import org.jetbrains.annotations.Nullable;
 /**
  * SPI interface for resource resolver type implementations to provide a mock
  * resource resolver factory.
+ * <p>Supported constructors for implementing classes:</p>
+ * <ul>
+ * <li>Empty constructor</li>
+ * <li>Constructor with {@link org.osgi.framework.BundleContext} parameter</li>
+ * </ul>
  */
 public interface ResourceResolverTypeAdapter {
 
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFileVaultXmlTest.java
similarity index 65%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFileVaultXmlTest.java
index 39c717a..6431531 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFileVaultXmlTest.java
@@ -16,8 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.jcrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFileVaultXmlTest;
+
+public class ContentLoaderFileVaultXmlTest extends AbstractContentLoaderFileVaultXmlTest {
+
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.JCR_MOCK;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
similarity index 63%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
index 39c717a..b920628 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.jcrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderFileVaultXmlTest;
+
+public class ContentLoaderFolderFileVaultXmlTest extends AbstractContentLoaderFolderFileVaultXmlTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.JCR_MOCK;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderJsonTest.java
similarity index 65%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderJsonTest.java
index 39c717a..4aaa87c 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/jcrmock/loader/ContentLoaderFolderJsonTest.java
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.jcrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+
+public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.JCR_MOCK;
+    }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderBinaryTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderBinaryTest.java
index d6babba..d2ca3df 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderBinaryTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderBinaryTest.java
@@ -98,14 +98,15 @@ public abstract class AbstractContentLoaderBinaryTest {
         assertMimeType(fileResource, "mime/test");
     }
 
-    private void assertSampleImageFileSize(Resource resource) throws IOException {
-        InputStream is = resource.adaptTo(InputStream.class);
-        assertNotNull("InputSteam is null for " + resource.getPath(), is);
-        byte[] binaryData = IOUtils.toByteArray(is);
-        assertEquals(SAMPLE_IMAGE_FILESIZE, binaryData.length);
+    static void assertSampleImageFileSize(Resource resource) throws IOException {
+        try (InputStream is = resource.adaptTo(InputStream.class)) {
+            assertNotNull("InputSteam is null for " + resource.getPath(), is);
+            byte[] binaryData = IOUtils.toByteArray(is);
+            assertEquals(SAMPLE_IMAGE_FILESIZE, binaryData.length);
+        }
     }
 
-    private void assertMimeType(Resource resource, String mimeType) {
+    static void assertMimeType(Resource resource, String mimeType) {
         assertNotNull(resource);
         assertEquals(mimeType, ResourceUtil.getValueMap(resource).get(JcrConstants.JCR_MIMETYPE, String.class));
     }
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFileVaultXmlTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFileVaultXmlTest.java
new file mode 100644
index 0000000..d71c4f6
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFileVaultXmlTest.java
@@ -0,0 +1,116 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling.loader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.ValueMap;
+import org.apache.sling.testing.mock.sling.NodeTypeDefinitionScanner;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+@SuppressWarnings("null")
+public abstract class AbstractContentLoaderFileVaultXmlTest {
+
+    @Rule
+    public SlingContext context = new SlingContext(getResourceResolverType());
+
+    protected abstract ResourceResolverType getResourceResolverType();
+
+    protected String path;
+
+    @Before
+    public void setUp() {
+        path = context.uniqueRoot().content();
+
+        try {
+            NodeTypeDefinitionScanner.get().register(context.resourceResolver().adaptTo(Session.class),
+                    ImmutableList.of("SLING-INF/nodetypes/app.cnd"),
+                    getResourceResolverType().getNodeTypeMode());
+        }
+        catch (RepositoryException ex) {
+            throw new RuntimeException("Unable to register namespaces.", ex);
+        }
+
+        context.load().fileVaultXml("/xml-jcr-import-samples/content/samples/en/.content.xml", path + "/sample/en");
+    }
+
+    @After
+    public final void tearDown() throws Exception {
+        // make sure all changes from ContentLoader are committed
+        assertFalse(context.resourceResolver().hasChanges());
+    }
+
+    @Test
+    public void testPageResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/sample/en");
+        assertEquals("app:Page", resource.getResourceType());
+    }
+
+    @Test
+    public void testPageJcrPrimaryType() throws RepositoryException {
+        Resource resource = context.resourceResolver().getResource(path + "/sample/en");
+        assertPrimaryNodeType(resource, "app:Page");
+    }
+
+    @Test
+    public void testPageContentResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/sample/en/jcr:content");
+        assertEquals("samples/sample-app/components/content/page/homepage", resource.getResourceType());
+    }
+
+    @Test
+    public void testPageContentJcrPrimaryType() throws RepositoryException {
+        Resource resource = context.resourceResolver().getResource(path + "/sample/en/jcr:content");
+        assertPrimaryNodeType(resource, "app:PageContent");
+    }
+
+    @Test
+    public void testPageContentProperties() {
+        Resource resource = context.resourceResolver().getResource(path + "/sample/en/jcr:content");
+        ValueMap props = ResourceUtil.getValueMap(resource);
+        assertEquals("HOME", props.get("navTitle", String.class));
+        assertEquals(true, props.get("includeAside", Boolean.class));
+    }
+
+    private void assertPrimaryNodeType(final Resource resource, final String nodeType) throws RepositoryException {
+        Node node = resource.adaptTo(Node.class);
+        if (node != null) {
+            assertEquals(nodeType, node.getPrimaryNodeType().getName());
+        } else {
+            ValueMap props = ResourceUtil.getValueMap(resource);
+            assertEquals(nodeType, props.get(JcrConstants.JCR_PRIMARYTYPE));
+        }
+    }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderFileVaultXmlTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderFileVaultXmlTest.java
new file mode 100644
index 0000000..473ecbf
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderFileVaultXmlTest.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling.loader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+@SuppressWarnings("null")
+public abstract class AbstractContentLoaderFolderFileVaultXmlTest {
+
+    @Rule
+    public SlingContext context = new SlingContext(getResourceResolverType());
+
+    protected abstract ResourceResolverType getResourceResolverType();
+
+    protected String path;
+
+    @Before
+    public void setUp() {
+        path = "/content";
+        context.load().folderFileVaultXml("src/test/resources/xml-jcr-import-samples", path);
+    }
+
+    @After
+    public final void tearDown() throws Exception {
+        // make sure all changes from ContentLoader are committed
+        assertFalse(context.resourceResolver().hasChanges());
+    }
+
+    @Test
+    public void testContentResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/samples/en/jcr:content");
+        assertEquals("samples/sample-app/components/content/page/homepage", resource.getResourceType());
+    }
+
+    @Test
+    public void testContentListChildren() {
+        Resource resource = context.resourceResolver().getResource(path + "/samples/en");
+        List<Resource> result = ImmutableList.copyOf(resource.listChildren());
+        assertEquals("jcr:content", result.get(0).getName());
+        assertEquals("tools", result.get(1).getName());
+    }
+
+    @Test
+    public void testDamResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/dam/talk.png/jcr:content");
+        assertEquals("app:AssetContent", resource.getResourceType());
+    }
+
+    @Test
+    public void testBinaryResource() throws IOException {
+        Resource fileResource = context.resourceResolver().getResource(path + "/dam/talk.png/jcr:content/renditions/original");
+        try (InputStream is = fileResource.adaptTo(InputStream.class)) {
+            assertNotNull("InputSteam is null for " + fileResource.getPath(), is);
+            byte[] binaryData = IOUtils.toByteArray(is);
+            assertEquals(8668, binaryData.length);
+        }
+    }
+
+}
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java
new file mode 100644
index 0000000..712309c
--- /dev/null
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/loader/AbstractContentLoaderFolderJsonTest.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.sling.loader;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+@SuppressWarnings("null")
+public abstract class AbstractContentLoaderFolderJsonTest {
+
+    @Rule
+    public SlingContext context = new SlingContext(getResourceResolverType());
+
+    protected abstract ResourceResolverType getResourceResolverType();
+
+    protected String path;
+
+    @Before
+    public void setUp() {
+        path = context.uniqueRoot().content();
+        context.load().folderJson("src/test/resources/json-import-samples", path + "/mount");
+    }
+
+    @After
+    public final void tearDown() throws Exception {
+        // make sure all changes from ContentLoader are committed
+        assertFalse(context.resourceResolver().hasChanges());
+    }
+
+    @Test
+    public void testContentResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/mount/content/jcr:content");
+        assertEquals("sample/components/homepage", resource.getResourceType());
+    }
+
+    @Test
+    public void testContentListChildren() {
+        Resource resource = context.resourceResolver().getResource(path + "/mount/content");
+        List<Resource> result = ImmutableList.copyOf(resource.listChildren());
+        assertEquals("jcr:content", result.get(0).getName());
+        assertEquals("toolbar", result.get(1).getName());
+    }
+
+    @Test
+    public void testDamResourceType() {
+        Resource resource = context.resourceResolver().getResource(path + "/mount/dam/portraits/scott_reynolds.jpg");
+        assertEquals("dam:Asset", resource.getResourceType());
+    }
+
+    @Test
+    public void testBinaryResource() throws IOException {
+        Resource fileResource = context.resourceResolver().getResource(path + "/mount/binary/sample-image.gif");
+        AbstractContentLoaderBinaryTest.assertSampleImageFileSize(fileResource);
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFileVaultXmlTest.java
similarity index 64%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFileVaultXmlTest.java
index 39c717a..b3a87c7 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFileVaultXmlTest.java
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.rrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFileVaultXmlTest;
+
+public class ContentLoaderFileVaultXmlTest extends AbstractContentLoaderFileVaultXmlTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
similarity index 63%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
index 39c717a..89e34c2 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderFileVaultXmlTest.java
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.rrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderFileVaultXmlTest;
+
+public class ContentLoaderFolderFileVaultXmlTest extends AbstractContentLoaderFolderFileVaultXmlTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+    }
+
+}
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
similarity index 64%
copy from core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
copy to core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
index 39c717a..01f0c5c 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/loader/package-info.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/loader/ContentLoaderFolderJsonTest.java
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * Helpers for importing test content into the mocked repositories / resource hierarchies.
- */
-@org.osgi.annotation.versioning.Version("1.2.0")
-package org.apache.sling.testing.mock.sling.loader;
+package org.apache.sling.testing.mock.sling.rrmock.loader;
+
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
+import org.apache.sling.testing.mock.sling.loader.AbstractContentLoaderFolderJsonTest;
+
+public class ContentLoaderFolderJsonTest extends AbstractContentLoaderFolderJsonTest {
+
+    @Override
+    protected ResourceResolverType getResourceResolverType() {
+        return ResourceResolverType.RESOURCERESOLVER_MOCK;
+    }
+
+}
diff --git a/core/src/test/resources/json-import-samples/binary/sample-image.gif b/core/src/test/resources/json-import-samples/binary/sample-image.gif
new file mode 100644
index 0000000..8b310f6
Binary files /dev/null and b/core/src/test/resources/json-import-samples/binary/sample-image.gif differ
diff --git a/core/src/test/resources/xml-jcr-import-samples/.content.xml b/core/src/test/resources/xml-jcr-import-samples/.content.xml
new file mode 100644
index 0000000..b264022
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/.content.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:rep="internal" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+    jcr:mixinTypes="[rep:AccessControllable,rep:RepoAccessControllable]"
+    jcr:primaryType="rep:root"
+    sling:resourceType="sling:redirect"
+    sling:target="/index.html" />
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/.content.xml
new file mode 100644
index 0000000..115c72c
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/.content.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:rep="internal" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+    jcr:mixinTypes="[mix:lockable,rep:AccessControllable,sling:Redirect]"
+    jcr:primaryType="sling:OrderedFolder"
+    jcr:title="Content Root"
+    sling:resourceType="sling:redirect"
+    sling:target="/geohome">
+  <dam />
+  <samples />
+</jcr:root>
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/dam/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/dam/.content.xml
new file mode 100644
index 0000000..64f25b1
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/dam/.content.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:rep="internal" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+    jcr:mixinTypes="[mix:lockable,rep:AccessControllable]"
+    jcr:primaryType="sling:OrderedFolder">
+  <talk.png />
+</jcr:root>
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/.content.xml
new file mode 100644
index 0000000..e207a1e
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/.content.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:app="http://sample.com/app/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:primaryType="app:Asset">
+  <jcr:content
+      jcr:primaryType="app:AssetContent">
+    <metadata
+        app:Bitsperpixel="{Long}4"
+        app:extracted="{Date}2015-09-19T14:33:36.078+02:00"
+        app:Fileformat="PNG"
+        app:MIMEtype="image/png"
+        app:Numberofimages="{Long}1"
+        app:Numberoftextualcomments="{Long}3"
+        app:Physicalheightindpi="{Long}72"
+        app:Physicalheightininches="{Decimal}3.750854253768921"
+        app:Physicalwidthindpi="{Long}72"
+        app:Physicalwidthininches="{Decimal}6.668185710906982"
+        app:Progressive="no"
+        app:sha1="29e02b493473c2beaf851002b67b6f1b700be978"
+        app:size="{Long}6652"
+        app:writebackEnable="False"
+        dc:format="image/png"
+        dc:modified="{Date}2014-09-19T21:20:26.812+02:00"
+        jcr:primaryType="nt:unstructured"
+        writebackEnable="{Boolean}true" />
+  </jcr:content>
+</jcr:root>
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original
new file mode 100644
index 0000000..0d42760
Binary files /dev/null and b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original differ
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original.dir/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original.dir/.content.xml
new file mode 100644
index 0000000..1813b25
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/original.dir/.content.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0"
+    jcr:primaryType="nt:file">
+  <jcr:content
+      jcr:mimeType="image/png"
+      jcr:primaryType="nt:resource" />
+</jcr:root>
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/web.1280.1280.png b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/web.1280.1280.png
new file mode 100644
index 0000000..27b0374
Binary files /dev/null and b/core/src/test/resources/xml-jcr-import-samples/content/dam/talk.png/_jcr_content/renditions/web.1280.1280.png differ
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/samples/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/samples/.content.xml
new file mode 100644
index 0000000..c96141e
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/samples/.content.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+    jcr:primaryType="sling:OrderedFolder">
+  <en />
+</jcr:root>
diff --git a/core/src/test/resources/xml-jcr-import-samples/content/samples/en/.content.xml b/core/src/test/resources/xml-jcr-import-samples/content/samples/en/.content.xml
new file mode 100644
index 0000000..c394cf9
--- /dev/null
+++ b/core/src/test/resources/xml-jcr-import-samples/content/samples/en/.content.xml
@@ -0,0 +1,195 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+    
+    http://www.apache.org/licenses/LICENSE-2.0
+    
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+-->
+<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:app="http://sample.com/jcr/app/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
+    jcr:primaryType="app:Page">
+  <jcr:content
+      app:cloudserviceconfigs="[[]]"
+      app:deviceGroups="[/etc/mobile/groups/responsive]"
+      app:template="samples/sample-app/templates/content/homepage"
+      jcr:primaryType="app:PageContent"
+      jcr:title="en"
+      sling:resourceType="samples/sample-app/components/content/page/homepage"
+      includeAside="{Boolean}true"
+      includeAsideBar="{Boolean}true"
+      includeTeaserBar="{Boolean}true"
+      includeTeaserbar="{Boolean}true"
+      inheritAside="{Boolean}false"
+      inheritTeaserbar="{Boolean}false"
+      navTitle="HOME"
+      pageTitle="Sample Site">
+    <teaserbar
+        jcr:primaryType="nt:unstructured"
+        sling:resourceType="samples/sample-app/components/content/teaserbar/teaserbarParsys">
+      <teaserbaritem
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/teaserbar/teaserbarItem"
+          linkContentRef="/content/samples/en/conference"
+          linkMediaDownload="{Boolean}false"
+          linkTitle="This should help you with your decision"
+          linkType="internal"
+          linkWindowFeatures="default"
+          linkWindowTarget="_self"
+          mediaRef="/content/dam/samples/content/user.png"
+          teaserContent="Still not convinced to attend? Need persuasion? Facts for your boss?"
+          title="Why to attend" />
+      <teaserbaritem_0
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/teaserbar/teaserbarItem"
+          linkContentRef="/content/samples/en/venue"
+          linkMediaDownload="{Boolean}false"
+          linkTitle="More information"
+          linkType="internal"
+          linkWindowFeatures="default"
+          linkWindowTarget="_self"
+          mediaRef="/content/dam/samples/content/location.png"
+          teaserContent="Take a look at the new venue for 2013. The Kulturbrauerei in the Prenzlauer Berg district."
+          title="Location" />
+      <teaserbaritem_1
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/teaserbar/teaserbarItem"
+          linkContentRef="/content/samples/en/conference/call-for-papers"
+          linkMediaDownload="{Boolean}false"
+          linkTitle="Submit your proposal here"
+          linkType="internal"
+          linkWindowFeatures="default"
+          linkWindowTarget="_self"
+          mediaRef="/content/dam/samples/content/talk.png"
+          teaserContent="If you have insight and experiences with Apache Sling and want to share them? We are actually asking for your participation!"
+          title="Want to share?" />
+      <teaserbaritem_2
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/teaserbar/teaserbarItem"
+          linkContentRef="/content/samples/en/archive"
+          linkMediaDownload="{Boolean}false"
+          linkTitle="Dive into the archive"
+          linkType="internal"
+          linkWindowFeatures="default"
+          linkWindowTarget="_self"
+          mediaRef="/content/dam/samples/content/archive.png"
+          teaserContent="adaptTo() is not a new event. Take a look at what was said and done previously."
+          title="Take a look back" />
+    </teaserbar>
+    <aside
+        jcr:primaryType="nt:unstructured"
+        sling:resourceType="samples/sample-app/components/content/aside/asideParsys">
+      <asidesponsorteaser
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/aside/asideSponsorTeaser"
+          title="Sponsors">
+        <images
+            jcr:primaryType="nt:unstructured"
+            sling:resourceType="samples/sample-app/components/content/aside/asideSponsorTeaserParsys">
+          <asidesponsorteaserit_0
+              jcr:primaryType="nt:unstructured"
+              sling:resourceType="samples/sample-app/components/content/aside/asideSponsorTeaserItem"
+              imageHeight="41"
+              imageWidth="200"
+              linkExternalRef="http://www.pro-vision.de"
+              linkType="external"
+              linkWindowFeatures="default"
+              linkWindowTarget="_blank"
+              mediaRef="/content/dam/samples/content/provision-logo.png" />
+        </images>
+      </asidesponsorteaser>
+      <asidesocialteaser
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/aside/asideSocialTeaser"
+          title="Follow us">
+        <images
+            jcr:primaryType="nt:unstructured"
+            sling:resourceType="samples/sample-app/components/content/aside/asideSponsorTeaserParsys">
+          <asidesocialteaserite
+              jcr:primaryType="nt:unstructured"
+              sling:resourceType="samples/sample-app/components/content/aside/asideSocialTeaserItem"
+              linkExternalRef="http://twitter.com/adaptto"
+              linkMediaDownload="{Boolean}false"
+              linkTitle="@adaptTo"
+              linkType="external"
+              linkWindowFeatures="default"
+              linkWindowTarget="_blank"
+              mediaRef="/content/dam/samples/content/twitter-icon.png"
+              title="on twitter" />
+        </images>
+      </asidesocialteaser>
+    </aside>
+    <content
+        jcr:primaryType="nt:unstructured"
+        sling:resourceType="sample/wcm/parsys/components/parsys">
+      <contentrichtext
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/common/contentRichText"
+          text="&lt;p&gt;adaptTo() is a meetup in Berlin focused on Apache Sling including Apache Jackrabbit and Apache Felix and is addressed to all using this stack or parts of it.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a data=&quot;{&amp;quot;linkType&amp;quot;:&amp;quot;internal&amp;quot;,&amp;quot;linkContentRef&amp;quot;:&amp;quot;/content/samples/handler/en/conference&amp;quot;,&amp;quot;linkWindowTarget&amp;quot;:&amp;quot;_self&amp;quot;,&amp;quot;linkWindowFeatures&amp;quot;:&amp;quot;defa [...]
+      <contentheadline
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/common/contentHeadline"
+          headline="Extended Call for Papers"
+          smaller="{Boolean}true" />
+      <contentrichtext_0
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/common/contentRichText"
+          text="&lt;p&gt;Although we got some great submissions for adaptTo() 2013, we still have some slots for further sessions. Therefore we extend the timeslot for submissions to the call for papers and for feedback by two weeks. This means you still can submit you submissions till 06.05.2013. We're looking forward to get more of your great talks.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a data=&quot;{&amp;quot;linkType&amp;quot;:&amp;quot;internal&amp;quot;,&amp;quot;linkContentRef&amp;quot;:&amp [...]
+    </content>
+    <stage
+        jcr:primaryType="nt:unstructured"
+        sling:resourceType="sample/wcm/parsys/components/parsys">
+      <stageheader
+          jcr:primaryType="nt:unstructured"
+          sling:resourceType="samples/sample-app/components/content/stage/stageheader"
+          linkMediaDownload="{Boolean}false"
+          linkType="internal"
+          linkWindowFeatures="default"
+          linkWindowTarget="_self"
+          mediaRef="/content/dam/samples/content/stageheader-outside2.jpg"
+          subtitle="23.–25. September 2013&#xA;Kulturbrauerei Berlin"
+          title="adaptTo() 2013">
+        <links
+            jcr:primaryType="nt:unstructured"
+            sling:resourceType="samples/sample-app/components/content/stage/stageheaderParsys">
+          <stageheaderlinkitem
+              jcr:primaryType="nt:unstructured"
+              sling:resourceType="samples/sample-app/components/content/stage/stageheaderLinkItem"
+              linkContentRef="/content/samples/en/tickets"
+              linkMediaDownload="{Boolean}false"
+              linkTitle="Get tickets now"
+              linkType="internal"
+              linkWindowFeatures="default"
+              linkWindowTarget="_self" />
+          <stageheaderlinkitem_0
+              jcr:primaryType="nt:unstructured"
+              sling:resourceType="samples/sample-app/components/content/stage/stageheaderLinkItem"
+              linkContentRef="/content/samples/en/conference/call-for-papers"
+              linkMediaDownload="{Boolean}false"
+              linkTitle="Submit paper"
+              linkType="internal"
+              linkWindowFeatures="default"
+              linkWindowTarget="_self" />
+        </links>
+      </stageheader>
+    </stage>
+    <image
+        jcr:primaryType="nt:unstructured" />
+  </jcr:content>
+  <tools />
+  <conference />
+  <extra jcr:primaryType="nt:unstructured">
+    <extracontent/>
+    <binaryfile.xml/>
+  </extra>
+</jcr:root>
diff --git a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
index 74231df..ff8d07c 100644
--- a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
+++ b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextMemberTest.java
@@ -19,10 +19,9 @@
 package org.apache.sling.testing.mock.sling.junit5;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.sling.api.resource.Resource;
-import org.apache.sling.testing.resourceresolver.MockResourceResolver;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -38,7 +37,7 @@ class SlingContextMemberTest {
 
     @BeforeEach
     void setUp() {
-        assertTrue(context.resourceResolver() instanceof MockResourceResolver);
+        assertEquals(ResourceResolverType.RESOURCERESOLVER_MOCK, context.resourceResolverType());
 
         context.create().resource("/content/test", "prop1", "value1");
     }
diff --git a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
index fc956ab..485d9a7 100644
--- a/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
+++ b/junit5/src/test/java/org/apache/sling/testing/mock/sling/junit5/SlingContextTest.java
@@ -19,11 +19,10 @@
 package org.apache.sling.testing.mock.sling.junit5;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.context.modelsautoreg.ClasspathRegisteredModel;
-import org.apache.sling.testing.resourceresolver.MockResourceResolver;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -38,7 +37,7 @@ class SlingContextTest {
 
     @BeforeEach
     void setUp(SlingContext context) {
-        assertTrue(context.resourceResolver() instanceof MockResourceResolver);
+        assertEquals(ResourceResolverType.RESOURCERESOLVER_MOCK, context.resourceResolverType());
 
         context.create().resource("/content/test", "prop1", "value1");
     }
diff --git a/parent/pom.xml b/parent/pom.xml
index 2a5ae85..b3894d5 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -215,6 +215,37 @@
         </dependency>
 
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.contentparser.api</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.contentparser.json</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.contentparser.xml-jcr</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.jackrabbit.vault</groupId>
+            <artifactId>org.apache.jackrabbit.vault</artifactId>
+            <version>3.1.44</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.fsresource</artifactId>
+            <version>2.1.17-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>commons-beanutils</groupId>
+            <artifactId>commons-beanutils</artifactId>
+            <version>1.8.3</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.mockito</groupId>
             <artifactId>mockito-core</artifactId>
             <version>3.7.0</version>