You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/11/25 13:33:43 UTC

[isis] 02/02: ISIS-2039: moving type discovery to an earlier stage in bootstrapping

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

ahuber pushed a commit to branch 2039-Redesign_of_Config
in repository https://gitbox.apache.org/repos/asf/isis.git

commit 737c773db1fdfbb3c1fbe0998b9e89f917e7aa30
Author: Andi Huber <ah...@apache.org>
AuthorDate: Sun Nov 25 14:33:35 2018 +0100

    ISIS-2039: moving type discovery to an earlier stage in bootstrapping
    
    Integration Test Bootstrapping works.
    
    Task-Url: https://issues.apache.org/jira/browse/ISIS-2039
---
 .../java/org/apache/isis/applib/AppManifest.java   |   5 +-
 .../isis/commons/internal/reflection/_Reflect.java |  37 ++
 core/config/pom.xml                                |  10 +
 .../commons/config/ConfigurationConstants.java     |   1 +
 .../core/commons/config/IsisConfiguration.java     |  19 +-
 .../configbuilder/IsisConfigurationBuilder.java    |   4 +-
 .../IsisConfigurationBuilderDefault.java           |   4 +-
 .../configbuilder/IsisConfigurationDefault.java    |  20 +-
 .../commons/configbuilder/ModulePackageHelper.java | 198 +++++++++
 .../PersistenceCapableTypeFinder.java              |   2 +-
 .../IsisSystemEnvironmentPluginForTesting.java     |   1 +
 .../isis/core/metamodel/facets/Annotations.java    |  32 +-
 .../core/metamodel/progmodel/FacetFactorySet.java  |  56 +--
 .../core/metamodel/services/ServicesInjector.java  |  15 +-
 .../ApplicationFeatureRepositoryDefault.java       |  14 +-
 .../FixturesInstallerFromConfiguration.java        | 136 ++++---
 .../HeadlessWithBootstrappingAbstract.java         |   3 +-
 .../isis/core/runtime/headless/IsisSystem.java     | 127 +++---
 .../runtime/headless/IsisSystemBootstrapper.java   |  86 ++--
 .../services/ServicesInstallerFromAnnotation.java  | 109 ++---
 .../services/email/EmailServiceDefault.java        |   3 -
 .../system/session/IsisSessionFactoryBuilder.java  |   2 +-
 .../IsisComponentProvider.java                     | 442 +++++++++------------
 .../IsisComponentProviderBuilder.java              |  32 +-
 .../IsisComponentProvider_within_Test.java         |   5 +-
 .../wicket/viewer/IsisWicketApplication.java       |  14 +-
 .../viewer/integration/isis/IsisInjectModule.java  |  13 +-
 27 files changed, 797 insertions(+), 593 deletions(-)

diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
index 9bc437e..972f5c0 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest.java
@@ -157,7 +157,7 @@ public interface AppManifest {
      */
     public final static class Registry {
 
-        public final static List<String> FRAMEWORK_PROVIDED_SERVICES = Collections.unmodifiableList(Arrays.asList(
+        public final static List<String> FRAMEWORK_PROVIDED_SERVICE_PACKAGES = Collections.unmodifiableList(Arrays.asList(
                 "org.apache.isis.applib",
                 "org.apache.isis.core.wrapper" ,
                 "org.apache.isis.core.metamodel.services" ,
@@ -167,7 +167,8 @@ public interface AppManifest {
                 "org.apache.isis.viewer.restfulobjects.rendering.service" ,
                 "org.apache.isis.objectstore.jdo.datanucleus.service.support" ,
                 "org.apache.isis.objectstore.jdo.datanucleus.service.eventbus" ,
-                "org.apache.isis.viewer.wicket.viewer.services"));
+                "org.apache.isis.viewer.wicket.viewer.services", 
+                "org.apache.isis.core.integtestsupport.components"));
 
         private static Registry instance = new Registry();
         public static Registry instance() {
diff --git a/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java b/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
index cf4db82..21962c8 100644
--- a/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
+++ b/core/commons/src/main/java/org/apache/isis/commons/internal/reflection/_Reflect.java
@@ -23,6 +23,7 @@ import static org.apache.isis.commons.internal.base._NullSafe.stream;
 import static org.apache.isis.commons.internal.base._With.mapIfPresentElse;
 import static org.apache.isis.commons.internal.base._With.requires;
 
+import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.Member;
 import java.lang.reflect.Method;
@@ -163,6 +164,42 @@ public final class _Reflect {
                 }, false);
     }
 
+    /**
+     * Searches for annotation on provided class, and if not found for the
+     * superclass.
+     */
+    public static <T extends Annotation> T getAnnotation(final Class<?> cls, final Class<T> annotationClass) {
+        if (cls == null) {
+            return null;
+        }
+        final T annotation = cls.getAnnotation(annotationClass);
+        if (annotation != null) {
+            return annotation;
+        }
+
+        // search superclasses
+        final Class<?> superclass = cls.getSuperclass();
+        if (superclass != null) {
+            try {
+                final T annotationFromSuperclass = getAnnotation(superclass, annotationClass);
+                if (annotationFromSuperclass != null) {
+                    return annotationFromSuperclass;
+                }
+            } catch (final SecurityException e) {
+                // fall through
+            }
+        }
+
+        // search implemented interfaces
+        final Class<?>[] interfaces = cls.getInterfaces();
+        for (final Class<?> iface : interfaces) {
+            final T annotationFromInterface = getAnnotation(iface, annotationClass);
+            if (annotationFromInterface != null) {
+                return annotationFromInterface;
+            }
+        }
+        return null;
+    }
 
 
 }
diff --git a/core/config/pom.xml b/core/config/pom.xml
index e5f03f3..f7b2241 100644
--- a/core/config/pom.xml
+++ b/core/config/pom.xml
@@ -63,6 +63,15 @@
             <groupId>org.apache.isis.core</groupId>
             <artifactId>isis-core-applib</artifactId>
         </dependency>
+        
+        <!-- [2039] only to discover persistence capable classes, not required if every 
+        	relevant entity is annotated with @DomainObject-->
+		<dependency>
+        	<groupId>javax.jdo</groupId>
+        	<artifactId>jdo-api</artifactId>
+        	<version>${jdo-api.version}</version>
+        	<scope>provided</scope>
+        </dependency>
     
         <!-- TESTS -->
         <dependency>
@@ -87,6 +96,7 @@
         	<artifactId>isis-core-applib</artifactId>
         	<type>test-jar</type>
         </dependency>
+
     </dependencies>
 
     <profiles>
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/config/ConfigurationConstants.java b/core/config/src/main/java/org/apache/isis/core/commons/config/ConfigurationConstants.java
index 283f666..92f15e2 100644
--- a/core/config/src/main/java/org/apache/isis/core/commons/config/ConfigurationConstants.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/config/ConfigurationConstants.java
@@ -31,6 +31,7 @@ public final class ConfigurationConstants {
     
     /**
      * Key used to lookup {@link AppManifest} (if any) from the {@link IsisConfiguration}.
+     * @deprecated AppManifest lookup changed with 2.0.0-M2
      */
     public static final String APP_MANIFEST_KEY = ConfigurationConstants.ROOT + "appManifest";
 
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/commons/config/IsisConfiguration.java
index b373e03..f63b470 100644
--- a/core/config/src/main/java/org/apache/isis/core/commons/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/config/IsisConfiguration.java
@@ -22,9 +22,10 @@ package org.apache.isis.core.commons.config;
 import java.awt.Color;
 import java.awt.Font;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
-import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.AppManifest2;
 import org.apache.isis.applib.Module;
 import org.apache.isis.applib.PropertyResource;
 import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
@@ -93,7 +94,7 @@ public interface IsisConfiguration {
      * @return
      * @since 2.0.0-M2
      */
-    static IsisConfiguration buildFromAppManifest(AppManifest appManifest) {
+    static IsisConfiguration buildFromAppManifest(AppManifest2 appManifest) {
         clear();
         acceptBuilder(builder->{
             builder.addAppManifest(appManifest);
@@ -101,7 +102,17 @@ public interface IsisConfiguration {
         return getConfiguration();
     }
     
-    public AppManifest getAppManifest();
+    /**
+     * @since 2.0.0-M2
+     */
+    public AppManifest2 getAppManifest();
+
+    /**
+     * @since 2.0.0-M2
+     * @deprecated [2039] only used to trigger type discovery with registration 
+     */
+    public void triggerTypeDiscovery();
+    
 
     /**
      * Creates a new IsisConfiguration containing the properties starting with
@@ -265,4 +276,6 @@ public interface IsisConfiguration {
         return null;
     }
 
+    
+
 }
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
index 172286b..00787ba 100644
--- a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilder.java
@@ -20,7 +20,7 @@ package org.apache.isis.core.commons.configbuilder;
 
 import java.util.List;
 
-import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.AppManifest2;
 import org.apache.isis.applib.Module;
 import org.apache.isis.applib.PropertyResource;
 import org.apache.isis.core.commons.config.IsisConfiguration;
@@ -80,7 +80,7 @@ public interface IsisConfigurationBuilder {
      * @param appManifest
      * @since 2.0.0-M2
      */
-    void addAppManifest(AppManifest appManifest);
+    void addAppManifest(AppManifest2 appManifest);
 
     /** internal only **/
     IsisConfiguration build();
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilderDefault.java b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilderDefault.java
index a43b345..b346843 100644
--- a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilderDefault.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationBuilderDefault.java
@@ -27,7 +27,7 @@ import java.util.Set;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.AppManifest2;
 import org.apache.isis.applib.AppManifestAbstract2;
 import org.apache.isis.applib.Module;
 import org.apache.isis.applib.PropertyResource;
@@ -275,7 +275,7 @@ final class IsisConfigurationBuilderDefault implements IsisConfigurationBuilder
     }
     
     @Override
-    public void addAppManifest(AppManifest appManifest) {
+    public void addAppManifest(AppManifest2 appManifest) {
         configuration.setAppManifest(appManifest);
         appManifest.getConfigurationProperties().forEach((k, v)->{
             put(k, v);
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationDefault.java b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationDefault.java
index 6899f23..a5e8ff6 100644
--- a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationDefault.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/IsisConfigurationDefault.java
@@ -31,7 +31,8 @@ import java.util.StringTokenizer;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.AppManifest2;
+import org.apache.isis.commons.internal.base._Lazy;
 import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -60,7 +61,7 @@ class IsisConfigurationDefault implements IsisConfiguration {
      * derived lazily from {@link #properties}.
      */
     private Properties applicationProperties;
-    private AppManifest appManifest;
+    private AppManifest2 appManifest;
 
     // ////////////////////////////////////////////////
     // Constructor
@@ -84,14 +85,25 @@ class IsisConfigurationDefault implements IsisConfiguration {
     // ////////////////////////////////////////////////
     
     @Override
-    public AppManifest getAppManifest() {
+    public AppManifest2 getAppManifest() {
         return appManifest;
     }
     
-    public void setAppManifest(AppManifest appManifest) {
+    public void setAppManifest(AppManifest2 appManifest) {
         this.appManifest = appManifest;
     }
     
+    // ////////////////////////////////////////////////
+    // Module Package Names
+    // ////////////////////////////////////////////////
+    
+    _Lazy<Integer> typeDiscovery = _Lazy.threadSafe(ModulePackageHelper::triggerTypeDiscovery);
+    
+    @Override
+    public void triggerTypeDiscovery() {
+        typeDiscovery.get();
+    }
+    
     
     // ////////////////////////////////////////////////
     // ResourceStreamSource
diff --git a/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/ModulePackageHelper.java b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/ModulePackageHelper.java
new file mode 100644
index 0000000..6c47d39
--- /dev/null
+++ b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/ModulePackageHelper.java
@@ -0,0 +1,198 @@
+/*
+ *  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.commons.configbuilder;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import javax.annotation.Nullable;
+import javax.xml.bind.annotation.XmlElement;
+
+import org.apache.isis.applib.AppManifest;
+import org.apache.isis.applib.annotation.DomainObject;
+import org.apache.isis.applib.annotation.DomainObjectLayout;
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.DomainServiceLayout;
+import org.apache.isis.applib.annotation.Mixin;
+import org.apache.isis.applib.annotation.Nature;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.annotation.ViewModel;
+import org.apache.isis.applib.annotation.ViewModelLayout;
+import org.apache.isis.applib.fixturescripts.DiscoverableFixtureScript;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.collections._Sets;
+import org.apache.isis.commons.internal.reflection._Reflect;
+import org.apache.isis.config.internal._Config;
+import org.apache.isis.core.plugins.classdiscovery.ClassDiscovery;
+import org.apache.isis.core.plugins.classdiscovery.ClassDiscoveryPlugin;
+
+/**
+ * @since 2.0.0-M2
+ */
+class ModulePackageHelper {
+
+    public static int triggerTypeDiscovery() {
+        
+        final List<String> moduleAndFrameworkPackages = 
+                findAndRegisterTypes(_Config.getConfiguration().getAppManifest());
+        
+        return moduleAndFrameworkPackages.size();
+        
+    }
+    
+    // -- HELPER
+    
+    private static Stream<String> modulePackageNamesFrom(final AppManifest appManifest) {
+        
+        final List<Class<?>> modules = appManifest.getModules();
+        
+        if (modules == null || modules.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "If an appManifest is provided then it must return a non-empty set of modules");
+        }
+
+        return modules.stream()
+                .map(Class::getPackage)
+                .map(Package::getName);
+    }
+    
+    private static List<String> findAndRegisterTypes(final AppManifest appManifest) {
+        
+        System.out.println("!!!!!!!!!!!!!! findAndRegisterTypes");
+        
+        final AppManifest.Registry registry = AppManifest.Registry.instance();
+
+        final List<String> moduleAndFrameworkPackages = _Lists.newArrayList();
+        moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICE_PACKAGES);
+        
+        modulePackageNamesFrom(appManifest)
+            .forEach(moduleAndFrameworkPackages::add);
+
+        final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(moduleAndFrameworkPackages);
+
+        final Set<Class<?>> domainServiceTypes = _Sets.newLinkedHashSet();
+        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainService.class));
+        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainServiceLayout.class));
+        
+        final Set<Class<?>> persistenceCapableTypes = PersistenceCapableTypeFinder.find(discovery);
+
+        final Set<Class<? extends FixtureScript>> fixtureScriptTypes = discovery.getSubTypesOf(FixtureScript.class)
+                .stream()
+                .filter(aClass -> {
+                    // the fixtureScript types are introspected just to provide a drop-down when running fixture scripts
+                    // in prototyping mode (though they may be introspected lazily if actually run).
+                    // we therefore try to limit the set of fixture types eagerly introspected at startup
+                    //
+                    // specifically, we ignore as a fixture script if annotated with @Programmatic
+                    // (though directly implementing DiscoverableFixtureScript takes precedence and will NOT ignore)
+                    return DiscoverableFixtureScript.class.isAssignableFrom(aClass) ||
+                            _Reflect.getAnnotation(aClass, Programmatic.class) == null;
+                })
+                .collect(Collectors.toSet());
+
+        final Set<Class<?>> domainObjectTypes = _Sets.newLinkedHashSet();
+        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObject.class));
+        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObjectLayout.class));
+
+        final Set<Class<?>> mixinTypes = _Sets.newHashSet();
+        mixinTypes.addAll(discovery.getTypesAnnotatedWith(Mixin.class));
+        domainObjectTypes.stream()
+        .filter(input -> {
+            final DomainObject annotation = input.getAnnotation(DomainObject.class);
+            return annotation != null && annotation.nature() == Nature.MIXIN;
+        })
+        .forEach(mixinTypes::add);
+
+        final Set<Class<?>> viewModelTypes = _Sets.newLinkedHashSet();
+        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModel.class));
+        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModelLayout.class));
+
+        final Set<Class<?>> xmlElementTypes = _Sets.newLinkedHashSet();
+        xmlElementTypes.addAll(discovery.getTypesAnnotatedWith(XmlElement.class));
+
+        // add in any explicitly registered services...
+        domainServiceTypes.addAll(appManifest.getAdditionalServices());
+        
+        domainServiceTypes.forEach(s->{
+            if(s.getName().contains("Headless"))
+                System.out.println("!!!!!!!!!!!!!! * "+s);
+        });
+
+        // Reflections seems to have a bug whereby it will return some classes outside the
+        // set of packages that we want (think this is to do with the fact that it matches based on
+        // the prefix and gets it wrong); so we double check and filter out types outside our
+        // required set of packages.
+
+        // for a tiny bit of efficiency, we append a '.' to each package name here, outside the loops
+        final List<String> packagesWithDotSuffix =
+                moduleAndFrameworkPackages.stream()
+                .map(s -> s != null ? s + "." : null)
+                .collect(Collectors.toList());
+
+        registry.setDomainServiceTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainServiceTypes));
+        registry.setPersistenceCapableTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, persistenceCapableTypes));
+        registry.setFixtureScriptTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, fixtureScriptTypes));
+        registry.setMixinTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, mixinTypes));
+        registry.setDomainObjectTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainObjectTypes));
+        registry.setViewModelTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, viewModelTypes));
+        registry.setXmlElementTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, xmlElementTypes));
+        
+        return moduleAndFrameworkPackages;
+    }
+    
+    static <T> Set<Class<? extends T>> withinPackageAndNotAnonymous(
+            final Collection<String> packageNames,
+            final Set<Class<? extends T>> classes) {
+        
+        final Set<Class<? extends T>> classesWithin = _Sets.newLinkedHashSet();
+        for (Class<? extends T> clz : classes) {
+            final String className = clz.getName();
+            if(containedWithin(packageNames, className) && notAnonymous(clz)) {
+                classesWithin.add(clz);
+            }
+        }
+        return classesWithin;
+    }
+    
+    static private boolean containedWithin(final Collection<String> packageNames, final String className) {
+        for (String packageName : packageNames) {
+            if (className.startsWith(packageName)) {
+                return true;
+            }
+        }
+        System.out.println("!!! skipping " + className);
+        
+        return false;
+    }
+
+    private static <T> boolean notAnonymous(final Class<? extends T> clz) {
+        try {
+            return !clz.isAnonymousClass();
+        } catch(NoClassDefFoundError error) {
+            return false; // ignore, assume anonymous
+        }
+    }
+    
+    
+}
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/PersistenceCapableTypeFinder.java b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/PersistenceCapableTypeFinder.java
similarity index 97%
rename from core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/PersistenceCapableTypeFinder.java
rename to core/config/src/main/java/org/apache/isis/core/commons/configbuilder/PersistenceCapableTypeFinder.java
index a7f402a..9a381d2 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/PersistenceCapableTypeFinder.java
+++ b/core/config/src/main/java/org/apache/isis/core/commons/configbuilder/PersistenceCapableTypeFinder.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.core.runtime.systemusinginstallers;
+package org.apache.isis.core.commons.configbuilder;
 
 import java.lang.annotation.Annotation;
 import java.util.LinkedHashSet;
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/components/IsisSystemEnvironmentPluginForTesting.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/components/IsisSystemEnvironmentPluginForTesting.java
index 822598c..7241f24 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/components/IsisSystemEnvironmentPluginForTesting.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/components/IsisSystemEnvironmentPluginForTesting.java
@@ -11,6 +11,7 @@ import org.apache.isis.core.plugins.environment.IsisSystemEnvironmentPlugin;
  * Java 7 ServiceLoader mechanism.
  *  
  * @since 2.0.0-M2
+ * @deprecated [2039] experimental
  */
 public class IsisSystemEnvironmentPluginForTesting implements IsisSystemEnvironmentPlugin {
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
index 7032cb5..75a73ff 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/Annotations.java
@@ -45,6 +45,7 @@ import org.apache.isis.applib.annotation.PropertyLayout;
 import org.apache.isis.applib.annotation.Title;
 import org.apache.isis.commons.internal.base._Casts;
 import org.apache.isis.commons.internal.collections._Lists;
+import org.apache.isis.commons.internal.reflection._Reflect;
 import org.apache.isis.core.commons.lang.ThrowableExtensions;
 import org.apache.isis.core.commons.reflection.Reflect;
 import org.apache.isis.core.metamodel.exceptions.MetaModelException;
@@ -84,36 +85,7 @@ public final class Annotations  {
      * Added to allow bytecode-mangling libraries such as CGLIB to be supported.
      */
     public static <T extends Annotation> T getAnnotation(final Class<?> cls, final Class<T> annotationClass) {
-        if (cls == null) {
-            return null;
-        }
-        final T annotation = cls.getAnnotation(annotationClass);
-        if (annotation != null) {
-            return annotation;
-        }
-
-        // search superclasses
-        final Class<?> superclass = cls.getSuperclass();
-        if (superclass != null) {
-            try {
-                final T annotationFromSuperclass = getAnnotation(superclass, annotationClass);
-                if (annotationFromSuperclass != null) {
-                    return annotationFromSuperclass;
-                }
-            } catch (final SecurityException e) {
-                // fall through
-            }
-        }
-
-        // search implemented interfaces
-        final Class<?>[] interfaces = cls.getInterfaces();
-        for (final Class<?> iface : interfaces) {
-            final T annotationFromInterface = getAnnotation(iface, annotationClass);
-            if (annotationFromInterface != null) {
-                return annotationFromInterface;
-            }
-        }
-        return null;
+        return _Reflect.getAnnotation(cls, annotationClass);
     }
 
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/FacetFactorySet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/FacetFactorySet.java
index 7f34c46..6a9a994 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/FacetFactorySet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/progmodel/FacetFactorySet.java
@@ -21,6 +21,7 @@ package org.apache.isis.core.metamodel.progmodel;
 
 import java.util.List;
 
+import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.commons.config.ConfigurationConstants;
 import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
@@ -65,32 +66,10 @@ public interface FacetFactorySet {
     class Util {
         private Util(){}
 
-        public static void includeFacetFactories(
-                final IsisConfigurationBuilder configurationBuilder, 
-                final FacetFactorySet programmingModel) {
-            
-            final String[] facetFactoriesIncludeClassNames = configurationBuilder.peekAtList(ReflectorConstants.FACET_FACTORY_INCLUDE_CLASS_NAME_LIST);
-            if (facetFactoriesIncludeClassNames != null) {
-                for (final String facetFactoryClassName : facetFactoriesIncludeClassNames) {
-                    final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
-                    programmingModel.addFactory(facetFactory);
-                }
-            }
-        }
-
-        public static void excludeFacetFactories(
-                final IsisConfigurationBuilder configurationBuilder, 
-                final FacetFactorySet programmingModel) {
-            
-            final String[] facetFactoriesExcludeClassNames = configurationBuilder.peekAtList(ReflectorConstants.FACET_FACTORY_EXCLUDE_CLASS_NAME_LIST);
-            for (final String facetFactoryClassName : facetFactoriesExcludeClassNames) {
-                final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
-                programmingModel.removeFactory(facetFactory);
-            }
-        }
-        
-//        public static void includeFacetFactories(final IsisConfiguration configuration, final FacetFactorySet programmingModel) {
-//            final String[] facetFactoriesIncludeClassNames = configuration.getList(ReflectorConstants.FACET_FACTORY_INCLUDE_CLASS_NAME_LIST);
+//[2039]        
+//        public static void includeFacetFactories(final FacetFactorySet programmingModel) {
+//            
+//            final String[] facetFactoriesIncludeClassNames = configurationBuilder.peekAtList(ReflectorConstants.FACET_FACTORY_INCLUDE_CLASS_NAME_LIST);
 //            if (facetFactoriesIncludeClassNames != null) {
 //                for (final String facetFactoryClassName : facetFactoriesIncludeClassNames) {
 //                    final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
@@ -99,13 +78,34 @@ public interface FacetFactorySet {
 //            }
 //        }
 //
-//        public static void excludeFacetFactories(final IsisConfiguration configuration, final FacetFactorySet programmingModel) {
-//            final String[] facetFactoriesExcludeClassNames = configuration.getList(ReflectorConstants.FACET_FACTORY_EXCLUDE_CLASS_NAME_LIST);
+//        public static void excludeFacetFactories(
+//                final IsisConfigurationBuilder configurationBuilder, 
+//                final FacetFactorySet programmingModel) {
+//            
+//            final String[] facetFactoriesExcludeClassNames = configurationBuilder.peekAtList(ReflectorConstants.FACET_FACTORY_EXCLUDE_CLASS_NAME_LIST);
 //            for (final String facetFactoryClassName : facetFactoriesExcludeClassNames) {
 //                final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
 //                programmingModel.removeFactory(facetFactory);
 //            }
 //        }
         
+        public static void includeFacetFactories(final IsisConfiguration configuration, final FacetFactorySet programmingModel) {
+            final String[] facetFactoriesIncludeClassNames = configuration.getList(ReflectorConstants.FACET_FACTORY_INCLUDE_CLASS_NAME_LIST);
+            if (facetFactoriesIncludeClassNames != null) {
+                for (final String facetFactoryClassName : facetFactoriesIncludeClassNames) {
+                    final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
+                    programmingModel.addFactory(facetFactory);
+                }
+            }
+        }
+
+        public static void excludeFacetFactories(final IsisConfiguration configuration, final FacetFactorySet programmingModel) {
+            final String[] facetFactoriesExcludeClassNames = configuration.getList(ReflectorConstants.FACET_FACTORY_EXCLUDE_CLASS_NAME_LIST);
+            for (final String facetFactoryClassName : facetFactoriesExcludeClassNames) {
+                final Class<? extends FacetFactory> facetFactory = InstanceUtil.loadClass(facetFactoryClassName, FacetFactory.class);
+                programmingModel.removeFactory(facetFactory);
+            }
+        }
+        
     }
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
index 4fcbe09..c756dd8 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ServicesInjector.java
@@ -41,9 +41,10 @@ import org.apache.isis.commons.internal.collections._Collections;
 import org.apache.isis.commons.internal.collections._Maps;
 import org.apache.isis.commons.internal.collections._Multimaps;
 import org.apache.isis.commons.internal.collections._Multimaps.ListMultimap;
+import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.commons.components.ApplicationScopedComponent;
-import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.util.ToString;
 import org.apache.isis.core.metamodel.exceptions.MetaModelException;
 import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
@@ -93,13 +94,11 @@ public class ServicesInjector implements ApplicationScopedComponent, ServiceRegi
     // -- BUILDER
     
     public static ServicesInjectorBuilder builder() {
-        return new ServicesInjectorBuilder();
-    }
-    
-    public static ServicesInjectorBuilder builderOf(IsisConfigurationBuilder configBuilder) {
-        return builder()
-                .autowireSetters(configBuilder.peekAtBoolean(KEY_SET_PREFIX, true))
-                .autowireInject(configBuilder.peekAtBoolean(KEY_INJECT_PREFIX, true));
+        final IsisConfiguration config = _Config.getConfiguration();
+        return new ServicesInjectorBuilder()
+                .addService(config)
+                .autowireSetters(config.getBoolean(KEY_SET_PREFIX, true))
+                .autowireInject(config.getBoolean(KEY_INJECT_PREFIX, true));
     }
     
     public static ServicesInjectorBuilder builderForTesting() {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
index df98224..e03f2d6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/appfeat/ApplicationFeatureRepositoryDefault.java
@@ -18,8 +18,6 @@
  */
 package org.apache.isis.core.metamodel.services.appfeat;
 
-import static org.apache.isis.commons.internal.base._NullSafe.stream;
-
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -38,7 +36,6 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.applib.services.appfeat.ApplicationFeatureRepository;
 import org.apache.isis.applib.services.appfeat.ApplicationMemberType;
-import org.apache.isis.applib.services.config.ConfigurationService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
@@ -58,6 +55,9 @@ import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.specimpl.ContributeeMember;
 
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+import static org.apache.isis.config.internal._Config.getConfiguration;
+
 @DomainService(
         nature = NatureOfService.DOMAIN,
         repositoryFor = ApplicationFeature.class,
@@ -88,14 +88,11 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
     }
 
     private boolean isEagerInitialize() {
-        final String configuredValue = configurationService.getProperty(KEY);
+        final String configuredValue = getConfiguration().getString(KEY);
         return "eager".equalsIgnoreCase(configuredValue) ||
                 "eagerly".equalsIgnoreCase(configuredValue);
     }
 
-
-
-
     // -- initializeIfRequired
 
     enum InitializationState {
@@ -558,9 +555,6 @@ public class ApplicationFeatureRepositoryDefault implements ApplicationFeatureRe
     ServiceRegistry serviceRegistry;
 
     @javax.inject.Inject
-    ConfigurationService configurationService;
-
-    @javax.inject.Inject
     SpecificationLoader specificationLoader;
 
     @javax.inject.Inject
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
index c976e4d..0bc663e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/fixtures/FixturesInstallerFromConfiguration.java
@@ -19,10 +19,12 @@
 
 package org.apache.isis.core.runtime.fixtures;
 
+import java.util.List;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import org.apache.isis.core.commons.config.ConfigurationConstants;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
@@ -31,29 +33,29 @@ public class FixturesInstallerFromConfiguration extends FixturesInstallerAbstrac
 
     private static final Logger LOG = LoggerFactory.getLogger(FixturesInstallerFromConfiguration.class);
 
-    public static final String FIXTURES = ConfigurationConstants.ROOT + "fixtures";
+//    public static final String FIXTURES = ConfigurationConstants.ROOT + "fixtures";
 
-    /**
-     * @deprecated - just adds to the cognitive load...
-     */
-    @Deprecated
-    private static final String FIXTURES_PREFIX = ConfigurationConstants.ROOT + "fixtures.prefix";
+//    /**
+//     * @deprecated - just adds to the cognitive load...
+//     */
+//    @Deprecated
+//    private static final String FIXTURES_PREFIX = ConfigurationConstants.ROOT + "fixtures.prefix";
 
     public FixturesInstallerFromConfiguration(final IsisSessionFactory isisSessionFactory) {
         super(isisSessionFactory);
     }
 
-    @Override
     protected void addFixturesTo(final FixturesInstallerDelegate delegate) {
-
-        final FixtureConfig fixtureConfig = getFixtureConfig();
+        
+        final List<Class<? extends FixtureScript>> fixtureClasses = 
+                configuration.getAppManifest().getFixtures();
 
         try {
             boolean fixtureLoaded = false;
-            for (final String element : fixtureConfig.getFixtures()) {
-                final String fixtureFullyQualifiedName = fixtureConfig.getFixturePrefix() + element;
-                LOG.info("  adding fixture {}", fixtureFullyQualifiedName);
-                final Object fixture = InstanceUtil.createInstance(fixtureFullyQualifiedName);
+            for (final Class<? extends FixtureScript> fixtureClass : fixtureClasses) {
+                
+                LOG.info("  adding fixture {}", fixtureClass.getName());
+                final Object fixture = InstanceUtil.createInstance(fixtureClass);
                 fixtureLoaded = true;
                 delegate.addFixture(fixture);
             }
@@ -65,47 +67,69 @@ public class FixturesInstallerFromConfiguration extends FixturesInstallerAbstrac
         }
     }
 
-    private static class FixtureConfig {
-
-        // -- fixtures
-
-        private String[] fixtures;
-
-        String[] getFixtures() {
-            return fixtures;
-        }
-
-        void setFixtures(String[] fixtures) {
-            this.fixtures = fixtures;
-        }
-
-        // -- fixturePrefix
-
-        private String fixturePrefix;
-        String getFixturePrefix() {
-            return fixturePrefix;
-        }
-
-        void setFixturePrefix(String fixturePrefix) {
-            fixturePrefix = fixturePrefix == null ? "" : fixturePrefix.trim();
-            if (fixturePrefix.length() > 0 && !fixturePrefix.endsWith(ConfigurationConstants.DELIMITER)) {
-                fixturePrefix = fixturePrefix + ConfigurationConstants.DELIMITER;
-            }
-
-            this.fixturePrefix = fixturePrefix;
-        }
-
-
-
-    }
-
-    private FixtureConfig getFixtureConfig() {
-        final FixtureConfig fixtureConfig = new FixtureConfig();
-
-        fixtureConfig.setFixtures(configuration.getList(FIXTURES));
-        fixtureConfig.setFixturePrefix(configuration.getString(FIXTURES_PREFIX));
-
-        return fixtureConfig;
-    }
+    
+//TODO[2039] remove    
+//    @Override
+//    protected void addFixturesTo(final FixturesInstallerDelegate delegate) {
+//
+//        final FixtureConfig fixtureConfig = getFixtureConfig();
+//
+//        try {
+//            boolean fixtureLoaded = false;
+//            for (final String element : fixtureConfig.getFixtures()) {
+//                final String fixtureFullyQualifiedName = fixtureConfig.getFixturePrefix() + element;
+//                LOG.info("  adding fixture {}", fixtureFullyQualifiedName);
+//                final Object fixture = InstanceUtil.createInstance(fixtureFullyQualifiedName);
+//                fixtureLoaded = true;
+//                delegate.addFixture(fixture);
+//            }
+//            if (!fixtureLoaded) {
+//                LOG.debug("No fixtures loaded from configuration");
+//            }
+//        } catch (final IllegalArgumentException | SecurityException e) {
+//            throw new IsisException(e);
+//        }
+//    }
+//
+//    private static class FixtureConfig {
+//
+//        // -- fixtures
+//
+//        private String[] fixtures;
+//
+//        String[] getFixtures() {
+//            return fixtures;
+//        }
+//
+//        void setFixtures(String[] fixtures) {
+//            this.fixtures = fixtures;
+//        }
+//
+//        // -- fixturePrefix
+//
+//        private String fixturePrefix;
+//        String getFixturePrefix() {
+//            return fixturePrefix;
+//        }
+//
+//        void setFixturePrefix(String fixturePrefix) {
+//            fixturePrefix = fixturePrefix == null ? "" : fixturePrefix.trim();
+//            if (fixturePrefix.length() > 0 && !fixturePrefix.endsWith(ConfigurationConstants.DELIMITER)) {
+//                fixturePrefix = fixturePrefix + ConfigurationConstants.DELIMITER;
+//            }
+//
+//            this.fixturePrefix = fixturePrefix;
+//        }
+//
+//    }
+
+//    private FixtureConfig getFixtureConfig() {
+//        final FixtureConfig fixtureConfig = new FixtureConfig();
+//
+//        fixtureConfig.setFixtures(configuration.getList(FIXTURES));
+//        //fixtureConfig.setFixturePrefix(configuration.getString(FIXTURES_PREFIX));
+//
+//        return fixtureConfig;
+//    }
 
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
index b067cdf..8235cbc 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
@@ -29,6 +29,7 @@ import org.apache.isis.applib.Module;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.services.xactn.TransactionService;
 import org.apache.isis.commons.internal.base._Strings;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.factory.InstanceUtil;
 import org.apache.isis.core.runtime.headless.logging.LeveledLogger;
 import org.apache.isis.core.runtime.headless.logging.LogConfig;
@@ -96,7 +97,7 @@ public abstract class HeadlessWithBootstrappingAbstract extends HeadlessAbstract
                 ? InstanceUtil.createInstance(moduleFqcn, Module.class)
                         : module;
                 this.isisSystemBootstrapper =
-                        new IsisSystemBootstrapper(logConfig, moduleToUse);
+                        IsisSystemBootstrapper.of(logConfig, IsisConfiguration.buildFromModuleTree(moduleToUse));
     }
 
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
index 24b3416..516e5bf 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
@@ -25,8 +25,8 @@ import java.util.stream.Collectors;
 import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.fixtures.FixtureClock;
 import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelInvalidException;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
@@ -37,8 +37,6 @@ import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder;
 import org.apache.isis.core.runtime.systemusinginstallers.IsisComponentProvider;
 
-import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
-
 
 /**
  * Wraps a plain {@link IsisSessionFactoryBuilder}.
@@ -47,7 +45,7 @@ import static org.apache.isis.commons.internal.base._Casts.uncheckedCast;
  *     This is a simplification of <tt>IsisSystemForTest</tt>, removing dependencies on junit and specsupport.
  * </p>
  */
-public class IsisSystem {
+public final class IsisSystem {
 
     // -- getElseNull, get, set
 
@@ -70,71 +68,79 @@ public class IsisSystem {
         ISFT.set(isft);
     }
 
-    // -- Builder
-
-    public static class Builder<T extends Builder<T, S>, S extends IsisSystem> {
-
-        protected AuthenticationRequest authenticationRequest = new AuthenticationRequestNameOnly("tester");
-
-        protected AppManifest appManifest;
-
-        public T with(AuthenticationRequest authenticationRequest) {
-            this.authenticationRequest = authenticationRequest;
-            return uncheckedCast(this);
-        }
-
-        public T with(AppManifest appManifest) {
-            this.appManifest = appManifest;
-            return uncheckedCast(this);
-        }
-
-        public S build() {
-            final IsisSystem isisSystem =
-                    new IsisSystem(
-                            appManifest != null ? appManifest : AppManifest.noop(),
-                            authenticationRequest);
-            return configure(uncheckedCast(isisSystem));
-        }
-
-        protected S configure(final S isisSystem) {
-            Runtime.getRuntime().addShutdownHook(new Thread() {
-                @Override
-                public synchronized void run() {
-                    try {
-                        isisSystem.closeSession();
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-
-                    try {
-                        if(isisSystem.isisSessionFactory != null) {
-                            isisSystem.isisSessionFactory.destroyServicesAndShutdown();
-                        }
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-            });
-
-            return isisSystem;
-        }
 
+    public static IsisSystem ofConfiguration(IsisConfiguration isisConfiguration) {
+        
+        AppManifest appManifest = isisConfiguration.getAppManifest();
+        AuthenticationRequest authenticationRequest = new AuthenticationRequestNameOnly("tester");
+        
+        return new IsisSystem(appManifest, authenticationRequest);
     }
-
-    public static <T extends Builder<T, S>, S extends IsisSystem> Builder<T, S> builder() {
-        return new Builder<>();
-    }
+    
+    
+    // -- Builder
+//TODO[2039] remove
+//    public static class Builder<T extends Builder<T, S>, S extends IsisSystem> {
+//
+//        protected AuthenticationRequest authenticationRequest = new AuthenticationRequestNameOnly("tester");
+//
+//        protected AppManifest appManifest;
+//
+//        public T with(AuthenticationRequest authenticationRequest) {
+//            this.authenticationRequest = authenticationRequest;
+//            return uncheckedCast(this);
+//        }
+//
+//        public T with(AppManifest appManifest) {
+//            this.appManifest = appManifest;
+//            return uncheckedCast(this);
+//        }
+//
+//        public S build() {
+//            final IsisSystem isisSystem =
+//                    new IsisSystem(
+//                            appManifest != null ? appManifest : AppManifest.noop(),
+//                            authenticationRequest);
+//            return configure(uncheckedCast(isisSystem));
+//        }
+//
+//        protected S configure(final S isisSystem) {
+//            Runtime.getRuntime().addShutdownHook(new Thread() {
+//                @Override
+//                public synchronized void run() {
+//                    try {
+//                        isisSystem.closeSession();
+//                    } catch (Exception e) {
+//                        e.printStackTrace();
+//                    }
+//
+//                    try {
+//                        if(isisSystem.isisSessionFactory != null) {
+//                            isisSystem.isisSessionFactory.destroyServicesAndShutdown();
+//                        }
+//                    } catch (Exception e) {
+//                        e.printStackTrace();
+//                    }
+//                }
+//            });
+//
+//            return isisSystem;
+//        }
+//
+//    }
+//
+//    public static <T extends Builder<T, S>, S extends IsisSystem> Builder<T, S> builder() {
+//        return new Builder<>();
+//    }
 
     // -- constructor, fields
 
-    // these fields 'xxxForComponentProvider' are used to initialize the IsisComponentProvider, but shouldn't be used thereafter.
     protected final AppManifest appManifest;
-
     protected final AuthenticationRequest authenticationRequestIfAny;
     protected AuthenticationSession authenticationSession;
 
 
-    protected IsisSystem(
+    private IsisSystem(
             final AppManifest appManifest,
             final AuthenticationRequest authenticationRequestIfAny) {
         this.appManifest = appManifest;
@@ -173,7 +179,7 @@ public class IsisSystem {
                     .appManifest(appManifest)
                     .build();
             
-            _Config.acceptBuilder(IsisContext.EnvironmentPrimer::primeEnvironment);
+            //[2039] _Config.acceptBuilder(IsisContext.EnvironmentPrimer::primeEnvironment);
 
             final IsisSessionFactoryBuilder isisSessionFactoryBuilder = 
                     new IsisSessionFactoryBuilder(componentProvider, appManifest);
@@ -255,4 +261,5 @@ public class IsisSystem {
         return servicesInjector.lookupServiceElseFail(serviceClass);
     }
 
+
 }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
index f725ca4..983e4d2 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
@@ -27,14 +27,14 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.AppManifest2;
-import org.apache.isis.applib.AppManifestAbstract2;
-import org.apache.isis.applib.Module;
 import org.apache.isis.applib.fixtures.TickingFixtureClock;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
 import org.apache.isis.applib.services.metamodel.MetaModelService;
 import org.apache.isis.applib.services.registry.ServiceRegistry;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.ensure.Ensure;
 import org.apache.isis.core.runtime.headless.logging.LeveledLogger;
 import org.apache.isis.core.runtime.headless.logging.LogConfig;
 import org.apache.isis.core.runtime.system.context.IsisContext;
@@ -49,38 +49,56 @@ public class IsisSystemBootstrapper {
      */
     private static ThreadLocal<AppManifest2> isftAppManifest = new ThreadLocal<>();
 
-
-    private final AppManifest2 appManifest2;
+    private final IsisConfiguration isisConfiguration;
+//    private final AppManifest2 appManifest2;
     private final LeveledLogger logger;
-
-    public IsisSystemBootstrapper(
-            final LogConfig logConfig,
-            final Module module) {
-        this(logConfig, AppManifestAbstract2.Builder.forModule(module).build());
-    }
-
-    public IsisSystemBootstrapper(
+    
+    public static IsisSystemBootstrapper of(LogConfig logConfig, IsisConfiguration isisConfiguration) {
+        return new IsisSystemBootstrapper(logConfig, isisConfiguration);
+    }
+    
+//[2039]
+//    public IsisSystemBootstrapper(
+//            final LogConfig logConfig,
+//            final Module module) {
+//        this(logConfig, AppManifestAbstract2.Builder.forModule(module).build());
+//    }
+//
+//    public IsisSystemBootstrapper(
+//            final LogConfig logConfig,
+//            final AppManifest2 appManifest2) {
+//
+//        this.appManifest2 = appManifest2;
+//        this.logger = new LeveledLogger(LOG, logConfig.getTestLoggingLevel());
+//    }
+
+    private IsisSystemBootstrapper(
             final LogConfig logConfig,
-            final AppManifest2 appManifest2) {
+            final IsisConfiguration isisConfiguration) {
+        
+        Ensure.ensure("Should have an IsisConfiguration!", isisConfiguration!=null);
+        Ensure.ensure("Should have an AppManifest!", isisConfiguration.getAppManifest()!=null);
 
-        this.appManifest2 = appManifest2;
+//        this.appManifest2 = isisConfiguration.getAppManifest();
+        this.isisConfiguration = isisConfiguration;
         this.logger = new LeveledLogger(LOG, logConfig.getTestLoggingLevel());
     }
-
-    public AppManifest2 getAppManifest2() {
-        return appManifest2;
-    }
-
-    /**
-     * Corresponding to {@link AppManifest2} provided in {@link #IsisSystemBootstrapper(LogConfig, AppManifest2)}, or
-     * (equivalently) the {@link Module} provided directly in {@link #IsisSystemBootstrapper(LogConfig, Module)}.
-     */
-    public Module getModule() {
-        return appManifest2.getModule();
-    }
+    
+//    
+//    public AppManifest2 getAppManifest2() {
+//        return appManifest2;
+//    }
+//
+//    /**
+//     * Corresponding to {@link AppManifest2} provided in {@link #IsisSystemBootstrapper(LogConfig, AppManifest2)}, or
+//     * (equivalently) the {@link Module} provided directly in {@link #IsisSystemBootstrapper(LogConfig, Module)}.
+//     */
+//    public Module getModule() {
+//        return appManifest2.getModule();
+//    }
 
     public IsisSystem bootstrapIfRequired() {
-        bootstrapUsing(appManifest2);
+        bootstrapUsingConfig();
 
         return IsisSystem.get();
     }
@@ -95,9 +113,9 @@ public class IsisSystemBootstrapper {
     }
 
 
-    private void bootstrapUsing(AppManifest2 appManifest2) {
+    private void bootstrapUsingConfig() {
 
-        final SystemState systemState = determineSystemState(appManifest2);
+        final SystemState systemState = determineSystemState(isisConfiguration.getAppManifest());
         switch (systemState) {
 
         case BOOTSTRAPPED_SAME_MODULES:
@@ -114,7 +132,7 @@ public class IsisSystemBootstrapper {
         case NOT_BOOTSTRAPPED:
 
             long t0 = System.currentTimeMillis();
-            setupSystem(appManifest2);
+            setupSystem(isisConfiguration);
             long t1 = System.currentTimeMillis();
 
             log("##########################################################################");
@@ -146,19 +164,17 @@ public class IsisSystemBootstrapper {
         return m1Modules.containsAll(m2Modules) && m2Modules.containsAll(m1Modules);
     }
 
-    private static IsisSystem setupSystem(final AppManifest2 appManifest2) {
+    private static IsisSystem setupSystem(IsisConfiguration isisConfiguration) {
 
         final IsisSystem isft =
-                IsisSystem.builder()
-                    .with(appManifest2)
-                    .build();
+                IsisSystem.ofConfiguration(isisConfiguration);
 
         isft.setUpSystem();
 
         // save both the system and the manifest
         // used to bootstrap the system onto thread-local
         IsisSystem.set(isft);
-        isftAppManifest.set(appManifest2);
+        isftAppManifest.set(isisConfiguration.getAppManifest());
 
         return isft;
     }
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
index bafa37a..ee65e58 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ServicesInstallerFromAnnotation.java
@@ -25,50 +25,27 @@ import java.util.Set;
 import java.util.SortedMap;
 import java.util.SortedSet;
 import java.util.function.Predicate;
-import java.util.stream.Collectors;
 
 import javax.annotation.PreDestroy;
 
 import org.apache.isis.applib.AppManifest;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.commons.internal.base._Strings;
 import org.apache.isis.commons.internal.collections._Lists;
 import org.apache.isis.commons.internal.collections._Maps;
+import org.apache.isis.commons.internal.exceptions._Exceptions;
 import org.apache.isis.config.internal._Config;
-import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.facets.object.domainservice.DomainServiceMenuOrder;
 import org.apache.isis.core.metamodel.util.DeweyOrderComparator;
-import org.apache.isis.core.plugins.classdiscovery.ClassDiscovery;
-import org.apache.isis.core.plugins.classdiscovery.ClassDiscoveryPlugin;
 
 public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
 
-    // -- constants
 
     //private static final Logger LOG = LoggerFactory.getLogger(ServicesInstallerFromAnnotation.class);
 
     public static final String NAME = "annotation";
-    public final static String PACKAGE_PREFIX_KEY = "isis.services.ServicesInstallerFromAnnotation.packagePrefix";
-
-    /**
-     * These package prefixes (core and modules) are always included.
-     *
-     * <p>
-     * It's important that any services annotated {@link org.apache.isis.applib.annotation.DomainService} and residing
-     * in any of these packages must have no side-effects.
-     *
-     * <p>
-     *     Services are ordered according to the {@link org.apache.isis.applib.annotation.DomainService#menuOrder() menuOrder},
-     *     with the first service found used.
-     * </p>
-     */
-    public final static String PACKAGE_PREFIX_STANDARD =
-            AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES.stream()
-            .collect(Collectors.joining(","));
-
-    // -- constructor, fields
+    
+//[2039]    
+//    public final static String PACKAGE_PREFIX_KEY = "isis.services.ServicesInstallerFromAnnotation.packagePrefix";
+
 
     private final ServiceInstantiator serviceInstantiator;
 
@@ -82,21 +59,6 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
     }
 
 
-    // -- packagePrefixes
-    private String packagePrefixes;
-
-    /**
-     * For integration testing.
-     *
-     * <p>
-     *     Otherwise these are read from the {@link org.apache.isis.core.commons.config.IsisConfiguration}
-     * </p>
-     */
-    public void withPackagePrefixes(final String... packagePrefixes) {
-        this.packagePrefixes = _NullSafe.stream(packagePrefixes).collect(Collectors.joining(","));
-    }
-
-
     // -- init, shutdown
 
     @Override
@@ -112,16 +74,8 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
         }
 
         try {
-
-            if(packagePrefixes == null) {
-                this.packagePrefixes = PACKAGE_PREFIX_STANDARD;
-                String packagePrefixes = 
-                        _Config.applyConfig(config->config.getString(PACKAGE_PREFIX_KEY));
-                        
-                if(!_Strings.isNullOrEmpty(packagePrefixes)) {
-                    this.packagePrefixes = this.packagePrefixes + "," + packagePrefixes;
-                }
-            }
+           
+            _Config.getConfiguration().triggerTypeDiscovery(); // registers types in registry
 
         } finally {
             initialized = true;
@@ -154,6 +108,7 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
             appendServices(positionedServices);
 
             this.services = ServicesInstallerUtils.instantiateServicesFrom(positionedServices, serviceInstantiator);
+            
         }
         return services;
     }
@@ -164,14 +119,16 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
     public void appendServices(final SortedMap<String, SortedSet<String>> positionedServices) {
         initIfRequired();
 
-        final List<String> packagePrefixList = asList(packagePrefixes);
-
         Set<Class<?>> domainServiceTypes = AppManifest.Registry.instance().getDomainServiceTypes();
         if(domainServiceTypes == null) {
-            // if no appManifest
-            final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(packagePrefixList);
-
-            domainServiceTypes = discovery.getTypesAnnotatedWith(DomainService.class);
+            //[2039]
+//            // if no appManifest
+//            final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(modulePackageNames);
+//
+//            domainServiceTypes = discovery.getTypesAnnotatedWith(DomainService.class);
+            
+            _Exceptions.throwUnexpectedCodeReach();
+            
         }
 
         final List<Class<?>> domainServiceClasses = _Lists.filter(domainServiceTypes, instantiatable());
@@ -181,7 +138,11 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
             // we want the class name in order to instantiate it
             // (and *not* the value of the @DomainServiceLayout(named=...) annotation attribute)
             final String fullyQualifiedClassName = cls.getName();
-            final String name = nameOf(cls);
+            //final String name = nameOf(cls);
+            
+            if(fullyQualifiedClassName.contains("Headless"))
+                System.out.println("!!!! " + fullyQualifiedClassName);
+            
 
             ServicesInstallerUtils.appendInPosition(positionedServices, order, fullyQualifiedClassName);
         }
@@ -191,20 +152,20 @@ public class ServicesInstallerFromAnnotation extends ServicesInstallerAbstract {
 
     // -- helpers: nameOf, asList
 
-    private static String nameOf(final Class<?> cls) {
-        final DomainServiceLayout domainServiceLayout = cls.getAnnotation(DomainServiceLayout.class);
-        String name = domainServiceLayout != null ? domainServiceLayout.named(): null;
-        if(name == null) {
-            name = cls.getName();
-        }
-        return name;
-    }
-
-    private static List<String> asList(final String csv) {
-        return _Strings.splitThenStream(csv, ",")
-        .map(String::trim)
-        .collect(Collectors.toList());
-    }
+//    private static String nameOf(final Class<?> cls) {
+//        final DomainServiceLayout domainServiceLayout = cls.getAnnotation(DomainServiceLayout.class);
+//        String name = domainServiceLayout != null ? domainServiceLayout.named(): null;
+//        if(name == null) {
+//            name = cls.getName();
+//        }
+//        return name;
+//    }
+
+//    private static List<String> asList(final String csv) {
+//        return _Strings.splitThenStream(csv, ",")
+//        .map(String::trim)
+//        .collect(Collectors.toList());
+//    }
 
 
     // -- domain events
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/email/EmailServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/email/EmailServiceDefault.java
index d1d9054..f57da46 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/email/EmailServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/email/EmailServiceDefault.java
@@ -273,9 +273,6 @@ public class EmailServiceDefault implements EmailService {
     }
     // endregion
 
-
-    // endregion
-
     @javax.inject.Inject
     IsisConfiguration configuration;
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
index 57442fd..38eae5e 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/session/IsisSessionFactoryBuilder.java
@@ -74,7 +74,7 @@ public class IsisSessionFactoryBuilder {
     public IsisSessionFactoryBuilder(final AppManifest appManifest) {
         this(IsisComponentProvider.builder()
                 .appManifest(appManifest)
-                .addConfigPackageAsResourceStreamSource()
+//                .addConfigPackageAsResourceStreamSource()
                 .build(),
                 appManifest);
     }
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 a98e668..3393fb9 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
@@ -21,58 +21,26 @@ package org.apache.isis.core.runtime.systemusinginstallers;
 
 import java.util.Collection;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import javax.annotation.Nullable;
-import javax.xml.bind.annotation.XmlElement;
 
 import org.apache.isis.applib.AppManifest;
-import org.apache.isis.applib.annotation.DomainObject;
-import org.apache.isis.applib.annotation.DomainObjectLayout;
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.DomainServiceLayout;
-import org.apache.isis.applib.annotation.Mixin;
-import org.apache.isis.applib.annotation.Nature;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.annotation.ViewModel;
-import org.apache.isis.applib.annotation.ViewModelLayout;
-import org.apache.isis.applib.fixturescripts.DiscoverableFixtureScript;
-import org.apache.isis.applib.fixturescripts.FixtureScript;
-import org.apache.isis.commons.internal.base._NullSafe;
-import org.apache.isis.commons.internal.collections._Lists;
-import org.apache.isis.commons.internal.collections._Sets;
-import org.apache.isis.config.internal._Config;
-import org.apache.isis.core.commons.config.ConfigurationConstants;
-import org.apache.isis.core.commons.configbuilder.IsisConfigurationBuilder;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.commons.factory.InstanceUtil;
-import org.apache.isis.core.commons.lang.ClassFunctions;
 import org.apache.isis.core.metamodel.facetapi.MetaModelRefiner;
-import org.apache.isis.core.metamodel.facets.Annotations;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
 import org.apache.isis.core.metamodel.progmodel.ProgrammingModelAbstract.DeprecatedPolicy;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.specloader.ReflectorConstants;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.metamodel.specloader.validator.MetaModelValidator;
-import org.apache.isis.core.plugins.classdiscovery.ClassDiscovery;
-import org.apache.isis.core.plugins.classdiscovery.ClassDiscoveryPlugin;
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authorization.AuthorizationManager;
-import org.apache.isis.core.runtime.fixtures.FixturesInstallerFromConfiguration;
-import org.apache.isis.core.runtime.services.ServicesInstallerFromAnnotation;
-import org.apache.isis.core.runtime.services.ServicesInstallerFromConfiguration;
 import org.apache.isis.core.runtime.services.ServicesInstallerFromConfigurationAndAnnotation;
 import org.apache.isis.core.runtime.system.IsisSystemException;
 import org.apache.isis.progmodels.dflt.JavaReflectorHelper;
 import org.apache.isis.progmodels.dflt.ProgrammingModelFacetsJava5;
 
 import static org.apache.isis.commons.internal.base._With.requires;
-import static org.apache.isis.config.internal._Config.acceptBuilder;
-import static org.apache.isis.config.internal._Config.applyBuilder;
+import static org.apache.isis.config.internal._Config.getConfiguration;
 
 /**
  * 
@@ -113,17 +81,16 @@ public final class IsisComponentProvider {
 
         this.appManifest = requires(appManifest, "appManifest");
         
-        putAppManifestKey(appManifest);
-        findAndRegisterTypes(appManifest);
-        specifyServicesAndRegisteredEntitiesUsing(appManifest);
-
-        addToConfigurationUsing(appManifest);
+//[2039]        putAppManifestKey(appManifest);
+//        findAndRegisterTypes(appManifest);
+//        specifyServicesAndRegisteredEntitiesUsing(appManifest);
+//        addToConfigurationUsing(appManifest);
 
         this.services = new ServicesInstallerFromConfigurationAndAnnotation().getServices();
 
-        final String fixtureClassNamesCsv = classNamesFrom(getAppManifest().getFixtures());
-        
-        _Config.put(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
+        //[2039]using configuration directly instead
+        //final String fixtureClassNamesCsv = classNamesFrom(getAppManifest().getFixtures());
+        //_Config.put(FixturesInstallerFromConfiguration.FIXTURES, fixtureClassNamesCsv);
 
         this.authenticationManager = authenticationManager;
         this.authorizationManager = authorizationManager;
@@ -134,198 +101,183 @@ public final class IsisComponentProvider {
     }
 
     // -- helpers (appManifest)
-
-    private void putAppManifestKey(final AppManifest appManifest) {
-        // required to prevent RegisterEntities validation from complaining
-        // if it can't find any @PersistenceCapable entities in a module
-        // that contains only services.
-        _Config.put(ConfigurationConstants.APP_MANIFEST_KEY, appManifest.getClass().getName() );
-    }
-
-    private void findAndRegisterTypes(final AppManifest appManifest) {
-        final Stream<String> modulePackages = modulePackageNamesFrom(appManifest);
-        final AppManifest.Registry registry = AppManifest.Registry.instance();
-
-        final List<String> moduleAndFrameworkPackages = _Lists.newArrayList();
-        moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
-        
-        modulePackages.forEach(moduleAndFrameworkPackages::add);
-
-        final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(moduleAndFrameworkPackages);
-
-        final Set<Class<?>> domainServiceTypes = _Sets.newLinkedHashSet();
-        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainService.class));
-        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainServiceLayout.class));
-
-        final Set<Class<?>> persistenceCapableTypes = PersistenceCapableTypeFinder.find(discovery);
-
-        final Set<Class<? extends FixtureScript>> fixtureScriptTypes = discovery.getSubTypesOf(FixtureScript.class)
-                .stream()
-                .filter(aClass -> {
-                    // the fixtureScript types are introspected just to provide a drop-down when running fixture scripts
-                    // in prototyping mode (though they may be introspected lazily if actually run).
-                    // we therefore try to limit the set of fixture types eagerly introspected at startup
-                    //
-                    // specifically, we ignore as a fixture script if annotated with @Programmatic
-                    // (though directly implementing DiscoverableFixtureScript takes precedence and will NOT ignore)
-                    return DiscoverableFixtureScript.class.isAssignableFrom(aClass) ||
-                            Annotations.getAnnotation(aClass, Programmatic.class) == null;
-                })
-                .collect(Collectors.toSet());
-
-        final Set<Class<?>> domainObjectTypes = _Sets.newLinkedHashSet();
-        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObject.class));
-        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObjectLayout.class));
-
-        final Set<Class<?>> mixinTypes = _Sets.newHashSet();
-        mixinTypes.addAll(discovery.getTypesAnnotatedWith(Mixin.class));
-        domainObjectTypes.stream()
-        .filter(input -> {
-            final DomainObject annotation = input.getAnnotation(DomainObject.class);
-            return annotation != null && annotation.nature() == Nature.MIXIN;
-        })
-        .forEach(mixinTypes::add);
-
-        final Set<Class<?>> viewModelTypes = _Sets.newLinkedHashSet();
-        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModel.class));
-        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModelLayout.class));
-
-        final Set<Class<?>> xmlElementTypes = _Sets.newLinkedHashSet();
-        xmlElementTypes.addAll(discovery.getTypesAnnotatedWith(XmlElement.class));
-
-        // add in any explicitly registered services...
-        domainServiceTypes.addAll(appManifest.getAdditionalServices());
-
-        // Reflections seems to have a bug whereby it will return some classes outside the
-        // set of packages that we want (think this is to do with the fact that it matches based on
-        // the prefix and gets it wrong); so we double check and filter out types outside our
-        // required set of packages.
-
-        // for a tiny bit of efficiency, we append a '.' to each package name here, outside the loops
-        List<String> packagesWithDotSuffix =
-                _Lists.map(moduleAndFrameworkPackages, (@Nullable final String s) -> {
-                        return s != null ? s + "." : null;
-                });
-
-        registry.setDomainServiceTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainServiceTypes));
-        registry.setPersistenceCapableTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, persistenceCapableTypes));
-        registry.setFixtureScriptTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, fixtureScriptTypes));
-        registry.setMixinTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, mixinTypes));
-        registry.setDomainObjectTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainObjectTypes));
-        registry.setViewModelTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, viewModelTypes));
-        registry.setXmlElementTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, xmlElementTypes));
-    }
-
-    static <T> Set<Class<? extends T>> withinPackageAndNotAnonymous(
-            final List<String> packagesWithDotSuffix,
-            final Set<Class<? extends T>> classes) {
-        Set<Class<? extends T>> classesWithin = _Sets.newLinkedHashSet();
-        for (Class<? extends T> clz : classes) {
-            final String className = clz.getName();
-            if(containedWithin(packagesWithDotSuffix, className) && notAnonymous(clz)) {
-                classesWithin.add(clz);
-            }
-        }
-        return classesWithin;
-    }
-
-    static private boolean containedWithin(final List<String> packagesWithDotSuffix, final String className) {
-        for (String packageWithDotSuffix : packagesWithDotSuffix) {
-            if (className.startsWith(packageWithDotSuffix)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static <T> boolean notAnonymous(final Class<? extends T> clz) {
-        try {
-            return !clz.isAnonymousClass();
-        } catch(NoClassDefFoundError error) {
-            return false; // ignore, assume anonymous
-        }
-    }
-
-    private void specifyServicesAndRegisteredEntitiesUsing(final AppManifest appManifest) {
-        final Stream<String> packageNames = modulePackageNamesFrom(appManifest);
-        final String packageNamesCsv = packageNames.collect(Collectors.joining(","));
-
-        acceptBuilder(builder->{
-            builder.add(ServicesInstallerFromAnnotation.PACKAGE_PREFIX_KEY, packageNamesCsv);
-        });
-
-        final List<Class<?>> additionalServices = appManifest.getAdditionalServices();
-        if(additionalServices != null) {
-            final String additionalServicesCsv = classNamesFrom(additionalServices);
-            appendToPropertyCsvValue(ServicesInstallerFromConfiguration.SERVICES_KEY, additionalServicesCsv);
-        }
-    }
-
-    private void appendToPropertyCsvValue(final String servicesKey, final String additionalServicesCsv) {
-        final String existingServicesCsv = _Config.peekAtString(servicesKey);
-        final String servicesCsv = join(existingServicesCsv, additionalServicesCsv);
-        _Config.put(servicesKey, servicesCsv);
-    }
-
-    private static String join(final String csv1, final String csv2) {
-        if (csv1 == null) {
-            return csv2;
-        }
-        if (csv2 == null) {
-            return csv1;
-        }
-        return csv1 + "," + csv2;
-    }
-
-    private Stream<String> modulePackageNamesFrom(final AppManifest appManifest) {
-        List<Class<?>> modules = appManifest.getModules();
-        if (modules == null || modules.isEmpty()) {
-            throw new IllegalArgumentException(
-                    "If an appManifest is provided then it must return a non-empty set of modules");
-        }
-
-        return modules.stream().map(ClassFunctions.packageNameOf());
-    }
-
-    protected String classNamesFrom(final List<?> objectsOrClasses) {
-        if (objectsOrClasses == null) {
-            return null;
-        }
-        
-        final Stream<String> fixtureClassNames = _NullSafe.stream(objectsOrClasses)
-                .map(classNameOf());
-                
-        return fixtureClassNames.collect(Collectors.joining(","));
-                
-    }
-
-    private static Function<Object, String> classNameOf() {
-        return new Function<Object, String>() {
-            @Nullable @Override
-            public String apply(final Object input) {
-                Class<?> aClass = input instanceof Class ? (Class<?>) input : input.getClass();
-                return aClass.getName();
-            }
-        };
-    }
-
-    private void addToConfigurationUsing(final AppManifest appManifest) {
-        final Map<String, String> configurationProperties = appManifest.getConfigurationProperties();
-        
-        if (configurationProperties == null) {
-            return;
-        }
-        
-        acceptBuilder(builder->{
-        
-            for (Map.Entry<String, String> configProp : configurationProperties.entrySet()) {
-                builder.add(configProp.getKey(), configProp.getValue());
-            }
-        
-        });
-        
-        
-    }
+//[2039] moved to config module
+//    private void putAppManifestKey(final AppManifest appManifest) {
+//        // required to prevent RegisterEntities validation from complaining
+//        // if it can't find any @PersistenceCapable entities in a module
+//        // that contains only services.
+//        _Config.put(ConfigurationConstants.APP_MANIFEST_KEY, appManifest.getClass().getName() );
+//    }
+//
+//    private void findAndRegisterTypes(final AppManifest appManifest) {
+//        final Stream<String> modulePackages = modulePackageNamesFrom(appManifest);
+//        final AppManifest.Registry registry = AppManifest.Registry.instance();
+//
+//        final List<String> moduleAndFrameworkPackages = _Lists.newArrayList();
+//        moduleAndFrameworkPackages.addAll(AppManifest.Registry.FRAMEWORK_PROVIDED_SERVICES);
+//        
+//        modulePackages.forEach(moduleAndFrameworkPackages::add);
+//
+//        final ClassDiscovery discovery = ClassDiscoveryPlugin.get().discover(moduleAndFrameworkPackages);
+//
+//        final Set<Class<?>> domainServiceTypes = _Sets.newLinkedHashSet();
+//        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainService.class));
+//        domainServiceTypes.addAll(discovery.getTypesAnnotatedWith(DomainServiceLayout.class));
+//
+//        final Set<Class<?>> persistenceCapableTypes = PersistenceCapableTypeFinder.find(discovery);
+//
+//        final Set<Class<? extends FixtureScript>> fixtureScriptTypes = discovery.getSubTypesOf(FixtureScript.class)
+//                .stream()
+//                .filter(aClass -> {
+//                    // the fixtureScript types are introspected just to provide a drop-down when running fixture scripts
+//                    // in prototyping mode (though they may be introspected lazily if actually run).
+//                    // we therefore try to limit the set of fixture types eagerly introspected at startup
+//                    //
+//                    // specifically, we ignore as a fixture script if annotated with @Programmatic
+//                    // (though directly implementing DiscoverableFixtureScript takes precedence and will NOT ignore)
+//                    return DiscoverableFixtureScript.class.isAssignableFrom(aClass) ||
+//                            Annotations.getAnnotation(aClass, Programmatic.class) == null;
+//                })
+//                .collect(Collectors.toSet());
+//
+//        final Set<Class<?>> domainObjectTypes = _Sets.newLinkedHashSet();
+//        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObject.class));
+//        domainObjectTypes.addAll(discovery.getTypesAnnotatedWith(DomainObjectLayout.class));
+//
+//        final Set<Class<?>> mixinTypes = _Sets.newHashSet();
+//        mixinTypes.addAll(discovery.getTypesAnnotatedWith(Mixin.class));
+//        domainObjectTypes.stream()
+//        .filter(input -> {
+//            final DomainObject annotation = input.getAnnotation(DomainObject.class);
+//            return annotation != null && annotation.nature() == Nature.MIXIN;
+//        })
+//        .forEach(mixinTypes::add);
+//
+//        final Set<Class<?>> viewModelTypes = _Sets.newLinkedHashSet();
+//        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModel.class));
+//        viewModelTypes.addAll(discovery.getTypesAnnotatedWith(ViewModelLayout.class));
+//
+//        final Set<Class<?>> xmlElementTypes = _Sets.newLinkedHashSet();
+//        xmlElementTypes.addAll(discovery.getTypesAnnotatedWith(XmlElement.class));
+//
+//        // add in any explicitly registered services...
+//        domainServiceTypes.addAll(appManifest.getAdditionalServices());
+//
+//        // Reflections seems to have a bug whereby it will return some classes outside the
+//        // set of packages that we want (think this is to do with the fact that it matches based on
+//        // the prefix and gets it wrong); so we double check and filter out types outside our
+//        // required set of packages.
+//
+//        // for a tiny bit of efficiency, we append a '.' to each package name here, outside the loops
+//        List<String> packagesWithDotSuffix =
+//                _Lists.map(moduleAndFrameworkPackages, (@Nullable final String s) -> {
+//                        return s != null ? s + "." : null;
+//                });
+//
+//        registry.setDomainServiceTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainServiceTypes));
+//        registry.setPersistenceCapableTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, persistenceCapableTypes));
+//        registry.setFixtureScriptTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, fixtureScriptTypes));
+//        registry.setMixinTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, mixinTypes));
+//        registry.setDomainObjectTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, domainObjectTypes));
+//        registry.setViewModelTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, viewModelTypes));
+//        registry.setXmlElementTypes(withinPackageAndNotAnonymous(packagesWithDotSuffix, xmlElementTypes));
+//    }
+//
+//    static <T> Set<Class<? extends T>> withinPackageAndNotAnonymous(
+//            final List<String> packagesWithDotSuffix,
+//            final Set<Class<? extends T>> classes) {
+//        Set<Class<? extends T>> classesWithin = _Sets.newLinkedHashSet();
+//        for (Class<? extends T> clz : classes) {
+//            final String className = clz.getName();
+//            if(containedWithin(packagesWithDotSuffix, className) && notAnonymous(clz)) {
+//                classesWithin.add(clz);
+//            }
+//        }
+//        return classesWithin;
+//    }
+//
+//    static private boolean containedWithin(final List<String> packagesWithDotSuffix, final String className) {
+//        for (String packageWithDotSuffix : packagesWithDotSuffix) {
+//            if (className.startsWith(packageWithDotSuffix)) {
+//                return true;
+//            }
+//        }
+//        return false;
+//    }
+//
+//    private static <T> boolean notAnonymous(final Class<? extends T> clz) {
+//        try {
+//            return !clz.isAnonymousClass();
+//        } catch(NoClassDefFoundError error) {
+//            return false; // ignore, assume anonymous
+//        }
+//    }
+//
+//
+//    private void specifyServicesAndRegisteredEntitiesUsing(final AppManifest appManifest) {
+//        final Stream<String> packageNames = modulePackageNamesFrom(appManifest);
+//        final String packageNamesCsv = packageNames.collect(Collectors.joining(","));
+//
+//        final List<Class<?>> additionalServices = appManifest.getAdditionalServices();
+//        if(additionalServices != null) {
+//            final String additionalServicesCsv = classNamesFrom(additionalServices);
+//            appendToPropertyCsvValue(ServicesInstallerFromConfiguration.SERVICES_KEY, additionalServicesCsv);
+//        }
+//    }
+//
+//    private void appendToPropertyCsvValue(final String servicesKey, final String additionalServicesCsv) {
+//        final String existingServicesCsv = _Config.peekAtString(servicesKey);
+//        final String servicesCsv = join(existingServicesCsv, additionalServicesCsv);
+//        _Config.put(servicesKey, servicesCsv);
+//    }
+//
+//    private static String join(final String csv1, final String csv2) {
+//        if (csv1 == null) {
+//            return csv2;
+//        }
+//        if (csv2 == null) {
+//            return csv1;
+//        }
+//        return csv1 + "," + csv2;
+//    }
+//
+//    protected String classNamesFrom(final List<?> objectsOrClasses) {
+//        if (objectsOrClasses == null) {
+//            return null;
+//        }
+//        
+//        final Stream<String> fixtureClassNames = _NullSafe.stream(objectsOrClasses)
+//                .map(classNameOf());
+//                
+//        return fixtureClassNames.collect(Collectors.joining(","));
+//                
+//    }
+//
+//    private static Function<Object, String> classNameOf() {
+//        return new Function<Object, String>() {
+//            @Nullable @Override
+//            public String apply(final Object input) {
+//                Class<?> aClass = input instanceof Class ? (Class<?>) input : input.getClass();
+//                return aClass.getName();
+//            }
+//        };
+//    }
+//
+//    private void addToConfigurationUsing(final AppManifest appManifest) {
+//        final Map<String, String> configurationProperties = appManifest.getConfigurationProperties();
+//        
+//        if (configurationProperties == null) {
+//            return;
+//        }
+//        
+//        acceptBuilder(builder->{
+//        
+//            for (Map.Entry<String, String> configProp : configurationProperties.entrySet()) {
+//                builder.add(configProp.getKey(), configProp.getValue());
+//            }
+//        
+//        });
+//    }
 
     // -- provideAuth*
 
@@ -340,7 +292,7 @@ public final class IsisComponentProvider {
     // -- provideServiceInjector
 
     public ServicesInjector provideServiceInjector() {
-        return applyBuilder(ServicesInjector::builderOf)
+        return ServicesInjector.builder()
                 .addServices(services)
                 .build();
     }
@@ -351,9 +303,10 @@ public final class IsisComponentProvider {
             final ServicesInjector servicesInjector,
             final Collection<MetaModelRefiner> metaModelRefiners)  throws IsisSystemException {
 
-        final ProgrammingModel programmingModel = applyBuilder(this::createProgrammingModel);
-
-        final MetaModelValidator mmv = createMetaModelValidator();
+        final IsisConfiguration configuration = getConfiguration();
+        
+        final ProgrammingModel programmingModel = createProgrammingModel(configuration);
+        final MetaModelValidator mmv = createMetaModelValidator(configuration);
 
         return JavaReflectorHelper.createObjectReflector(
                 programmingModel, metaModelRefiners,
@@ -361,21 +314,22 @@ public final class IsisComponentProvider {
                 servicesInjector);
     }
 
-    protected MetaModelValidator createMetaModelValidator() {
+    protected MetaModelValidator createMetaModelValidator(IsisConfiguration configuration) {
         
         final String metaModelValidatorClassName =
-                _Config.peekAtString(
+                configuration.getString(
                         ReflectorConstants.META_MODEL_VALIDATOR_CLASS_NAME,
                         ReflectorConstants.META_MODEL_VALIDATOR_CLASS_NAME_DEFAULT);
         return InstanceUtil.createInstance(metaModelValidatorClassName, MetaModelValidator.class);
     }
 
-    protected ProgrammingModel createProgrammingModel(IsisConfigurationBuilder builder) {
-        final DeprecatedPolicy deprecatedPolicy = DeprecatedPolicy.parse(builder);
+    protected ProgrammingModel createProgrammingModel(IsisConfiguration configuration) {
+        
+        final DeprecatedPolicy deprecatedPolicy = DeprecatedPolicy.parse(configuration);
 
         final ProgrammingModel programmingModel = new ProgrammingModelFacetsJava5(deprecatedPolicy);
-        ProgrammingModel.Util.includeFacetFactories(builder, programmingModel);
-        ProgrammingModel.Util.excludeFacetFactories(builder, programmingModel);
+        ProgrammingModel.Util.includeFacetFactories(configuration, programmingModel);
+        ProgrammingModel.Util.excludeFacetFactories(configuration, programmingModel);
         return programmingModel;
     }
 
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderBuilder.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderBuilder.java
index 086a943..c93b873 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderBuilder.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProviderBuilder.java
@@ -19,7 +19,7 @@ public class IsisComponentProviderBuilder {
     private AppManifest appManifest;
     private AuthenticationManager authenticationManager;
     private AuthorizationManager authorizationManager;
-    private final List<ResourceStreamSource> resourceStreamSources = _Lists.newArrayList();
+//    private final List<ResourceStreamSource> resourceStreamSources = _Lists.newArrayList();
     
     public IsisComponentProviderBuilder appManifest(AppManifest appManifest) {
         this.appManifest = appManifest;
@@ -36,21 +36,21 @@ public class IsisComponentProviderBuilder {
         return this;
     }
     
-    public IsisComponentProviderBuilder addResourceStreamSource(ResourceStreamSource source) {
-        resourceStreamSources.add(source);
-        return this;
-    }
+//    public IsisComponentProviderBuilder addResourceStreamSource(ResourceStreamSource source) {
+//        resourceStreamSources.add(source);
+//        return this;
+//    }
     
     // -- SHORTCUTS
     
-    /**
-     * Default will read <tt>isis.properties</tt> (and other optional property files) from the 'config'
-     * package on the current classpath.
-     */
-    public IsisComponentProviderBuilder addConfigPackageAsResourceStreamSource() {
-        addResourceStreamSource(ResourceStreamSourceContextLoaderClassPath.create("config"));
-        return this;
-    }
+//    /**
+//     * Default will read <tt>isis.properties</tt> (and other optional property files) from the 'config'
+//     * package on the current classpath.
+//     */
+//    public IsisComponentProviderBuilder addConfigPackageAsResourceStreamSource() {
+//        addResourceStreamSource(ResourceStreamSourceContextLoaderClassPath.create("config"));
+//        return this;
+//    }
     
     // -- BUILD
     
@@ -62,9 +62,9 @@ public class IsisComponentProviderBuilder {
         authorizationManager = computeIfAbsent(authorizationManager, 
                 AuthorizationManagerStandard::new);
         
-        acceptBuilder(builder->{
-            resourceStreamSources.forEach(builder::addResourceStreamSource);
-        });
+//        acceptBuilder(builder->{
+//            resourceStreamSources.forEach(builder::addResourceStreamSource);
+//        });
         
         return new IsisComponentProvider(appManifest, authenticationManager, authorizationManager);
     }
diff --git a/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java b/core/runtime/src/test/java/org/apache/isis/core/commons/configbuilder/IsisComponentProvider_within_Test.java
similarity index 90%
rename from core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java
rename to core/runtime/src/test/java/org/apache/isis/core/commons/configbuilder/IsisComponentProvider_within_Test.java
index f67b411..8e6e93d 100644
--- a/core/runtime/src/test/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider_within_Test.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/commons/configbuilder/IsisComponentProvider_within_Test.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.runtime.systemusinginstallers;
+package org.apache.isis.core.commons.configbuilder;
 
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
@@ -40,7 +40,8 @@ public class IsisComponentProvider_within_Test {
         final String budgetAssignmentPackageWithDot =
                 SomeServiceNotToInclude.class.getPackage().getName()  + ".";
 
-        final Set<Class<?>> within = IsisComponentProvider.withinPackageAndNotAnonymous(Arrays.asList(budgetPackageWithDot),
+        final Set<Class<?>> within = ModulePackageHelper.withinPackageAndNotAnonymous(
+                Arrays.asList(budgetPackageWithDot),
                 _Sets.of(SomeServiceToInclude.class, SomeServiceNotToInclude.class));
 
         Assert.assertThat(within.size(), is(equalTo(1)));
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
index 0cb84c9..bd169aa 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/IsisWicketApplication.java
@@ -247,7 +247,7 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
 
         // --- prepare the configuration prior to init()
         
-        prepareConfigurationBuilder(getServletContext());
+        prepareConfigurationBuilder(getServletContext()); // FIXME[2039] do this in the ServletContextListener
         
         super.internalInit();
 
@@ -284,7 +284,7 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
         // that's suitable for the entire web-application to use as default.
         _Context.setDefaultClassLoader(this.getClass().getClassLoader(), true);
         
-        final IsisConfiguration configuration;
+        final IsisConfiguration configuration = _Config.getConfiguration();
         
         List<Future<Object>> futures = null;
         try {
@@ -303,8 +303,10 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
             //
             // create IsisSessionFactory
             //
-            final IsisInjectModule isisModule = newIsisModule();
-            final Injector injector = Guice.createInjector(isisModule, newIsisWicketModule());
+            final Injector injector = Guice.createInjector(
+                    newIsisModule(), 
+                    newIsisWicketModule(configuration));
+            
             initWicketComponentInjection(injector);
             
             injector.injectMembers(this); // populates this.isisSessionFactory
@@ -314,8 +316,6 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
                 WebRequestCycleForIsis webRequestCycleForIsis = (WebRequestCycleForIsis) requestCycleListenerForIsis;
                 webRequestCycleForIsis.setPageClassRegistry(pageClassRegistry);
             }
-
-            configuration = _Config.getConfiguration();
             
             this.getMarkupSettings().setStripWicketTags(determineStripWicketTags(configuration));
 
@@ -544,7 +544,7 @@ implements ComponentFactoryRegistryAccessor, PageClassRegistryAccessor, WicketVi
     /**
      * Override if required
      */
-    protected Module newIsisWicketModule() {
+    protected Module newIsisWicketModule(IsisConfiguration isisConfiguration) {
         return new IsisWicketModule(getServletContext());
     }
 
diff --git a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/isis/IsisInjectModule.java b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/isis/IsisInjectModule.java
index 68c0f9f..d4a3541 100644
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/isis/IsisInjectModule.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/isis/IsisInjectModule.java
@@ -24,8 +24,8 @@ import com.google.inject.Provides;
 import com.google.inject.Singleton;
 
 import org.apache.isis.applib.AppManifest;
-import org.apache.isis.config.internal._Config;
 import org.apache.isis.core.commons.config.AppConfigLocator;
+import org.apache.isis.core.commons.config.IsisConfiguration;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactoryBuilder;
@@ -35,15 +35,20 @@ public class IsisInjectModule extends AbstractModule {
 
     @Override
     protected void configure() {
-        AppConfigLocator.getAppConfig().isisConfiguration();
+        
+        System.err.println("!!!!!!!!!! IsisInjectModule.configure "+Thread.currentThread().getName());
+        
+        IsisConfiguration isisConfiguration = AppConfigLocator.getAppConfig().isisConfiguration();
+        bind(IsisConfiguration.class).toInstance(isisConfiguration);
     }
 
     @Provides
     @com.google.inject.Inject
     @Singleton
-    protected IsisSessionFactory provideIsisSessionFactory() {
+    protected IsisSessionFactory provideIsisSessionFactory(IsisConfiguration isisConfiguration) {
+        
+        AppManifest appManifest = isisConfiguration.getAppManifest();
         
-        AppManifest appManifest = _Config.getConfiguration().getAppManifest();
         
         System.err.println("!!!!!!!!!! provideIsisSessionFactory STAGE 1 "+Thread.currentThread().getName());