/*
 * 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.launchpad.testservices.serversidetests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.security.AccessControlEntry;
import javax.jcr.security.AccessControlList;
import javax.jcr.security.AccessControlManager;
import javax.jcr.security.AccessControlPolicy;
import javax.servlet.http.HttpServletRequest;

import org.apache.jackrabbit.api.security.user.Authorizable;
import org.apache.sling.api.resource.NonExistingResource;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.resource.ValueMap;
import org.apache.sling.jcr.base.util.AccessControlUtil;
import org.apache.sling.junit.annotations.SlingAnnotationsTestRunner;
import org.apache.sling.junit.annotations.TestReference;
import org.apache.sling.launchpad.testservices.events.EventsCounter;
import org.apache.sling.launchpad.testservices.exported.FakeSlingHttpServletRequest;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@RunWith(SlingAnnotationsTestRunner.class)
public class ResourceResolverTest {

    public static final String PROP_REDIRECT_INTERNAL = "sling:internalRedirect";
    public static final String PROP_REDIRECT_EXTERNAL = "sling:redirect";
    public static final String MAPPING_EVENT_TOPIC = "org/apache/sling/api/resource/ResourceResolverMapping/CHANGED";

    private static final Logger logger = LoggerFactory.getLogger(ResourceResolverTest.class);
    private static ResourceResolver resResolver;
    private static Session session;
    private String rootPath;
    private Node rootNode;
    private Node mapRoot;
    private String [] vanity;
    private static List<String> toDelete = new ArrayList<String>();
    private static ResourceResolverFactory cleanupResolverFactory;
    private MappingsFacade mappingsFacade;
    
    @TestReference
    private EventsCounter eventsCounter;
    
    @TestReference
    private ResourceResolverFactory resourceResolverFactory;  
    
    private Node maybeCreateNode(Node parent, String name, String type) throws RepositoryException {
        if(parent.hasNode(name)) {
            return parent.getNode(name);
        } else {
            return parent.addNode(name, type);
        }
    }
    
    private void saveMappings(Session s) throws Exception {
        final String saveMappingsError = mappingsFacade.saveMappings(s);
        if(saveMappingsError != null) {
            fail(saveMappingsError);
        }
    }

    @Before
    public synchronized void setup() throws Exception {
        closeResolver();
        resResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
        cleanupResolverFactory = resourceResolverFactory;
        session = resResolver.adaptTo(Session.class);
        mappingsFacade = new MappingsFacade(eventsCounter);
        
        // Do the mappings setup only once, and clean it up 
        // after all tests
        rootNode = maybeCreateNode(session.getRootNode(), "content", "nt:unstructured");
        rootPath = rootNode.getPath();
        session.save();
        if(toDelete.isEmpty()) {
            final Node mapRoot = maybeCreateNode(session.getRootNode(), "etc", "nt:folder");
            final Node map = maybeCreateNode(mapRoot, "map", "sling:Mapping");
            final Node http = maybeCreateNode(map, "http", "sling:Mapping");
            maybeCreateNode(http, "localhost.80", "sling:Mapping");
            final Node https = maybeCreateNode(map, "https", "sling:Mapping");
            maybeCreateNode(https, "localhost.443", "sling:Mapping");
            toDelete.add(map.getPath());
            toDelete.add(rootNode.getPath());
        }
        
        mapRoot = session.getNode("/etc");
        session.save();
        
        // define a vanity path for the rootPath
        vanity = new String[] {"testVanity","testV", "testVanityToUpdate"};
        rootNode.setProperty("sling:vanityPath", vanity);
        rootNode.addMixin("sling:VanityPath");
        saveMappings(session);
    }
    
    private void closeResolver() {
        if(session != null) {
            if(session.isLive()) {
                session.logout();
            }
            session = null;
        }
        if (resResolver != null ) {
            resResolver.close();
            resResolver = null;
        }
        
    }

    @After
    public void deleteTestNodes() throws Exception {
        logger.debug("{} test done, deleting test nodes", ResourceResolverTest.class.getSimpleName());
        final ResourceResolver resolver = cleanupResolverFactory.getAdministrativeResourceResolver(null);
        final Session session = resolver.adaptTo(Session.class);
        
        try {
            for(String path : toDelete) {
                if(session.itemExists(path)) {
                    session.getItem(path).remove();
                }
            }
            toDelete.clear();
            session.save();
        } finally {
            session.logout();
            resolver.close();
        }
    }
    
    @Test public void test_clone_based_on_anonymous() throws Exception {
        final ResourceResolver anon0 = this.resourceResolverFactory.getResourceResolver((Map<String, Object>) null);
        final Session anon0Session = anon0.adaptTo(Session.class);
        assertEquals("anonymous", anon0.getUserID());

        // same user and workspace
        final ResourceResolver anon1 = anon0.clone(null);
        final Session anon1Session = anon1.adaptTo(Session.class);
        assertEquals(anon0.getUserID(), anon1.getUserID());
        assertEquals(anon0Session.getWorkspace().getName(),
            anon1Session.getWorkspace().getName());
        anon1.close();

        // same workspace but admin user
        final Map<String, Object> admin0Cred = new HashMap<String, Object>();
        admin0Cred.put(ResourceResolverFactory.USER, "admin");
        admin0Cred.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
        final ResourceResolver admin0 = anon0.clone(admin0Cred);
        final Session admin0Session = admin0.adaptTo(Session.class);
        assertEquals("admin", admin0.getUserID());
        assertEquals(anon0Session.getWorkspace().getName(),
            admin0Session.getWorkspace().getName());
        admin0.close();

        // same user but different workspace
        final Map<String, Object> anon2Cred = new HashMap<String, Object>();
        final ResourceResolver anon2 = anon0.clone(anon2Cred);
        assertEquals("anonymous", anon2.getUserID());
        anon2.close();

        // different user and workspace
        final Map<String, Object> admin1Cred = new HashMap<String, Object>();
        admin1Cred.put(ResourceResolverFactory.USER, "admin");
        admin1Cred.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
        final ResourceResolver admin1 = anon0.clone(admin1Cred);
        assertEquals("admin", admin1.getUserID());
        admin1.close();

        anon0.close();
    }

    @Test public void test_clone_based_on_admin() throws Exception {
        final ResourceResolver admin0 = this.resourceResolverFactory.getAdministrativeResourceResolver((Map<String, Object>) null);
        final Session admin0Session = admin0.adaptTo(Session.class);
        assertEquals("admin", admin0.getUserID());

        // same user and workspace
        final ResourceResolver admin1 = admin0.clone(null);
        final Session admin1Session = admin1.adaptTo(Session.class);
        assertEquals(admin0.getUserID(), admin1.getUserID());
        assertEquals(admin0Session.getWorkspace().getName(),
            admin1Session.getWorkspace().getName());
        admin1.close();

        // same workspace but anonymous user
        final Map<String, Object> anon0Cred = new HashMap<String, Object>();
        anon0Cred.put(ResourceResolverFactory.USER, "anonymous");
        final ResourceResolver anon0 = admin0.clone(anon0Cred);
        final Session anon0Session = anon0.adaptTo(Session.class);
        assertEquals("anonymous", anon0.getUserID());
        assertEquals(admin0Session.getWorkspace().getName(),
            anon0Session.getWorkspace().getName());
        anon0.close();

        // same user but different workspace
        final Map<String, Object> admin2Cred = new HashMap<String, Object>();
        final ResourceResolver admin2 = admin0.clone(admin2Cred);
        assertEquals("admin", admin2.getUserID());
        admin2.close();

        // different user and workspace
        final Map<String, Object> anon1Cred = new HashMap<String, Object>();
        anon1Cred.put(ResourceResolverFactory.USER, "anonymous");
        final ResourceResolver anon1 = admin0.clone(anon1Cred);
        assertEquals("anonymous", anon1.getUserID());
        anon1.close();

        admin0.close();
    }

    /*@Test public void test_attributes_from_session() throws Exception {
        // test assumes admin password is admin (which is default)

        final Credentials creds0 = new SimpleCredentials("admin",
            "admin".toCharArray());
        final Session session0 = getRepository().login(creds0);
        final Map<String, Object> authInfo = new HashMap<String, Object>();
        authInfo.put(ResourceResolverFactory.USER, "admin");
        authInfo.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
        authInfo.put("testAttributeString", "AStringValue");
        authInfo.put("testAttributeNumber", 999);

        final ResourceResolver resolver0 = resFac.getResourceResolver(authInfo);

        final Iterator<String> attrNames0 = resolver0.getAttributeNames();
        assertTrue("Expected one attribute", attrNames0.hasNext());
        final String attrName0 = attrNames0.next();
        assertEquals("Expected attribute name to address session",
            JcrResourceConstants.AUTHENTICATION_INFO_SESSION, attrName0);
        assertFalse("Expected no more attributes", attrNames0.hasNext());
        assertEquals("Expected session attribute to be the session", session0,
            resolver0.getAttribute(attrName0));

        assertEquals("Expected no Session attributes", 0,
            session0.getAttributeNames().length);

        resolver0.close();
        assertTrue("Expect session to still be live after resolver close",
            session0.isLive());
        session0.logout();

        final SimpleCredentials creds1 = new SimpleCredentials("admin",
            "admin".toCharArray());
        creds1.setAttribute("testAttributeString", "AStringValue");
        creds1.setAttribute("testAttributeNumber", 999);
        final Session session1 = getRepository().login(creds1);

        final ResourceResolver resolver1 = resFac.getResourceResolver(authInfo);

        assertEquals("Expected 2 Session attributes", 2,
            session1.getAttributeNames().length);
        assertEquals("AStringValue",
            session1.getAttribute("testAttributeString"));
        assertEquals(999, session1.getAttribute("testAttributeNumber"));

        assertEquals(
            session1,
            resolver1.getAttribute(JcrResourceConstants.AUTHENTICATION_INFO_SESSION));
        assertEquals("AStringValue",
            resolver1.getAttribute("testAttributeString"));
        assertEquals(999, resolver1.getAttribute("testAttributeNumber"));

        final Iterator<String> attrNames1 = resolver1.getAttributeNames();
        assertTrue("Expecting first attribute", attrNames1.hasNext());
        attrNames1.next();
        assertTrue("Expecting second attribute", attrNames1.hasNext());
        attrNames1.next();
        assertTrue("Expecting third attribute", attrNames1.hasNext());
        attrNames1.next();
        assertFalse("Expecting no more attribute", attrNames1.hasNext());

        resolver1.close();
        assertTrue("Expect session to still be live after resolver close",
            session1.isLive());
        session1.logout();
    }*/

    @Test public void test_attributes_from_authInfo() throws Exception {
        final Map<String, Object> authInfo = new HashMap<String, Object>();
        authInfo.put(ResourceResolverFactory.USER, "admin");
        authInfo.put(ResourceResolverFactory.PASSWORD, "admin".toCharArray());
        authInfo.put("testAttributeString", "AStringValue");
        authInfo.put("testAttributeNumber", 999);
        final ResourceResolver rr = this.resourceResolverFactory.getResourceResolver(authInfo);
        final Session s = rr.adaptTo(Session.class);

        try {
            assertEquals("Expect 3 session attributes", 3,
                s.getAttributeNames().length);
            assertEquals("AStringValue", s.getAttribute("testAttributeString"));
            assertEquals(999, s.getAttribute("testAttributeNumber"));
            assertEquals("admin", s.getAttribute(ResourceResolverFactory.USER));
            assertNull(session.getAttribute(ResourceResolverFactory.PASSWORD));

            assertEquals("AStringValue", rr.getAttribute("testAttributeString"));
            assertEquals(999, rr.getAttribute("testAttributeNumber"));
            assertEquals("admin", rr.getAttribute(ResourceResolverFactory.USER));
            assertNull(rr.getAttribute(ResourceResolverFactory.PASSWORD));

            final HashSet<String> validNames = new HashSet<String>();
            validNames.add(ResourceResolverFactory.USER);
            validNames.add("testAttributeString");
            validNames.add("testAttributeNumber");
            final Iterator<String> names = rr.getAttributeNames();
            assertTrue(validNames.remove(names.next()));
            assertTrue(validNames.remove(names.next()));
            assertTrue(validNames.remove(names.next()));
            assertFalse("Expect no more names", names.hasNext());
            assertTrue("Expect validNames set to be empty now",
                validNames.isEmpty());
        } finally {
            rr.close();
        }
    }

    @Test public void testGetResource() throws Exception {
        // existing resource
        Resource res = resResolver.getResource(rootPath);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
            res.getResourceType());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        // missing resource
        String path = rootPath + "/missing";
        res = resResolver.getResource(path);
        assertNull(res);
    }

    @Test public void testResolveResource() throws Exception {
        // existing resource
        HttpServletRequest request = new FakeSlingHttpServletRequest(rootPath);
        Resource res = resResolver.resolve(request, rootPath);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
            res.getResourceType());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        // missing resource below root should resolve "missing resource"
        String path = rootPath + "/missing";
        res = resResolver.resolve(new FakeSlingHttpServletRequest(path), path);
        assertNotNull(res);
        assertEquals(path, res.getPath());
        assertEquals(Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());

        assertNull(res.adaptTo(Node.class));

        // root with selectors/ext should resolve root
        path = rootPath + ".print.a4.html";
        res = resResolver.resolve(new FakeSlingHttpServletRequest(path), path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
            res.getResourceType());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        // missing resource should return NON_EXISTING Resource
        path = rootPath + System.currentTimeMillis();
        res = resResolver.resolve(new FakeSlingHttpServletRequest(path), path);
        assertNotNull(res);
        assertTrue(ResourceUtil.isNonExistingResource(res));
        assertEquals(path, res.getPath());
        assertEquals(Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());
    }



    @Test public void testResolveResourceExternalRedirect() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");
        localhost443.setProperty(PROP_REDIRECT_EXTERNAL,
            "http://localhost");

        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, rootPath);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals("sling:redirect", res.getResourceType());
            assertNotNull(res.adaptTo(ValueMap.class));
            assertEquals("http://localhost" + rootPath,
                res.adaptTo(ValueMap.class).get("sling:target", String.class));
        } finally {
            localhost443.getProperty(PROP_REDIRECT_EXTERNAL).remove();
            session.save();
        }
    }

    @Test public void testResolveResourceInternalRedirectUrl() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");
        localhost443.setProperty(PROP_REDIRECT_INTERNAL,
            "http://localhost");

        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, rootPath);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
        } finally {
            localhost443.getProperty(PROP_REDIRECT_INTERNAL).remove();
            session.save();
        }
    }

    @Test public void testResolveResourceInternalRedirectPath() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");

        Node toContent = localhost443.addNode("_playground_designground_",
            "sling:Mapping");
        toContent.setProperty("sling:match",
            "(playground|designground)");
        toContent.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/$1");
        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, "/playground.html");
            assertNotNull(res);
            assertEquals("/content/playground.html", res.getPath());

            res = resResolver.resolve(request, "/playground/en.html");
            assertNotNull(res);
            assertEquals("/content/playground/en.html", res.getPath());

            res = resResolver.resolve(request, "/libs/nt/folder.html");
            assertNotNull(res);
            assertEquals("/libs/nt/folder.html", res.getPath());
        } finally {
            toContent.remove();
            session.save();
        }
    }
    
    @Test public void testResolveResourceInternalRedirectPathAndVanityPath() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
                null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");

        localhost443.setProperty(PROP_REDIRECT_INTERNAL,
                "/example");
        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, vanity[0]);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            
            //see SLING-3428
            res = resResolver.resolve(request, vanity[1]);
            assertNotNull(res);
            assertEquals("/example/"+vanity[1], res.getPath());
        } finally {
            localhost443.getProperty(PROP_REDIRECT_INTERNAL).remove();
            session.save();
        }     
    }

    @Test public void testResolveResourceInternalRedirectPathUpdate() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https", null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");
        Node toContent = localhost443.addNode("_playground_designground_", "sling:Mapping");
        toContent.setProperty("sling:match", "(playground|designground)");
        toContent.setProperty(PROP_REDIRECT_INTERNAL, "/content/$1");

        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, "/playground.html");
            assertNotNull(res);
            assertEquals("/content/playground.html", res.getPath());

            res = resResolver.resolve(request, "/playground/en.html");
            assertNotNull(res);
            assertEquals("/content/playground/en.html", res.getPath());

            res = resResolver.resolve(request, "/libs/nt/folder.html");
            assertNotNull(res);
            assertEquals("/libs/nt/folder.html", res.getPath());

            // update the match
            toContent.setProperty("sling:match", "(homeground|foreignground)");
            saveMappings(session);

            res = resResolver.resolve(request, "/homeground.html");
            assertNotNull(res);
            assertEquals("/content/homeground.html", res.getPath());

            res = resResolver.resolve(request, "/foreignground/en.html");
            assertNotNull(res);
            assertEquals("/content/foreignground/en.html", res.getPath());

            res = resResolver.resolve(request, "/libs/nt/folder.html");
            assertNotNull(res);
            assertEquals("/libs/nt/folder.html", res.getPath());
        } finally {
            toContent.remove();
            session.save();
        }
    }

    @Test public void testResolveResourceInternalRedirectExact() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            null, -1, rootPath);
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");
        Node toContent = localhost443.addNode("virtual", "sling:Mapping");
        toContent.setProperty("sling:match", "virtual$");
        toContent.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/virtual.html");

        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, "/virtual");
            assertNotNull(res);
            assertEquals("/content/virtual.html", res.getPath());

            res = resResolver.resolve(request, "/virtual.html");
            assertNotNull(res);
            assertEquals("/virtual.html", res.getPath());

            res = resResolver.resolve(request, "/virtual/child.html");
            assertNotNull(res);
            assertEquals("/virtual/child.html", res.getPath());

            String url = resResolver.map(null, "/content/virtual.html");
            assertNotNull(url);
            assertEquals("https://localhost/virtual", url);

            url = resResolver.map(request, "/content/virtual.html");
            assertNotNull(url);
            assertEquals("/virtual", url);
        } finally {
            toContent.remove();
            session.save();
        }
    }

    @Test public void testResolveResourceInternalRedirectDepthFirst()
            throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            null, -1, rootPath);

        // map anything
        Node localhost443 = mapRoot.getNode("map/https/localhost.443");
        localhost443.setProperty(PROP_REDIRECT_INTERNAL,
            "/content2");

        // map only ../virtual
        Node toContent = localhost443.addNode("virtual", "sling:Mapping");
        toContent.setProperty("sling:match", "virtual$");
        toContent.setProperty(PROP_REDIRECT_INTERNAL,
            "/content2/virtual.html");

        try {
            saveMappings(session);
            Resource res = resResolver.resolve(request, "/virtual");
            assertNotNull(res);
            assertEquals("/content2/virtual.html", res.getPath());

            res = resResolver.resolve(request, "/virtual.html");
            assertNotNull(res);
            assertEquals("/content2/virtual.html", res.getPath());

            res = resResolver.resolve(request, "/virtual/child.html");
            assertNotNull(res);
            assertEquals("/content2/virtual/child.html", res.getPath());
        } finally {
            localhost443.getProperty(PROP_REDIRECT_INTERNAL).remove();
            toContent.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttp80() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest(null,
            "virtual.host.com", -1, rootPath);
        Node virtualhost80 = mapRoot.getNode("map/http").addNode(
            "virtual.host.com.80", "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/virtual");

        try {
            saveMappings(session);
            final Resource res0 = resResolver.resolve(request, "/playground.html");
            assertNotNull(res0);
            assertEquals("/content/virtual/playground.html", res0.getPath());

            final Resource res1 = resResolver.resolve(request,
                "/playground/en.html");
            assertNotNull(res1);
            assertEquals("/content/virtual/playground/en.html", res1.getPath());

            final String mapped00 = resResolver.map(res0.getPath());
            assertEquals("http://virtual.host.com/playground.html", mapped00);
            final String mapped01 = resResolver.map(request, res0.getPath());
            assertEquals("/playground.html", mapped01);

            final String mapped10 = resResolver.map(res1.getPath());
            assertEquals("http://virtual.host.com/playground/en.html", mapped10);
            final String mapped11 = resResolver.map(request, res1.getPath());
            assertEquals("/playground/en.html", mapped11);
        } finally {
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttp80Multiple() throws Exception {

        final String de = "de";
        final String en = "en";
        final String hostDE = de + ".host.com";
        final String hostEN = en + ".host.com";
        final String contentDE = "/content/" + de;
        final String contentEN = "/content/" + en;

        Node virtualhost80a = mapRoot.getNode("map/http").addNode(
            hostDE + ".80", "sling:Mapping");
        virtualhost80a.setProperty(PROP_REDIRECT_INTERNAL,
            contentDE);
        Node virtualhost80 = mapRoot.getNode("map/http").addNode(hostEN + ".80",
            "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            contentEN);

        try {
            saveMappings(session);
            
            // de content mapping
            final HttpServletRequest requestDE = new FakeSlingHttpServletRequest(
                null, hostDE, -1, rootPath);
            final Resource resDE0 = resResolver.resolve(requestDE,
                "/playground.html");
            assertNotNull(resDE0);
            assertEquals(contentDE + "/playground.html", resDE0.getPath());

            final Resource resDE1 = resResolver.resolve(requestDE,
                "/playground/index.html");
            assertNotNull(resDE1);
            assertEquals(contentDE + "/playground/index.html", resDE1.getPath());

            final String mappedDE00 = resResolver.map(resDE0.getPath());
            assertEquals("http://" + hostDE + "/playground.html", mappedDE00);
            final String mappedDE01 = resResolver.map(requestDE, resDE0.getPath());
            assertEquals("/playground.html", mappedDE01);

            final String mappedDE10 = resResolver.map(resDE1.getPath());
            assertEquals("http://" + hostDE + "/playground/index.html", mappedDE10);
            final String mappedDE11 = resResolver.map(requestDE, resDE1.getPath());
            assertEquals("/playground/index.html", mappedDE11);

            // en content mapping

            final HttpServletRequest requestEN = new FakeSlingHttpServletRequest(
                null, hostEN, -1, rootPath);
            final Resource resEN0 = resResolver.resolve(requestEN,
                "/playground.html");
            assertNotNull(resEN0);
            assertEquals(contentEN + "/playground.html", resEN0.getPath());

            final Resource resEN1 = resResolver.resolve(requestEN,
                "/playground/index.html");
            assertNotNull(resEN1);
            assertEquals(contentEN + "/playground/index.html", resEN1.getPath());

            final String mappedEN00 = resResolver.map(resEN0.getPath());
            assertEquals("http://" + hostEN + "/playground.html", mappedEN00);
            final String mappedEN01 = resResolver.map(requestEN, resEN0.getPath());
            assertEquals("/playground.html", mappedEN01);

            final String mappedEN10 = resResolver.map(resEN1.getPath());
            assertEquals("http://" + hostEN + "/playground/index.html", mappedEN10);
            final String mappedEN11 = resResolver.map(requestEN, resEN1.getPath());
            assertEquals("/playground/index.html", mappedEN11);
        } finally {
            virtualhost80a.remove();
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttp80MultipleRoot() throws Exception {

        final String de = "de";
        final String en = "en";
        final String fr = "fr";
        final String hostDE = de + ".host.com";
        final String hostEN = en + ".host.com";
        final String hostFR = fr + ".host.com";

        Node virtualhost80a = mapRoot.getNode("map/http").addNode(
            hostDE + ".80", "sling:Mapping");
        virtualhost80a.setProperty(PROP_REDIRECT_INTERNAL,
            "/");
        Node virtualhost80 = mapRoot.getNode("map/http").addNode(hostEN + ".80",
            "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            "/");

        try {
            saveMappings(session);
            
            // de content mapping
            final HttpServletRequest requestDE = new FakeSlingHttpServletRequest(
                null, hostDE, -1, rootPath);
            final Resource resDE0 = resResolver.resolve(requestDE,
                "/playground.html");
            assertNotNull(resDE0);
            assertEquals("/playground.html", resDE0.getPath());

            final Resource resDE1 = resResolver.resolve(requestDE,
                "/playground/index.html");
            assertNotNull(resDE1);
            assertEquals("/playground/index.html", resDE1.getPath());

            final String mappedDE00 = resResolver.map(resDE0.getPath());
            assertEquals("http://" + hostDE + "/playground.html", mappedDE00);
            final String mappedDE01 = resResolver.map(requestDE, resDE0.getPath());
            assertEquals("/playground.html", mappedDE01);

            final String mappedDE10 = resResolver.map(resDE1.getPath());
            assertEquals("http://" + hostDE + "/playground/index.html", mappedDE10);
            final String mappedDE11 = resResolver.map(requestDE, resDE1.getPath());
            assertEquals("/playground/index.html", mappedDE11);

            // en content mapping

            final HttpServletRequest requestEN = new FakeSlingHttpServletRequest(
                null, hostEN, -1, rootPath);
            final Resource resEN0 = resResolver.resolve(requestEN,
                "/playground.html");
            assertNotNull(resEN0);
            assertEquals("/playground.html", resEN0.getPath());

            final Resource resEN1 = resResolver.resolve(requestEN,
                "/playground/index.html");
            assertNotNull(resEN1);
            assertEquals("/playground/index.html", resEN1.getPath());

            // here we get back the hostDE, since this is the first configured
            // and we have no request information to map the correct of the
            // duplicate entries !
            final String mappedEN00 = resResolver.map(resEN0.getPath());
            assertEquals("http://" + hostDE + "/playground.html", mappedEN00);

            // here we expect the path without scheme/host/port since we have
            // the request and can select the right mapping
            final String mappedEN01 = resResolver.map(requestEN, resEN0.getPath());
            assertEquals("/playground.html", mappedEN01);

            // here we get back the hostDE, since this is the first configured
            // and we have no request information to map the correct of the
            // duplicate entries !
            final String mappedEN10 = resResolver.map(resEN1.getPath());
            assertEquals("http://" + hostDE + "/playground/index.html", mappedEN10);

            // here we expect the path without scheme/host/port since we have
            // the request and can select the right mapping
            final String mappedEN11 = resResolver.map(requestEN, resEN1.getPath());
            assertEquals("/playground/index.html", mappedEN11);

            final HttpServletRequest requestFR = new FakeSlingHttpServletRequest(
                null, hostFR, -1, rootPath);
            final Resource resFR1 = resResolver.resolve(requestFR,
                "/playground/index.html");
            assertNotNull(resFR1);
            assertEquals("/playground/index.html", resFR1.getPath());

            // here we get back the hostDE, since this is the first configured
            // and we have no request information to map the correct of the
            // duplicate entries !
            final String mappedFR10 = resResolver.map(resFR1.getPath());
            assertEquals("http://" + hostDE + "/playground/index.html", mappedFR10);

            // here we get back the hostDE, since this is the first configured
            // and we have request information which does not map any of the
            // configured duplicate entries !
            final String mappedFR11 = resResolver.map(requestFR, resFR1.getPath());
            assertEquals("http://" + hostDE + "/playground/index.html", mappedFR11);
        } finally {
            virtualhost80a.remove();
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttp8080() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest(null,
            "virtual.host.com", 8080, rootPath);
        Node virtualhost80 = mapRoot.getNode("map/http").addNode(
            "virtual.host.com.8080", "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/virtual");

        try {
            saveMappings(session);
            final Resource res0 = resResolver.resolve(request, "/playground.html");
            assertNotNull(res0);
            assertEquals("/content/virtual/playground.html", res0.getPath());

            final Resource res1 = resResolver.resolve(request,
                "/playground/en.html");
            assertNotNull(res1);
            assertEquals("/content/virtual/playground/en.html", res1.getPath());

            final String mapped00 = resResolver.map(res0.getPath());
            assertEquals("http://virtual.host.com:8080/playground.html", mapped00);
            final String mapped01 = resResolver.map(request, res0.getPath());
            assertEquals("/playground.html", mapped01);

            final String mapped10 = resResolver.map(res1.getPath());
            assertEquals("http://virtual.host.com:8080/playground/en.html",
                mapped10);
            final String mapped11 = resResolver.map(request, res1.getPath());
            assertEquals("/playground/en.html", mapped11);
        } finally {
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttp8080Root() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest(null,
            "virtual.host.com", 8080, rootPath);
        Node virtualhost80 = mapRoot.getNode("map/http").addNode(
            "virtual.host.com.8080", "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            "/");

        try {
            saveMappings(session);
            final Resource res0 = resResolver.resolve(request, "/playground.html");
            assertNotNull(res0);
            assertEquals("/playground.html", res0.getPath());

            final Resource res1 = resResolver.resolve(request,
                "/playground/en.html");
            assertNotNull(res1);
            assertEquals("/playground/en.html", res1.getPath());

            final String mapped00 = resResolver.map(res0.getPath());
            assertEquals("http://virtual.host.com:8080/playground.html", mapped00);
            final String mapped01 = resResolver.map(request, res0.getPath());
            assertEquals("/playground.html", mapped01);

            final String mapped10 = resResolver.map(res1.getPath());
            assertEquals("http://virtual.host.com:8080/playground/en.html",
                mapped10);
            final String mapped11 = resResolver.map(request, res1.getPath());
            assertEquals("/playground/en.html", mapped11);
        } finally {
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttps443() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            "virtual.host.com", -1, rootPath);
        Node virtualhost443 = mapRoot.getNode("map/https").addNode(
            "virtual.host.com.443", "sling:Mapping");
        virtualhost443.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/virtual");

        try {
            saveMappings(session);
            final Resource res0 = resResolver.resolve(request, "/playground.html");
            assertNotNull(res0);
            assertEquals("/content/virtual/playground.html", res0.getPath());

            final Resource res1 = resResolver.resolve(request,
                "/playground/en.html");
            assertNotNull(res1);
            assertEquals("/content/virtual/playground/en.html", res1.getPath());

            final String mapped00 = resResolver.map(res0.getPath());
            assertEquals("https://virtual.host.com/playground.html", mapped00);
            final String mapped01 = resResolver.map(request, res0.getPath());
            assertEquals("/playground.html", mapped01);

            final String mapped10 = resResolver.map(res1.getPath());
            assertEquals("https://virtual.host.com/playground/en.html", mapped10);
            final String mapped11 = resResolver.map(request, res1.getPath());
            assertEquals("/playground/en.html", mapped11);
        } finally {
            virtualhost443.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttps4443() throws Exception {
        HttpServletRequest request = new FakeSlingHttpServletRequest("https",
            "virtual.host.com", 4443, rootPath);
        Node virtualhost4443 = mapRoot.getNode("map/https").addNode(
            "virtual.host.com.4443", "sling:Mapping");
        virtualhost4443.setProperty(PROP_REDIRECT_INTERNAL,
            "/content/virtual");
        
        try {
            saveMappings(session);
            final Resource res0 = resResolver.resolve(request, "/playground.html");
            assertNotNull(res0);
            assertEquals("/content/virtual/playground.html", res0.getPath());

            final Resource res1 = resResolver.resolve(request,
                "/playground/en.html");
            assertNotNull(res1);
            assertEquals("/content/virtual/playground/en.html", res1.getPath());

            final String mapped00 = resResolver.map(res0.getPath());
            assertEquals("https://virtual.host.com:4443/playground.html", mapped00);
            final String mapped01 = resResolver.map(request, res0.getPath());
            assertEquals("/playground.html", mapped01);

            final String mapped10 = resResolver.map(res1.getPath());
            assertEquals("https://virtual.host.com:4443/playground/en.html",
                mapped10);
            final String mapped11 = resResolver.map(request, res1.getPath());
            assertEquals("/playground/en.html", mapped11);
        } finally {
            virtualhost4443.remove();
            session.save();
        }
    }

    @Test public void testResolveVirtualHostHttpVsHttps() throws Exception {

        final String host0 = "www.host.com";
        final String host1 = "secure.host.com";
        final String content = "/content/page";

        Node virtualhost80 = mapRoot.getNode("map/http").addNode(host0 + ".80",
            "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            content);
        Node virtualhost443 = mapRoot.getNode("map/https").addNode(
            host0 + ".443", "sling:Mapping");
        virtualhost443.setProperty(PROP_REDIRECT_INTERNAL,
            content);

        // HTTP request
        try {
            saveMappings(session);
            final HttpServletRequest requestHttp0 = new FakeSlingHttpServletRequest(
                null, host0, -1, rootPath);
            final Resource resHttp0 = resResolver.resolve(requestHttp0, "/playground.html");
            assertNotNull(resHttp0);
            assertEquals(content + "/playground.html", resHttp0.getPath());

            final Resource resHttp1 = resResolver.resolve(requestHttp0,
            "/playground/index.html");
            assertNotNull(resHttp1);
            assertEquals(content + "/playground/index.html", resHttp1.getPath());

            // HTTPS request
            final HttpServletRequest requestHttps0 = new FakeSlingHttpServletRequest(
                "https", host0, -1, rootPath);
            final Resource resHttps0 = resResolver.resolve(requestHttps0, "/playground.html");
            assertNotNull(resHttps0);
            assertEquals(content + "/playground.html", resHttps0.getPath());

            final Resource resHttps1 = resResolver.resolve(requestHttps0,
                "/playground/index.html");
            assertNotNull(resHttps1);
            assertEquals(content + "/playground/index.html", resHttps1.getPath());

            // HTTP Mapping

            final String mappedHttp00 = resResolver.map(resHttp0.getPath());
            assertEquals("http://" + host0 + "/playground.html", mappedHttp00);
            final String mappedHttp01 = resResolver.map(requestHttp0, resHttp0.getPath());
            assertEquals("/playground.html", mappedHttp01);

            final String mappedHttp10 = resResolver.map(resHttp1.getPath());
            assertEquals("http://" + host0 + "/playground/index.html", mappedHttp10);
            final String mappedHttp11 = resResolver.map(requestHttp0, resHttp1.getPath());
            assertEquals("/playground/index.html", mappedHttp11);

            // HTTPS Mapping

            final HttpServletRequest requestHttp1 = new FakeSlingHttpServletRequest(
                null, host1, -1, rootPath);
            final HttpServletRequest requestHttps1 = new FakeSlingHttpServletRequest(
                "https", host1, -1, rootPath);

            final String mappedHttps00 = resResolver.map(resHttps0.getPath());
            assertEquals("http://" + host0 + "/playground.html", mappedHttps00);
            final String mappedHttps01 = resResolver.map(requestHttps0, resHttps0.getPath());
            assertEquals("/playground.html", mappedHttps01);
            final String mappedHttps02 = resResolver.map(requestHttp1, resHttps0.getPath());
            assertEquals("http://" + host0 + "/playground.html", mappedHttps02);
            final String mappedHttps03 = resResolver.map(requestHttps1, resHttps0.getPath());
            assertEquals("https://" + host0 + "/playground.html", mappedHttps03);

            final String mappedHttps10 = resResolver.map(resHttps1.getPath());
            assertEquals("http://" + host0 + "/playground/index.html", mappedHttps10);
            final String mappedHttps11 = resResolver.map(requestHttps0, resHttps1.getPath());
            assertEquals("/playground/index.html", mappedHttps11);
            final String mappedHttps12 = resResolver.map(requestHttp1, resHttps1.getPath());
            assertEquals("http://" + host0 + "/playground/index.html", mappedHttps12);
            final String mappedHttps13 = resResolver.map(requestHttps1, resHttps1.getPath());
            assertEquals("https://" + host0 + "/playground/index.html", mappedHttps13);
        } finally {
            virtualhost80.remove();
            virtualhost443.remove();
            session.save();
        }
    }

    @Test public void testResolveResourceAlias() throws Exception {
        // define an alias for the rootPath
        String alias = "testAlias";
        rootNode.setProperty("sling:alias", alias);

        try {
            saveMappings(session);
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias + ".print.html");

            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + alias + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
        } finally {
            rootNode.getProperty("sling:alias").remove();
            session.save();
        }
    }

    @Test public void testResolveResourceAliasWithUpdate() throws Exception {
        // define an alias for the rootPath
        String [] alias = {"testAlias","testAliasToUpdate"};
        rootNode.setProperty("sling:alias", alias);

        try {
            saveMappings(session);
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias[1] + ".print.html");

            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                    + alias[1] + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            //update alias  
            String [] aliasUpdated =  {"testAlias","testAliasUpdated"};
            rootNode.setProperty("sling:alias", aliasUpdated);
            saveMappings(session);

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + aliasUpdated[1] + ".print.html");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                    + aliasUpdated[1] + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        } finally {
            rootNode.getProperty("sling:alias").remove();
            session.save();
        }
    }
    
    @Test public void testResolveRemovedResourceAlias() throws Exception {
        // define an alias for the rootPath
        String alias = "testAlias";
        rootNode.setProperty("sling:alias", alias);

        saveMappings(session);
        String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias + ".print.html");

        HttpServletRequest request = new FakeSlingHttpServletRequest(path);
        Resource res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + alias + ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        //remove alias property
        rootNode.getProperty("sling:alias").remove();
        saveMappings(session);

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias + ".print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);

        assertNotNull(res);
        assertTrue(res instanceof NonExistingResource);
        assertEquals("/"+alias+".print.html", res.getPath());
        
        //create new child with alias
        String childNodeName = "rootChildAlias";
        Node childNode = maybeCreateNode(rootNode, childNodeName, "nt:unstructured");
        childNode.setProperty("sling:alias", "childAlias");
        saveMappings(session);

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)+ "/"+ rootPath
                + "/childAlias.print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath+"/"+childNodeName, res.getPath());
        assertEquals(childNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(childNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)+ "/"+ rootPath + "/childAlias" +
                ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath+"/"+childNodeName, res.getPath());
        assertEquals(childNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(childNode.isSame(res.adaptTo(Node.class)));

        
        //remove the child node with the alias
        childNode.remove();
        saveMappings(session);
        
        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)+ "/"+ rootPath + "/childAlias" +
                ".print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        
        assertNotNull(res);
        assertTrue(res instanceof NonExistingResource);
        assertEquals (rootPath + "/childAlias.print.html", res.getPath());
    }
    
    @Test public void testResolveResourceAliasJcrContent() throws Exception {
        // define an alias for the rootPath in the jcr:content child node
        String alias = "testAlias";
        Node content = rootNode.addNode("jcr:content", "nt:unstructured");
        content.setProperty("sling:alias", alias);

        try {
            saveMappings(session);
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias + ".print.html");

            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + alias + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias + "/" + alias + ".print.html");
            res = resResolver.resolve(request, path);
            assertEquals("GET request resolution does not go up the path",
                    Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());

            Node child = rootNode.addNode("child", "nt:unstructured");
            child.setProperty("sling:alias", alias);

            try {
                saveMappings(session);
                res = resResolver.resolve(request, path);
                assertEquals(child.getPath(), res.getPath());
            } finally {
                child.remove();
                session.save();
            }
        } finally {
            content.remove();
            session.save();
        }

    }

    @Test public void testResolveResourceAliasJcrContentWithUpdate() throws Exception {
        // define an alias for the rootPath in the jcr:content child node
        String [] alias = {"testAlias","testAliasToUpdate"};
        Node content = rootNode.addNode("jcr:content", "nt:unstructured");
        content.setProperty("sling:alias", alias);

        try {
            saveMappings(session);
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias[1] + ".print.html");

            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + alias[1] + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            //update alias  
            String [] aliasUpdated =  {"testAlias","testAliasUpdated"};
            content.setProperty("sling:alias", aliasUpdated);
            saveMappings(session);

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + aliasUpdated[1] + ".print.html");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                    + aliasUpdated[1] + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        } finally {
            content.remove();
            session.save();
        }

    }
    
    @Test public void testResolveRemovedesourceAliasJcrContent() throws Exception {
        // define an alias for the rootPath in the jcr:content child node
        String alias = "testAlias";
        Node content = rootNode.addNode("jcr:content", "nt:unstructured");
        content.setProperty("sling:alias", alias);

        try {
            saveMappings(session);
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + alias + ".print.html");

            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + alias + ".print.html/suffix.pdf");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(rootPath, res.getPath());
            assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

            assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias + "/" + alias + ".print.html");
            res = resResolver.resolve(request, path);
            assertEquals("GET request resolution does not go up the path",
                    Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());

            //remove alias property
            content.getProperty("sling:alias").remove();
            saveMappings(session);

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias + ".print.html");
            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            
            assertNotNull(res);
            assertTrue(res instanceof NonExistingResource);
            assertEquals("/"+alias+".print.html", res.getPath());  

        } finally {
            content.remove();
            session.save();
        }

    }
    
    
    @Test public void testResolveVanityPath() throws Exception {
        String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanity[0] + ".print.html");

        HttpServletRequest request = new FakeSlingHttpServletRequest(path);
        Resource res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + vanity[0] + ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
        
        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanity[1] + ".print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + vanity[1] + ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
    }
    
    @Test public void testResolveVanityPathWithUpdate() throws Exception {
        String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanity[2] + ".print.html");

        HttpServletRequest request = new FakeSlingHttpServletRequest(path);
        Resource res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + vanity[2] + ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
        
        //update vanityPath
        String [] vanityPathUpdated = new String[] {"testVanity","testV", "testVanityUpdated"};
        rootNode.setProperty("sling:vanityPath", vanityPathUpdated);
        saveMappings(session);
        
        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanityPathUpdated[2] + ".print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath) + "/"
                + vanityPathUpdated[2] + ".print.html/suffix.pdf");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html/suffix.pdf",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));
        
        
        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanity[2] + ".print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertTrue(res instanceof NonExistingResource);
        assertEquals("/"+vanity[2]+".print.html", res.getPath());
    }
    
    @Test public void testResolveRemovedVanityPath() throws Exception {          
        String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/" + vanity[0] + ".print.html");

        HttpServletRequest request = new FakeSlingHttpServletRequest(path);
        Resource res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(rootNode.isSame(res.adaptTo(Node.class)));

        //remove vanityPath property
        rootNode.getProperty("sling:vanityPath").remove();
        saveMappings(session);

        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertTrue(res instanceof NonExistingResource);
        assertEquals("/"+vanity[0]+".print.html", res.getPath());

        //restore vanityPath
        rootNode.setProperty("sling:vanityPath", vanity);
        saveMappings(session);

        //create new child with vanity path
        Node childNode = maybeCreateNode(rootNode, "rootChild", "nt:unstructured");
        childNode.setProperty("sling:vanityPath", "childVanity");
        childNode.addMixin("sling:VanityPath");
        saveMappings(session);

        path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                + "/childVanity.print.html");

        request = new FakeSlingHttpServletRequest(path);
        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertEquals(childNode.getPath(), res.getPath());
        assertEquals(childNode.getPrimaryNodeType().getName(),
                res.getResourceType());

        assertEquals(".print.html",
                res.getResourceMetadata().getResolutionPathInfo());

        assertNotNull(res.adaptTo(Node.class));
        assertTrue(childNode.isSame(res.adaptTo(Node.class)));

        //remove node with vanity path
        childNode.remove();
        saveMappings(session);

        res = resResolver.resolve(request, path);
        assertNotNull(res);
        assertTrue(res instanceof NonExistingResource);
        assertEquals("/childVanity.print.html", res.getPath());
    }
    
    @Ignore //see SLING-3558
    @Test public void testResolveRemovedMixinVanityPath() throws Exception {   
        Node childNode = null;
        
        try  {
            //create new child with vanity path without mixin
            childNode = maybeCreateNode(rootNode, "rootChild", "nt:unstructured");
            childNode.setProperty("sling:vanityPath", "childVanity");
            saveMappings(session);
            
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");
            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertTrue(res instanceof NonExistingResource);
            assertEquals("/childVanity.print.html", res.getPath());
            
            //add mixin
            childNode.addMixin("sling:VanityPath");
            saveMappings(session);
            
            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");

            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(childNode.getPath(), res.getPath());
            assertEquals(childNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(childNode.isSame(res.adaptTo(Node.class)));
            
            //remove mixin  
            childNode.removeMixin("sling:VanityPath");
            saveMappings(session);

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");
            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertTrue(res instanceof NonExistingResource);
            assertEquals("/childVanity.print.html", res.getPath());
        } finally {
            if (childNode != null){
                childNode.remove();
                saveMappings(session);
            }
        }
    }
    
    @Test public void testResolveVanityPathWithVanityOrder() throws Exception {    
        Node childNode = null;
        Node childNode2 = null;
        
        try  {
            //create new child with vanity path
            childNode = maybeCreateNode(rootNode, "rootChild", "nt:unstructured");
            childNode.setProperty("sling:vanityPath", "childVanity");
            childNode.addMixin("sling:VanityPath");
            saveMappings(session);
                       
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");
            HttpServletRequest request = new FakeSlingHttpServletRequest(path);
            Resource res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(childNode.getPath(), res.getPath());
            assertEquals(childNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(childNode.isSame(res.adaptTo(Node.class)));
            
            //create another child with the same vanity path
            childNode2 = maybeCreateNode(rootNode, "rootChild2", "nt:unstructured");
            childNode2.setProperty("sling:vanityPath", "childVanity");
            childNode2.addMixin("sling:VanityPath");
            saveMappings(session);
 
            assertNotNull(res);
            assertEquals(childNode.getPath(), res.getPath());
            assertEquals(childNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(childNode.isSame(res.adaptTo(Node.class)));
            
            //add vanityOrder to childNode2
            childNode2.setProperty("sling:vanityOrder", 100);
            saveMappings(session);
            
            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");
            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            
            assertNotNull(res);
            assertEquals(childNode2.getPath(), res.getPath());
            assertEquals(childNode2.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(childNode2.isSame(res.adaptTo(Node.class)));
            
            //add vanityOrder to childNode higher than childNode2
            childNode.setProperty("sling:vanityOrder", 1000);
            saveMappings(session);
            
            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/childVanity.print.html");
            request = new FakeSlingHttpServletRequest(path);
            res = resResolver.resolve(request, path);
            assertNotNull(res);
            assertEquals(childNode.getPath(), res.getPath());
            assertEquals(childNode.getPrimaryNodeType().getName(),
                    res.getResourceType());

            assertEquals(".print.html",
                    res.getResourceMetadata().getResolutionPathInfo());

            assertNotNull(res.adaptTo(Node.class));
            assertTrue(childNode.isSame(res.adaptTo(Node.class)));
            
        } finally {
            if (childNode != null){
                childNode.remove();                 
            }
            if (childNode2 != null){
                childNode2.remove();                 
            }
            session.save();
        }            
    }

    
    @Test public void testGetDoesNotGoUp() throws Exception {

        final String path = rootPath + "/nothing";

        {
            final Resource res = resResolver.resolve(
                new FakeSlingHttpServletRequest(path, "POST"), path);
            assertNotNull(res);
            assertEquals("POST request resolution does not go up the path",
                Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());
        }

        {
            final Resource res = resResolver.resolve(
                new FakeSlingHttpServletRequest(path, "GET"), path);
            assertNotNull(res);
            assertEquals("GET request resolution does not go up the path",
                Resource.RESOURCE_TYPE_NON_EXISTING, res.getResourceType());
        }
    }

    @Test public void testGetRemovesExtensionInResolution() throws Exception {
        final String path = rootPath + ".whatever";
        final Resource res = resResolver.resolve(
            new FakeSlingHttpServletRequest(path, "GET"), path);
        assertNotNull(res);
        assertEquals(rootPath, res.getPath());
        assertEquals(rootNode.getPrimaryNodeType().getName(),
            res.getResourceType());
    }

    @Test public void testStarResourcePlain() throws Exception {
        final String path = rootPath + "/" + System.currentTimeMillis() + "/*";
        testStarResourceHelper(path, "GET");
        testStarResourceHelper(path, "POST");
        testStarResourceHelper(path, "PUT");
        testStarResourceHelper(path, "DELETE");
    }

    @Test public void testStarResourceExtension() throws Exception {
        final String path = rootPath + "/" + System.currentTimeMillis()
            + "/*.html";
        testStarResourceHelper(path, "GET");
        testStarResourceHelper(path, "POST");
        testStarResourceHelper(path, "PUT");
        testStarResourceHelper(path, "DELETE");
    }

    @Test public void testStarResourceSelectorExtension() throws Exception {
        final String path = rootPath + "/" + System.currentTimeMillis()
            + "/*.print.a4.html";
        testStarResourceHelper(path, "GET");
        testStarResourceHelper(path, "POST");
        testStarResourceHelper(path, "PUT");
        testStarResourceHelper(path, "DELETE");
    }

    @Test public void testSlingFolder() throws Exception {

        // create a folder
        String folderPath = "folder";
        Node folder = rootNode.addNode(folderPath, "sling:Folder");
        rootNode.getSession().save();

        try {
            // test default child node type
            Node child = folder.addNode("child0");
            folder.getSession().save();
            assertEquals("sling:Folder", child.getPrimaryNodeType().getName());

            // test explicit sling:Folder child
            child = folder.addNode("child1", "sling:Folder");
            folder.getSession().save();
            assertEquals("sling:Folder", child.getPrimaryNodeType().getName());

            // test explicit nt:folder child
            child = folder.addNode("child2", "nt:folder");
            folder.getSession().save();
            assertEquals("nt:folder", child.getPrimaryNodeType().getName());

            // test any child node -- use nt:unstructured here
            child = folder.addNode("child3", "nt:unstructured");
            folder.getSession().save();
            assertEquals("nt:unstructured", child.getPrimaryNodeType().getName());
        } finally {
            folder.remove();
            session.save();
        }
    }

    @Test public void testMap() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            path = "/child";
            mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapURLEscaping() throws Exception {

        final String mapHostInternal = "internal.host.com";
        final String mapRootInternal = "/content/internal";

        Node internalRedirect = mapRoot.getNode("map/http").addNode(
            mapHostInternal + ".80", "sling:Mapping");
        internalRedirect.setProperty(
            PROP_REDIRECT_INTERNAL, mapRootInternal);

        try {
            saveMappings(session);
            
            final String path = "/sample with spaces";
            final String escapedPath = "/sample%20with%20spaces";

            // ---------------------------------------------------------------------
            // internal redirect

            // a) test map(String)
            // => return full URL, escaped
            String mapped = resResolver.map(mapRootInternal + path);
            assertEquals("http://" + mapHostInternal + escapedPath, mapped);

            // b) test map(HttpServletRequest, String) with "localhost"
            // => return full URL, escaped
            mapped = resResolver.map(new FakeSlingHttpServletRequest(rootPath),
                mapRootInternal + path);
            assertEquals("http://" + mapHostInternal + escapedPath, mapped);

            // c) test map(HttpServletRequest, String) with "internal.host.com"
            // => only return path, escaped, because request host/port matches (cut
            // off host part)
            mapped = resResolver.map(new FakeSlingHttpServletRequest(null,
                mapHostInternal, -1, rootPath), mapRootInternal + path);
            assertEquals(escapedPath, mapped);

            // ---------------------------------------------------------------------
            // no mapping config
            // => return only escaped path

            final String unmappedRoot = "/unmappedRoot";

            // a) test map(String)
            mapped = resResolver.map(unmappedRoot + path);
            assertEquals(unmappedRoot + escapedPath, mapped);

            // b) test map(HttpServletRequest, String)
            mapped = resResolver.map(new FakeSlingHttpServletRequest(rootPath),
                unmappedRoot + path);
            assertEquals(unmappedRoot + escapedPath, mapped);
        } finally {
            internalRedirect.remove();
            session.save();
        }

    }

    @Test public void testMapNamespaceMangling() throws Exception {

        final String mapHost = "virtual.host.com";
        final String mapRootPath = "/content/virtual";
        final String contextPath = "/context";

        Node virtualhost80 = mapRoot.getNode("map/http").addNode(
            mapHost + ".80", "sling:Mapping");
        virtualhost80.setProperty(PROP_REDIRECT_INTERNAL,
            mapRootPath);

        try {
            saveMappings(session);
            
            // ---------------------------------------------------------------------
            // tests expecting paths without context

            final HttpServletRequest virtualRequest = new FakeSlingHttpServletRequest(
                null, mapHost, -1, rootPath);

            // simple mapping - cut off prefix and add host
            final String pathv0 = "/sample";
            final String mappedv0 = resResolver.map(virtualRequest, mapRootPath
                + pathv0);
            assertEquals("Expect unmangled path", pathv0, mappedv0);

            // expected name mangling without host prefix
            final String pathv1 = "/sample/jcr:content";
            final String mangledv1 = "/sample/_jcr_content";
            final String mappedv1 = resResolver.map(virtualRequest, mapRootPath
                + pathv1);
            assertEquals("Expect mangled path", mangledv1, mappedv1);

            // ---------------------------------------------------------------------
            // tests expecting paths with context "/context"

            ((FakeSlingHttpServletRequest) virtualRequest).setContextPath(contextPath);

            // simple mapping - cut off prefix and add host
            final String pathvc0 = "/sample";
            final String mappedvc0 = resResolver.map(virtualRequest, mapRootPath
                + pathvc0);
            assertEquals("Expect unmangled path", contextPath + pathv0, mappedvc0);

            // expected name mangling without host prefix
            final String pathvc1 = "/sample/jcr:content";
            final String mangledvc1 = "/sample/_jcr_content";
            final String mappedvc1 = resResolver.map(virtualRequest, mapRootPath
                + pathvc1);
            assertEquals("Expect mangled path", contextPath + mangledvc1, mappedvc1);

            // ---------------------------------------------------------------------
            // tests expecting absolute URLs without context

            final HttpServletRequest foreignRequest = new FakeSlingHttpServletRequest(
                null, "foreign.host.com", -1, rootPath);

            final String pathf0 = "/sample";
            final String mappedf0 = resResolver.map(foreignRequest, mapRootPath
                + pathf0);
            assertEquals("Expect unmangled absolute URI", "http://" + mapHost
                + pathf0, mappedf0);

            final String pathf1 = "/sample/jcr:content";
            final String mangledf1 = "/sample/_jcr_content";
            final String mappedf1 = resResolver.map(foreignRequest, mapRootPath
                + pathf1);
            assertEquals("Expect mangled absolute URI", "http://" + mapHost
                + mangledf1, mappedf1);

            // ---------------------------------------------------------------------
            // tests expecting absolute URLs with context "/context"

            ((FakeSlingHttpServletRequest) foreignRequest).setContextPath(contextPath);

            final String pathfc0 = "/sample";
            final String mappedfc0 = resResolver.map(foreignRequest, mapRootPath
                + pathfc0);
            assertEquals("Expect unmangled absolute URI", "http://" + mapHost
                + contextPath + pathfc0, mappedfc0);

            final String pathfc1 = "/sample/jcr:content";
            final String mangledfc1 = "/sample/_jcr_content";
            final String mappedfc1 = resResolver.map(foreignRequest, mapRootPath
                + pathfc1);
            assertEquals("Expect mangled absolute URI", "http://" + mapHost
                + contextPath + mangledfc1, mappedfc1);
        } finally {
            virtualhost80.remove();
            session.save();
        }
    }

    @Test public void testMapContext() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            path = "/child";
            mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapExtension() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = ".html";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapSelectorsExtension() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = ".sel1.sel2.html";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapExtensionSuffix() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = ".html/some/suffx.pdf";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapFragment() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = "#sec:1";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapQuery() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = "?a:b=2";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapFragmentQuery() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = "#sec:1?a:b=1";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapEmptyPath() throws Exception {
        String mapped = resResolver.map("");
        assertEquals("/", mapped);
    }

    @Test public void testMapExtensionFragmentQuery() throws Exception {
        String path = rootNode.getPath();
        String mapped = resResolver.map(path);
        assertEquals(path, mapped);

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // absolute path, expect rootPath segment to be
            // cut off the mapped path because we map the rootPath
            // onto root
            final String selExt = ".html#sec:1?a:b=1";
            path = "/child" + selExt;
            mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void testMapResourceAlias() throws Exception {
        // define an alias for the rootPath
        String alias = "testAlias";
        rootNode.setProperty("sling:alias", alias);
        saveMappings(session);

        try {
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias);
            String mapped = resResolver.map(rootNode.getPath());
            assertEquals(path, mapped);
            Node child = rootNode.addNode("child");
            session.save();

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias+"/child");
            mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);
        } finally {
            rootNode.getProperty("sling:alias").remove();
            if ( rootNode.hasNode("child") ) {
                rootNode.getNode("child").remove();
            }
            session.save();
        }
     }

    @Test public void testMapResourceAliasJcrContent() throws Exception {
        // define an alias for the rootPath in the jcr:content child node
        String alias = "testAlias";
        Node content = rootNode.addNode("jcr:content", "nt:unstructured");
        content.setProperty("sling:alias", alias);
        saveMappings(session);

        try {
            String path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias);
            String mapped = resResolver.map(rootNode.getPath());
            assertEquals(path, mapped);

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias+"/_jcr_content");
            mapped = resResolver.map(content.getPath());
            assertEquals(path, mapped);

            Node child = content.addNode("child");
            session.save();

            path = ResourceUtil.normalize(ResourceUtil.getParent(rootPath)
                    + "/" + alias+"/_jcr_content/child");
            mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);
        } finally {
            content.remove();
            session.save();
        }
    }

    @Test public void test_resolve() throws Exception {

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/child";
            String mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/child",
                res.getResourceMetadata().getResolutionPath());
            assertEquals("", res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);

            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            session.save();

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/child/grandchild";
            String mappedEnkel = resResolver.map(grandchild.getPath());
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/child/grandchild",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals("", resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_extension() throws Exception {

        final String selExt = ".html";

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/child" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/child",
                res.getResourceMetadata().getResolutionPath());
            assertEquals(selExt, res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);
            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            session.save();

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/child/grandchild" + selExt;
            String mappedEnkel = resResolver.map(grandchild.getPath() + selExt);
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/child/grandchild",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals(selExt,
                resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_selectors_extension() throws Exception {

        final String selExt = ".sel1.sel2.html";

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/child" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/child",
                res.getResourceMetadata().getResolutionPath());
            assertEquals(selExt, res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);
            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            session.save();

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/child/grandchild" + selExt;
            String mappedEnkel = resResolver.map(grandchild.getPath() + selExt);
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/child/grandchild",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals(selExt,
                resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_extension_suffix() throws Exception {

        final String selExt = ".html/some/suffx.pdf";

        Node child = rootNode.addNode("child");
        session.save();

        try {
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/child" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);

            assertEquals(child.getPath(), resNode.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    /**
     * Test the order property of the vanity paths
     */
    @Test public void test_resolve_with_sling_vanity_path_order() throws Exception {
        final String vanityPath = "/ordering";

        // create two nodes - child2 with a higher order
        Node child1 = rootNode.addNode("child1");
        child1.addMixin("sling:VanityPath");
        child1.setProperty("sling:vanityPath", vanityPath);
        child1.setProperty("sling:vanityOrder", 100);
        Node child2 = rootNode.addNode("child2");
        child2.addMixin("sling:VanityPath");
        child2.setProperty("sling:vanityPath", vanityPath);
        child2.setProperty("sling:vanityOrder", 200);

        try {
            saveMappings(session);


            // we should get child2 now
            Resource rsrc = resResolver.resolve(vanityPath);
            assertNotNull(rsrc);
            assertFalse("Resource should exist", ResourceUtil.isNonExistingResource(rsrc));
            assertEquals("Path does not match", child2.getPath(), rsrc.getPath());

            // remove 2
            child2.remove();
            saveMappings(session);

            // we should get child 1 now
            rsrc = resResolver.resolve(vanityPath);
            assertNotNull(rsrc);
            assertFalse("Resource should exist", ResourceUtil.isNonExistingResource(rsrc));
            assertEquals("Path does not match", child1.getPath(), rsrc.getPath());

            // readding child2
            child2 = rootNode.addNode("child2");
            child2.addMixin("sling:VanityPath");
            child2.setProperty("sling:vanityPath", vanityPath);
            child2.setProperty("sling:vanityOrder", 200);
            saveMappings(session);

            // we should get child2 now
            rsrc = resResolver.resolve(vanityPath);
            assertNotNull(rsrc);
            assertFalse("Resource should exist", ResourceUtil.isNonExistingResource(rsrc));
            assertEquals("Path does not match", child2.getPath(), rsrc.getPath());

            // change order of child 1 to make it higher than child 2
            child1.setProperty("sling:vanityOrder", 300);
            saveMappings(session);

            // we should get child 1 now
            rsrc = resResolver.resolve(vanityPath);
            assertNotNull(rsrc);
            assertFalse("Resource should exist", ResourceUtil.isNonExistingResource(rsrc));
            assertEquals("Path does not match", child1.getPath(), rsrc.getPath());

            // change order of child 1 to make it lower than child 2
            child1.setProperty("sling:vanityOrder", 50);
            saveMappings(session);

            // we should get child 2 now
            rsrc = resResolver.resolve(vanityPath);
            assertNotNull(rsrc);
            assertFalse("Resource should exist", ResourceUtil.isNonExistingResource(rsrc));
            assertEquals("Path does not match", child2.getPath(), rsrc.getPath());
        } finally {
            child1.remove();
            if ( rootNode.hasNode("child2") ) {
                rootNode.getNode("child2").remove();
            }
            session.save();
        }
    }

    @Test public void test_resolve_with_sling_alias() throws Exception {

        Node child = rootNode.addNode("child");
        child.setProperty("sling:alias", "kind");
        saveMappings(session);

        try {
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/kind";
            String mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/kind",
                res.getResourceMetadata().getResolutionPath());
            assertEquals("", res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);

            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            grandchild.setProperty("sling:alias", "enkel");
            saveMappings(session);

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/kind/enkel";
            String mappedEnkel = resResolver.map(grandchild.getPath());
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/kind/enkel",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals("", resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_with_sling_alias_limited_access() throws Exception {
        
        Principal testUserPrincipal = new Principal() {
            public String getName() {
                return "testuser";
            }
        };
        
        AccessControlUtil.getUserManager(session).createUser("testuser", "password", testUserPrincipal, null);        
        Node child = rootNode.addNode("child");
        Node grandChild = child.addNode("grandChild");
        grandChild.setProperty("sling:alias", "enkel");
        saveMappings(session);
        session.save();
        
        //deny jcr:all on /
        AccessControlUtil.replaceAccessControlEntry(session, "/", testUserPrincipal, null, new String[] {"jcr:all"}, null, "last");
        //grant read on /content/child
        AccessControlUtil.replaceAccessControlEntry(session, child.getPath(), testUserPrincipal, new String[] {"jcr:read"}, null, null, "last");
        session.save();
        
        try {
            final Map<String, Object> authInfo = new HashMap<String, Object>();
            authInfo.put(ResourceResolverFactory.USER, "testuser");
            authInfo.put(ResourceResolverFactory.PASSWORD, "password".toCharArray());
            ResourceResolver testUserResolver = resourceResolverFactory.getResourceResolver(authInfo);

            try {
                //testing map
                String path = grandChild.getPath();
                String mapped = testUserResolver.map(path);
                assertEquals("/child/enkel", mapped);
                
                //testing resolve
                path = grandChild.getPath();
                Resource res = testUserResolver.resolve(null, path);
                assertNotNull(res);
                assertFalse(res instanceof NonExistingResource);
                assertEquals(path, res.getPath());
                
                path = child.getPath()+"/enkel";
                res = testUserResolver.resolve(null, path);
                assertNotNull(res);
                assertFalse(res instanceof NonExistingResource);
                assertEquals(grandChild.getPath(), res.getPath());
            } finally {
                if (testUserResolver != null && testUserResolver.isLive()) {
                    testUserResolver.close();
                } 
            }
        } finally {
            removeAce(session, testUserPrincipal, "/");
            child.remove();
            Authorizable authorizable = AccessControlUtil.getUserManager(session).getAuthorizable("testuser");
            authorizable.remove();
            session.save();
        }
    }

    
    @Test public void test_resolve_with_sling_alias_multi_value() throws Exception {

        Node child = rootNode.addNode("child");
        child.setProperty("sling:alias", new String[] {
            "kind", "enfant" });

        try {
            saveMappings(session);
            
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/kind";
            String mapped = resResolver.map(child.getPath());
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/kind",
                res.getResourceMetadata().getResolutionPath());
            assertEquals("", res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);

            assertEquals(child.getPath(), resNode.getPath());

            // expect enfant due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnfant = "/enfant";
            String mappedEnfant = resResolver.map(child.getPath());
            assertEquals(path, mappedEnfant); // map always selects first alias

            Resource resEnfant = resResolver.resolve(null, pathEnfant);
            assertNotNull(resEnfant);
            assertEquals(rootNode.getPath() + "/enfant",
                resEnfant.getResourceMetadata().getResolutionPath());
            assertEquals("", resEnfant.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnfant = resEnfant.adaptTo(Node.class);
            assertNotNull(resNodeEnfant);

            assertEquals(child.getPath(), resNodeEnfant.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            grandchild.setProperty("sling:alias", "enkel");
            saveMappings(session);

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/kind/enkel";
            String mappedEnkel = resResolver.map(grandchild.getPath());
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/kind/enkel",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals("", resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnfantEnkel = "/enfant/enkel";
            String mappedEnfantEnkel = resResolver.map(grandchild.getPath());
            assertEquals(pathEnkel, mappedEnfantEnkel); // map always selects first alias

            Resource resEnfantEnkel = resResolver.resolve(null, pathEnfantEnkel);
            assertNotNull(resEnfantEnkel);
            assertEquals(rootNode.getPath() + "/enfant/enkel",
                resEnfantEnkel.getResourceMetadata().getResolutionPath());
            assertEquals("", resEnfantEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnfantEnkel = resEnfantEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnfantEnkel);
            assertEquals(grandchild.getPath(), resNodeEnfantEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_with_sling_alias_extension() throws Exception {

        final String selExt = ".html";

        Node child = rootNode.addNode("child");
        child.setProperty("sling:alias", "kind");

        try {
            saveMappings(session);
            
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/kind" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/kind",
                res.getResourceMetadata().getResolutionPath());
            assertEquals(selExt, res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);
            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            grandchild.setProperty("sling:alias", "enkel");
            saveMappings(session);

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/kind/enkel" + selExt;
            String mappedEnkel = resResolver.map(grandchild.getPath() + selExt);
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/kind/enkel",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals(selExt,
                resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_with_sling_alias_selectors_extension()
            throws Exception {

        final String selExt = ".sel1.sel2.html";

        Node child = rootNode.addNode("child");
        child.setProperty("sling:alias", "kind");

        try {
            saveMappings(session);
            
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/kind" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            assertNotNull(res);
            assertEquals(rootNode.getPath() + "/kind",
                res.getResourceMetadata().getResolutionPath());
            assertEquals(selExt, res.getResourceMetadata().getResolutionPathInfo());

            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);
            assertEquals(child.getPath(), resNode.getPath());

            // second level alias
            Node grandchild = child.addNode("grandchild");
            grandchild.setProperty("sling:alias", "enkel");
            saveMappings(session);

            // expect kind/enkel due to alias and no parent due to mapping
            // the rootPath onto root
            String pathEnkel = "/kind/enkel" + selExt;
            String mappedEnkel = resResolver.map(grandchild.getPath() + selExt);
            assertEquals(pathEnkel, mappedEnkel);

            Resource resEnkel = resResolver.resolve(null, pathEnkel);
            assertNotNull(resEnkel);
            assertEquals(rootNode.getPath() + "/kind/enkel",
                resEnkel.getResourceMetadata().getResolutionPath());
            assertEquals(selExt,
                resEnkel.getResourceMetadata().getResolutionPathInfo());

            Node resNodeEnkel = resEnkel.adaptTo(Node.class);
            assertNotNull(resNodeEnkel);
            assertEquals(grandchild.getPath(), resNodeEnkel.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    @Test public void test_resolve_with_sling_alias_extension_suffix()
            throws Exception {

        final String selExt = ".html/some/suffx.pdf";

        Node child = rootNode.addNode("child");
        child.setProperty("sling:alias", "kind");

        try {
            saveMappings(session);
            
            // expect kind due to alias and no parent due to mapping
            // the rootPath onto root
            String path = "/kind" + selExt;
            String mapped = resResolver.map(child.getPath() + selExt);
            assertEquals(path, mapped);

            Resource res = resResolver.resolve(null, path);
            Node resNode = res.adaptTo(Node.class);
            assertNotNull(resNode);

            assertEquals(child.getPath(), resNode.getPath());
        } finally {
            child.remove();
            session.save();
        }
    }

    // ---------- internal
    
    private void removeAce(Session adminSession, Principal principal, String absPath) throws Exception{
        
        AccessControlManager accessControlManager = adminSession.getAccessControlManager();
        AccessControlPolicy [] policies = accessControlManager.getPolicies(absPath);

        for (AccessControlPolicy plc : policies) {
            if (plc instanceof AccessControlList) {
                boolean modified = false;
                AccessControlList acl = ((AccessControlList) plc);
                for (AccessControlEntry ace : acl.getAccessControlEntries()) {
                    if (principal.equals(ace.getPrincipal())) {
                        acl.removeAccessControlEntry(ace);
                        modified = true;
                    }
                }
                if (modified) {
                    accessControlManager.setPolicy(absPath, acl);
                }
            }
        }

        if (adminSession.hasPendingChanges()) {
            adminSession.save();
        }
    }
    
    private void testStarResourceHelper(final String path, final String method) {
        final Resource res = resResolver.resolve(
            new FakeSlingHttpServletRequest(path, method), path);
        assertNotNull(res);
        assertTrue(ResourceUtil.isStarResource(res));
        assertEquals("sling:syntheticStarResource", res.getResourceType());
    }
}
