diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/Activator.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/Activator.java
new file mode 100644
index 0000000..2e4f012
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/Activator.java
@@ -0,0 +1,68 @@
+/*
+ * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     Nuxeo - initial API and implementation
+ */
+
+package org.nuxeo.ecm.core.opencmis.bindings;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+
+/**
+ * This bundle activator insures that the init sequence happens in the right order.
+ */
+public class Activator implements BundleActivator, FrameworkListener {
+
+    private static final Log log = LogFactory.getLog(Activator.class);
+
+    /*
+     * Called when our bundle is started. All we do is ask for an event when the
+     * entire Framework is ready.
+     *
+     * @see
+     * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+     * )
+     */
+    @Override
+    public void start(BundleContext context) throws Exception {
+        context.addFrameworkListener(this);
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+
+    }
+
+    /*
+     * This is the point where the initialization actually occurs. This is
+     * called by the framework when it's finished initializing and we echo that
+     * message to the object that we have delayed.
+     */
+    @Override
+    public void frameworkEvent(FrameworkEvent event) {
+        try {
+            if (event.getType() == FrameworkEvent.STARTED) {
+                ContextListenerDelayer.activate(event);
+            }
+        } catch (Exception e) {
+            log.error("Unable to initialize/configure the Cmis service", e);
+        }
+    }
+
+}
diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/ContextListenerDelayer.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/ContextListenerDelayer.java
new file mode 100644
index 0000000..7822058
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/ContextListenerDelayer.java
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2010 Nuxeo SAS (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ *     Nuxeo - initial API and implementation
+ */
+
+package org.nuxeo.ecm.core.opencmis.bindings;
+
+import java.util.ArrayList;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+import org.osgi.framework.FrameworkEvent;
+
+/**
+ * This class is just a wrapper to hold the initialization of Nuxeo Cmis
+ * until we have received the "go ahead"
+ * from the Runtime and that everything is fully initialized.
+ *
+ */
+public class ContextListenerDelayer implements ServletContextListener {
+
+    /*
+     * this is the true object but because of differences in initialization
+     * sequence we have to delay this until nuxeo is fully up and all the user's
+     * configuration files have been loaded into extension points
+     */
+
+    protected NuxeoCmisContextListener delayed = new NuxeoCmisContextListener();
+
+    /*
+     * Saved from the original call so we can feed it to the true object later
+     */
+    protected ServletContextEvent delayedEvent;
+
+    /*
+     * We don't call the constructor directly -- the servlet container does so
+     * we have to hold a list of all the objects of this type created. this
+     * number should be 1, be we track "all of them" just in case.
+     */
+    private static ArrayList<ContextListenerDelayer> created = new ArrayList<ContextListenerDelayer>();
+
+    /*
+     * We have to keep track of whether or not activate has been called already
+     * because in some packagings (jetty) the framework ready method is called
+     * BEFORE the war container instantiates the objects. Sigh.
+     */
+    protected static boolean hasBeenActivated = false;
+
+    /*
+     * No need to delay this method.
+     */
+    @Override
+    public void contextDestroyed(ServletContextEvent sce) {
+        delayed.contextDestroyed(sce);
+    }
+
+    /*
+     * Make the list of all objects created of this type.
+     */
+    public ContextListenerDelayer() {
+        created.add(this);
+    }
+
+    /*
+     * This is where the true object expects to be initialzed but we prevent it.
+     */
+    @Override
+    public void contextInitialized(ServletContextEvent sce) {
+        delayedEvent = sce;
+        if (hasBeenActivated) {
+            // we are running AFTER the framework is created so no
+            // sense in delaying further
+            delayed.contextInitialized(sce);
+        }
+    }
+
+    /*
+     * Do the work that should have happened at contextInitialized() now if the
+     * Framework is fully up.
+     */
+    public void frameworkEvent(FrameworkEvent event) {
+        if (delayedEvent == null) {
+            // OSGi activation done before ServletContextListener init
+            // will initialize later as a standard ServletContextListener
+            return;
+        }
+        if (event.getType() == FrameworkEvent.STARTED) {
+            delayed.contextInitialized(delayedEvent);
+        }
+    }
+
+    /*
+     * Walk the list of objects of this type we have created echoing the
+     * framework event. Note: This method is static!
+     */
+
+    public static void activate(FrameworkEvent event) {
+        // this list will be size 0 if no objects were created
+        // before the framework is ready, thus we use the
+        // has been activated flag
+        for (ContextListenerDelayer delayer : created) {
+            delayer.frameworkEvent(event);
+        }
+        hasBeenActivated = true;
+    }
+
+}
diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisContextListener.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisContextListener.java
index 4f452e0..aae1dab 100644
--- a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisContextListener.java
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisContextListener.java
@@ -16,12 +16,17 @@ import javax.servlet.ServletContextListener;
 
 import org.apache.chemistry.opencmis.commons.server.CmisServiceFactory;
 import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuxeo.runtime.api.Framework;
 
 /**
  * Servlet context listener that sets up the CMIS service factory in the servlet
  * context as expected by
  * {@link org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet}
  * or
+ * {@link org.apache.chemistry.opencmis.server.impl.browser.CmisBrowserBindingServlet}
+ * or
  * {@link org.apache.chemistry.opencmis.server.impl.webservices.AbstractService}
  * .
  *
@@ -29,12 +34,20 @@ import org.apache.chemistry.opencmis.server.impl.CmisRepositoryContextListener;
  */
 public class NuxeoCmisContextListener implements ServletContextListener {
 
+    private static final Log log = LogFactory.getLog(NuxeoCmisContextListener.class);
+    
     @Override
     public void contextInitialized(ServletContextEvent sce) {
-        CmisServiceFactory factory = new NuxeoCmisServiceFactory();
-        factory.init(null);
-        sce.getServletContext().setAttribute(
-                CmisRepositoryContextListener.SERVICES_FACTORY, factory);
+        try {
+            NuxeoCmisServiceFactoryManager manager = 
+                    Framework.getService(NuxeoCmisServiceFactoryManager.class);
+            CmisServiceFactory factory = manager.getNuxeoCmisServiceFactory();
+            sce.getServletContext().setAttribute(
+                    CmisRepositoryContextListener.SERVICES_FACTORY, factory);            
+        } catch (Exception e) {
+            log.error("NuxeoCmisContextListener caught exception during initialization", e);
+            throw new RuntimeException(e);
+        }        
     }
 
     @Override
diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactory.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactory.java
index 8ba76b4..cf21f03 100644
--- a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactory.java
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactory.java
@@ -20,7 +20,9 @@ import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentExcep
 import org.apache.chemistry.opencmis.commons.impl.server.AbstractServiceFactory;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
 import org.apache.chemistry.opencmis.commons.server.CmisService;
-import org.apache.chemistry.opencmis.server.support.CmisServiceWrapper;
+import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService;
+import org.apache.chemistry.opencmis.server.support.wrapper.CmisServiceWrapperManager;
+import org.apache.chemistry.opencmis.server.support.wrapper.ConformanceCmisServiceWrapper;
 import org.apache.commons.lang.StringUtils;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepositories;
@@ -32,6 +34,8 @@ import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
  * Called for each method dispatch by
  * {@link org.apache.chemistry.opencmis.server.impl.atompub.CmisAtomPubServlet}
  * or
+ * {@link org.apache.chemistry.opencmis.server.impl.atompub.CmisBrowserBindingServlet}
+ * or
  * {@link org.apache.chemistry.opencmis.server.impl.webservices.AbstractService}.
  */
 public class NuxeoCmisServiceFactory extends AbstractServiceFactory {
@@ -43,9 +47,16 @@ public class NuxeoCmisServiceFactory extends AbstractServiceFactory {
 
     protected Map<String, NuxeoRepository> repositories;
 
+    private CmisServiceWrapperManager wrapperManager;
+    
     @Override
     public void init(Map<String, String> parameters) {
         repositories = Collections.synchronizedMap(new HashMap<String, NuxeoRepository>());
+
+        wrapperManager = new CmisServiceWrapperManager();
+        wrapperManager.addWrappersFromServiceFactoryParameters(parameters);
+        wrapperManager.addOuterWrapper(ConformanceCmisServiceWrapper.class,
+                DEFAULT_TYPES_MAX_ITEMS, DEFAULT_TYPES_DEPTH, DEFAULT_MAX_ITEMS, DEFAULT_DEPTH);
     }
 
     @Override
@@ -56,26 +67,26 @@ public class NuxeoCmisServiceFactory extends AbstractServiceFactory {
     @Override
     public CmisService getService(CallContext context) {
         String repositoryId = context.getRepositoryId();
-        NuxeoRepository repository;
-        if (StringUtils.isEmpty(repositoryId)) {
-            repository = null;
-        } else {
+        NuxeoRepository repository = null;
+        if (!StringUtils.isEmpty(repositoryId)) {
             repository = NuxeoRepositories.getRepository(repositoryId);
             if (repository == null) {
                 throw new CmisInvalidArgumentException("No such repository: "
                         + repositoryId);
             }
         }
-        NuxeoCmisService service = new NuxeoCmisService(repository, context);
-        if (repository != null && service.getCoreSession() == null) {
+        NuxeoCmisService nuxeoCmisService = new NuxeoCmisService(repository);
+        CallContextAwareCmisService service =
+                (CallContextAwareCmisService) wrapperManager.wrap(nuxeoCmisService);
+
+        // hand over the call context to the service object
+        service.setCallContext(context);
+        if (repository != null && nuxeoCmisService.getCoreSession() == null) {
             throw new CmisInvalidArgumentException("No such repository: "
                     + repositoryId);
         }
 
-        // wrap the service to provide default parameter checks
-        return new CmisServiceWrapper<NuxeoCmisService>(service,
-                DEFAULT_TYPES_MAX_ITEMS, DEFAULT_TYPES_DEPTH,
-                DEFAULT_MAX_ITEMS, DEFAULT_DEPTH);
+        return service;
     }
 
 }
diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryDescriptor.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryDescriptor.java
new file mode 100644
index 0000000..d53ee07
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryDescriptor.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ */
+package org.nuxeo.ecm.core.opencmis.bindings;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.nuxeo.common.xmap.annotation.XNode;
+import org.nuxeo.common.xmap.annotation.XNodeMap;
+import org.nuxeo.common.xmap.annotation.XObject;
+
+/**
+ * Nuxeo CmisServiceFactory Descriptor.
+ */
+@XObject(value = "factory")
+public class NuxeoCmisServiceFactoryDescriptor {
+
+    @XNode("@name")
+    protected String name;
+
+    @XNode("@class")
+    private Class<? extends NuxeoCmisServiceFactory> factoryClass;
+
+    public Class<? extends NuxeoCmisServiceFactory> getFactoryClass() {
+        return factoryClass == null 
+                ? NuxeoCmisServiceFactory.class : factoryClass;
+    }
+
+    public void setNuxeoCmisServiceFactoryClass(Class<? extends NuxeoCmisServiceFactory> klass) {
+        factoryClass = klass;
+    }
+    
+    @XNodeMap(value = "parameter", key = "@name", type = HashMap.class, componentType = String.class)
+    public Map<String, String> factoryParameters = new HashMap<String, String>();
+
+    public NuxeoCmisServiceFactoryDescriptor() {
+    }
+
+    /** Copy constructor. */
+    public NuxeoCmisServiceFactoryDescriptor(NuxeoCmisServiceFactoryDescriptor other) {
+        factoryClass = other.factoryClass;
+        factoryParameters = new HashMap<String, String>(other.factoryParameters);
+    }
+
+    public void merge(NuxeoCmisServiceFactoryDescriptor other) {
+        if (other.factoryClass != null) {
+            factoryClass = other.factoryClass;
+        }
+        factoryParameters.putAll(other.factoryParameters);
+    }
+
+}
diff --git a/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryManager.java b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryManager.java
new file mode 100644
index 0000000..3da84ad
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/java/org/nuxeo/ecm/core/opencmis/bindings/NuxeoCmisServiceFactoryManager.java
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ * 
+ */
+package org.nuxeo.ecm.core.opencmis.bindings;
+
+import java.util.Map;
+
+import org.nuxeo.runtime.model.ComponentContext;
+import org.nuxeo.runtime.model.ComponentInstance;
+import org.nuxeo.runtime.model.DefaultComponent;
+import org.nuxeo.runtime.model.SimpleContributionRegistry;
+
+/**
+ *
+ */
+public class NuxeoCmisServiceFactoryManager extends DefaultComponent {
+    private static final String XP_FACTORY = "factory";
+
+    protected NuxeoCmisServiceFactoryDescriptorRegistry registry = 
+            new NuxeoCmisServiceFactoryDescriptorRegistry();
+
+    protected static class NuxeoCmisServiceFactoryDescriptorRegistry extends
+            SimpleContributionRegistry<NuxeoCmisServiceFactoryDescriptor> {
+
+        @Override
+        public String getContributionId(NuxeoCmisServiceFactoryDescriptor contrib) {
+            return XP_FACTORY;
+        }
+
+        @Override
+        public NuxeoCmisServiceFactoryDescriptor clone(NuxeoCmisServiceFactoryDescriptor orig) {
+            return new NuxeoCmisServiceFactoryDescriptor(orig);
+        }
+
+        @Override
+        public void merge(NuxeoCmisServiceFactoryDescriptor src, NuxeoCmisServiceFactoryDescriptor dst) {
+            dst.merge(src);
+        }
+
+        @Override
+        public boolean isSupportingMerge() {
+            return true;
+        }
+
+        public void clear() {
+            currentContribs.clear();
+        }
+
+        public NuxeoCmisServiceFactoryDescriptor getNuxeoCmisServiceFactoryDescriptor() {
+            return getCurrentContribution(XP_FACTORY);
+        }
+    }
+
+    @Override
+    public void activate(ComponentContext context) throws Exception {
+        registry.clear();
+    }
+
+    @Override
+    public void deactivate(ComponentContext context) throws Exception {
+        registry.clear();
+    }
+
+    @Override
+    public void registerContribution(Object contrib, String xpoint,
+            ComponentInstance contributor) {
+        if (XP_FACTORY.equals(xpoint)) {
+            addContribution((NuxeoCmisServiceFactoryDescriptor) contrib);
+        } else {
+            throw new RuntimeException("Unknown extension point: " + xpoint);
+        }
+    }
+
+    @Override
+    public void unregisterContribution(Object contrib, String xpoint,
+            ComponentInstance contributor) throws Exception {
+        if (XP_FACTORY.equals(xpoint)) {
+            removeContribution((NuxeoCmisServiceFactoryDescriptor) contrib);
+        } else {
+            throw new RuntimeException("Unknown extension point: " + xpoint);
+        }
+    }
+
+    protected void addContribution(NuxeoCmisServiceFactoryDescriptor descriptor) {
+        registry.addContribution(descriptor);
+    }
+
+    protected void removeContribution(NuxeoCmisServiceFactoryDescriptor descriptor) {
+        registry.removeContribution(descriptor);
+    }
+
+    /**
+     * Get NuxeoCmisServiceFactory based on contributed NuxeoCmisServiceFactoryDescriptors
+     */
+    public NuxeoCmisServiceFactory getNuxeoCmisServiceFactory() {
+        NuxeoCmisServiceFactoryDescriptor descriptor = 
+                registry.getNuxeoCmisServiceFactoryDescriptor();
+
+        Class<? extends NuxeoCmisServiceFactory> factoryClass = null; 
+        Map<String, String> factoryParameters = null;
+        if (descriptor != null) {
+            factoryClass = descriptor.getFactoryClass();
+            factoryParameters = descriptor.factoryParameters;
+        }
+        NuxeoCmisServiceFactory nuxeoCmisServiceFactory;
+        try {
+            nuxeoCmisServiceFactory = factoryClass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            throw new RuntimeException("Cannot instantiate nuxeoCmisServiceFactory: "
+                    + factoryClass.getName(), e);
+        }
+        
+        nuxeoCmisServiceFactory.init(factoryParameters);
+        return nuxeoCmisServiceFactory;
+    }
+
+}
diff --git a/nuxeo-opencmis-bindings/src/main/resources/META-INF/MANIFEST.MF b/nuxeo-opencmis-bindings/src/main/resources/META-INF/MANIFEST.MF
index e6300ba..4b8d845 100644
--- a/nuxeo-opencmis-bindings/src/main/resources/META-INF/MANIFEST.MF
+++ b/nuxeo-opencmis-bindings/src/main/resources/META-INF/MANIFEST.MF
@@ -9,7 +9,9 @@ Eclipse-ExtensibleAPI: true
 Nuxeo-Component: OSGI-INF/atom-contrib.xml,
  OSGI-INF/soap-contrib.xml,
  OSGI-INF/json-contrib.xml,
- OSGI-INF/ws-contrib.xml
+ OSGI-INF/ws-contrib.xml,
+ OSGI-INF/servicefactorymanager-service.xml,
+ OSGI-INF/servicefactorymanager-contrib.xml
 Bundle-Version: 5.4.2.qualifier
 Import-Package: com.sun.xml.ws.api.handler;resolution:=optional,
  javax.servlet,
@@ -26,3 +28,4 @@ Import-Package: com.sun.xml.ws.api.handler;resolution:=optional,
  org.nuxeo.runtime.api,
  org.nuxeo.runtime.api.login
 Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-Activator: org.nuxeo.ecm.core.opencmis.bindings.Activator
diff --git a/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/deployment-fragment.xml b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/deployment-fragment.xml
index 7e71bd8..8540fc3 100644
--- a/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/deployment-fragment.xml
+++ b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/deployment-fragment.xml
@@ -4,7 +4,9 @@
   <extension target="web#LISTENER">
     <listener>
       <listener-class>
-        org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisContextListener
+        <!-- this is a wrapper that holds off running NuxeoCmisContextListener
+        (the real listener) until Nuxeo is fully initialized -->
+        org.nuxeo.ecm.core.opencmis.bindings.ContextListenerDelayer
       </listener-class>
     </listener>
   </extension>
diff --git a/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-contrib.xml b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-contrib.xml
new file mode 100644
index 0000000..bc2a97b
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-contrib.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0"?>
+<component name="org.nuxeo.ecm.core.opencmis.bindings.servicefactorymanager.contrib" version="1.0.0">
+
+  <extension target="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" 
+      point="factory">
+    <factory class="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory" />
+  </extension>
+
+</component>
diff --git a/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-service.xml b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-service.xml
new file mode 100644
index 0000000..9406ed3
--- /dev/null
+++ b/nuxeo-opencmis-bindings/src/main/resources/OSGI-INF/servicefactorymanager-service.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<component name="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" version="1.0.0">
+
+  <implementation
+    class="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" />
+
+  <service>
+    <provide interface="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" />
+  </service>
+
+  <documentation>
+    The nuxeo cmis service factory manager the NuxeoCmisServiceFactory class and parameters
+    to be extended.
+    
+    <code>
+      <extension target="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" 
+          point="factory">
+        <factory class="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory">
+          <parameter name="servicewrapper.1">com.example.my.SimpleWrapper</parameter>
+          <parameter name="servicewrapper.2">com.example.my.AdvancedWrapper,1,cmis:documents</parameter>
+          <parameter name="servicewrapper.3">com.example.my.DebuggingWrapper,testRepositoryId</parameter>
+        </factory>
+      </extension>
+    </code>
+    
+  </documentation>
+  
+  <extension-point name="factory">
+    <documentation>
+      This service provides an extension point to override the NuxeoCmisServiceFactory 
+      class and parameters.
+    </documentation>
+
+    <object class="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryDescriptor" />
+  </extension-point>
+
+</component>
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoBinding.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoBinding.java
index 52b8f53..bcbd743 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoBinding.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoBinding.java
@@ -12,9 +12,12 @@
 package org.nuxeo.ecm.core.opencmis.impl.client;
 
 import org.apache.chemistry.opencmis.commons.enums.BindingType;
+import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.spi.AuthenticationProvider;
 import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
 import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
+import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
 
 /**
@@ -22,9 +25,13 @@ import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
  */
 public class NuxeoBinding implements CmisBinding {
 
-    public final NuxeoCmisService service;
+    public final CmisService service;
 
-    public NuxeoBinding(NuxeoCmisService service) {
+    private NuxeoCmisService nuxeoCmisService = null;
+    
+    private static final BindingsObjectFactory objectFactory = new BindingsObjectFactoryImpl();
+
+    public NuxeoBinding(CmisService service) {
         this.service = service;
     }
 
@@ -34,53 +41,53 @@ public class NuxeoBinding implements CmisBinding {
     }
 
     @Override
-    public NuxeoCmisService getRepositoryService() {
+    public CmisService getRepositoryService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getNavigationService() {
+    public CmisService getNavigationService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getObjectService() {
+    public CmisService getObjectService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getDiscoveryService() {
+    public CmisService getDiscoveryService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getRelationshipService() {
+    public CmisService getRelationshipService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getVersioningService() {
+    public CmisService getVersioningService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getAclService() {
+    public CmisService getAclService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getMultiFilingService() {
+    public CmisService getMultiFilingService() {
         return service;
     }
 
     @Override
-    public NuxeoCmisService getPolicyService() {
+    public CmisService getPolicyService() {
         return service;
     }
 
     @Override
     public BindingsObjectFactory getObjectFactory() {
-        return service.getObjectFactory();
+        return objectFactory;
     }
 
     @Override
@@ -111,4 +118,19 @@ public class NuxeoBinding implements CmisBinding {
         // TODO Auto-generated method stub
         throw new UnsupportedOperationException();
     }
+    
+    public CoreSession getCoreSession() {
+        return getNuxeoCmisService() == null ? null : nuxeoCmisService.getCoreSession();
+    }
+
+    /*
+     * Get potentially wrapped NuxeoCmisService
+     */
+    public NuxeoCmisService getNuxeoCmisService() {
+        if (nuxeoCmisService == null) {
+            nuxeoCmisService = NuxeoCmisService.extractFromCmisService(service);
+        }
+        return nuxeoCmisService;
+    }
+    
 }
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoDocument.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoDocument.java
index 9405771..30e47ef 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoDocument.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoDocument.java
@@ -45,14 +45,18 @@ public class NuxeoDocument extends NuxeoFileableObject implements Document {
 
     @Override
     public void cancelCheckOut() {
-        service.cancelCheckOut(getId());
+        service.cancelCheckOut(getRepositoryId(), getId(), null);
     }
 
     @Override
     public ObjectId checkIn(boolean major, Map<String, ?> properties,
             ContentStream contentStream, String checkinComment) {
-        String verId = service.checkIn(getId(), major, properties, type,
-                contentStream, checkinComment);
+        Holder<String> idHolder = new Holder<String>(getId());
+        service.checkIn(getRepositoryId(), idHolder, major, 
+                objectFactory.convertProperties(properties, type, null, UPDATABILITY_READWRITE),
+                objectFactory.convertContentStream(contentStream), checkinComment, 
+                null, null, null, null);
+        String verId = idHolder.getValue();
         return session.createObjectId(verId);
     }
 
@@ -66,7 +70,9 @@ public class NuxeoDocument extends NuxeoFileableObject implements Document {
 
     @Override
     public ObjectId checkOut() {
-        String pwcId = service.checkOut(getId());
+        Holder<String> idHolder = new Holder<String>(getId());
+        service.checkOut(getRepositoryId(), idHolder, null, null);
+        String pwcId = idHolder.getValue();
         return session.createObjectId(pwcId);
     }
 
@@ -86,7 +92,7 @@ public class NuxeoDocument extends NuxeoFileableObject implements Document {
         if (context == null) {
             context = session.getDefaultContext();
         }
-        NuxeoObjectData newData = service.copy(getId(), target.getId(),
+        NuxeoObjectData newData = nuxeoCmisService.copy(getId(), target.getId(),
                 properties, type, versioningState, policies, addACEs,
                 removeACEs, context);
         return (NuxeoDocument) session.getObjectFactory().convertObject(
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFileableObject.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFileableObject.java
index 08fb858..6860562 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFileableObject.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFileableObject.java
@@ -46,7 +46,7 @@ public abstract class NuxeoFileableObject extends NuxeoObject implements
             CoreSession coreSession = data.doc.getCoreSession();
             DocumentModel parent = coreSession.getParentDocument(new IdRef(
                     getId()));
-            if (parent == null || service.isFilteredOut(parent)) {
+            if (parent == null || nuxeoCmisService.isFilteredOut(parent)) {
                 return Collections.emptyList();
             }
             Folder folder = (Folder) session.getObject(parent,
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFolder.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFolder.java
index 14dfdc7..4cbb743 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFolder.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoFolder.java
@@ -94,7 +94,7 @@ public class NuxeoFolder extends NuxeoFileableObject implements Folder {
         if (context == null) {
             context = session.getDefaultContext();
         }
-        NuxeoObjectData newData = service.copy(source.getId(), getId(),
+        NuxeoObjectData newData = nuxeoCmisService.copy(source.getId(), getId(),
                 properties, type, versioningState, policies, addACEs,
                 removeACEs, context);
         return (NuxeoDocument) session.getObjectFactory().convertObject(
@@ -184,7 +184,7 @@ public class NuxeoFolder extends NuxeoFileableObject implements Folder {
                 List<CmisObject> items = new ArrayList<CmisObject>();
                 DocumentModelList children;
                 try {
-                    children = service.getCoreSession().getChildren(
+                    children = nuxeoCmisService.getCoreSession().getChildren(
                             data.doc.getRef());
                 } catch (ClientException e) {
                     throw new CmisRuntimeException(e.toString(), e);
@@ -193,7 +193,7 @@ public class NuxeoFolder extends NuxeoFileableObject implements Folder {
                 long skip = skipCount;
                 // TODO orderBy
                 for (DocumentModel child : children) {
-                    if (service.isFilteredOut(child)) {
+                    if (nuxeoCmisService.isFilteredOut(child)) {
                         continue;
                     }
                     totalItems++;
@@ -248,7 +248,7 @@ public class NuxeoFolder extends NuxeoFileableObject implements Folder {
             CoreSession coreSession = data.doc.getCoreSession();
             DocumentModel parent = coreSession.getParentDocument(new IdRef(
                     getId()));
-            if (parent == null || service.isFilteredOut(parent)) {
+            if (parent == null || nuxeoCmisService.isFilteredOut(parent)) {
                 return null;
             }
             return parent.getId();
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObject.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObject.java
index b9dfc14..46c4da4 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObject.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObject.java
@@ -43,6 +43,7 @@ import org.apache.chemistry.opencmis.commons.enums.ExtensionLevel;
 import org.apache.chemistry.opencmis.commons.enums.Updatability;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
@@ -60,7 +61,11 @@ public abstract class NuxeoObject implements CmisObject {
 
     protected final NuxeoSession session;
 
-    protected final NuxeoCmisService service;
+    protected final CmisService service;
+    
+    protected final NuxeoCmisService nuxeoCmisService;
+    
+    protected final NuxeoObjectFactory objectFactory;
 
     public final NuxeoObjectData data;
 
@@ -87,6 +92,8 @@ public abstract class NuxeoObject implements CmisObject {
             ObjectType type) {
         this.session = session;
         service = session.getService();
+        nuxeoCmisService = NuxeoCmisService.extractFromCmisService(service);
+        objectFactory = session.getObjectFactory();
         this.data = data;
         this.type = type;
     }
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObjectFactory.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObjectFactory.java
index a1adbde..f3cbf9a 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObjectFactory.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoObjectFactory.java
@@ -162,7 +162,14 @@ public class NuxeoObjectFactory implements ObjectFactory {
 
     @Override
     public ContentStream convertContentStream(ContentStream contentStream) {
-        throw new UnsupportedOperationException();
+        if (contentStream == null) {
+            return null;
+        }
+        BigInteger length = (contentStream.getLength() < 0 
+                ? null : BigInteger.valueOf(contentStream.getLength()));
+
+        return of.createContentStream(contentStream.getFileName(), length,
+                contentStream.getMimeType(), contentStream.getStream());
     }
 
     @Override
@@ -187,6 +194,9 @@ public class NuxeoObjectFactory implements ObjectFactory {
     public Properties convertProperties(Map<String, ?> properties,
             ObjectType type, Collection<SecondaryType> secondaryTypes,
             Set<Updatability> updatabilityFilter) {
+        if (properties == null) {
+            return null;
+        }
         // TODO secondaryTypes
         // TODO updatabilityFilter
         PropertiesImpl props = new PropertiesImpl();
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoSession.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoSession.java
index 395b4b5..80a7dd9 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoSession.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/client/NuxeoSession.java
@@ -61,12 +61,11 @@ import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedExceptio
 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.BulkUpdateObjectIdAndChangeTokenImpl;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.api.DocumentModel;
-import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoObjectData;
-import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
 
 /**
  * Nuxeo Persistent Session, having a direct connection to a Nuxeo
@@ -86,20 +85,18 @@ public class NuxeoSession implements Session {
 
     protected final NuxeoObjectFactory objectFactory;
 
-    private final NuxeoCmisService service;
+    private final CmisService service;
 
     private final NuxeoBinding binding;
 
     private OperationContext defaultContext = DEFAULT_CONTEXT;
 
-    public NuxeoSession(CoreSession coreSession, NuxeoRepository repository,
-            CallContext context) {
-        this.coreSession = coreSession;
-        repositoryId = repository.getId();
+    public NuxeoSession(NuxeoBinding binding, CallContext context) {
+        this.coreSession = binding.getCoreSession();
+        repositoryId = context.getRepositoryId();
         objectFactory = new NuxeoObjectFactory(this);
-
-        service = new NuxeoCmisService(repository, context, coreSession);
-        binding = new NuxeoBinding(service);
+        service = binding.service;
+        this.binding = binding;
     }
 
     @Override
@@ -112,7 +109,7 @@ public class NuxeoSession implements Session {
         return binding;
     }
 
-    public NuxeoCmisService getService() {
+    public CmisService getService() {
         return service;
     }
 
@@ -357,7 +354,7 @@ public class NuxeoSession implements Session {
         if (context == null) {
             throw new CmisInvalidArgumentException("Missing operation context");
         }
-        NuxeoObjectData data = service.getObject(repositoryId, objectId,
+        ObjectData data = service.getObject(repositoryId, objectId,
                 context.getFilterString(),
                 Boolean.valueOf(context.isIncludeAllowableActions()),
                 context.getIncludeRelationships(),
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoCmisService.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoCmisService.java
index b5565db..d319d21 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoCmisService.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoCmisService.java
@@ -77,6 +77,7 @@ import org.apache.chemistry.opencmis.commons.exceptions.CmisInvalidArgumentExcep
 import org.apache.chemistry.opencmis.commons.exceptions.CmisNotSupportedException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
 import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.Constants;
 import org.apache.chemistry.opencmis.commons.impl.WSConverter;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.AbstractPropertyData;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFactoryImpl;
@@ -95,9 +96,12 @@ import org.apache.chemistry.opencmis.commons.impl.dataobjects.PropertyIdImpl;
 import org.apache.chemistry.opencmis.commons.impl.jaxb.CmisTypeContainer;
 import org.apache.chemistry.opencmis.commons.impl.server.AbstractCmisService;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.server.ObjectInfo;
 import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
 import org.apache.chemistry.opencmis.commons.spi.Holder;
+import org.apache.chemistry.opencmis.server.support.wrapper.AbstractCmisServiceWrapper;
+import org.apache.chemistry.opencmis.server.support.wrapper.CallContextAwareCmisService;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
@@ -141,7 +145,7 @@ import org.nuxeo.runtime.api.Framework;
 /**
  * Nuxeo implementation of the CMIS Services, on top of a {@link CoreSession}.
  */
-public class NuxeoCmisService extends AbstractCmisService {
+public class NuxeoCmisService extends AbstractCmisService implements CallContextAwareCmisService {
 
     public static final int DEFAULT_TYPE_LEVELS = 2;
 
@@ -163,51 +167,50 @@ public class NuxeoCmisService extends AbstractCmisService {
 
     protected final NuxeoRepository repository;
 
-    protected final CoreSession coreSession;
+    protected CoreSession coreSession;
 
     /* To avoid refetching it several times per session. */
     protected String cachedChangeLogToken;
 
-    /** When false, we don't own the core session and shouldn't close it. */
-    protected final boolean coreSessionOwned;
-
     /** Filter that hides HiddenInNavigation and deleted objects. */
     protected final Filter documentFilter;
 
-    protected final CallContext callContext;
+    protected CallContext callContext;
 
-    /** Constructor called by binding. */
-    public NuxeoCmisService(NuxeoRepository repository, CallContext callContext) {
-        this.repository = repository;
-        this.callContext = callContext;
-        this.coreSession = repository == null ? null
-                : openCoreSession(repository.getId());
-        coreSessionOwned = true;
-        documentFilter = getDocumentFilter();
+    public static NuxeoCmisService extractFromCmisService(CmisService service) {
+        if (service == null) {
+            throw new IllegalArgumentException("CmisService must not be null");
+        }
+        CmisService currentService = service;
+        for(;;) {
+            if (currentService instanceof NuxeoCmisService) {
+                return (NuxeoCmisService) currentService;
+            }
+            if (!(currentService instanceof AbstractCmisServiceWrapper)) {
+                return null;
+            }
+            currentService = ((AbstractCmisServiceWrapper) currentService).getWrappedService();
+        }
     }
-
-    /** Constructor called by high-level session from existing core session. */
-    public NuxeoCmisService(NuxeoRepository repository,
-            CallContext callContext, CoreSession coreSession) {
+    
+    /** Constructor called by binding. */
+    public NuxeoCmisService(NuxeoRepository repository) {
         this.repository = repository;
-        this.callContext = callContext;
-        this.coreSession = coreSession;
-        coreSessionOwned = false;
         documentFilter = getDocumentFilter();
     }
-
+    
     // called in a finally block from dispatcher
     @Override
     public void close() {
-        if (coreSession != null && coreSessionOwned) {
+        if (coreSession != null) {
             closeCoreSession();
         }
         clearObjectInfos();
     }
 
-    protected CoreSession openCoreSession(String repositoryName) {
+    protected CoreSession openCoreSession(String repositoryName, String username) {
         try {
-            return CoreInstance.openCoreSession(repositoryName);
+            return CoreInstance.openCoreSession(repositoryName, username);
         } catch (ClientException e) {
             throw new CmisRuntimeException(e.toString(), e);
         }
@@ -229,10 +232,31 @@ public class NuxeoCmisService extends AbstractCmisService {
         return objectFactory;
     }
 
+    @Override
     public CallContext getCallContext() {
         return callContext;
     }
 
+    /**
+     * Sets a new call context.
+     *
+     * This method should only be called by the service factory.
+     *
+     * @param callContext
+     *            the new call context
+     */
+    @Override
+    public void setCallContext(CallContext callContext) {
+        this.callContext = callContext;
+        if (coreSession != null) {
+            closeCoreSession();
+        }
+        String username = callContext.getBinding().equals(CallContext.BINDING_LOCAL)
+                ? callContext.getUsername() : null;
+        coreSession = repository == null ? null
+                : openCoreSession(repository.getId(), username);
+    }
+
     /** Gets the filter that hides HiddenInNavigation and deleted objects. */
     protected Filter getDocumentFilter() {
         Filter facetFilter = new FacetFilter(FacetNames.HIDDEN_IN_NAVIGATION,
@@ -1431,7 +1455,8 @@ public class NuxeoCmisService extends AbstractCmisService {
                                 id, includeRelationships, coreSession, this);
                         od.setRelationships(relationships);
                     }
-                    if (renditionFilter != null && renditionFilter.length() > 0) {
+                    if (renditionFilter != null && renditionFilter.length() > 0
+                            && !renditionFilter.equals(Constants.RENDITION_NONE)) {
                         if (doc == null) {
                             doc = getDocumentModel(id);
                         }
diff --git a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoObjectData.java b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoObjectData.java
index 9634739..f37b2ec 100644
--- a/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoObjectData.java
+++ b/nuxeo-opencmis-impl/src/main/java/org/nuxeo/ecm/core/opencmis/impl/server/NuxeoObjectData.java
@@ -53,6 +53,7 @@ import org.apache.chemistry.opencmis.commons.impl.dataobjects.BindingsObjectFact
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.PolicyIdListImpl;
 import org.apache.chemistry.opencmis.commons.impl.dataobjects.RenditionDataImpl;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
 import org.nuxeo.common.utils.StringUtils;
 import org.nuxeo.ecm.core.api.ClientException;
@@ -81,7 +82,7 @@ public class NuxeoObjectData implements ObjectData {
 
     public static final String REND_KIND_NUXEO_RENDITION = "nuxeo:rendition";
 
-    public NuxeoCmisService service;
+    public CmisService service;
 
     public DocumentModel doc;
 
@@ -111,8 +112,10 @@ public class NuxeoObjectData implements ObjectData {
     private Map<String, Properties> propertiesCache = new HashMap<String, Properties>();
 
     private CallContext callContext;
+    
+    private NuxeoCmisService nuxeoCmisService;
 
-    public NuxeoObjectData(NuxeoCmisService service, DocumentModel doc,
+    public NuxeoObjectData(CmisService service, DocumentModel doc,
             String filter, Boolean includeAllowableActions,
             IncludeRelationships includeRelationships, String renditionFilter,
             Boolean includePolicyIds, Boolean includeAcl,
@@ -125,15 +128,16 @@ public class NuxeoObjectData implements ObjectData {
         this.renditionFilter = renditionFilter;
         this.includePolicyIds = includePolicyIds;
         this.includeAcl = includeAcl;
-        type = service.repository.getTypeDefinition(NuxeoTypeHelper.mappedId(doc.getType()));
-        callContext = service.callContext;
+        nuxeoCmisService = NuxeoCmisService.extractFromCmisService(service);
+        type = nuxeoCmisService.repository.getTypeDefinition(NuxeoTypeHelper.mappedId(doc.getType()));
+        callContext = nuxeoCmisService.callContext;
     }
 
-    protected NuxeoObjectData(NuxeoCmisService service, DocumentModel doc) {
+    protected NuxeoObjectData(CmisService service, DocumentModel doc) {
         this(service, doc, null, null, null, null, null, null, null);
     }
 
-    public NuxeoObjectData(NuxeoCmisService service, DocumentModel doc,
+    public NuxeoObjectData(CmisService service, DocumentModel doc,
             OperationContext context) {
         this(service, doc, context.getFilterString(),
                 Boolean.valueOf(context.isIncludeAllowableActions()),
@@ -391,7 +395,7 @@ public class NuxeoObjectData implements ObjectData {
     @Override
     public List<ObjectData> getRelationships() {
         return getRelationships(getId(), includeRelationships,
-                doc.getCoreSession(), service);
+                doc.getCoreSession(), nuxeoCmisService);
     }
 
     public static List<ObjectData> getRelationships(String id,
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/LastModifiedServiceWrapper.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/LastModifiedServiceWrapper.java
new file mode 100644
index 0000000..cfe12bb
--- /dev/null
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/LastModifiedServiceWrapper.java
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and contributors.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the GNU Lesser General Public License
+ * (LGPL) version 2.1 which accompanies this distribution, and is available at
+ * http://www.gnu.org/licenses/lgpl-2.1.html
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * Contributors:
+ */
+package org.nuxeo.ecm.core.opencmis.impl;
+
+import java.math.BigInteger;
+import java.util.GregorianCalendar;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.chemistry.opencmis.commons.data.ExtensionsData;
+import org.apache.chemistry.opencmis.commons.data.ObjectInFolderList;
+import org.apache.chemistry.opencmis.commons.enums.IncludeRelationships;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisObjectNotFoundException;
+import org.apache.chemistry.opencmis.commons.exceptions.CmisRuntimeException;
+import org.apache.chemistry.opencmis.commons.impl.DateTimeHelper;
+import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
+import org.apache.chemistry.opencmis.server.support.wrapper.AbstractCmisServiceWrapper;
+import org.nuxeo.ecm.core.api.ClientException;
+import org.nuxeo.ecm.core.api.CoreSession;
+import org.nuxeo.ecm.core.api.DocumentModel;
+import org.nuxeo.ecm.core.api.DocumentRef;
+import org.nuxeo.ecm.core.api.IdRef;
+import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
+
+/**
+ * Test service wrapper that adds "Last-Modified" header to GetChildren NavigationService response.
+ *
+ * @since 5.9.5
+ */
+public class LastModifiedServiceWrapper extends AbstractCmisServiceWrapper {
+
+    public LastModifiedServiceWrapper(CmisService service) {
+        super(service);
+    }
+
+    @Override
+    public ObjectInFolderList getChildren(String repositoryId, String folderId,
+            String filter, String orderBy, Boolean includeAllowableActions,
+            IncludeRelationships includeRelationships, String renditionFilter,
+            Boolean includePathSegment, BigInteger maxItems,
+            BigInteger skipCount, ExtensionsData extension) {
+        GregorianCalendar lastModified;
+        try {
+            DocumentModel doc = getDocumentModel(folderId);
+            lastModified = (GregorianCalendar) doc.getPropertyValue("dc:modified");
+        } catch (ClientException e) {
+            throw new CmisRuntimeException(e.toString(), e);
+        }
+        
+        ObjectInFolderList children = getWrappedService().getChildren(repositoryId, folderId, 
+                filter, orderBy, includeAllowableActions, includeRelationships, renditionFilter,
+                includePathSegment, maxItems, skipCount, extension);
+        
+        String lastModifiedResHeader = DateTimeHelper.formatHttpDateTime(lastModified);
+        setResponseHeader("Last-Modified", lastModifiedResHeader);
+        return children;
+    }
+    
+    private DocumentModel getDocumentModel(String id) throws ClientException {
+        NuxeoCmisService nuxeoCmisService = NuxeoCmisService.extractFromCmisService(this);
+        CoreSession coreSession = nuxeoCmisService.getCoreSession();
+        DocumentRef docRef = new IdRef(id);
+        if (!coreSession.exists(docRef)) {
+            throw new CmisObjectNotFoundException(docRef.toString());
+        }
+        DocumentModel doc = coreSession.getDocument(docRef);
+        if (nuxeoCmisService.isFilteredOut(doc)) {
+            throw new CmisObjectNotFoundException(docRef.toString());
+        }
+        return doc;
+    }
+
+    private void setResponseHeader(String headerName, String headerValue) {
+        HttpServletResponse response = 
+                (HttpServletResponse) getCallContext().get(CallContext.HTTP_SERVLET_RESPONSE);
+        response.setHeader(headerName, headerValue);
+    }
+
+}
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoBindingTestCase.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoBindingTestCase.java
index b71c78e..2542a0f 100644
--- a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoBindingTestCase.java
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoBindingTestCase.java
@@ -21,20 +21,21 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.chemistry.opencmis.commons.SessionParameter;
 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.spi.CmisBinding;
 import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
 import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
 import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory;
+import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager;
 import org.nuxeo.ecm.core.opencmis.impl.client.NuxeoBinding;
-import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepositories;
-import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
 import org.nuxeo.ecm.core.storage.sql.SQLRepositoryTestCase;
+import org.nuxeo.runtime.api.Framework;
 
 public class NuxeoBindingTestCase {
 
-    public static final String USERNAME = "test";
+    public static final String USERNAME = "Administrator";
 
     public static final String PASSWORD = "test";
 
@@ -72,10 +73,12 @@ public class NuxeoBindingTestCase {
         params.put(SessionParameter.LOCAL_FACTORY,
                 NuxeoCmisServiceFactory.class.getName());
 
-        init();
+        initBinding();
     }
 
     protected void deployBundles() throws Exception {
+        // NuxeoCmisServiceFactoryManager registration
+        nuxeotc.deployBundle("org.nuxeo.ecm.core.opencmis.bindings");
         // QueryMaker registration
         nuxeotc.deployBundle("org.nuxeo.ecm.core.opencmis.impl");
         // MyDocType
@@ -104,28 +107,31 @@ public class NuxeoBindingTestCase {
                 "OSGI-INF/types-contrib.xml");
     }
 
-    /** Init fields from session. */
-    public void init() throws Exception {
+    public void initBinding() throws Exception {
+        initBinding(USERNAME);
+    }
+
+    public void initBinding(String username) throws Exception {
         repositoryId = nuxeotc.getRepositoryId();
         CoreSession coreSession = nuxeotc.getSession();
         rootFolderId = coreSession.getRootDocument().getId();
 
+        NuxeoCmisServiceFactoryManager manager =
+                Framework.getLocalService(NuxeoCmisServiceFactoryManager.class);
+        NuxeoCmisServiceFactory serviceFactory = manager.getNuxeoCmisServiceFactory();
         ThresholdOutputStreamFactory streamFactory = ThresholdOutputStreamFactory.newInstance(
-                new File((String) System.getProperty("java.io.tmpdir")),
+                new File(System.getProperty("java.io.tmpdir")),
                 THRESHOLD, MAX_SIZE, false);
         HttpServletRequest request = null;
         HttpServletResponse response = null;
         CallContextImpl context = new CallContextImpl(
                 CallContext.BINDING_LOCAL, CmisVersion.CMIS_1_1, repositoryId,
                 FakeServletContext.getServletContext(), request, response,
-                new NuxeoCmisServiceFactory(), streamFactory);
-        context.put(CallContext.USERNAME, USERNAME);
+                serviceFactory, streamFactory);
+        context.put(CallContext.USERNAME, username);
         context.put(CallContext.PASSWORD, PASSWORD);
-        NuxeoRepository repository = new NuxeoRepository(repositoryId,
-                rootFolderId);
+        CmisService service = serviceFactory.getService(context);
         // use manual local bindings to keep the session open
-        NuxeoCmisService service = new NuxeoCmisService(repository, context,
-                coreSession);
         binding = new NuxeoBinding(service);
     }
 
@@ -142,6 +148,7 @@ public class NuxeoBindingTestCase {
     }
 
     public void tearDown() throws Exception {
+        closeBinding();
         if (nuxeotc != null) {
             nuxeotc.closeSession();
             nuxeotc.tearDown();
@@ -149,4 +156,10 @@ public class NuxeoBindingTestCase {
         NuxeoRepositories.clear();
     }
 
+    public void closeBinding() {
+        if (binding != null) {
+            binding.close();
+        }
+    }
+
 }
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoSessionTestCase.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoSessionTestCase.java
index 344b0dd..6d6aa1a 100644
--- a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoSessionTestCase.java
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/NuxeoSessionTestCase.java
@@ -32,6 +32,7 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TimeZone;
 
 import javax.servlet.http.HttpServletResponse;
 
@@ -73,12 +74,10 @@ import org.nuxeo.ecm.core.api.ClientException;
 import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.api.IdRef;
 import org.nuxeo.ecm.core.api.Lock;
-import org.nuxeo.ecm.core.api.NuxeoPrincipal;
 import org.nuxeo.ecm.core.opencmis.impl.client.NuxeoSession;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepositories;
 import org.nuxeo.ecm.core.opencmis.tests.Helper;
 import org.nuxeo.ecm.core.storage.sql.SQLRepositoryTestCase;
-import org.nuxeo.ecm.platform.usermanager.NuxeoPrincipalImpl;
 
 /**
  * Tests that hit the high-level Session abstraction.
@@ -137,6 +136,8 @@ public abstract class NuxeoSessionTestCase extends SQLRepositoryTestCase {
         deployBundle("org.nuxeo.ecm.platform.audit");
         deployContrib("org.nuxeo.ecm.core.opencmis.tests.tests",
                 "OSGI-INF/audit-persistence-config.xml");
+        // NuxeoCmisServiceFactoryManager registration
+        deployBundle("org.nuxeo.ecm.core.opencmis.bindings");
         // QueryMaker registration
         deployBundle("org.nuxeo.ecm.core.opencmis.impl");
         // these deployments needed for NuxeoAuthenticationFilter.loginAs
@@ -347,9 +348,14 @@ public abstract class NuxeoSessionTestCase extends SQLRepositoryTestCase {
 
     @Test
     public void testCreateRelationship() throws Exception {
+        if (!isAtomPub && !isBrowser) {
+            // createRelationship admin user only empowered for AtomPub & Browser tests
+            return;
+        }
+
         String id1 = session.getObjectByPath("/testfolder1/testfile1").getId();
         String id2 = session.getObjectByPath("/testfolder1/testfile2").getId();
-
+        
         Map<String, Serializable> properties = new HashMap<String, Serializable>();
         properties.put(PropertyIds.OBJECT_TYPE_ID, "Relation");
         properties.put(PropertyIds.NAME, "rel");
@@ -357,16 +363,6 @@ public abstract class NuxeoSessionTestCase extends SQLRepositoryTestCase {
         properties.put(PropertyIds.TARGET_ID, id2);
         ObjectId relid = session.createRelationship(properties);
 
-        // note: has to be an administrator to get relations
-        closeSession();
-        NuxeoPrincipal admin = new NuxeoPrincipalImpl("admin", false, true);
-        super.session = openSessionAs(admin);
-        tearDownCmisSession();
-        Thread.sleep(1000); // otherwise sometimes fails to set up again
-        // for tests, server-side TrustingLoginProvider makes "admin*" an admin
-        setUpCmisSession(admin.getName());
-
-        session.clear(); // clear cache
         ItemIterable<Relationship> rels = session.getRelationships(
                 session.createObjectId(id1), false,
                 RelationshipDirection.SOURCE, null,
@@ -914,6 +910,52 @@ public abstract class NuxeoSessionTestCase extends SQLRepositoryTestCase {
         assertNotNull(ws);
     }
 
+    @Test
+    public void testLastModifiedServiceWrapper() throws Exception {
+        tearDownData();
+        tearDownCmisSession();
+        Thread.sleep(1000); // otherwise sometimes fails to set up again
+        // deploy the LastModifiedServiceWrapper
+        deployContrib("org.nuxeo.ecm.core.opencmis.tests.tests",
+                "OSGI-INF/test-servicefactorymanager-contrib.xml");
+        setUpCmisSession();
+        setUpData();
+
+        GregorianCalendar lastModifiedCalendar = Helper.getCalendar(2007, 4, 1, 12, 0, 0, TimeZone.getDefault());
+        Folder folder = (Folder) session.getObjectByPath("/testfolder1");
+        Map<String, Serializable> properties = new HashMap<String, Serializable>();
+        properties.put("dc:description", "my description");
+        properties.put("dc:modified", lastModifiedCalendar);
+        folder.updateProperties(properties, true);
+
+        // check Last-Modified Cache Response Header
+        if (isAtomPub || isBrowser) {
+            RepositoryInfo ri = session.getRepositoryInfo();
+            String uri = ri.getThinClientUri() + ri.getId() + "/";
+            uri += isAtomPub ? "children?id=" : "root?objectId=";
+            uri += folder.getId();
+            String lastModified = DateUtil.formatDate(lastModifiedCalendar.getTime());
+            String encoding = Base64.encodeBytes(
+                    new String(USERNAME + ":" + PASSWORD).getBytes());
+            DefaultHttpClient client = new DefaultHttpClient();
+            HttpGet request = new HttpGet(uri);
+            HttpResponse response = null;
+            request.setHeader("Authorization", "Basic " + encoding);
+            try {
+                response = client.execute(request);
+                assertEquals(HttpServletResponse.SC_OK,
+                        response.getStatusLine().getStatusCode());
+                assertEquals(lastModified,
+                        response.getLastHeader("Last-Modified").getValue());
+            } finally {
+                client.getConnectionManager().shutdown();
+            }
+        }
+
+        assertEquals(lastModifiedCalendar.getTimeInMillis(),
+                ((GregorianCalendar) folder.getPropertyValue("dc:modified")).getTimeInMillis());
+    }
+
     protected void checkValue(String prop, Object expected, CmisObject ob) {
         Object value = ob.getPropertyValue(prop);
         if (expected == NOT_NULL) {
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBinding.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBinding.java
index 59ed5ca..0fc05c1 100644
--- a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBinding.java
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBinding.java
@@ -135,8 +135,8 @@ public class TestNuxeoBinding extends NuxeoBindingTestCase {
     }
 
     @Override
-    public void init() throws Exception {
-        super.init();
+    public void initBinding(String username) throws Exception {
+        super.initBinding(username);
         repoService = binding.getRepositoryService();
         objService = binding.getObjectService();
         navService = binding.getNavigationService();
@@ -1223,9 +1223,8 @@ public class TestNuxeoBinding extends NuxeoBindingTestCase {
         res = query(statement);
         assertEquals(3, res.getNumItems().intValue());
 
-        nuxeotc.closeSession();
-        nuxeotc.session = nuxeotc.openSessionAs("bob");
-        init();
+        closeBinding();
+        initBinding("bob");
 
         statement = "SELECT cmis:objectId FROM File";
         res = query(statement);
@@ -2154,10 +2153,9 @@ public class TestNuxeoBinding extends NuxeoBindingTestCase {
 
     @Test
     public void testQueryJoinWithSecurity() throws Exception {
-        nuxeotc.closeSession();
-        nuxeotc.session = nuxeotc.openSessionAs("bob");
+        closeBinding();
+        initBinding("bob");
         // only testfile1 and testfile2 are accessible by bob
-        init();
 
         String statement;
         ObjectList res;
@@ -2920,9 +2918,8 @@ public class TestNuxeoBinding extends NuxeoBindingTestCase {
         assertEquals(id2, getValue(od, PropertyIds.TARGET_ID));
 
         // normal user has security applied to its queries
-        nuxeotc.closeSession();
-        nuxeotc.session = nuxeotc.openSessionAs("john");
-        init();
+        closeBinding();
+        initBinding("john");
 
         statement = "SELECT A.cmis:objectId, B.cmis:objectId"
                 + " FROM cmis:document A"
@@ -2933,9 +2930,8 @@ public class TestNuxeoBinding extends NuxeoBindingTestCase {
         assertEquals(0, res.getNumItems().intValue());
 
         // bob has Browse on testfile1 and testfile2
-        nuxeotc.closeSession();
-        nuxeotc.session = nuxeotc.openSessionAs("bob");
-        init();
+        closeBinding();
+        initBinding("bob");
 
         // no security check on relationship itself
         statement = "SELECT A.cmis:objectId, B.cmis:objectId"
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBindingRenditions.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBindingRenditions.java
index 474deb2..fcd08a5 100644
--- a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBindingRenditions.java
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoBindingRenditions.java
@@ -60,8 +60,8 @@ public class TestNuxeoBindingRenditions extends NuxeoBindingTestCase {
     }
 
     @Override
-    public void init() throws Exception {
-        super.init();
+    public void initBinding() throws Exception {
+        super.initBinding();
         objService = binding.getObjectService();
     }
 
diff --git a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoSessionLocal.java b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoSessionLocal.java
index 5b72636..5f1b2e5 100644
--- a/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoSessionLocal.java
+++ b/nuxeo-opencmis-tests/src/test/java/org/nuxeo/ecm/core/opencmis/impl/TestNuxeoSessionLocal.java
@@ -16,30 +16,39 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.GregorianCalendar;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.junit.Before;
 import org.junit.After;
-import org.junit.Test;
-
 import static org.junit.Assert.*;
 
+import org.apache.chemistry.opencmis.client.api.SessionFactory;
+import org.apache.chemistry.opencmis.client.bindings.CmisBindingFactory;
+import org.apache.chemistry.opencmis.client.runtime.SessionFactoryImpl;
 import org.apache.chemistry.opencmis.commons.PropertyIds;
+import org.apache.chemistry.opencmis.commons.SessionParameter;
 import org.apache.chemistry.opencmis.commons.data.Properties;
 import org.apache.chemistry.opencmis.commons.data.PropertyData;
+import org.apache.chemistry.opencmis.commons.enums.BindingType;
 import org.apache.chemistry.opencmis.commons.enums.CmisVersion;
 import org.apache.chemistry.opencmis.commons.server.CallContext;
+import org.apache.chemistry.opencmis.commons.server.CmisService;
 import org.apache.chemistry.opencmis.commons.spi.BindingsObjectFactory;
 import org.apache.chemistry.opencmis.server.impl.CallContextImpl;
 import org.apache.chemistry.opencmis.server.shared.ThresholdOutputStreamFactory;
+import org.nuxeo.ecm.core.api.CoreSession;
 import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactory;
+import org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager;
+import org.nuxeo.ecm.core.opencmis.impl.client.NuxeoBinding;
 import org.nuxeo.ecm.core.opencmis.impl.client.NuxeoSession;
 import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoCmisService;
-import org.nuxeo.ecm.core.opencmis.impl.server.NuxeoRepository;
 import org.nuxeo.ecm.core.opencmis.tests.Helper;
+import org.nuxeo.runtime.api.Framework;
 
 /**
  * Test the high-level session using a local connection.
@@ -51,38 +60,44 @@ public class TestNuxeoSessionLocal extends NuxeoSessionTestCase {
     private static final int MAX_SIZE = -1;
 
     @Override
-    @Before
     public void setUpCmisSession() throws Exception {
         setUpCmisSession(USERNAME);
     }
 
     @Override
     protected void setUpCmisSession(String username) throws Exception {
+
+        NuxeoCmisServiceFactoryManager manager =
+                Framework.getLocalService(NuxeoCmisServiceFactoryManager.class);
+        NuxeoCmisServiceFactory serviceFactory = manager.getNuxeoCmisServiceFactory();
         ThresholdOutputStreamFactory streamFactory = ThresholdOutputStreamFactory.newInstance(
-                new File((String) System.getProperty("java.io.tmpdir")),
+                new File(System.getProperty("java.io.tmpdir")),
                 THRESHOLD, MAX_SIZE, false);
         HttpServletRequest request = null;
         HttpServletResponse response = null;
         CallContextImpl context = new CallContextImpl(
                 CallContext.BINDING_LOCAL, CmisVersion.CMIS_1_1, getRepositoryId(),
                 FakeServletContext.getServletContext(), request, response,
-                new NuxeoCmisServiceFactory(), streamFactory);
+                serviceFactory, streamFactory);
         context.put(CallContext.USERNAME, username);
         context.put(CallContext.PASSWORD, PASSWORD);
-        NuxeoRepository repository = new NuxeoRepository(getRepositoryId(),
-                getRootFolderId());
-        session = new NuxeoSession(getCoreSession(), repository, context);
+        CmisService service = serviceFactory.getService(context);
+        NuxeoBinding binding = new NuxeoBinding(service);
+        session = new NuxeoSession(binding, context);
     }
 
     @Override
-    @After
     public void tearDownCmisSession() throws Exception {
-        session = null;
+        if (session != null) {
+            session.getBinding().close();
+            session.clear();
+            session = null;
+        }
     }
 
     protected String createDocumentMyDocType() {
-        NuxeoCmisService service = ((NuxeoSession) session).getService();
-        BindingsObjectFactory factory = service.getObjectFactory();
+        BindingsObjectFactory factory = 
+                ((NuxeoSession) session).getBinding().getObjectFactory();
         List<PropertyData<?>> props = new ArrayList<PropertyData<?>>();
         props.add(factory.createPropertyIdData(PropertyIds.NAME, "My Title"));
         props.add(factory.createPropertyIdData(PropertyIds.OBJECT_TYPE_ID,
@@ -99,8 +114,9 @@ public class TestNuxeoSessionLocal extends NuxeoSessionTestCase {
                 55);
         props.add(factory.createPropertyDateTimeData("my:date", expectedDate));
         Properties properties = factory.createPropertiesData(props);
-        String id = service.createDocument(getRepositoryId(), properties,
-                rootFolderId, null, null, null, null, null, null);
+        ((NuxeoSession) session).getService();
+        String id = ((NuxeoSession) session).getService().createDocument(getRepositoryId(), 
+                properties, rootFolderId, null, null, null, null, null, null);
         assertNotNull(id);
         return id;
     }
diff --git a/nuxeo-opencmis-tests/src/test/resources/OSGI-INF/test-servicefactorymanager-contrib.xml b/nuxeo-opencmis-tests/src/test/resources/OSGI-INF/test-servicefactorymanager-contrib.xml
new file mode 100644
index 0000000..58e808b
--- /dev/null
+++ b/nuxeo-opencmis-tests/src/test/resources/OSGI-INF/test-servicefactorymanager-contrib.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<component name="org.nuxeo.ecm.core.opencmis.tests.servicefactorymanager">
+
+  <extension target="org.nuxeo.ecm.core.opencmis.bindings.NuxeoCmisServiceFactoryManager" 
+      point="factory">
+    <factory name="factoryWithLastModifiedServiceWrapper">
+      <parameter name="servicewrapper.1">
+        org.nuxeo.ecm.core.opencmis.impl.LastModifiedServiceWrapper</parameter>
+    </factory>
+  </extension>
+
+</component>
