SLING-5537 : Remove deprecated features from JCR Base

git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1731720 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractNamespaceMappingRepository.java b/src/main/java/org/apache/sling/jcr/base/AbstractNamespaceMappingRepository.java
deleted file mode 100644
index 8112cb5..0000000
--- a/src/main/java/org/apache/sling/jcr/base/AbstractNamespaceMappingRepository.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * 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.jcr.base;
-
-import org.apache.sling.jcr.api.NamespaceMapper;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.osgi.framework.BundleContext;
-import org.osgi.util.tracker.ServiceTracker;
-
-import aQute.bnd.annotation.ProviderType;
-
-/**
- * The <code>AbstractNamespaceMappingRepository</code> is an abstract
- * implementation of the {@link SlingRepository} interface which provides
- * default support for namespace mapping.
- *
- * @deprecated as of API version 2.3 (bundle version 2.2.2). Use
- *             {@link NamespaceMappingSupport} or
- *             {@link AbstractSlingRepositoryManager} and
- *             {@link AbstractSlingRepository2} instead.
- */
-@Deprecated
-@ProviderType
-public abstract class AbstractNamespaceMappingRepository extends NamespaceMappingSupport implements SlingRepository {
-
-    private ServiceTracker namespaceMapperTracker;
-
-    @Override
-    protected final NamespaceMapper[] getNamespaceMapperServices() {
-        if (namespaceMapperTracker != null) {
-            // call namespace mappers
-            final Object[] nsMappers = namespaceMapperTracker.getServices();
-            if (nsMappers != null) {
-                NamespaceMapper[] mappers = new NamespaceMapper[nsMappers.length];
-                System.arraycopy(nsMappers, 0, mappers, 0, nsMappers.length);
-                return mappers;
-            }
-        }
-        return null;
-    }
-
-    protected void setup(final BundleContext bundleContext) {
-        super.setup(bundleContext, this);
-        this.namespaceMapperTracker = new ServiceTracker(bundleContext, NamespaceMapper.class.getName(), null);
-        this.namespaceMapperTracker.open();
-    }
-
-    @Override
-    protected void tearDown() {
-        if ( this.namespaceMapperTracker != null ) {
-            this.namespaceMapperTracker.close();
-            this.namespaceMapperTracker = null;
-        }
-        super.tearDown();
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
deleted file mode 100644
index 524e8ac..0000000
--- a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository.java
+++ /dev/null
@@ -1,1200 +0,0 @@
-/*
- * 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.jcr.base;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.Dictionary;
-
-import javax.jcr.Credentials;
-import javax.jcr.LoginException;
-import javax.jcr.NoSuchWorkspaceException;
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
-import javax.jcr.Value;
-import javax.jcr.Workspace;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.base.util.RepositoryAccessor;
-import org.apache.sling.serviceusermapping.ServiceUserMapper;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceFactory;
-import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
-import org.osgi.service.log.LogService;
-import org.slf4j.LoggerFactory;
-
-import aQute.bnd.annotation.ProviderType;
-
-/**
- * The <code>AbstractSlingRepository</code> is an abstract implementation of the
- * {@link SlingRepository} interface which provides default support for attached
- * repositories as well as ensuring live repository connection, reconnecting if
- * needed. Implementations of the <code>SlingRepository</code> interface may
- * wish to extend this class to benefit from a default implementation.
- * <p>
- * As of version 2.2 (bundle version 2.2.0) the registration of repository
- * services based on this abstract base class works differently. To be able to
- * know the calling bundle to implement the
- * {@link #loginService(String, String)} method the service is registered as a
- * service factory. Yet this component is registered as a non-service component
- * with Declarative Services handling its registration itself so the the
- * {@code ServiceFactory} cannot simply create instances of this class. The
- * solution is for the service factory to create a proxy to the actual component
- * object. All method calls are just routed through with the exception of the
- * {@link #loginService(String, String)} method which is routed to a new
- * internal method taking the calling bundle as an additional argument.
- * <p>
- * The changes to support this new registration mechanism are as follows:
- * <ul>
- * <li>The {@link #registerService()} method is now final.</li>
- * <li>The {@link #getServiceRegistrationInterfaces()} and
- * {@link #getServiceRegistrationProperties()} methods have been added and can
- * be overwritten by implementations of this class. The
- * {@link #registerService()} method calls these new methods to get the
- * interfaces and properties for the service registration.</li>
- * </ul>
- * Implementations of this class overwriting the {@link #registerService()}
- * method must replace this overwritten method with overwriting the new
- * {@link #getServiceRegistrationInterfaces()} and/or
- * {@link #getServiceRegistrationProperties()} methods.
- *
- * @deprecated as of API version 2.3 (bundle version 2.2.2). Use
- *             {@link AbstractSlingRepositoryManager} and
- *             {@link AbstractSlingRepository2} instead.
- */
-@Deprecated
-@ProviderType
-@Component(componentAbstract=true)
-public abstract class AbstractSlingRepository
-    extends AbstractNamespaceMappingRepository
-    implements SlingRepository, Runnable {
-
-    public static final String DEFAULT_ANONYMOUS_USER = "anonymous";
-
-    public static final String DEFAULT_ANONYMOUS_PASS = "anonymous";
-
-    public static final String DEFAULT_ADMIN_USER = "admin";
-
-    public static final String DEFAULT_ADMIN_PASS = "admin";
-
-    // For backwards compatibility loginAdministrative is still enabled
-    // In future releases, this default may change to false.
-    public static final boolean DEFAULT_LOGIN_ADMIN_ENABLED = true;
-
-    @Property
-    public static final String PROPERTY_DEFAULT_WORKSPACE = "defaultWorkspace";
-
-    @Property(value=DEFAULT_ANONYMOUS_USER)
-    public static final String PROPERTY_ANONYMOUS_USER = "anonymous.name";
-
-    @Property(value=DEFAULT_ANONYMOUS_PASS)
-    public static final String PROPERTY_ANONYMOUS_PASS = "anonymous.password";
-
-    @Property(value=DEFAULT_ADMIN_USER)
-    public static final String PROPERTY_ADMIN_USER = "admin.name";
-
-    @Property(value=DEFAULT_ADMIN_PASS)
-    public static final String PROPERTY_ADMIN_PASS = "admin.password";
-
-    @Property(boolValue = DEFAULT_LOGIN_ADMIN_ENABLED)
-    public static final String PROPERTY_LOGIN_ADMIN_ENABLED = "admin.login.enabled";
-
-    /**
-     * The default value for the number of seconds to wait between two
-     * consecutive checks while the repository is active (value is 10).
-     */
-    public static final int DEFAULT_POLL_ACTIVE = 10;
-
-    /**
-     * The default value for the number of seconds to wait between two
-     * consecutive checks while the repository is not active (value is 10).
-     */
-    public static final int DEFAULT_POLL_INACTIVE = 10;
-
-    @Property(intValue=DEFAULT_POLL_ACTIVE)
-    public static final String PROPERTY_POLL_ACTIVE = "poll.active";
-
-    @Property(intValue=DEFAULT_POLL_INACTIVE)
-    public static final String PROPERTY_POLL_INACTIVE = "poll.inactive";
-
-    /** The minimum number of seconds allowed for any of the two poll times */
-    public static final int MIN_POLL = 2;
-
-    @Reference
-    private LogService log;
-
-    @Reference()
-    private ServiceUserMapper serviceUserMapper;
-
-    private ComponentContext componentContext;
-
-    private Repository repository;
-
-    private ServiceRegistration repositoryService;
-
-    private String defaultWorkspace;
-
-    private String anonUser;
-
-    private char[] anonPass;
-
-    private String adminUser;
-
-    private char[] adminPass;
-
-    private boolean disableLoginAdministrative;
-
-    // the poll interval used while the repository is not active
-    private long pollTimeInActiveSeconds;
-
-    // the poll interval used while the repository is active
-    private long pollTimeActiveSeconds;
-
-    // whether the repository checker task should be active. this field
-    // is managed by the startRepositoryPinger and stopRepositoryPinger methods
-    private boolean running;
-
-    // the background thread constantly checking the repository
-    private Thread repositoryPinger;
-
-    protected AbstractSlingRepository() {
-    }
-
-    /**
-     * Returns the default workspace, which may be <code>null</code> meaning
-     * to use the repository provided default workspace. Declared final to make
-     * sure the SLING-256 rule is enforced.
-     */
-    @Override
-    public final String getDefaultWorkspace() {
-        return defaultWorkspace;
-    }
-
-    private void setDefaultWorkspace(String defaultWorkspace) {
-        // normalize the default workspace name: trim leading and trailing
-        // blanks and set to null in case the trimmed name is empty
-        if (defaultWorkspace != null) {
-            defaultWorkspace = defaultWorkspace.trim();
-            if (defaultWorkspace.length() == 0) {
-                defaultWorkspace = null;
-            }
-        }
-
-        log(LogService.LOG_DEBUG,
-            "setDefaultWorkspace: Setting the default workspace to "
-                + defaultWorkspace);
-        this.defaultWorkspace = defaultWorkspace;
-    }
-
-    /**
-     * Logs in as an anonymous user. This implementation simply returns the
-     * result of calling {@link #login(Credentials, String)}
-     */
-    @Override
-    public Session login() throws LoginException, RepositoryException {
-        return this.login(null, null);
-    }
-
-    @Override
-    public final Session loginAdministrative(String workspace) throws RepositoryException {
-        if (this.disableLoginAdministrative) {
-            log(LogService.LOG_ERROR, "SlingRepository.loginAdministrative is disabled. Please use SlingRepository.loginService.");
-            throw new LoginException();
-        }
-
-        log(LogService.LOG_WARNING,
-            "SlingRepository.loginAdministrative is deprecated. Please use SlingRepository.loginService.");
-        return loginAdministrativeInternal(workspace);
-    }
-
-    /**
-     * This method always throws {@code LoginException} because it does
-     * not directly have the calling bundle at its disposition to decide
-     * on the required service name.
-     * <p>
-     * This method is final and cannot be overwritten by extensions. See the
-     * class comments for full details on how this works.
-     *
-     * @since 2.2 (bundle version 2.2.0)
-     */
-    @Override
-    public final Session loginService(String subServiceName, String workspace) throws LoginException,
-            RepositoryException {
-        log(LogService.LOG_ERROR,
-            "loginService: Cannot get using Bundle because this SlingRepository service is not a ServiceFactory");
-        throw new LoginException();
-    }
-
-    @Override
-    public Session login(Credentials credentials) throws LoginException,
-            RepositoryException {
-        return this.login(credentials, null);
-    }
-
-    @Override
-    public Session login(String workspace) throws LoginException,
-            NoSuchWorkspaceException, RepositoryException {
-        return this.login(null, workspace);
-    }
-
-    @Override
-    public Session login(Credentials credentials, String workspace)
-            throws LoginException, NoSuchWorkspaceException,
-            RepositoryException {
-
-        // if already stopped, don't retrieve a session
-        if (this.componentContext == null || this.getRepository() == null) {
-            throw new RepositoryException("Sling Repository not ready");
-        }
-
-        if (credentials == null) {
-            credentials = getAnonCredentials(this.anonUser);
-        }
-
-        // check the workspace
-        if (workspace == null) {
-            workspace = this.getDefaultWorkspace();
-        }
-
-        try {
-            log(LogService.LOG_DEBUG, "login: Logging in to workspace '"
-                + workspace + "'");
-            Session session = getRepository().login(credentials, workspace);
-
-            // if the defualt workspace is null, acquire a session from the pool
-            // and use the workspace used as the new default workspace
-            if (workspace == null) {
-                String defaultWorkspace = session.getWorkspace().getName();
-                log(LogService.LOG_DEBUG, "login: Using " + defaultWorkspace
-                    + " as the default workspace instead of 'null'");
-                setDefaultWorkspace(defaultWorkspace);
-            }
-
-            return this.getNamespaceAwareSession(session);
-
-        } catch (NoSuchWorkspaceException nswe) {
-            // if the desired workspace is the default workspace, try to create
-            // (but not if using the repository-supplied default workspace)
-            if (workspace != null
-                && workspace.equals(this.getDefaultWorkspace())
-                && this.createWorkspace(workspace)) {
-                return this.getRepository().login(credentials, workspace);
-            }
-
-            // otherwise (any workspace) or if workspace creation fails
-            // just forward the original exception
-            throw nswe;
-
-        } catch (RuntimeException re) {
-            // SLING-702: Jackrabbit throws IllegalStateException if the
-            // repository has already been shut down ...
-            throw new RepositoryException(re.getMessage(), re);
-        }
-    }
-
-    /**
-     * Actual implementation of the {@link #loginService(String, String)} method
-     * taking into account the bundle calling this method.
-     * <p>
-     * This method is final and cannot be overwritten by extensions. See the
-     * class comments for full details on how this works.
-     *
-     * @param usingBundle The bundle requesting access
-     * @param subServiceName Subservice name (may be {@code null})
-     * @param workspace The workspace to access
-     * @return The session authenticated with the service user
-     * @throws LoginException If authentication fails or if no user is defined
-     *             for the requesting service (bundle)
-     * @throws RepositoryException If a general error occurrs creating the
-     *             session
-     *
-     * @since 2.2 (bundle version 2.2.0)
-     */
-    final Session loginService(final Bundle usingBundle, final String subServiceName, final String workspace)
-            throws LoginException, RepositoryException {
-        final String userName = this.serviceUserMapper.getServiceUserID(usingBundle, subServiceName);
-        if (userName == null) {
-            throw new LoginException("Cannot derive user name for bundle "
-                + usingBundle + " and sub service " + subServiceName);
-        }
-        final SimpleCredentials creds = new SimpleCredentials(userName, new char[0]);
-
-        Session admin = null;
-        try {
-            admin = this.loginAdministrativeInternal(workspace);
-            return admin.impersonate(creds);
-        } finally {
-            if (admin != null) {
-                admin.logout();
-            }
-        }
-    }
-
-    /**
-     * Actual (unprotected) implementation of administrative login.
-     * <p>
-     * This methods is internally used to administratively login.
-     *
-     * @param workspace The workspace to login to (or {@code null} to use the
-     *            {@link #getDefaultWorkspace() default workspace}.
-     * @return The administrative session
-     * @throws RepositoryException if an error occurrs.
-     */
-    protected Session loginAdministrativeInternal(String workspace) throws RepositoryException {
-        Credentials sc = getAdministrativeCredentials(this.adminUser);
-        return this.login(sc, workspace);
-    }
-
-    /**
-     * @param anonUser the user name of the anon user.
-     * @return a Credentials implementation that represents the anon user.
-     */
-    protected Credentials getAnonCredentials(String anonUser) {
-        // NB: this method is overridden in the Jackrabbit Service bundle to avoid using the anon password. SLING-1282
-        return new SimpleCredentials(anonUser, anonPass);
-    }
-
-    /**
-     * @param adminUser the name of the administrative user.
-     * @return a Credentials implementation that represents the administrative user.
-     */
-    protected Credentials getAdministrativeCredentials(String adminUser){
-        // NB: this method is overridden in the Jackrabbit Service bundle to avoid using the admin password. SLING-1282
-        return new SimpleCredentials(adminUser, adminPass);
-    }
-
-
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.jcr.Repository#getDescriptor(java.lang.String)
-     */
-    @Override
-    public String getDescriptor(String name) {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.getDescriptor(name);
-        }
-
-        log(LogService.LOG_ERROR, "getDescriptor: Repository not available");
-        return null;
-    }
-
-    /*
-     * (non-Javadoc)
-     *
-     * @see javax.jcr.Repository#getDescriptorKeys()
-     */
-    @Override
-    public String[] getDescriptorKeys() {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.getDescriptorKeys();
-        }
-
-        log(LogService.LOG_ERROR, "getDescriptorKeys: Repository not available");
-        return new String[0];
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Value getDescriptorValue(String key) {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.getDescriptorValue(key);
-        }
-
-        log(LogService.LOG_ERROR, "getDescriptorValue: Repository not available");
-        return null;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Value[] getDescriptorValues(String key) {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.getDescriptorValues(key);
-        }
-
-        log(LogService.LOG_ERROR, "getDescriptorValues: Repository not available");
-        return null;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isSingleValueDescriptor(String key) {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.isSingleValueDescriptor(key);
-        }
-
-        log(LogService.LOG_ERROR, "isSingleValueDescriptor: Repository not available");
-        return false;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isStandardDescriptor(String key) {
-        Repository repo = getRepository();
-        if (repo != null) {
-            return repo.isStandardDescriptor(key);
-        }
-
-        log(LogService.LOG_ERROR, "isStandardDescriptor: Repository not available");
-        return false;
-    }
-
-    // ---------- logging ------------------------------------------------------
-
-    protected void log(int level, String message) {
-        this.log(level, message, null);
-    }
-
-    protected void log(int level, String message, Throwable t) {
-        LogService log = this.log;
-        if (log != null) {
-            if (componentContext != null) {
-                log.log(componentContext.getServiceReference(), level, message,
-                    t);
-            } else {
-                log.log(level, message, t);
-            }
-        }
-    }
-
-    // ---------- Repository Access -------------------------------------------
-
-    /**
-     * Returns a new instance of the {@link RepositoryAccessor} class to access
-     * a repository over RMI or through JNDI.
-     * <p>
-     * Extensions of this method may return an extension of the
-     * {@link RepositoryAccessor} class if the provide extended functionality.
-     */
-    protected RepositoryAccessor getRepositoryAccessor() {
-        return new RepositoryAccessor();
-    }
-
-    /**
-     * Acquires the repository by calling the
-     * {@link org.apache.sling.jcr.base.util.RepositoryAccessor#getRepositoryFromURL(String)}
-     * with the value of the
-     * {@link org.apache.sling.jcr.base.util.RepositoryAccessor#REPOSITORY_URL_OVERRIDE_PROPERTY}
-     * framework or configuration property. If the property exists and a
-     * repository can be accessed using this property, that repository is
-     * returned. Otherwise <code>null</code> is returned.
-     * <p>
-     * Extensions of this class may overwrite this method with implementation
-     * specific acquisition semantics and may call this base class method or not
-     * as the implementation sees fit.
-     * <p>
-     * This method does not throw any <code>Throwable</code> but instead just
-     * returns <code>null</code> if not repository is available. Any problems
-     * trying to acquire the repository must be caught and logged as
-     * appropriate.
-     *
-     * @return The acquired JCR <code>Repository</code> or <code>null</code>
-     *         if not repository can be acquired.
-     */
-    protected Repository acquireRepository() {
-        // if the environment provides a repository override URL, other settings
-        // are ignored
-        String overrideUrl = (String) componentContext.getProperties().get(
-            RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY);
-        if (overrideUrl == null) {
-            overrideUrl = componentContext.getBundleContext().getProperty(
-                RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY);
-        }
-
-        if (overrideUrl != null && overrideUrl.length() > 0) {
-            log(LogService.LOG_INFO,
-                "acquireRepository: Will not use embedded repository due to property "
-                    + RepositoryAccessor.REPOSITORY_URL_OVERRIDE_PROPERTY + "="
-                    + overrideUrl + ", acquiring repository using that URL");
-            return getRepositoryAccessor().getRepositoryFromURL(overrideUrl);
-        }
-
-        log(LogService.LOG_DEBUG,
-            "acquireRepository: No existing repository to access");
-        return null;
-    }
-
-    /**
-     * This method is called after a repository has been acquired by
-     * {@link #acquireRepository()} but before the repository is registered as a
-     * service.
-     * <p>
-     * Implementations may overwrite this method but MUST call this base class
-     * implementation first.
-     *
-     * @param repository The JCR <code>Repository</code> to setup.
-     */
-    protected void setupRepository(Repository repository) {
-        this.setup(componentContext.getBundleContext());
-    }
-
-    /**
-     * Registers this component as an OSGi service with the types provided by
-     * the {@link #getServiceRegistrationInterfaces()} method and properties
-     * provided by the {@link #getServiceRegistrationProperties()} method.
-     * <p>
-     * As of version 2.2 (bundle version 2.2.0) this method is final and cannot
-     * be overwritten because the mechanism of service registration using a
-     * service factory is required to fully implement the
-     * {@link #loginService(String, String)} method. See the class comments for
-     * full details on how this works.
-     *
-     * @return The OSGi <code>ServiceRegistration</code> object representing the
-     *         registered service.
-     */
-    protected final ServiceRegistration registerService() {
-        final Dictionary<String, Object> props = getServiceRegistrationProperties();
-        final String[] interfaces = getServiceRegistrationInterfaces();
-
-        return componentContext.getBundleContext().registerService(interfaces, new ServiceFactory() {
-            @Override
-            public Object getService(Bundle bundle, ServiceRegistration registration) {
-                return SlingRepositoryProxyHandler.createProxy(interfaces, AbstractSlingRepository.this, bundle);
-            }
-
-            @Override
-            public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
-                // nothing to do (GC does the work for us)
-            }
-        }, props);
-    }
-
-    /**
-     * Return the service registration properties to be used to register the
-     * repository service in {@link #registerService()}.
-     * <p>
-     * This method may be overwritten to return additional service registration
-     * properties. But it is strongly recommended to always include the
-     * properties returned from this method.
-     *
-     * @return The service registration properties to be used to register the
-     *         repository service in {@link #registerService()}
-     *
-     * @since 2.2 (bundle version 2.2.0)
-     */
-    @SuppressWarnings("unchecked")
-    protected Dictionary<String, Object> getServiceRegistrationProperties() {
-        return componentContext.getProperties();
-    }
-
-    /**
-     * Returns the service types to be used to register the repository service
-     * in {@link #registerService()}. All interfaces returned must be accessible
-     * to the class loader of the class of this instance.
-     * <p>
-     * This method may be overwritten to return additional types but the types
-     * returned from this base implementation must always be included.
-     *
-     * @return The service types to be used to register the repository service
-     *         in {@link #registerService()}
-     *
-     * @since 2.2 (bundle version 2.2.0)
-     */
-    protected String[] getServiceRegistrationInterfaces() {
-        return new String[] {
-            SlingRepository.class.getName(), Repository.class.getName()
-        };
-    }
-
-    /**
-     * Returns the repository underlying this instance or <code>null</code> if
-     * no repository is currently being available.
-     */
-    protected Repository getRepository() {
-        return repository;
-    }
-
-    /**
-     * Checks that the given <code>repository</code> is still available. This
-     * implementation tries to get the <code>Repository.SPEC_NAME_DESC</code>
-     * descriptor from the repository and returns <code>true</code> if the
-     * returned value is not <code>null</code>.
-     * <p>
-     * Extensions of this class may overwrite this method to implement different
-     * access checks. The contract of this method must be obeyed, though in a
-     * sense, the <code>true</code> must only be returned if
-     * <code>repository</code> is actually usable.
-     *
-     * @param repository The JCR <code>Repository</code> to check for
-     *            availability.
-     * @return <code>true</code> if <code>repository</code> is not
-     *         <code>null</code> and accessible.
-     */
-    protected boolean pingRepository(Repository repository) {
-        if (repository != null) {
-            try {
-                return repository.getDescriptor(Repository.SPEC_NAME_DESC) != null;
-            } catch (Throwable t) {
-                log(LogService.LOG_DEBUG, "pingRepository: Repository "
-                    + repository + " does not seem to be available any more", t);
-            }
-        }
-
-        // fall back to unavailable
-        return false;
-    }
-
-    /** Ping our current repository and check that admin login (required by Sling) works. */
-    protected boolean pingAndCheck() {
-        if(repository == null) {
-            throw new IllegalStateException("Repository is null");
-        }
-
-        boolean result = false;
-
-        if(pingRepository(repository)) {
-            try {
-                final Session s = loginAdministrativeInternal(getDefaultWorkspace());
-                s.logout();
-                result = true;
-            } catch(RepositoryException re) {
-                log.log(LogService.LOG_INFO, "pingAndCheck; loginAdministrative failed", re);
-            }
-        }
-
-        return result;
-    }
-
-    /**
-     * Unregisters the service represented by the
-     * <code>serviceRegistration</code>.
-     * <p>
-     * This method may be overwritten by extensions of this class as long as it
-     * is made sure, the given service registration is unregistered.
-     */
-    protected void unregisterService(ServiceRegistration serviceRegistration) {
-        serviceRegistration.unregister();
-    }
-
-    /**
-     * Performs any cleanups before the repository is actually disposed off by
-     * the {@link #disposeRepository(Repository)} method.
-     * <p>
-     * This method is meant for cleanup tasks before the repository is actually
-     * disposed off. Extensions of this class may overwrite but must call this
-     * base class implementation.
-     *
-     * @param repository
-     */
-    protected void tearDown(Repository repository) {
-        this.tearDown();
-    }
-
-    /**
-     * Disposes off the given <code>repository</code>. This base class
-     * implementation does nothing. Extensions should overwrite if any special
-     * disposal operation is required.
-     *
-     * @param repository
-     */
-    protected void disposeRepository(Repository repository) {
-        // nothing to do here ...
-    }
-
-    // --------- SCR integration -----------------------------------------------
-
-    protected ComponentContext getComponentContext() {
-        return this.componentContext;
-    }
-
-    /**
-     * This method must be called if overwritten by implementations !!
-     *
-     * @throws nothing, but allow derived classes to throw any Exception
-     */
-    protected void activate(final ComponentContext componentContext) throws Exception {
-        this.componentContext = componentContext;
-
-        @SuppressWarnings("unchecked")
-        Dictionary<String, Object> properties = componentContext.getProperties();
-
-        setDefaultWorkspace(this.getProperty(properties,
-            PROPERTY_DEFAULT_WORKSPACE, null));
-        this.anonUser = this.getProperty(properties, PROPERTY_ANONYMOUS_USER,
-            DEFAULT_ANONYMOUS_USER);
-        this.anonPass = this.getProperty(properties, PROPERTY_ANONYMOUS_PASS,
-            DEFAULT_ANONYMOUS_PASS).toCharArray();
-
-        this.adminUser = this.getProperty(properties, PROPERTY_ADMIN_USER,
-            DEFAULT_ADMIN_USER);
-        this.adminPass = this.getProperty(properties, PROPERTY_ADMIN_PASS,
-            DEFAULT_ADMIN_PASS).toCharArray();
-
-        this.disableLoginAdministrative = !this.getProperty(properties, PROPERTY_LOGIN_ADMIN_ENABLED,
-            DEFAULT_LOGIN_ADMIN_ENABLED);
-
-        setPollTimeActive(getIntProperty(properties, PROPERTY_POLL_ACTIVE));
-        setPollTimeInActive(getIntProperty(properties, PROPERTY_POLL_INACTIVE));
-
-        // immediately try to start the repository while activating
-        // this component instance
-        try {
-            if (startRepository()) {
-                log(LogService.LOG_INFO, "Repository started successfully");
-            } else {
-                log(LogService.LOG_WARNING,
-                    "Repository startup failed, will try later");
-            }
-        } catch (Throwable t) {
-            log(LogService.LOG_WARNING,
-                "activate: Unexpected problem starting repository", t);
-        }
-
-        // launch the background repository checker now
-        startRepositoryPinger();
-    }
-
-    /**
-     * This method must be called if overwritten by implementations !!
-     *
-     * @param componentContext
-     */
-    protected void deactivate(final ComponentContext componentContext) {
-        // stop the background thread
-        stopRepositoryPinger();
-
-        // ensure the repository is really disposed off
-        if (repository != null || repositoryService != null) {
-            log(LogService.LOG_INFO,
-                "deactivate: Repository still running, forcing shutdown");
-
-            try {
-                stopRepository();
-            } catch (Throwable t) {
-                log(LogService.LOG_WARNING,
-                    "deactivate: Unexpected problem stopping repository", t);
-            }
-        }
-
-        this.componentContext = null;
-    }
-
-    protected void bindLog(LogService log) {
-        this.log = log;
-    }
-
-    protected void unbindLog(LogService log) {
-        if (this.log == log) {
-            this.log = null;
-        }
-    }
-
-    // ---------- internal -----------------------------------------------------
-
-    private String getProperty(Dictionary<String, Object> properties,
-            String name, String defaultValue) {
-        Object prop = properties.get(name);
-        return (prop instanceof String) ? (String) prop : defaultValue;
-    }
-
-    private int getIntProperty(Dictionary<String, Object> properties,
-            String name) {
-        Object prop = properties.get(name);
-        if (prop instanceof Number) {
-            return ((Number) prop).intValue();
-        } else if (prop != null) {
-            try {
-                return Integer.decode(String.valueOf(prop)).intValue();
-            } catch (NumberFormatException nfe) {
-                // don't really care
-            }
-        }
-
-        return -1;
-    }
-
-    private boolean getProperty(Dictionary<String, Object> properties, String name, boolean defaultValue) {
-        Object prop = properties.get(name);
-        if (prop instanceof Boolean) {
-            return ((Boolean) prop).booleanValue();
-        } else if (prop instanceof String) {
-            return Boolean.valueOf((String) prop);
-        }
-
-        return defaultValue;
-    }
-
-    private boolean createWorkspace(String workspace) {
-        this.log(LogService.LOG_INFO, "createWorkspace: Requested workspace "
-            + workspace + " does not exist, trying to create");
-
-        Session tmpSession = null;
-        try {
-            Credentials sc = getAdministrativeCredentials(this.adminUser);
-            tmpSession = this.getRepository().login(sc);
-            Workspace defaultWs = tmpSession.getWorkspace();
-            defaultWs.createWorkspace(workspace);
-            return true;
-        } catch (Throwable t) {
-            this.log(LogService.LOG_ERROR,
-                "createWorkspace: Cannot create requested workspace "
-                    + workspace, t);
-        } finally {
-            if (tmpSession != null) {
-                tmpSession.logout();
-            }
-        }
-
-        // fall back to failure
-        return false;
-    }
-
-    // ---------- Background operation checking repository availability --------
-
-    private void setPollTimeActive(int seconds) {
-        if (seconds < MIN_POLL) {
-            seconds = DEFAULT_POLL_ACTIVE;
-        }
-        pollTimeActiveSeconds = seconds;
-    }
-
-    private void setPollTimeInActive(int seconds) {
-        if (seconds < MIN_POLL) {
-            seconds = DEFAULT_POLL_INACTIVE;
-        }
-        pollTimeInActiveSeconds = seconds;
-    }
-
-    private void startRepositoryPinger() {
-        if (repositoryPinger == null) {
-            // make sure the ping will be running
-            running = true;
-
-            // create and start the thread
-            repositoryPinger = new Thread(this, "Repository Pinger");
-            repositoryPinger.start();
-        }
-    }
-
-    private void stopRepositoryPinger() {
-
-        // make sure the thread is terminating
-        running = false;
-
-        // nothing to do if the thread is not running at all
-        Thread rpThread = repositoryPinger;
-        if (rpThread == null) {
-            return;
-        }
-
-        // clear the repositoryPinger thread field
-        repositoryPinger = null;
-
-        // notify the thread for it to be able to shut down
-        synchronized (rpThread) {
-            rpThread.notifyAll();
-        }
-
-        // wait at most 10 seconds for the thread to terminate
-        try {
-            rpThread.join(10000L);
-        } catch (InterruptedException ie) {
-            // don't care here
-        }
-
-        // consider it an error if the thread is still running !!
-        if (rpThread.isAlive()) {
-            log(LogService.LOG_ERROR,
-                "stopRepositoryPinger: Timed waiting for thread " + rpThread
-                    + " to terminate");
-        }
-
-    }
-
-    private boolean startRepository() {
-        try {
-            log(LogService.LOG_DEBUG,
-                "startRepository: calling acquireRepository()");
-            Repository newRepo = acquireRepository();
-            if (newRepo != null) {
-
-                // ensure we really have the repository
-                log(LogService.LOG_DEBUG,
-                    "startRepository: got a Repository, calling pingRepository()");
-                if (pingRepository(newRepo)) {
-                    repository = newRepo;
-
-                    if(pingAndCheck()) {
-                        log(LogService.LOG_DEBUG,
-                            "startRepository: pingRepository() and pingAndCheck() successful, calling setupRepository()");
-                        setupRepository(newRepo);
-
-                        log(LogService.LOG_DEBUG,
-                            "startRepository: calling registerService()");
-                        repositoryService = registerService();
-
-                        log(LogService.LOG_DEBUG,
-                            "registerService() successful, registration="
-                                + repositoryService);
-
-                        return true;
-                    }
-
-                    // ping succeeded but pingAndCheck fail, we have to drop
-                    // the repository in this situation and restart from
-                    // scratch later
-                    log(
-                        LogService.LOG_DEBUG,
-                        "pingRepository() successful but pingAndCheck() fails, calling disposeRepository()");
-
-                    // drop reference
-                    repository = null;
-
-                } else {
-
-                    // otherwise let go of the repository and fail startup
-                    log(LogService.LOG_DEBUG,
-                        "startRepository: pingRepository() failed, calling disposeRepository()");
-
-                }
-
-                // ping or pingAndCheck failed: dispose off repository
-                disposeRepository(newRepo);
-            }
-        } catch (Throwable t) {
-            // consider an uncaught problem an error
-            log(
-                LogService.LOG_ERROR,
-                "startRepository: Uncaught Throwable trying to access Repository, calling stopRepository()",
-                t);
-
-            // repository might be partially started, stop anything left
-            stopRepository();
-        }
-
-        return false;
-    }
-
-    private void stopRepository() {
-        if (repositoryService != null) {
-            try {
-                log(LogService.LOG_DEBUG,
-                    "Unregistering SlingRepository service, registration="
-                        + repositoryService);
-                unregisterService(repositoryService);
-            } catch (Throwable t) {
-                log(
-                    LogService.LOG_INFO,
-                    "stopRepository: Uncaught problem unregistering the repository service",
-                    t);
-            }
-            repositoryService = null;
-        }
-
-        if (repository != null) {
-            Repository oldRepo = repository;
-            repository = null;
-
-            try {
-                tearDown(oldRepo);
-            } catch (Throwable t) {
-                log(
-                    LogService.LOG_INFO,
-                    "stopRepository: Uncaught problem tearing down the repository",
-                    t);
-            }
-
-            try {
-                disposeRepository(oldRepo);
-            } catch (Throwable t) {
-                log(
-                    LogService.LOG_INFO,
-                    "stopRepository: Uncaught problem disposing the repository",
-                    t);
-            }
-        }
-    }
-
-    @Override
-    public void run() {
-        // start polling with a small value to be faster at system startup
-        // we'll increase the polling time after each try
-        long pollTimeMsec = 100L;
-        final long MSEC = 1000L;
-        final int pollTimeFactor = 2;
-        Object waitLock = repositoryPinger;
-
-        try {
-
-            while (running) {
-
-                // wait first before starting to check
-                synchronized (waitLock) {
-                    try {
-                        // no debug logging, see SLING-505
-                        // log(LogService.LOG_DEBUG, "Waiting " + pollTime + " seconds before checking repository");
-                        waitLock.wait(pollTimeMsec);
-                    } catch (InterruptedException ie) {
-                        // don't care, go ahead
-                    }
-                }
-
-                long newPollTime = pollTimeMsec;
-                if (running) {
-
-                    Repository repo = repository;
-                    boolean ok = false;
-                    if (repo == null) {
-                        // No Repository yet, try to start
-                        if (startRepository()) {
-                            log(LogService.LOG_INFO, "Repository started successfully");
-                            ok = true;
-                            newPollTime = pollTimeActiveSeconds * MSEC;
-                        } else {
-                            // ramp up poll time, up to the max of our configured times
-                            newPollTime = Math.min(pollTimeMsec * pollTimeFactor, Math.max(pollTimeInActiveSeconds, pollTimeActiveSeconds) * MSEC);
-                        }
-
-                    } else if (pingAndCheck()) {
-                        ok = true;
-                        newPollTime = pollTimeActiveSeconds * MSEC;
-
-                    } else {
-                        // Repository disappeared
-                        log(LogService.LOG_INFO,
-                            "run: Repository not accessible anymore, unregistering service");
-                        stopRepository();
-                        newPollTime = pollTimeInActiveSeconds * MSEC;
-                    }
-
-                    if(newPollTime != pollTimeMsec) {
-                        pollTimeMsec = newPollTime;
-                        log(LogService.LOG_DEBUG,
-                                "Repository Pinger interval set to " + pollTimeMsec + " msec, repository is "
-                                + (ok ? "available" : "NOT available")
-                                );
-                    }
-                }
-            }
-
-            // thread is terminating due to "running" being set to false
-            log(LogService.LOG_INFO, "Repository Pinger stopping on request");
-
-        } catch (Throwable t) {
-            // try to log the cause for thread termination
-            log(LogService.LOG_ERROR, "Repository Pinger caught unexpected issue", t);
-
-        } finally {
-
-            // whatever goes on, make sure the repository is disposed of
-            // at the end of the thread....
-            log(LogService.LOG_INFO, "Stopping repository on shutdown");
-            stopRepository();
-        }
-    }
-
-    /**
-     * The <code>SlingRepositoryProxyHandler</code> class implements a proxy for all
-     * service interfaces under which the {@link AbstractSlingRepository}
-     * implementation is registered.
-     * <p>
-     * All calls a directly handed through to the object except for the
-     * {@code loginService} call which is routed through
-     * {@code AbstractSlingRepository.loginService(Bundle, String, String)} method
-     * to influence logging in by the calling bundle.
-     *
-     * @since 2.2 (bundle version 2.2.0)
-     */
-    private static class SlingRepositoryProxyHandler implements InvocationHandler {
-
-        // The name of the method to re-route
-        private static final String LOGIN_SERVICE_NAME = "loginService";
-
-        // The delegatee object to which all calls are routed
-        private final AbstractSlingRepository delegatee;
-
-        // The bundle using this proxy service instance
-        private final Bundle usingBundle;
-
-        /**
-         * Creates a new proxy instance for the given {@code delegatee} object. The
-         * proxy is handled by a new instance of this
-         * {@code SlingRepositoryProxyHandler} handler.
-         *
-         * @param interfaceNames The list of interfaces to implement and expose in
-         *            the proxy
-         * @param delegatee The object to which to route all method calls
-         * @param usingBundle The bundle making use of the proxy
-         * @return The proxy to be used by client code or {@code null} if not all
-         *         service interfaces can be loaded by the class loader of the
-         *         {@code delegatee} object.
-         */
-        static Object createProxy(final String[] interfaceNames, final AbstractSlingRepository delegatee,
-                final Bundle usingBundle) {
-
-            // get the interface classes to create the proxy
-            final ClassLoader cl = delegatee.getClass().getClassLoader();
-            final Class<?>[] interfaces = new Class<?>[interfaceNames.length];
-            for (int i = 0; i < interfaces.length; i++) {
-                try {
-                    interfaces[i] = cl.loadClass(interfaceNames[i]);
-                } catch (ClassNotFoundException e) {
-                    LoggerFactory.getLogger(SlingRepositoryProxyHandler.class).error(
-                        "createProxy: Cannot load interface class " + interfaceNames[i], e);
-                    return null;
-                }
-            }
-
-            // create the proxy
-            final InvocationHandler handler = new SlingRepositoryProxyHandler(delegatee, usingBundle);
-            return Proxy.newProxyInstance(cl, interfaces, handler);
-        }
-
-        private SlingRepositoryProxyHandler(final AbstractSlingRepository delegatee, final Bundle usingBundle) {
-            this.delegatee = delegatee;
-            this.usingBundle = usingBundle;
-        }
-
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-            if (SlingRepositoryProxyHandler.LOGIN_SERVICE_NAME.equals(method.getName()) && args != null && args.length == 2) {
-                return this.delegatee.loginService(this.usingBundle, (String) args[0], (String) args[1]);
-            }
-
-            // otherwise forward to the AbstractSlingRepository implementation
-            try {
-                return method.invoke(this.delegatee, args);
-            } catch (InvocationTargetException ite) {
-                throw ite.getTargetException();
-            }
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
index 4de0aad..e292e6f 100644
--- a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
+++ b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepository2.java
@@ -121,26 +121,6 @@
     }
 
     /**
-     * Wraps the given session with support for name spaces defined by bundles
-     * deployed in the OSGi framework. See {@link NamespaceMappingSupport} for
-     * details about namespace support in Sling.
-     * <p>
-     * To fully support namespaces, this method must be called from each
-     * implementation of any of the {@code login} methods implemented by this
-     * class or its extensions.
-     *
-     * @param session The {@code Session} to wrap. This must not be {@code null}
-     * @return The wrapped session
-     * @throws RepositoryException If an error occurrs wrapping the session
-     * @throws NullPointerException If {@code session} is {@code null}
-     * @deprecated as of API version 2.4 (bundle version 2.3)
-     */
-    @Deprecated
-    protected final Session getNamespaceAwareSession(Session session) throws RepositoryException {
-        return this.getSlingRepositoryManager().getNamespaceAwareSession(session);
-    }
-
-    /**
      * Creates an administrative session to access the indicated workspace.
      * <p>
      * This method is called by the {@link #loginAdministrative(String)} and
@@ -286,7 +266,7 @@
             }
 
             final Session session = repository.login(credentials, workspace);
-            return getNamespaceAwareSession(session);
+            return session;
 
         } catch (final RuntimeException re) {
             // SLING-702: Jackrabbit throws IllegalStateException if the
@@ -393,7 +373,7 @@
         }
 
         logger.debug("SlingRepository.loginAdministrative is deprecated. Please use SlingRepository.loginService.");
-        return getNamespaceAwareSession(createAdministrativeSession(workspace));
+        return createAdministrativeSession(workspace);
     }
 
     // Remaining Repository service methods all backed by the actual
diff --git a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
index 66c4f28..fb188e3 100644
--- a/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
+++ b/src/main/java/org/apache/sling/jcr/base/AbstractSlingRepositoryManager.java
@@ -25,6 +25,7 @@
 
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.api.SlingRepositoryInitializer;
+import org.apache.sling.jcr.base.internal.loader.Loader;
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -77,7 +78,7 @@
  * @since API version 2.3 (bundle version 2.2.2)
  */
 @ProviderType
-public abstract class AbstractSlingRepositoryManager extends NamespaceMappingSupport {
+public abstract class AbstractSlingRepositoryManager {
 
     /** default log */
     private final Logger log = LoggerFactory.getLogger(getClass());
@@ -98,6 +99,8 @@
 
     private volatile ServiceTracker repoInitializerTracker;
 
+    private volatile Loader loader;
+
     /**
      * Returns the default workspace, which may be <code>null</code> meaning to
      * use the repository provided default workspace.
@@ -320,8 +323,8 @@
                 this.repository = newRepo;
                 this.masterSlingRepository = this.create(this.bundleContext.getBundle());
 
-                log.debug("start: setting up NamespaceMapping support");
-                this.setup(this.bundleContext, this.masterSlingRepository);
+                log.debug("start: setting up Loader");
+                this.loader = new Loader(this.masterSlingRepository, this.bundleContext);
 
                 log.debug("start: calling SlingRepositoryInitializer");
                 Throwable t = null;
@@ -401,8 +404,12 @@
                     Repository oldRepo = repository;
                     repository = null;
 
-                    // stop namespace support
-                    this.tearDown();
+                    // stop loader
+                    if ( this.loader != null ) {
+                        this.loader.dispose();
+                        this.loader = null;
+                    }
+                    // destroy repository
                     this.destroy(this.masterSlingRepository);
 
                     try {
diff --git a/src/main/java/org/apache/sling/jcr/base/NamespaceMappingSupport.java b/src/main/java/org/apache/sling/jcr/base/NamespaceMappingSupport.java
deleted file mode 100644
index ecc6728..0000000
--- a/src/main/java/org/apache/sling/jcr/base/NamespaceMappingSupport.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.jcr.base;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.sling.jcr.api.NamespaceMapper;
-import org.apache.sling.jcr.api.SlingRepository;
-import org.apache.sling.jcr.base.SessionProxyHandler.SessionProxyInvocationHandler;
-import org.apache.sling.jcr.base.internal.loader.Loader;
-import org.osgi.framework.BundleContext;
-
-import aQute.bnd.annotation.ProviderType;
-
-/**
- * The <code>NamespaceMappingSupport</code> is an abstract base class for
- * implementing support for dynamic namespace mapping in {@code SlingRepository}
- * instances.
- *
- * @see AbstractSlingRepositoryManager
- * @since API version 2.3 (bundle version 2.2.2)
- * @deprecated as of API version 2.4 (bundle version 2.3)
- */
-@Deprecated
-@ProviderType
-public abstract class NamespaceMappingSupport {
-
-    /** Namespace handler. */
-    private Loader namespaceHandler;
-
-    /** Session proxy handler. */
-    private SessionProxyHandler sessionProxyHandler;
-
-    /**
-     * Returns the {@code NamespaceMapper} services used by the
-     * {@link #getNamespaceAwareSession(Session)} method to define custom
-     * namespaces on sessions.
-     *
-     * @return the {@code NamespaceMapper} services or {@code null} if there are
-     *         none.
-     */
-    protected abstract NamespaceMapper[] getNamespaceMapperServices();
-
-    private SessionProxyHandler getSessionProxyHandler() {
-        return this.sessionProxyHandler;
-    }
-
-    private Loader getLoader() {
-        return this.namespaceHandler;
-    }
-
-    /**
-     * Sets up the namespace mapping support. This method is called by
-     * implementations of this class after having started (or acquired) the
-     * backing JCR repository instance.
-     * <p>
-     * This method may be overwritten but must be called from overwriting
-     * methods.
-     *
-     * @param bundleContext The OSGi {@code BundleContext} to access the
-     *            framework for namespacing setup
-     * @param repository The {@code SlingRepository} to register namespaces on
-     */
-    protected void setup(final BundleContext bundleContext, final SlingRepository repository) {
-        this.sessionProxyHandler = new SessionProxyHandler(this);
-        this.namespaceHandler = new Loader(repository, bundleContext);
-    }
-
-    /**
-     * Terminates namespace mapping support. This method is called by the
-     * implementations of this class before stopping (or letting go of) the
-     * backing JCR repository instance.
-     * <p>
-     * This method may be overwritten but must be called from overwriting
-     * methods.
-     */
-    protected void tearDown() {
-        if (this.namespaceHandler != null) {
-            this.namespaceHandler.dispose();
-            this.namespaceHandler = null;
-        }
-        this.sessionProxyHandler = null;
-    }
-
-    /**
-     * Helper method to dynamically define namespaces on the given session
-     * <p>
-     * This method is package private to allow to be accessed from the
-     * {@link SessionProxyInvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])}
-     * method.
-     *
-     * @param session The JCR {@code Session} to define name spaces on
-     * @throws RepositoryException if an error occurrs defining the name spaces
-     */
-    final void defineNamespacePrefixes(final Session session) throws RepositoryException {
-        final Loader localHandler = this.getLoader();
-        if (localHandler != null) {
-            // apply namespace mapping
-            localHandler.defineNamespacePrefixes(session);
-        }
-
-        // call namespace mappers
-        final NamespaceMapper[] nsMappers = getNamespaceMapperServices();
-        if (nsMappers != null) {
-            for (int i = 0; i < nsMappers.length; i++) {
-                nsMappers[i].defineNamespacePrefixes(session);
-            }
-        }
-    }
-
-    /**
-     * Return a namespace aware session.
-     * <p>
-     * This method must be called for each JCR {@code Session} to be returned
-     * from any of the repository {@code login} methods which are expected to
-     * support dynamically mapped namespaces.
-     *
-     * @param session The session convert into a namespace aware session
-     * @return The namespace aware session
-     * @throws RepositoryException If an error occurrs making the session
-     *             namespace aware
-     */
-    protected final Session getNamespaceAwareSession(final Session session) throws RepositoryException {
-        if (session == null) { // sanity check
-            return null;
-        }
-        defineNamespacePrefixes(session);
-
-        // to support namespace prefixes if session.impersonate is called
-        // we have to use a proxy
-        final SessionProxyHandler localHandler = this.getSessionProxyHandler();
-        if (localHandler != null) {
-            return localHandler.createProxy(session);
-        }
-        return session;
-    }
-}
diff --git a/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java b/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
deleted file mode 100644
index 5d8ab9c..0000000
--- a/src/main/java/org/apache/sling/jcr/base/SessionProxyHandler.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.jcr.base;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.jcr.Credentials;
-import javax.jcr.Session;
-
-/**
- * The session proxy handler creates session proxies to handle
- * the namespace mapping support if impersonate is called on
- * the session.
- * <p>
- * This class is not really part of the API is not intended to be used
- * directly by consumers or implementors of this API. It is used internally
- * to support namespace mapping.
- * @deprecated as of API version 2.4 (bundle version 2.3)
- */
-@Deprecated
-public class SessionProxyHandler  {
-
-    /** The array of proxied interfaces. */
-    private Class<?>[] interfaces;
-
-    /** The namespaceSupport */
-    private final NamespaceMappingSupport namespaceSupport;
-
-    public SessionProxyHandler(final NamespaceMappingSupport namespaceSupport) {
-        this.namespaceSupport = namespaceSupport;
-    }
-
-    /** Calculate the interfaces.
-     * This is done only once - we simply assume that the same namespaceSupport is
-     * emitting session from the same class.
-     */
-    private Class<?>[] getInterfaces(final Class<?> sessionClass) {
-        if ( interfaces == null ) {
-            synchronized ( SessionProxyHandler.class ) {
-                if ( interfaces == null ) {
-                    final HashSet<Class<?>> workInterfaces = new HashSet<Class<?>>();
-
-                    // Get *all* interfaces
-                    guessWorkInterfaces( sessionClass, workInterfaces );
-
-                    this.interfaces = workInterfaces.toArray( new Class[workInterfaces.size()] );
-
-                }
-            }
-        }
-        return interfaces;
-    }
-
-    /**
-     * Create a proxy for the session.
-     */
-    public Session createProxy(final Session session) {
-        final Class<?> sessionClass = session.getClass();
-        final Class<?>[] interfaces = getInterfaces(sessionClass);
-        return (Session)Proxy.newProxyInstance(sessionClass.getClassLoader(),
-                interfaces,
-                new SessionProxyInvocationHandler(session, this.namespaceSupport, interfaces));
-
-    }
-
-
-    public static final class SessionProxyInvocationHandler implements InvocationHandler {
-        private final Session delegatee;
-        private final NamespaceMappingSupport namespaceSupport;
-        private final Class<?>[] interfaces;
-
-        public SessionProxyInvocationHandler(final Session delegatee,
-                            final NamespaceMappingSupport namespaceSupport,
-                            final Class<?>[] interfaces) {
-            this.delegatee = delegatee;
-            this.namespaceSupport = namespaceSupport;
-            this.interfaces = interfaces;
-        }
-
-        /**
-         * @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
-         */
-        @Override
-        public Object invoke(Object proxy, Method method, Object[] args)
-        throws Throwable {
-            if ( method.getName().equals("impersonate") && args != null && args.length == 1) {
-                final Session session = this.delegatee.impersonate((Credentials)args[0]);
-                this.namespaceSupport.defineNamespacePrefixes(session);
-                final Class<?> sessionClass = session.getClass();
-                return Proxy.newProxyInstance(sessionClass.getClassLoader(),
-                        interfaces,
-                        new SessionProxyInvocationHandler(session, this.namespaceSupport, interfaces));
-            }
-            try {
-                return method.invoke(this.delegatee, args);
-            } catch (InvocationTargetException ite) {
-                throw ite.getTargetException();
-            }
-        }
-    }
-
-    /**
-     * Get a list of interfaces to proxy by scanning through
-     * all interfaces a class implements.
-     *
-     * @param clazz           the class
-     * @param workInterfaces  the set of current work interfaces
-     */
-    private void guessWorkInterfaces( final Class<?> clazz,
-                                      final Set<Class<?>> workInterfaces ) {
-        if ( null != clazz ) {
-            addInterfaces( clazz.getInterfaces(), workInterfaces );
-
-            guessWorkInterfaces( clazz.getSuperclass(), workInterfaces );
-        }
-    }
-
-    /**
-     * Get a list of interfaces to proxy by scanning through
-     * all interfaces a class implements.
-     *
-     * @param classInterfaces the array of interfaces
-     * @param workInterfaces  the set of current work interfaces
-     */
-    private void addInterfaces( final Class<?>[] classInterfaces,
-                                final Set<Class<?>> workInterfaces ) {
-        for ( int i = 0; i < classInterfaces.length; i++ ) {
-            workInterfaces.add( classInterfaces[i] );
-            addInterfaces(classInterfaces[i].getInterfaces(), workInterfaces);
-        }
-    }
-}
diff --git a/src/main/java/org/apache/sling/jcr/base/internal/loader/Loader.java b/src/main/java/org/apache/sling/jcr/base/internal/loader/Loader.java
index 809a02e..298d15b 100644
--- a/src/main/java/org/apache/sling/jcr/base/internal/loader/Loader.java
+++ b/src/main/java/org/apache/sling/jcr/base/internal/loader/Loader.java
@@ -33,7 +33,6 @@
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 
-import org.apache.sling.jcr.api.NamespaceMapper;
 import org.apache.sling.jcr.api.SlingRepository;
 import org.apache.sling.jcr.base.NodeTypeLoader;
 import org.osgi.framework.Bundle;
@@ -47,7 +46,7 @@
 /**
  * The <code>Loader</code> TODO
  */
-public class Loader implements NamespaceMapper, BundleListener {
+public class Loader implements BundleListener {
 
     public static final String NODETYPES_BUNDLE_HEADER = "Sling-Nodetypes";
 
@@ -63,9 +62,6 @@
     // bundles whose registration failed and should be retried
     private final List<Bundle> delayedBundles;
 
-    /** Namespace prefix table. */
-    private final Map<Long, NamespaceEntry[]> namespaceTable = new HashMap<Long, NamespaceEntry[]>();
-
     public Loader(final SlingRepository repository, final BundleContext bundleContext) {
         this.bundleContext = bundleContext;
         this.slingRepository = repository;
@@ -91,43 +87,39 @@
 
     //---------- NamespaceMapper interface
 
-    public void defineNamespacePrefixes(Session session)
+    private void defineNamespacePrefixes(final Session session, final List<NamespaceEntry> entries)
     throws RepositoryException {
-        final Iterator<NamespaceEntry[]> iter = this.namespaceTable.values().iterator();
-        while ( iter.hasNext() ) {
-            final NamespaceEntry[] entries = iter.next();
-            for(int i=0; i<entries.length; i++) {
+        for(final NamespaceEntry entry : entries) {
 
-                // the namespace prefixing is a little bit tricky:
-                String mappedPrefix = null;
-                // first, we check if the namespace is registered with a prefix
+            // the namespace prefixing is a little bit tricky:
+            String mappedPrefix = null;
+            // first, we check if the namespace is registered with a prefix
+            try {
+                mappedPrefix = session.getNamespacePrefix(entry.namespace);
+            } catch (NamespaceException ne) {
+                // the namespace is not registered yet, so we should do this
+                // can we directly use the desired prefix?
+                mappedPrefix = entry.prefix + "_new";
                 try {
-                    mappedPrefix = session.getNamespacePrefix(entries[i].namespace);
+                    session.getNamespaceURI(entry.prefix);
+                } catch (NamespaceException ne2) {
+                    // as an exception occured we can directly use the new prefix
+                    mappedPrefix = entry.prefix;
+                }
+                session.getWorkspace().getNamespaceRegistry().registerNamespace(mappedPrefix, entry.namespace);
+            }
+            // do we have to remap?
+            if ( mappedPrefix != null && !mappedPrefix.equals(entry.prefix ) ) {
+                // check if the prefix is already used?
+                String oldUri = null;
+                try {
+                    oldUri = session.getNamespaceURI(entry.prefix);
+                    session.setNamespacePrefix(entry.prefix + "_old", oldUri);
                 } catch (NamespaceException ne) {
-                    // the namespace is not registered yet, so we should do this
-                    // can we directly use the desired prefix?
-                    mappedPrefix = entries[i].prefix + "_new";
-                    try {
-                        session.getNamespaceURI(entries[i].prefix);
-                    } catch (NamespaceException ne2) {
-                        // as an exception occured we can directly use the new prefix
-                        mappedPrefix = entries[i].prefix;
-                    }
-                    session.getWorkspace().getNamespaceRegistry().registerNamespace(mappedPrefix, entries[i].namespace);
+                    // ignore: prefix is not used
                 }
-                // do we have to remap?
-                if ( mappedPrefix != null && !mappedPrefix.equals(entries[i].prefix ) ) {
-                    // check if the prefix is already used?
-                    String oldUri = null;
-                    try {
-                        oldUri = session.getNamespaceURI(entries[i].prefix);
-                        session.setNamespacePrefix(entries[i].prefix + "_old", oldUri);
-                    } catch (NamespaceException ne) {
-                        // ignore: prefix is not used
-                    }
-                    // finally set prefix
-                    session.setNamespacePrefix(entries[i].prefix, entries[i].namespace);
-                }
+                // finally set prefix
+                session.setNamespacePrefix(entry.prefix, entry.namespace);
             }
         }
     }
@@ -142,6 +134,7 @@
      * @param event The <code>BundleEvent</code> representing the bundle state
      *            change.
      */
+    @Override
     public final void bundleChanged(BundleEvent event) {
         // Take care: This is synchronous - take care to not block the system !!
         switch (event.getType()) {
@@ -162,7 +155,6 @@
     //---------- internal
 
     private void registerBundle(Bundle bundle) {
-        this.registerNamespaces(bundle);
         if (this.registerBundleInternal(bundle, false)) {
             // handle delayed bundles, might help now
             int currentSize = -1;
@@ -183,7 +175,6 @@
     }
 
     private void unregisterBundle(Bundle bundle) {
-        this.unregisterNamespaces(bundle);
         synchronized (delayedBundles) {
             delayedBundles.remove(bundle);
         }
@@ -198,7 +189,7 @@
      * Register namespaces defined in the bundle in the namespace table.
      * @param bundle The bundle.
      */
-    private void registerNamespaces(Bundle bundle) {
+    private void registerNamespaces(Bundle bundle) throws RepositoryException {
         final String definition = (String) bundle.getHeaders().get(NAMESPACES_BUNDLE_HEADER);
         if ( definition != null ) {
             log.debug("registerNamespaces: Bundle {} tries to register: {}",
@@ -219,21 +210,19 @@
                 }
             }
             if ( entries.size() > 0 ) {
-                this.namespaceTable.put(bundle.getBundleId(), entries.toArray(new NamespaceEntry[entries.size()]));
+                final Session session = this.getSession();
+                try {
+                    this.defineNamespacePrefixes(session, entries);
+                } finally {
+                    this.ungetSession(session);
+                }
             }
         }
     }
 
-    /**
-     * Unregister namespaces defined in the bundle.
-     * @param bundle The bundle.
-     */
-    protected void unregisterNamespaces(Bundle bundle) {
-        this.namespaceTable.remove(bundle.getBundleId());
-    }
-
     private boolean registerBundleInternal (Bundle bundle, boolean isRetry) {
         try {
+            this.registerNamespaces(bundle);
             if (this.registerNodeTypes(bundle, isRetry)) {
                 return true;
             }
diff --git a/src/main/java/org/apache/sling/jcr/base/package-info.java b/src/main/java/org/apache/sling/jcr/base/package-info.java
index e6f6233..2be8ae8 100644
--- a/src/main/java/org/apache/sling/jcr/base/package-info.java
+++ b/src/main/java/org/apache/sling/jcr/base/package-info.java
@@ -24,16 +24,8 @@
  * manage the actual JCR repository instance and
  * {@link org.apache.sling.jcr.base.AbstractSlingRepository2} being the
  * basis for the repository service instance handed to using bundles.
- * <p>
- * The old {@link org.apache.sling.jcr.base.AbstractSlingRepository}
- * class is being deprecated in favor of the new method of providing access
- * to JCR repositories. Likewise the
- * {@link org.apache.sling.jcr.base.AbstractNamespaceMappingRepository} is
- * deprecated in favor of the new
- * {@link org.apache.sling.jcr.base.NamespaceMappingSupport} abstract class
- * and said repository manager.
  */
-@Version("2.4")
+@Version("3.0")
 package org.apache.sling.jcr.base;
 
 import aQute.bnd.annotation.Version;
diff --git a/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java b/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
index 2b52c7f..3b6aa89 100644
--- a/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
+++ b/src/test/java/org/apache/sling/jcr/base/MockSlingRepositoryManager.java
@@ -26,19 +26,18 @@
 import javax.jcr.Repository;
 import javax.jcr.RepositoryException;
 
-import org.apache.sling.jcr.api.NamespaceMapper;
 import org.apache.sling.serviceusermapping.ServiceUserMapper;
 import org.osgi.framework.Bundle;
 
-/** Minimal AbstractSlingRepositoryManager used for testing */ 
+/** Minimal AbstractSlingRepositoryManager used for testing */
 class MockSlingRepositoryManager extends AbstractSlingRepositoryManager {
-    
+
     private final Repository repository;
-    
+
     MockSlingRepositoryManager(Repository repository) {
         this.repository = repository;
     }
-    
+
     @Override
     protected ServiceUserMapper getServiceUserMapper() {
         return null;
@@ -73,9 +72,4 @@
     @Override
     protected void disposeRepository(Repository repository) {
     }
-
-    @Override
-    protected NamespaceMapper[] getNamespaceMapperServices() {
-        return new NamespaceMapper[0];
-    }
 }
\ No newline at end of file
diff --git a/src/test/java/org/apache/sling/jcr/base/SessionProxyHandlerTest.java b/src/test/java/org/apache/sling/jcr/base/SessionProxyHandlerTest.java
deleted file mode 100644
index 4443866..0000000
--- a/src/test/java/org/apache/sling/jcr/base/SessionProxyHandlerTest.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * 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.jcr.base;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.doReturn;
-
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.sling.testing.mock.jcr.MockJcr;
-import org.junit.Test;
-import org.mockito.Mockito;
-
-public class SessionProxyHandlerTest {
-
-    /**
-     * Method verifies that session proxy with given repository manager could be created
-     * and proxy instance is a kind of <code>SessionProxyHandler.SessionProxyInvocationHandler</code>
-     * class.
-     */
-    @Test
-    public void testProxy() throws RepositoryException {
-        /* Create a new mockSession and mock it to return another one on impersonate() method call,
-         * since impersonate method doesn't implemented.
-         */
-        Session session = Mockito.spy(MockJcr.newSession("admin", "adminSpace"));
-        Session imperSession = MockJcr.newSession("test", "testSpace");
-        doReturn(imperSession).when(session).impersonate(null);
-
-        //Create a proxy handle and proxy session
-        SessionProxyHandler proxyHandler = new SessionProxyHandler(new MockSlingRepositoryManager(null));
-        Session proxySession = proxyHandler.createProxy(session);
-
-        //sessionForTest is a proxy which contains a link to the imperSession object
-        Session sessionForTest = proxySession.impersonate(null);
-        InvocationHandler handler = Proxy.getInvocationHandler(sessionForTest);
-
-        /* Checking that proxySession is a kind of SessionProxyHandler.SessionProxyInvocationHandler class.
-         * So we sure that proxy object creation works fine.
-         */
-        assertEquals(SessionProxyHandler.SessionProxyInvocationHandler.class, handler.getClass());
-
-        //Checking that others methods of proxy object works also well and doesn't call impersonate method
-        assertNotNull(sessionForTest.getRootNode());
-        assertNotNull(sessionForTest.getRepository());
-    }
-}