You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2015/09/16 07:06:36 UTC

[2/4] isis git commit: ISIS-1194: simplfying the bootstrap and wiring of components, in particular around PersistenceSessionFactory

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
index 8f7ff1a..713dff1 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactory.java
@@ -22,45 +22,26 @@ package org.apache.isis.core.runtime.system.persistence;
 import java.util.Map;
 import java.util.Set;
 
+import javax.jdo.PersistenceManagerFactory;
+
 import org.datanucleus.PropertyNames;
 import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
-import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
-import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpiAware;
-import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
 import org.apache.isis.core.runtime.persistence.FixturesInstalledFlag;
-import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller;
 import org.apache.isis.objectstore.jdo.datanucleus.JDOStateManagerForIsis;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableAnnotationInJdoApplibFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableMarkerInterfaceInJdoApplibFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.datastoreidentity.JdoDatastoreIdentityAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.discriminator.JdoDiscriminatorAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.object.version.JdoVersionAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.BigDecimalDerivedFromJdoColumnAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.MandatoryFromJdoColumnAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.MaxLengthDerivedFromJdoColumnAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent.JdoNotPersistentAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.JdoPrimaryKeyAnnotationFacetFactory;
-import org.apache.isis.objectstore.jdo.metamodel.specloader.validator.JdoMetaModelValidator;
 import org.apache.isis.objectstore.jdo.service.RegisterEntities;
 
-public class PersistenceSessionFactory implements MetaModelRefiner,
-        SpecificationLoaderSpiAware, ApplicationScopedComponent, FixturesInstalledFlag {
+public class PersistenceSessionFactory implements ApplicationScopedComponent, FixturesInstalledFlag {
 
     private static final Logger LOG = LoggerFactory.getLogger(PersistenceSessionFactory.class);
 
@@ -69,32 +50,11 @@ public class PersistenceSessionFactory implements MetaModelRefiner,
     private final DeploymentType deploymentType;
     private final IsisConfigurationDefault configuration;
 
-    private final ServicesInjectorSpi servicesInjector;
-    private final RuntimeContextFromSession runtimeContext;
-
-    private SpecificationLoaderSpi specificationLoader;
-
     public PersistenceSessionFactory(
             final DeploymentType deploymentType,
-            final ServicesInjectorSpi servicesInjector,
-            final IsisConfigurationDefault isisConfiguration,
-            final RuntimeContextFromSession runtimeContext) {
+            final IsisConfigurationDefault isisConfiguration) {
         this.deploymentType = deploymentType;
         this.configuration = isisConfiguration;
-        this.servicesInjector = servicesInjector;
-        this.runtimeContext = runtimeContext;
-    }
-
-    public DeploymentType getDeploymentType() {
-        return deploymentType;
-    }
-
-    public IsisConfigurationDefault getConfiguration() {
-        return configuration;
-    }
-
-    public ServicesInjectorSpi getServicesInjector() {
-        return servicesInjector;
     }
 
     //endregion
@@ -104,29 +64,6 @@ public class PersistenceSessionFactory implements MetaModelRefiner,
     private DataNucleusApplicationComponents applicationComponents;
 
     public final void init() {
-
-        // a bit of a workaround, but required if anything in the metamodel (for
-        // example, a
-        // ValueSemanticsProvider for a date value type) needs to use the Clock
-        // singleton
-        // we do this after loading the services to allow a service to prime a
-        // different clock
-        // implementation (eg to use an NTP time service).
-        if (!deploymentType.isProduction() && !Clock.isInitialized()) {
-            FixtureClock.initialize();
-        }
-
-        runtimeContext.injectInto(servicesInjector);
-
-        // wire up components
-        getSpecificationLoader().injectInto(runtimeContext);
-
-        for (Object service : servicesInjector.getRegisteredServices()) {
-            runtimeContext.injectInto(service);
-        }
-
-        servicesInjector.init();
-
         this.applicationComponents = createDataNucleusApplicationComponents(configuration);
     }
 
@@ -215,49 +152,24 @@ public class PersistenceSessionFactory implements MetaModelRefiner,
 
     //endregion
 
-    //region > MetaModelRefiner impl
-
-    @Override
-    public void refineProgrammingModel(ProgrammingModel programmingModel, IsisConfiguration configuration) {
-        programmingModel.addFactory(
-                JdoPersistenceCapableAnnotationFacetFactory.class, ProgrammingModel.Position.BEGINNING);
-        programmingModel.addFactory(JdoDatastoreIdentityAnnotationFacetFactory.class);
-
-        programmingModel.addFactory(JdoPrimaryKeyAnnotationFacetFactory.class);
-        programmingModel.addFactory(JdoNotPersistentAnnotationFacetFactory.class);
-        programmingModel.addFactory(JdoDiscriminatorAnnotationFacetFactory.class);
-        programmingModel.addFactory(JdoVersionAnnotationFacetFactory.class);
-
-        programmingModel.addFactory(JdoQueryAnnotationFacetFactory.class);
-
-        programmingModel.addFactory(BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.class);
-        programmingModel.addFactory(MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.class);
-        // must appear after JdoPrimaryKeyAnnotationFacetFactory (above)
-        // and also MandatoryFacetOnPropertyMandatoryAnnotationFactory
-        // and also PropertyAnnotationFactory
-        programmingModel.addFactory(MandatoryFromJdoColumnAnnotationFacetFactory.class);
-
-        programmingModel.addFactory(AuditableAnnotationInJdoApplibFacetFactory.class);
-        programmingModel.addFactory(AuditableMarkerInterfaceInJdoApplibFacetFactory.class);
-    }
-
-    @Override
-    public void refineMetaModelValidator(MetaModelValidatorComposite metaModelValidator, IsisConfiguration configuration) {
-        metaModelValidator.add(new JdoMetaModelValidator());
-    }
-
-    //endregion
-
-    //region > createPersisenceSession
 
+    //region > createPersistenceSession
 
     /**
      * Called by {@link org.apache.isis.core.runtime.system.session.IsisSessionFactory#openSession(AuthenticationSession)}.
      */
     public PersistenceSession createPersistenceSession(
+            final ServicesInjectorSpi servicesInjector,
             final SpecificationLoaderSpi specificationLoader,
             final AuthenticationSession authenticationSession) {
-        return new PersistenceSession(this, getConfiguration(), specificationLoader, authenticationSession);
+
+        final FixturesInstalledFlag fixturesInstalledFlag = this;
+        final PersistenceManagerFactory persistenceManagerFactory =
+                applicationComponents.getPersistenceManagerFactory();
+
+        return new PersistenceSession(
+                configuration, servicesInjector, specificationLoader,
+                authenticationSession, persistenceManagerFactory, fixturesInstalledFlag);
     }
 
     DataNucleusApplicationComponents getApplicationComponents() {
@@ -282,17 +194,5 @@ public class PersistenceSessionFactory implements MetaModelRefiner,
 
     //endregion
 
-    //region > dependencies (from init)
-
-    protected SpecificationLoaderSpi getSpecificationLoader() {
-        return specificationLoader;
-    }
-
-    @Override
-    public void setSpecificationLoaderSpi(final SpecificationLoaderSpi specificationLoader) {
-        this.specificationLoader = specificationLoader;
-    }
-
-    //endregion
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
new file mode 100644
index 0000000..f8b4428
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionFactoryMetamodelRefiner.java
@@ -0,0 +1,53 @@
+package org.apache.isis.core.runtime.system.persistence;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidatorComposite;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableAnnotationInJdoApplibFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.auditable.AuditableMarkerInterfaceInJdoApplibFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.datastoreidentity.JdoDatastoreIdentityAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.discriminator.JdoDiscriminatorAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.persistencecapable.JdoPersistenceCapableAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.object.version.JdoVersionAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.BigDecimalDerivedFromJdoColumnAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.MandatoryFromJdoColumnAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.column.MaxLengthDerivedFromJdoColumnAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.notpersistent.JdoNotPersistentAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.facets.prop.primarykey.JdoPrimaryKeyAnnotationFacetFactory;
+import org.apache.isis.objectstore.jdo.metamodel.specloader.validator.JdoMetaModelValidator;
+
+public class PersistenceSessionFactoryMetamodelRefiner implements MetaModelRefiner {
+
+    @Override
+    public void refineProgrammingModel(ProgrammingModel programmingModel, IsisConfiguration configuration) {
+        programmingModel.addFactory(
+                JdoPersistenceCapableAnnotationFacetFactory.class, ProgrammingModel.Position.BEGINNING);
+        programmingModel.addFactory(JdoDatastoreIdentityAnnotationFacetFactory.class);
+
+        programmingModel.addFactory(JdoPrimaryKeyAnnotationFacetFactory.class);
+        programmingModel.addFactory(JdoNotPersistentAnnotationFacetFactory.class);
+        programmingModel.addFactory(JdoDiscriminatorAnnotationFacetFactory.class);
+        programmingModel.addFactory(JdoVersionAnnotationFacetFactory.class);
+
+        programmingModel.addFactory(JdoQueryAnnotationFacetFactory.class);
+
+        programmingModel.addFactory(BigDecimalDerivedFromJdoColumnAnnotationFacetFactory.class);
+        programmingModel.addFactory(MaxLengthDerivedFromJdoColumnAnnotationFacetFactory.class);
+        // must appear after JdoPrimaryKeyAnnotationFacetFactory (above)
+        // and also MandatoryFacetOnPropertyMandatoryAnnotationFactory
+        // and also PropertyAnnotationFactory
+        programmingModel.addFactory(MandatoryFromJdoColumnAnnotationFacetFactory.class);
+
+        programmingModel.addFactory(AuditableAnnotationInJdoApplibFacetFactory.class);
+        programmingModel.addFactory(AuditableMarkerInterfaceInJdoApplibFacetFactory.class);
+    }
+
+    @Override
+    public void refineMetaModelValidator(
+            MetaModelValidatorComposite metaModelValidator,
+            IsisConfiguration configuration) {
+        metaModelValidator.add(new JdoMetaModelValidator());
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidAdapterHashMap.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidAdapterHashMap.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidAdapterHashMap.java
new file mode 100644
index 0000000..684e25b
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/OidAdapterHashMap.java
@@ -0,0 +1,131 @@
+/*
+ *  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.isis.core.runtime.system.persistence.adaptermanager;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.commons.components.SessionScopedComponent;
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.Oid;
+
+/**
+ * A map of the objects' identities and the adapters' of the objects.
+ */
+public class OidAdapterHashMap implements DebuggableWithTitle, Iterable<Oid>, SessionScopedComponent {
+
+    private static final Logger LOG = LoggerFactory.getLogger(OidAdapterHashMap.class);
+    public static final int DEFAULT_OID_ADAPTER_MAP_SIZE = 100;
+
+    private final Map<Oid, ObjectAdapter> adapterByOidMap = Maps.newHashMapWithExpectedSize(DEFAULT_OID_ADAPTER_MAP_SIZE);
+
+    //region > open, close
+
+    public void open() {
+        // nothing to do
+    }
+
+    public void close() {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("close");
+        }
+        adapterByOidMap.clear();
+    }
+
+    //endregion
+
+    //region > add, remove
+    /**
+     * Add an adapter for a given oid
+     */
+    public void add(final Oid oid, final ObjectAdapter adapter) {
+
+        adapterByOidMap.put(oid, adapter);
+        // log at end so that if toString needs adapters they're in maps.
+        if (LOG.isDebugEnabled()) {
+            // do not call toString() on adapter because would call hashCode on
+            // the pojo,
+            // which for Hibernate PersistentCollections would trigger a
+            // resolve.
+            LOG.debug("add oid: " + oid + " ; oid.hashCode: + #" + Long.toHexString(oid.hashCode()) + " ; adapter.hashCode(): #" + Long.toHexString(adapter.hashCode()));
+        }
+    }
+
+    /**
+     * Remove the adapter for the given oid
+     * 
+     * @return <tt>true</tt> if an adapter was removed.
+     */
+    public boolean remove(final Oid oid) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("remove oid: " + oid);
+        }
+        return adapterByOidMap.remove(oid) != null;
+    }
+
+    //endregion
+
+    //region > getAdapter, iterator
+    /**
+     * Get the adapter identified by the specified OID.
+     */
+    public ObjectAdapter getAdapter(final Oid oid) {
+        return adapterByOidMap.get(oid);
+    }
+
+    @Override
+    public Iterator<Oid> iterator() {
+        return adapterByOidMap.keySet().iterator();
+    }
+
+    //endregion
+
+    //region > debugging
+
+    @Override
+    public String debugTitle() {
+        return "Identity adapter map";
+    }
+
+    @Override
+    public void debugData(final DebugBuilder debug) {
+        int count = 1;
+        final Map<Oid, ObjectAdapter> copyForDebug = Maps.newHashMap(adapterByOidMap);
+        for (final Map.Entry<Oid, ObjectAdapter> entry : copyForDebug.entrySet()) {
+            Oid oid = entry.getKey();
+            final ObjectAdapter adapter = entry.getValue();
+            debug.append(count++, 5);
+            debug.append(" '");
+            debug.append(oid.toString(), 15);
+            debug.append("'    ");
+            debug.appendln(adapter != null ? adapter.toString() : "(MISSING OBJECT ?!)");
+        }
+    }
+
+    //endregion
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/PojoAdapterHashMap.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/PojoAdapterHashMap.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/PojoAdapterHashMap.java
new file mode 100644
index 0000000..9a810a4
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/PojoAdapterHashMap.java
@@ -0,0 +1,161 @@
+/*
+ *  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.isis.core.runtime.system.persistence.adaptermanager;
+
+import java.util.Iterator;
+import java.util.Map;
+
+import com.google.common.collect.Maps;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.core.commons.components.SessionScopedComponent;
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.core.commons.debug.DebuggableWithTitle;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+
+public class PojoAdapterHashMap implements DebuggableWithTitle, Iterable<ObjectAdapter>, SessionScopedComponent {
+
+    private static class IdentityHashKey {
+        private final Object pojo;
+
+        public IdentityHashKey(final Object pojo) {
+            this.pojo = pojo;
+        }
+
+        @Override
+        public int hashCode() {
+            return System.identityHashCode(pojo);
+        }
+
+        @Override
+        public boolean equals(final Object obj) {
+            return obj == this || (obj instanceof IdentityHashKey && ((IdentityHashKey) obj).pojo == pojo);
+        }
+    }
+
+    private static final Logger LOG = LoggerFactory.getLogger(PojoAdapterHashMap.class);
+    public static final int DEFAULT_POJO_ADAPTER_MAP_SIZE = OidAdapterHashMap.DEFAULT_OID_ADAPTER_MAP_SIZE;
+
+    protected final Map<Object, ObjectAdapter> adapterByPojoMap;
+
+    //region > Constructors, finalize
+    public PojoAdapterHashMap() {
+        this(DEFAULT_POJO_ADAPTER_MAP_SIZE);
+    }
+
+    public PojoAdapterHashMap(final int capacity) {
+        adapterByPojoMap = Maps.newHashMapWithExpectedSize(capacity);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("finalizing hash of pojos");
+        }
+    }
+    //endregion
+
+    //region > open, close
+
+    public void open() {
+        // nothing to do
+    }
+
+    public void close() {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("close");
+        }
+        adapterByPojoMap.clear();
+    }
+
+    //endregion
+
+    //region > add, remove
+
+    public void add(final Object pojo, final ObjectAdapter adapter) {
+        adapterByPojoMap.put(key(pojo), adapter);
+
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("add adapter: #" + key(pojo) + " -> #" + Long.toHexString(adapter.hashCode()));
+
+        }
+    }
+
+    public void remove(final ObjectAdapter object) {
+        if(LOG.isDebugEnabled()) {
+            LOG.debug("remove adapter: " + object);
+        }
+        adapterByPojoMap.remove(key(object.getObject()));
+    }
+
+    //endregion
+
+    //region > getAdapter, containsPojo
+
+    public boolean containsPojo(final Object pojo) {
+        return adapterByPojoMap.containsKey(key(pojo));
+    }
+
+    public ObjectAdapter getAdapter(final Object pojo) {
+        return adapterByPojoMap.get(key(pojo));
+    }
+
+    //endregion
+
+    //region > iterator, key
+    @Override
+    public Iterator<ObjectAdapter> iterator() {
+        return adapterByPojoMap.values().iterator();
+    }
+
+    private Object key(final Object pojo) {
+        return new IdentityHashKey(pojo);
+    }
+
+    //endregion
+
+    //region > Debugging
+
+    @Override
+    public void debugData(final DebugBuilder debug) {
+        int count = 0;
+        final Map<Object, ObjectAdapter> copyForDebug = Maps.newHashMap(adapterByPojoMap);
+        for (final Map.Entry<Object, ObjectAdapter> entry : copyForDebug.entrySet()) {
+            Object pojo = entry.getKey();
+            final ObjectAdapter object = entry.getValue();
+            debug.append(count++ + 1, 5);
+            debug.append(" '");
+            debug.append(pojo.toString(), 50);
+            debug.append("'    ");
+            debug.appendln(object.toString());
+        }
+    }
+
+    @Override
+    public String debugTitle() {
+        return "POJO Adapter Hashtable";
+    }
+
+    //endregion
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
new file mode 100644
index 0000000..4a35fe0
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/persistence/adaptermanager/RootAndCollectionAdapters.java
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.runtime.system.persistence.adaptermanager;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import com.google.common.collect.Maps;
+
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.oid.ParentedCollectionOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.spec.feature.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+
+/**
+ * A root {@link ObjectAdapter adapter} along with aggregated {@link ObjectAdapter adapters}
+ * for any of its {@link OneToManyAssociation collection}s that are currently present in
+ * the {@link AdapterManager map}s.
+ * 
+ * <p>
+ * Used for &quot;impact analysis&quot; when persisting transient root objects; all aggregated adapters
+ * must also be persisted.
+ */
+public class RootAndCollectionAdapters implements Iterable<ObjectAdapter> {
+
+    private final ObjectAdapter parentAdapter;
+    private final RootOid rootAdapterOid;
+    
+    private final Map<OneToManyAssociation, ObjectAdapter> collectionAdapters = Maps.newLinkedHashMap();
+
+    public RootAndCollectionAdapters(
+            final ObjectAdapter parentAdapter,
+            final AdapterManager adapterManager) {
+        Assert.assertNotNull(parentAdapter);
+        this.rootAdapterOid = (RootOid) parentAdapter.getOid();
+        this.parentAdapter = parentAdapter;
+        addCollectionAdapters(adapterManager);
+    }
+
+    public ObjectAdapter getRootAdapter() {
+        return parentAdapter;
+    }
+
+    /**
+     * Iterate over the
+     * {@link #addCollectionAdapter(OneToManyAssociation, ObjectAdapter)
+     * collection adapter}s (does not include the {@link #getRootAdapter() root
+     * adapter}.
+     */
+    @Override
+    public Iterator<ObjectAdapter> iterator() {
+        return getCollectionAdapters().values().iterator();
+    }
+
+    /**
+     * Which collections are present?
+     * @return
+     */
+    public Set<OneToManyAssociation> getCollections() {
+        return getCollectionAdapters().keySet();
+    }
+
+    /**
+     * Corresponding adapter for each collection (values).
+     * 
+     * @see #getCollections()
+     */
+    public ObjectAdapter getCollectionAdapter(final OneToManyAssociation otma) {
+        return collectionAdapters.get(otma);
+    }
+
+    
+    ////////////////////////////////////////////////////////////////////////
+    // Helpers
+    ////////////////////////////////////////////////////////////////////////
+
+    private void addCollectionAdapters(AdapterManager objectAdapterLookup) {
+        for (final OneToManyAssociation otma : parentAdapter.getSpecification().getCollections(Contributed.EXCLUDED)) {
+            final ParentedCollectionOid collectionOid = new ParentedCollectionOid((RootOid) rootAdapterOid, otma);
+            final ObjectAdapter collectionAdapter = objectAdapterLookup.getAdapterFor(collectionOid);
+            if (collectionAdapter != null) {
+                // collection adapters are lazily created and so there may not be one.
+                addCollectionAdapter(otma, collectionAdapter);
+            }
+        }
+    }
+
+    private void addCollectionAdapter(final OneToManyAssociation otma, final ObjectAdapter collectionAdapter) {
+        Assert.assertNotNull(otma);
+        Assert.assertNotNull(collectionAdapter);
+        collectionAdapters.put(otma, collectionAdapter);
+    }
+
+    private Map<OneToManyAssociation, ObjectAdapter> getCollectionAdapters() {
+        return Collections.unmodifiableMap(collectionAdapters);
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactory.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactory.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactory.java
index d8001fb..48267b1 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactory.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactory.java
@@ -24,6 +24,8 @@ import java.util.List;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
 import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -68,6 +70,7 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
     private final DeploymentType deploymentType;
     private final IsisConfiguration configuration;
     private final SpecificationLoaderSpi specificationLoaderSpi;
+    private final ServicesInjectorSpi servicesInjector;
     private final AuthenticationManager authenticationManager;
     private final AuthorizationManager authorizationManager;
     private final PersistenceSessionFactory persistenceSessionFactory;
@@ -76,6 +79,7 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
     public IsisSessionFactory(
             final DeploymentType deploymentType,
             final IsisConfiguration configuration,
+            final ServicesInjectorSpi servicesInjector,
             final SpecificationLoaderSpi specificationLoader,
             final AuthenticationManager authenticationManager,
             final AuthorizationManager authorizationManager,
@@ -84,6 +88,7 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
         ensureThatArg(deploymentType, is(not(nullValue())));
         ensureThatArg(configuration, is(not(nullValue())));
         ensureThatArg(specificationLoader, is(not(nullValue())));
+        ensureThatArg(servicesInjector, is(not(nullValue())));
         ensureThatArg(authenticationManager, is(not(nullValue())));
         ensureThatArg(authorizationManager, is(not(nullValue())));
         ensureThatArg(persistenceSessionFactory, is(not(nullValue())));
@@ -93,8 +98,9 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
         this.specificationLoaderSpi = specificationLoader;
         this.authenticationManager = authenticationManager;
         this.authorizationManager = authorizationManager;
+        this.servicesInjector = servicesInjector;
         this.persistenceSessionFactory = persistenceSessionFactory;
-        this.oidMarshaller = new OidMarshaller();;
+        this.oidMarshaller = new OidMarshaller();
     }
 
 
@@ -107,8 +113,17 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
      * Wires components as necessary, and then init}ializes all.
      */
     public void init() {
-        final ServicesInjectorSpi servicesInjector = persistenceSessionFactory.getServicesInjector();
-        specificationLoaderSpi.setServiceInjector(servicesInjector);
+
+        // a bit of a workaround, but required if anything in the metamodel (for
+        // example, a
+        // ValueSemanticsProvider for a date value type) needs to use the Clock
+        // singleton
+        // we do this after loading the services to allow a service to prime a
+        // different clock
+        // implementation (eg to use an NTP time service).
+        if (!deploymentType.isProduction() && !Clock.isInitialized()) {
+            FixtureClock.initialize();
+        }
 
         specificationLoaderSpi.init();
 
@@ -117,6 +132,9 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
 
         authenticationManager.init();
         authorizationManager.init();
+
+        servicesInjector.init();
+
         persistenceSessionFactory.init();
     }
 
@@ -135,7 +153,8 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
      */
     public IsisSession openSession(final AuthenticationSession authenticationSession) {
         final PersistenceSession persistenceSession =
-                persistenceSessionFactory.createPersistenceSession(getSpecificationLoader(), authenticationSession);
+                persistenceSessionFactory.createPersistenceSession(
+                        servicesInjector, getSpecificationLoader(), authenticationSession);
         ensureThatArg(persistenceSession, is(not(nullValue())));
 
         return newIsisSession(authenticationSession, persistenceSession);
@@ -199,7 +218,7 @@ public class IsisSessionFactory implements ApplicationScopedComponent {
     }
 
     public List<Object> getServices() {
-        return getPersistenceSessionFactory().getServicesInjector().getRegisteredServices();
+        return servicesInjector.getRegisteredServices();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index 42a1cb0..b2bbeb0 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@ -22,7 +22,6 @@ package org.apache.isis.core.runtime.systemusinginstallers;
 import java.util.Collection;
 import java.util.List;
 
-import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
 import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
@@ -30,7 +29,6 @@ import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authorization.AuthorizationManager;
 import org.apache.isis.core.runtime.fixtures.FixturesInstaller;
-import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.core.runtime.system.IsisSystemException;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
@@ -51,12 +49,14 @@ public interface IsisComponentProvider {
 
     FixturesInstaller provideFixturesInstaller();
 
-    SpecificationLoaderSpi provideSpecificationLoaderSpi(Collection<MetaModelRefiner> metaModelRefiners)
+    SpecificationLoaderSpi provideSpecificationLoaderSpi(
+            final DeploymentType deploymentType,
+            Collection<MetaModelRefiner> metaModelRefiners)
             throws IsisSystemException;
 
     PersistenceSessionFactory providePersistenceSessionFactory(
             final DeploymentType deploymentType,
             final ServicesInjectorSpi servicesInjectorSpi,
-            final RuntimeContextFromSession runtimeContext);
+            final SpecificationLoaderSpi specificationLoader);
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderDefault2.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderDefault2.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderDefault2.java
new file mode 100644
index 0000000..2f112c4
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderDefault2.java
@@ -0,0 +1,287 @@
+/*
+ *  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.isis.core.runtime.systemusinginstallers;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.fixtures.InstallableFixture;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.commons.resource.ResourceStreamSourceContextLoaderClassPath;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
+import org.apache.isis.core.metamodel.facetdecorator.FacetDecorator;
+import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
+import org.apache.isis.core.metamodel.layoutmetadata.json.LayoutMetadataReaderFromJson;
+import org.apache.isis.core.metamodel.metamodelvalidator.dflt.MetaModelValidatorDefault;
+import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
+import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
+import org.apache.isis.core.runtime.authentication.AuthenticationManager;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
+import org.apache.isis.core.runtime.authentication.standard.AuthenticationManagerStandard;
+import org.apache.isis.core.runtime.authentication.standard.Authenticator;
+import org.apache.isis.core.runtime.authentication.standard.AuthenticatorAbstract;
+import org.apache.isis.core.runtime.authorization.AuthorizationManager;
+import org.apache.isis.core.runtime.authorization.standard.AuthorizationManagerStandard;
+import org.apache.isis.core.runtime.fixtures.FixturesInstaller;
+import org.apache.isis.core.runtime.fixtures.FixturesInstallerFromConfiguration;
+import org.apache.isis.core.runtime.services.ServicesInstallerFromConfiguration;
+import org.apache.isis.core.runtime.services.ServicesInstallerFromConfigurationAndAnnotation;
+import org.apache.isis.core.runtime.system.DeploymentType;
+import org.apache.isis.core.runtime.system.IsisSystemException;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
+import org.apache.isis.core.runtime.transaction.facetdecorator.standard.StandardTransactionFacetDecorator;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller;
+import org.apache.isis.progmodels.dflt.JavaReflectorHelper;
+import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
+
+public class IsisComponentProviderDefault2 extends IsisComponentProviderAbstract {
+
+    private final ProgrammingModel programmingModel;
+    private final MetaModelValidator metaModelValidator;
+
+    public IsisComponentProviderDefault2(
+            final DeploymentType deploymentType,
+            final AppManifest appManifestIfAny,
+            final List<Object> servicesOverride,
+            final List<InstallableFixture> fixturesOverride,
+            final IsisConfiguration configurationOverride,
+            final ProgrammingModel programmingModelOverride,
+            final MetaModelValidator metaModelValidatorOverride) {
+        super(deploymentType, appManifestIfAny);
+
+        this.configuration = elseDefault(configurationOverride);
+
+        final String fixtureClassNamesCsv;
+        if(appManifest != null) {
+
+            putAppManifestKey(appManifest);
+            registerPackageNames(appManifest);
+            specifyServicesAndRegisteredEntitiesUsing(appManifest);
+
+            List<Class<? extends FixtureScript>> fixtureClasses = appManifest.getFixtures();
+            fixtureClassNamesCsv = classNamesFrom(fixtureClasses);
+
+            overrideConfigurationUsing(appManifest);
+
+            this.services = createServices(configuration);
+
+        } else {
+            fixtureClassNamesCsv = classNamesFrom(fixturesOverride);
+
+            this.services = elseDefault(servicesOverride, configuration);
+        }
+
+        putConfigurationProperty(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
+        this.fixturesInstaller = createFixturesInstaller(configuration);
+
+        // integration tests ignore appManifest for authentication and authorization.
+        this.authenticationManager = createAuthenticationManager(configuration);
+        this.authorizationManager = createAuthorizationManager(configuration);
+
+        this.programmingModel = elseDefault(programmingModelOverride, configuration);
+        this.metaModelValidator = elseDefault(metaModelValidatorOverride);
+
+    }
+
+
+
+    //region > appManifest
+
+    private List<Object> createServices(final IsisConfiguration configuration) {
+        final ServicesInstallerFromConfigurationAndAnnotation servicesInstaller =
+                new ServicesInstallerFromConfigurationAndAnnotation();
+        servicesInstaller.setConfiguration(configuration);
+        return servicesInstaller.getServices();
+    }
+
+
+    @Override
+    protected void doPutConfigurationProperty(final String key, final String value) {
+        // bit hacky :-(
+        IsisConfigurationDefault configurationDefault = (IsisConfigurationDefault) this.configuration;
+        configurationDefault.put(key, value);
+    }
+
+    //endregion
+
+    /**
+     * Default will read <tt>isis.properties</tt> (and other optional property files) from the &quot;config&quot;
+     * package on the current classpath.
+     */
+    private static IsisConfigurationDefault elseDefault(final IsisConfiguration configuration) {
+        return configuration != null
+                ? (IsisConfigurationDefault) configuration
+                : new IsisConfigurationDefault(ResourceStreamSourceContextLoaderClassPath.create("config"));
+    }
+
+    private static List<Object> elseDefault(
+            final List<Object> servicesOverride,
+            final IsisConfiguration configuration) {
+        return servicesOverride != null
+                ? servicesOverride
+                : createDefaultServices(configuration);
+    }
+
+    private static List<Object> createDefaultServices(
+            final IsisConfiguration configuration) {
+        final ServicesInstallerFromConfiguration servicesInstaller = new ServicesInstallerFromConfiguration();
+        servicesInstaller.setConfiguration(configuration);
+        return servicesInstaller.getServices();
+    }
+
+
+    private static ProgrammingModel elseDefault(final ProgrammingModel programmingModel, final IsisConfiguration configuration) {
+        return programmingModel != null
+                ? programmingModel
+                : createDefaultProgrammingModel(configuration);
+    }
+
+    // TODO: this is duplicating logic in JavaReflectorInstallerNoDecorators; need to unify.
+    private static ProgrammingModel createDefaultProgrammingModel(final IsisConfiguration configuration) {
+        final ProgrammingModelFacetsJava5 programmingModel = new ProgrammingModelFacetsJava5();
+
+        ProgrammingModel.Util.includeFacetFactories(configuration, programmingModel);
+        ProgrammingModel.Util.excludeFacetFactories(configuration, programmingModel);
+        return programmingModel;
+    }
+
+    private static MetaModelValidator elseDefault(final MetaModelValidator metaModelValidator) {
+        return metaModelValidator != null
+                ? metaModelValidator
+                : new MetaModelValidatorDefault();
+    }
+
+    private static FixturesInstaller createFixturesInstaller(final IsisConfiguration configuration) {
+        final FixturesInstallerFromConfiguration fixturesInstallerFromConfiguration = new FixturesInstallerFromConfiguration();
+        fixturesInstallerFromConfiguration.setConfiguration(configuration);
+        return fixturesInstallerFromConfiguration;
+    }
+
+    /**
+     * The standard authentication manager, configured with the default authenticator (allows all requests through).
+     */
+    private static AuthenticationManager createAuthenticationManager(final IsisConfiguration configuration) {
+        final AuthenticationManagerStandard authenticationManager = new AuthenticationManagerStandard(configuration);
+        Authenticator authenticator = new AuthenticatorBypass(configuration);
+        authenticationManager.addAuthenticator(authenticator);
+        return authenticationManager;
+    }
+
+    private static class AuthenticatorBypass extends AuthenticatorAbstract {
+
+        public AuthenticatorBypass(final IsisConfiguration configuration) {
+            super(configuration);
+        }
+
+        @Override
+        public boolean isValid(final AuthenticationRequest request) {
+            return true;
+        }
+
+        @Override
+        public boolean canAuthenticate(final Class<? extends AuthenticationRequest> authenticationRequestClass) {
+            return true;
+        }
+
+    }
+
+
+    /**
+     * The standard authorization manager, allowing all access.
+     */
+    private static AuthorizationManager createAuthorizationManager(final IsisConfiguration configuration) {
+        return new AuthorizationManagerStandard(configuration);
+    }
+
+
+    @Override
+    public DeploymentType getDeploymentType() {
+        return deploymentType;
+    }
+
+    @Override
+    public IsisConfigurationDefault getConfiguration() {
+        return configuration;
+    }
+
+    @Override
+    public List<Object> provideServices() {
+        return services;
+    }
+
+    @Override
+    public FixturesInstaller provideFixturesInstaller()  {
+        return fixturesInstaller;
+    }
+
+    @Override
+    public SpecificationLoaderSpi provideSpecificationLoaderSpi(
+            final DeploymentType deploymentType,
+            Collection<MetaModelRefiner> metaModelRefiners) throws IsisSystemException {
+
+        final DeploymentCategory deploymentCategory = deploymentType.getDeploymentCategory();
+
+        final Set<FacetDecorator> facetDecorators =
+                Sets.newHashSet((FacetDecorator) new StandardTransactionFacetDecorator(getConfiguration()));
+        final List<LayoutMetadataReader> layoutMetadataReaders =
+                Lists.<LayoutMetadataReader>newArrayList(new LayoutMetadataReaderFromJson());
+
+        return JavaReflectorHelper
+                .createObjectReflector(
+                        deploymentCategory, getConfiguration(), programmingModel,
+                        metaModelRefiners,
+                        facetDecorators, layoutMetadataReaders,
+                        metaModelValidator
+                );
+    }
+
+    @Override
+    public AuthenticationManager provideAuthenticationManager(DeploymentType deploymentType) {
+        return authenticationManager;
+    }
+
+    @Override
+    public AuthorizationManager provideAuthorizationManager(DeploymentType deploymentType) {
+        return authorizationManager;
+    }
+
+    @Override
+    public PersistenceSessionFactory providePersistenceSessionFactory(
+            DeploymentType deploymentType,
+            final ServicesInjectorSpi servicesInjectorSpi,
+            final SpecificationLoaderSpi specificationLoader) {
+        DataNucleusPersistenceMechanismInstaller installer =
+                new DataNucleusPersistenceMechanismInstaller();
+        return installer.createPersistenceSessionFactory(
+                deploymentType, configuration, servicesInjectorSpi
+        );
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
index 7fc8777..ea2afe4 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderUsingInstallers.java
@@ -34,7 +34,6 @@ import org.apache.isis.core.runtime.authorization.AuthorizationManagerInstaller;
 import org.apache.isis.core.runtime.fixtures.FixturesInstallerFromConfiguration;
 import org.apache.isis.core.runtime.installerregistry.InstallerLookup;
 import org.apache.isis.core.runtime.installerregistry.installerapi.PersistenceMechanismInstaller;
-import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.services.ServicesInstaller;
 import org.apache.isis.core.runtime.services.ServicesInstallerFromConfigurationAndAnnotation;
 import org.apache.isis.core.runtime.system.DeploymentType;
@@ -168,8 +167,9 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
 
     @Override
     public SpecificationLoaderSpi provideSpecificationLoaderSpi(
+            final DeploymentType deploymentType,
             final Collection<MetaModelRefiner> metaModelRefiners) {
-        return reflectorInstaller.createReflector(metaModelRefiners);
+        return reflectorInstaller.createReflector(deploymentType.getDeploymentCategory(), metaModelRefiners);
     }
 
 
@@ -177,10 +177,10 @@ public class IsisComponentProviderUsingInstallers extends IsisComponentProviderA
     public PersistenceSessionFactory providePersistenceSessionFactory(
             final DeploymentType deploymentType,
             final ServicesInjectorSpi servicesInjectorSpi,
-            final RuntimeContextFromSession runtimeContext) {
-        return persistenceMechanismInstaller.createPersistenceSessionFactory(deploymentType, servicesInjectorSpi,
-                getConfiguration(),
-                runtimeContext);
+            final SpecificationLoaderSpi specificationLoader) {
+        return persistenceMechanismInstaller.createPersistenceSessionFactory(
+                    deploymentType, getConfiguration(),
+                    servicesInjectorSpi);
     }
 
     //region > helpers

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
index d32ae01..07cf783 100644
--- a/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
+++ b/core/runtime/src/main/java/org/apache/isis/objectstore/jdo/datanucleus/DataNucleusPersistenceMechanismInstaller.java
@@ -29,7 +29,6 @@ import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.installerregistry.installerapi.PersistenceMechanismInstaller;
-import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.system.DeploymentType;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSessionFactory;
@@ -68,11 +67,10 @@ public class DataNucleusPersistenceMechanismInstaller extends InstallerAbstract
     @Override
     public PersistenceSessionFactory createPersistenceSessionFactory(
             final DeploymentType deploymentType,
-            final ServicesInjectorSpi servicesInjector,
             final IsisConfigurationDefault configuration,
-            final RuntimeContextFromSession runtimeContext) {
+            final ServicesInjectorSpi servicesInjector) {
 
-        return new PersistenceSessionFactory(deploymentType, servicesInjector, configuration, runtimeContext);
+        return new PersistenceSessionFactory(deploymentType, configuration);
     }
     //endregion
 

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/test/java/org/apache/isis/core/runtime/context/IsisContextTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/context/IsisContextTest.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/context/IsisContextTest.java
index 0832126..51afc3a 100644
--- a/core/runtime/src/test/java/org/apache/isis/core/runtime/context/IsisContextTest.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/context/IsisContextTest.java
@@ -29,6 +29,7 @@ import org.apache.isis.core.commons.authentication.AuthenticationSession;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.config.IsisConfigurationDefault;
 import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
+import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authentication.standard.SimpleSession;
@@ -57,6 +58,8 @@ public class IsisContextTest {
     private SpecificationLoaderSpi mockSpecificationLoader;
 
     @Mock
+    protected ServicesInjectorSpi mockServicesInjector;
+    @Mock
     protected PersistenceSessionFactory mockPersistenceSessionFactory;
     @Mock
     protected AuthenticationManager mockAuthenticationManager;
@@ -91,10 +94,10 @@ public class IsisContextTest {
                 mockSpecificationLoader,
                 mockAuthenticationManager,
                 mockAuthorizationManager,
-                mockContainer)
-        ;
+                mockContainer);
 
-        sessionFactory = new IsisSessionFactory(DeploymentType.UNIT_TESTING, configuration, mockSpecificationLoader, mockAuthenticationManager, mockAuthorizationManager, mockPersistenceSessionFactory);
+        sessionFactory = new IsisSessionFactory(DeploymentType.UNIT_TESTING, configuration, mockServicesInjector,
+                mockSpecificationLoader, mockAuthenticationManager, mockAuthorizationManager, mockPersistenceSessionFactory);
         authSession = new SimpleSession("tester", Collections.<String>emptyList());
         
         IsisContext.setConfiguration(configuration);
@@ -121,7 +124,7 @@ public class IsisContextTest {
         // expecting
         context.checking(new Expectations() {{
             one(mockPersistenceSessionFactory)
-                    .createPersistenceSession(mockSpecificationLoader, authSession);
+                    .createPersistenceSession(mockServicesInjector, mockSpecificationLoader, authSession);
             will(returnValue(mockPersistenceSession));
         }});
 

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/core/runtime/src/test/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionTest.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionTest.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionTest.java
index 57e8ffa..35a3dbe 100644
--- a/core/runtime/src/test/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionTest.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/system/persistence/PersistenceSessionTest.java
@@ -21,6 +21,8 @@ package org.apache.isis.core.runtime.system.persistence;
 
 import java.util.Collections;
 
+import javax.jdo.PersistenceManagerFactory;
+
 import org.jmock.Expectations;
 import org.jmock.Sequence;
 import org.jmock.auto.Mock;
@@ -39,11 +41,11 @@ import org.apache.isis.core.metamodel.app.IsisMetaModel;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext;
 import org.apache.isis.core.metamodel.services.ServicesInjectorDefault;
+import org.apache.isis.core.metamodel.services.ServicesInjectorSpi;
 import org.apache.isis.core.metamodel.services.container.DomainObjectContainerDefault;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.metamodel.specloader.InjectorMethodEvaluatorDefault;
 import org.apache.isis.core.runtime.persistence.adapter.PojoAdapter;
-import org.apache.isis.core.runtime.persistence.adaptermanager.AdapterManagerDefault;
 import org.apache.isis.core.runtime.persistence.internal.RuntimeContextFromSession;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.CreateObjectCommand;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.DestroyObjectCommand;
@@ -61,7 +63,6 @@ public class PersistenceSessionTest {
     public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
 
     private ServicesInjectorDefault servicesInjector;
-    private AdapterManagerDefault adapterManager;
 
     
     private PersistenceSession persistenceSession;
@@ -95,16 +96,19 @@ public class PersistenceSessionTest {
     private RuntimeContext mockRuntimeContext;
 
     @Mock
+    private ServicesInjectorSpi mockServicesInjector;
+
+    @Mock
     private IsisConfigurationDefault mockConfiguration;
-    
+
+    @Mock
+    private PersistenceManagerFactory mockPersistenceManager;
+
     @Mock
     private MessageBroker mockMessageBroker;
-    
 
     private IsisMetaModel isisMetaModel;
 
-
-
     public static class Customer {
     }
 
@@ -120,7 +124,7 @@ public class PersistenceSessionTest {
         context.ignoring(mockConfiguration);
         context.ignoring(mockAuditingService3);
 
-        isisMetaModel = new IsisMetaModel(mockRuntimeContext, new ProgrammingModelFacetsJava5(), new CustomerRepository());
+        isisMetaModel = new IsisMetaModel(new ProgrammingModelFacetsJava5(), new CustomerRepository());
         isisMetaModel.init();
         
         context.checking(new Expectations() {
@@ -140,7 +144,8 @@ public class PersistenceSessionTest {
                 new RuntimeContextFromSession(
                         DeploymentCategory.PRODUCTION,
                         mockConfiguration,
-                        servicesInjector);
+                        servicesInjector,
+                        mockSpecificationLoader);
         final DomainObjectContainerDefault container = new DomainObjectContainerDefault();
 
         runtimeContext.injectInto(container);
@@ -148,16 +153,16 @@ public class PersistenceSessionTest {
         servicesInjector = new ServicesInjectorDefault(
                 Collections.<Object>singletonList(container),new InjectorMethodEvaluatorDefault());
 
-        persistenceSession = new PersistenceSession(mockPersistenceSessionFactory, mockConfiguration,
-                mockSpecificationLoader, mockAuthenticationSession) {
+        persistenceSession = new PersistenceSession(mockConfiguration, mockServicesInjector, mockSpecificationLoader,
+                mockAuthenticationSession,
+                mockPersistenceManager, mockPersistenceSessionFactory
+        ) {
             @Override
             protected SpecificationLoaderSpi getSpecificationLoader() {
                 return isisMetaModel.getSpecificationLoader();
             }
             
         };
-        adapterManager = new AdapterManagerDefault(persistenceSession
-        );
 
         context.checking(new Expectations(){{
             allowing(mockAuthenticationSession).getUserName();

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/example/application/simpleapp/dom/pom.xml
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/pom.xml b/example/application/simpleapp/dom/pom.xml
index dae6495..c671dde 100644
--- a/example/application/simpleapp/dom/pom.xml
+++ b/example/application/simpleapp/dom/pom.xml
@@ -153,6 +153,7 @@
                 </dependency>
             </dependencies>
         </profile>
+
         <profile>
             <id>isis-validate</id>
             <activation>
@@ -165,6 +166,7 @@
                         <artifactId>isis-maven-plugin</artifactId>
                         <version>${isis.version}</version>
                         <configuration>
+                            <appManifest>domainapp.dom.DomainAppDomManifest</appManifest>
                             <isisConfigDir>../webapp/src/main/webapp/WEB-INF</isisConfigDir>
                         </configuration>
                         <dependencies>
@@ -195,6 +197,7 @@
                 </plugins>
             </build>
         </profile>
+
     </profiles>
 
 </project>

http://git-wip-us.apache.org/repos/asf/isis/blob/a129fd2d/example/application/simpleapp/dom/src/main/java/domainapp/dom/DomainAppDomManifest.java
----------------------------------------------------------------------
diff --git a/example/application/simpleapp/dom/src/main/java/domainapp/dom/DomainAppDomManifest.java b/example/application/simpleapp/dom/src/main/java/domainapp/dom/DomainAppDomManifest.java
new file mode 100644
index 0000000..c32996f
--- /dev/null
+++ b/example/application/simpleapp/dom/src/main/java/domainapp/dom/DomainAppDomManifest.java
@@ -0,0 +1,92 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package domainapp.dom;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+
+/**
+ * Bootstrap the application.
+ */
+public class DomainAppDomManifest implements AppManifest {
+
+    /**
+     * Load all services and entities found in (the packages and subpackages within) these modules
+     */
+    @Override
+    public List<Class<?>> getModules() {
+        return Arrays.asList(
+                DomainAppDomainModule.class  // domain (entities and repositories)
+        );
+    }
+
+    /**
+     * No additional services.
+     */
+    @Override
+    public List<Class<?>> getAdditionalServices() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Use shiro for authentication.
+     *
+     * <p>
+     *     NB: this is ignored for integration tests, which always use "bypass".
+     * </p>
+     */
+    @Override
+    public String getAuthenticationMechanism() {
+        return "shiro";
+    }
+
+    /**
+     * Use shiro for authorization.
+     *
+     * <p>
+     *     NB: this is ignored for integration tests, which always use "bypass".
+     * </p>
+     */
+    @Override
+    public String getAuthorizationMechanism() {
+        return "shiro";
+    }
+
+    /**
+     * No fixtures.
+     */
+    @Override
+    public List<Class<? extends FixtureScript>> getFixtures() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * No overrides.
+     */
+    @Override
+    public Map<String, String> getConfigurationProperties() {
+        return null;
+    }
+
+}