You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2017/12/13 09:59:14 UTC

[isis] 01/02: ISIS-1782: refactors/simplifies ModuleAbstract and AppManifest2, factors out ModuleOrBuilderAbstract as non-API internal class

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

danhaywood pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git

commit f1aa1e12e0718d265badb15d6a16721792d964c8
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Wed Dec 13 09:56:19 2017 +0000

    ISIS-1782: refactors/simplifies ModuleAbstract and AppManifest2, factors out ModuleOrBuilderAbstract as non-API internal class
    
    Also:
    - renames new adapter classes to HeadlessAbstract, HeadlessWithBootstrappingAbstact, and moves to runtime.
    - updates docs
---
 .../_rgcms_classes_AppManifest-bootstrapping.adoc  |  14 +-
 .../_rgcms_classes_AppManifest2-bootstrapping.adoc | 193 ++++++++++++++++++
 .../ugfun/_ugfun_building-blocks_modules.adoc      |   8 +-
 .../_ugtst_integ-test-support_abstract-class.adoc  |  99 ++++++----
 .../java/org/apache/isis/applib/AppManifest2.java  |   5 +
 .../apache/isis/applib/AppManifestAbstract.java    | 182 ++++-------------
 .../apache/isis/applib/AppManifestAbstract2.java   | 219 ++++++---------------
 .../org/apache/isis/applib/AppManifestBuilder.java |  52 -----
 .../main/java/org/apache/isis/applib/Module.java   | 113 ++++++++---
 .../org/apache/isis/applib/ModuleAbstract.java     | 170 ++--------------
 .../isis/applib/ModuleOrBuilderAbstract.java       | 128 ++++++++++++
 .../org/apache/isis/applib/PropertyResource.java   |  61 ++++++
 .../Module_Util_transitiveDependenciesOf_Test.java |   9 +-
 .../integtestsupport/IntegrationTestAbstract3.java |   6 +-
 .../core/integtestsupport/IsisSystemForTest.java   |   2 +
 .../scenarios/ObjectFactoryForIntegration.java     |   2 +-
 .../scenarios/ScenarioExecutionForIntegration.java |   4 +-
 .../core/runtime/headless/HeadlessAbstract.java}   |  11 +-
 .../HeadlessWithBootstrappingAbstract.java}        |  31 ++-
 .../headless}/IsisComponentProviderDefault.java    |   2 +-
 .../isis/core/runtime/headless}/IsisSystem.java    |   4 +-
 .../runtime/headless}/IsisSystemBootstrapper.java  |  10 +-
 .../auth/AuthenticationRequestNameOnly.java}       |  12 +-
 .../core/runtime/headless}/logging/LogConfig.java  |   2 +-
 .../core/runtime/headless}/logging/LogStream.java  |   2 +-
 ...sisSystemBootstrapper_haveSameModules_Test.java |   2 +-
 .../specs/CukeGlueIntegrationScopeAbstract.java    |  17 +-
 .../application/HelloWorldAppManifest.java         |   6 +-
 .../main/java/domainapp/dom/HelloWorldModule.java  |   6 +-
 .../bdd/specglue/BootstrappingGlue.java            |  16 +-
 .../bdd/specglue/CatalogOfFixturesGlue.java        |   4 +-
 .../modules/simple/SimpleModuleManifest.java       |   7 +-
 .../simple/specglue/SimpleObjectMenuGlue.java      |   4 +-
 33 files changed, 759 insertions(+), 644 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest-bootstrapping.adoc b/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest-bootstrapping.adoc
index 987c4d4..48fa4df 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest-bootstrapping.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest-bootstrapping.adoc
@@ -1,5 +1,7 @@
 [[_rgcms_classes_AppManifest-bootstrapping]]
 = `AppManifest` (bootstrapping)
+:toc:
+
 :Notice: 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 ag [...]
 :_basedir: ../../
 :_imagesdir: images/
@@ -9,7 +11,12 @@ This section describes how to implement the `AppManifest` interface to bootstrap
 
 [TIP]
 ====
-(As of `1.15.0`), the framework-provided `AppManifestAbstract` and `AppManifestAbstract.Builder` make it easy to write ``AppManifest`` that can be used both to bootstrap the application "proper", and to be tweaked for use within integration tests.
+As of `1.15.0`, the framework-provided `AppManifestAbstract` and `AppManifestAbstract.Builder` make it easy to write ``AppManifest`` that can be used both to bootstrap the application "proper", and to be tweaked for use within integration tests.
+====
+
+[TIP]
+====
+As of `1.16.0-SNAPSHOT`, the framework-provided `AppManifestAbstract2` and `AppManifestAbstract2.Builder` makes it even easier to write an `AppManifest`, this time using an implementation of a xref:rgcms.adoc#_rgcms_classes_Module[`Module`].
 ====
 
 
@@ -191,6 +198,11 @@ public Map<String, String> getConfigurationProperties() {
 [[__rgcms_classes_AppManifest-bootstrapping_bootstrapping]]
 == Bootstrapping
 
+[NOTE]
+====
+The recommendations in this section no longer apply if using the xref:../rgcms/rgcms.adoc#__rgcms_classes_AppManifest2-bootstrapping_bootstrapping[`AppManifest2`] interface and ``Module``s to bootstrap your application.
+====
+
 One of the primary goals of the `AppManifest` is to unify the bootstrapping of both integration tests and the webapp.
 This requires that the integration tests and webapp can both reference the implementation.
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest2-bootstrapping.adoc b/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest2-bootstrapping.adoc
new file mode 100644
index 0000000..14ec7dc
--- /dev/null
+++ b/adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_classes_AppManifest2-bootstrapping.adoc
@@ -0,0 +1,193 @@
+[[_rgcms_classes_AppManifest2-bootstrapping]]
+= `AppManifest2` (and `Module`) (`1.16.0-SNAPSHOT`)
+:Notice: 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 ag [...]
+:_basedir: ../../
+:_imagesdir: images/
+
+
+(As of `1.16.0-SNAPSHOT`), the bootstrapping of an Apache Isis application has been modularized using the `Module` interface, with `AppManifest2` an extension of the original xref:rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping[`AppManifest`] interface, defined in terms of `Module` also.
+
+A `Module` represents a collection of entities and domain services that provide a set of coherent functionality under a single package (and subpackages underneath), with the module class itself residing at the top-level package.
+
+Each `Module` can express its immediate dependencies (using `Module#getDependencies()` method); from this the framework computes the full set of modules (and therefore entities and domain services) that make up the application.
+
+Each `Module` can also optionally define additional dependencies on "legacy" modules (that is, those that do not implement `Module`) using `Module#getAdditionalModules()` method.
+These legacy modules simply define a package to search for entities and domain services.
+Legacy domain services can also be explicitly identified using `Module#getAdditionalServices()` method; such services do _not_ need to be annotated with xref:../rgant/rgant.adoc#_rgant_DomainService[`@DomainService`].
+
+A `Module` can also declare additional configuration properties (using either `Module#getIndividualConfigProps()` or `Module#getPropertyResources()`) that should be      contributed to the overall set of configuration properties used to bootstrap the application.
+
+Finally, each `Module` can also optionally define a reference-data fixture (for reference data entities of the module) and also a tear-down fixture (using `Module#{@link #getRefDataSetupFixture()` and `Module#getTeardownFixture()` respectively).
+These are executed automatically (and in the correct order) within integration tests, simplifying setup and teardown of such tests.
+
+
+[IMPORTANT]
+====
+Implementations of `Module` are expected to have value-semantics.
+Each `Module` can declare its respective dependencies (using `Module#getDependencies()`) simply by instantiating the `Module`s on which it depends.
+Any duplicates from the computed graph of all dependencies are automatically eliminated.
+====
+
+
+The application (or integration test) is still bootstrapped using an `AppManifest`, but using the `AppManifest2` sub-interface and corresponding `AppManifestAbstract2` abstract adapter.
+This latter class provides a `Builder` that allows an app manifest to be created from a single top-level `Module`.
+
+There are a number of similarities between a `Module` and an `AppManifestAbstract2.Builder`: both identify the set of modules that make up the application, along with additional services and configuration properties, and can derive a fixture script for start-up and tear-down.
+Because of this, the `IntegrationTestAbstract3` superclass actually requires just a `Module` to bootstrap rather than an `AppManifest`.
+(Underneath the covers `AppManifestAbstract2.Builder` can be instantiated from a `Module` instance, from whence the `AppManifest` to bootstrap the integration test is obtained).
+
+However there are some differences too, these relate to the difference between the running webapp vs integration tests.
+Specifically, only the `Builder` can specify the authentication mechanism, and only the `Builder` can specify an additional fixture script to run when the application starts (usually, to run up a demo app).
+
+
+[[_rgcms_classes_AppManifest2-bootstrapping_api]]
+== API
+
+The `AppManifest2` interface extends xref:rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping_api[`AppManifest`], additionally declaring the top-level `Module` that was used to create the app manifest, and fixtures for reference data setup and for teardown:
+
+[source,java]
+----
+public interface AppManifest2 extends AppManifest {
+    Module getModule();
+    FixtureScript getTeardownFixture();
+    FixtureScript getRefDataSetupFixture();
+}
+----
+
+The (inherited) `AppManifest#getModules()` - a list of classes representing the packages to be scanned for domain services and entities - is still used to actually bootstrap the application.
+It should therefore be computed from the transitive set of dependencies of the declared `Module`.
+The `AppManifestAbstract2` (or more precisely, its `Builder`) provides a suitable implementation of this.
+
+The `AppManifestAbstract2.Builder` is defined as:
+
+[source,java]
+----
+public abstract class AppManifestAbstract2 extends AppManifestAbstract implements AppManifest2 {
+    ...
+    public static class Builder extends AppManifestAbstract.BuilderAbstract<Builder> {
+
+        private Builder(Module module) { ... }
+        public Module getModule() { ... }
+
+        public Builder withAdditionalDependency(final Module dependency) { ... }
+        public Builder withAdditionalDependencies(final Set<Module> dependencies) { ... }
+
+        ...
+    }
+}
+----
+
+Additional `withXxx(...)` builder methods are inherited from xref:rgcms.adoc#__rgcms_classes_AppManifest-bootstrapping_bootstrapping[`AppManifestAbstract.Builder`].
+
+
+For example:
+
+[source,java]
+----
+public class DomainAppAppManifest extends AppManifestAbstract2 {
+
+    public DomainAppAppManifest() {
+        super(Builder
+                .forModule(new DomainAppApplicationModule())
+                .withConfigurationPropertiesFile(DomainAppAppManifest.class,
+                                                 "isis.properties",
+                                                 "authentication_shiro.properties",
+                                                 "persistor_datanucleus.properties",
+                                                 "viewer_restfulobjects.properties",
+                                                 "viewer_wicket.properties")
+                .withAuthMechanism("shiro"));
+    }
+}
+----
+
+The `Module` interface is defined as:
+
+[source,java]
+----
+public interface Module {
+    Set<Module> getDependencies();                  // <1>
+    Set<Class<?>> getAdditionalModules();           // <2>
+    Set<Class<?>> getAdditionalServices();          // <3>
+
+    FixtureScript getRefDataSetupFixture();         // <4>
+    FixtureScript getTeardownFixture();             // <5>
+
+    Map<String,String> getIndividualConfigProps();  // <6>
+    List<PropertyResource> getPropertyResources();
+}
+----
+<1> As per Maven's `<dependencies></dependencies> element.
+The framework calculates a full set of transitive dependencies from this.
+<2> Support for "legacy" modules that do not implement `Module`.
+These are added to the set of packages to scan for entities and domain services.
+<3>Each `Module` can define additional "legacy" domain services that have not been defined within modules,or that have not been annotated with xref:../rgant/rgant.adoc#_rgant_DomainService[`@DomainService`].
+<4> Optionally each `Module` can define a xref:rgcms.adoc#_rgcms_classes_super_FixtureScript[`FixtureScript`] which holds immutable "reference data".
+These are automatically executed whenever running integration tests (but are ignored when bootstrapping the runtime as a webapp.
+<5> Similarly, optionally each `Module` can define a tear-down xref:rgcms.adoc#_rgcms_classes_super_FixtureScript[`FixtureScript`], used to remove the contents of _all_ entities (both reference data and operational/transactional data).
+<6> Optionally each module can define additional configuration properties.
+These can either be specified as key-value pair, or by way of the `PropertyResource` class.
+The `PropertyResource` class identifies a property configuration file to load from the classpath, with respect to some other context class.
+
+Rather than implementing directly it's generally easiest for applications to inherit from the `ModuleAbstract` adapter.
+
+
+[source,java]
+----
+/**
+ * Adapter for {@link Module} which has a default no-op implementation.
+ *
+ * <p>
+ *     Subclasses can either override the methods, or can use the various {@link #withAdditionalModules(Class[])}.
+ * </p>
+ */
+public abstract class ModuleAbstract                                        // <1>
+        implements Module {
+
+    public ModuleAbstract withAdditionalModules(...) { ... }                // <2>
+    public ModuleAbstract withAdditionalServices(...) { ... }               // <3>
+
+    public ModuleAbstract withConfigurationProperties(...) { ... }          // <4>
+    public ModuleAbstract withConfigurationPropertiesFile(...) { ... }
+    public ModuleAbstract withConfigurationPropertyResources(...) { ... }
+    public ModuleAbstract withConfigurationPropertyResource(...) { ... }
+    public ModuleAbstract withConfigurationProperty(...) { ... }
+
+    public Set<Module> getDependencies() { return Collections.emptySet(); } // <5>
+
+    public Set<Class<?>> getAdditionalModules() { ... }                     // <2>
+    public Set<Class<?>> getAdditionalServices() { ... }                    // <3>
+
+    public FixtureScript getRefDataSetupFixture() { ... }                   // <6>
+    public FixtureScript getTeardownFixture() { ... }
+
+    public Map<String,String> getIndividualConfigProps() { ... }            // <4>
+    public List<PropertyResource> getPropertyResources() { ... }
+}
+----
+<1> This is slightly simplified; in fact `ModuleAbstract` inherits from an internal class (`ModuleOrBuilderAbstract`).
+The functionality of this superclass is listed above.
+<2> Builder-like methods to specify additional "legacy" ``Module``s.
+Alternatively, could override `getAdditonalModules()`.
+<3> Builder-like methods to specify additional "legacy" domain services.
+Alternatively, could override `getAdditonalServices()`.
+<4> Builder-like methods to specify additional configuration propeties specific to this module
+<5> Set of other ``Module``s on which this module depends (from which a full graph of transitive dependencies is calculated).
+<6> Optional reference data and teardown fixture scripts for the module.
+
+
+
+[[__rgcms_classes_AppManifest2-bootstrapping_bootstrapping]]
+== Bootstrapping
+
+One of the overarching goals is to ensure that integration tests and the webapp are bootstrapped in as similar a way as possible.
+xref:rgcms.adoc#__rgcms_classes_AppManifest-bootstrapping_bootstrapping[Previously] this was done by using a single `AppManifest` for both the tests and the webapp.
+
+However, this approach does have a significant drawback.
+The `AppManifest` implementation must (necessarily) reference all the modules wthin the application, and this therefore means that the integration tests are also scoped (or at least, have access to) the entire application.
+
+(As noted above), the `IntegrationTestAbstract3` adapter class is bootstrapped from a `Module` rather than an `AppManifest`.
+This therefore allows the integration tests to reside alongside the module that they exercise, and to bootstrap only the subset of the application required (that is, the module being tested and any of its transitive dependencies)..
+
+For more on `IntegrationTestAbstract3`, see the xref:../ugtst/ugtst.adoc#__ugtst_integ-test-support_abstract-class_IntegrationTestAbstract3[testing user guide].
+
+
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_modules.adoc b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_modules.adoc
index 1452a59..a8f5db8 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_modules.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugfun/_ugfun_building-blocks_modules.adoc
@@ -15,10 +15,12 @@ The bootstrapping of Apache Isis also relies on module classes.
 (Currently) the only role of these classes is to identify a fully qualified package name, for example `org.incode.modules.document`.
 The framework then performs classpath scanning across all such packages to locate any domain entities provided by that module (though some modules have no entities), all domain services provided by the module (every module is likely to define at least one), and also any fixture scripts provided by the module.
 
-[TIP]
-====
 In the same way that the Java module act as a namespace for domain objects, it's good practice to map domain entities to their own (database) schemas.
-====
+
+In previous versions a module class did not need to implement any specific interface; all the framework used was the package of the provided class.
+As of `1.16.0-SNAPSHOT` however, the xref:../rgcms/rgcms.adoc#_rgcms_classes_Module[`Module`] interface allows a module to specify its direct dependencies; from these all transitive dependencies are calculated.
+This should match the compile-time dependencies declared within Maven.
+The `Module` interface also allows a module to declare any configuration properties that should be contributed, as well as fixture scripts for reference data, and to tear down (for integration testing).
 
 
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_integ-test-support_abstract-class.adoc b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_integ-test-support_abstract-class.adoc
index 7b1d341..1024320 100644
--- a/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_integ-test-support_abstract-class.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_integ-test-support_abstract-class.adoc
@@ -8,6 +8,7 @@
 
 When writing integration tests, it's easiest to inherit from a base class:
 
+* as of (`1.16.0`), use `IntegrationTestAbstract3`
 * as of (`1.15.0`), use `IntegrationTestAbstract2`
 * for earlier releases, use (its superclass) `IntegrationTestAbstract`.
 
@@ -15,6 +16,45 @@ This base class xref:ugtst.adoc#_ugtst_integ-test-support_bootstrapping[bootstra
 
 
 
+[[__ugtst_integ-test-support_abstract-class_IntegrationTestAbstract3]]
+== `IntegrationTestAbstract3`
+
+(As of `1.16.0-SNAPSHOT`) we recommend that your integration tests inherit from Apache Isis' `IntegrationTestAbstract3` class.
+The primary benefit over `IntegrationTestAbstract2` (discussed xref:ugtst.adoc#__ugtst_integ-test-support_abstract-class_IntegrationTestAbstract2[below] is that it allows the test to be bootstrapped by passing in a `Module` rather than an `AppManifest`.
+
+For example:
+
+[source,java]
+----
+public abstract class DomainAppIntegTest
+                        extends IntegrationTestAbstract3 {
+
+    public DomainAppIntegTestAbstract() {
+        super(new DomainAppApplicationModule());
+    }
+}
+----
+
+
+However, the `IntegrationTestAbstract3` class also allows the module to be specified externally, using the `isis.integTest.module` system property, eg by updating the `pom.xml`.
+
+For example:
+
+[source,xml]
+----
+<properties>
+    <isis.integTest.module>
+        org.estatio.module.application.EstatioApplicationModule
+    </isis.integTest.module>
+</properties>
+
+----
+
+This is required when the codebase is organised as multiple "logical" modules within a single Maven "physical" module (ie `src/main/java` compilation unit).
+The integration testing framework will bootstrap the module specified by the system property and cache for all tests discovered within the physical module.
+
+
+
 [[__ugtst_integ-test-support_abstract-class_IntegrationTestAbstract2]]
 == `IntegrationTestAbstract2`
 
@@ -22,28 +62,38 @@ This base class xref:ugtst.adoc#_ugtst_integ-test-support_bootstrapping[bootstra
 
 [source,java]
 ----
-public abstract class DomainAppIntegTest extends IntegrationTestAbstract2 {
+public abstract class DomainAppIntegTest
+    extends IntegrationTestAbstract2 {
     ...
 }
 ----
 
+Bootstrapping is performed by calling either of the overloaded _static_ `bootstrapUsing(...)` methods:
+
+[source,java]
+----
+protected static void bootstrapUsing(final AppManifestAbstract.Builder builder) { ... }
+
+protected static void bootstrapUsing(final AppManifest appManifest) { ... }
+----
 
-Although not mandatory, this provides a number of helper/convenience methods and JUnit rules:
+
+Although not mandatory, this test class also provides a number of helper/convenience methods and JUnit rules:
 
 [source,java]
 ----
-    @Rule
-    public IsisTransactionRule isisTransactionRule =                         // <1>
-        new IsisTransactionRule();
-    @Rule
-    public JUnitRuleMockery2 context =                                       // <2>
-        JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
-    @Rule
-    public ExpectedException expectedExceptions =                            // <3>
-        ExpectedException.none();
-    @Rule
-    public ExceptionRecognizerTranslate exceptionRecognizerTranslations =    // <4>
-        ExceptionRecognizerTranslate.create();
+@Rule
+public IsisTransactionRule isisTransactionRule =                         // <1>
+    new IsisTransactionRule();
+@Rule
+public JUnitRuleMockery2 context =                                       // <2>
+    JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+@Rule
+public ExpectedException expectedExceptions =                            // <3>
+    ExpectedException.none();
+@Rule
+public ExceptionRecognizerTranslate exceptionRecognizerTranslations =    // <4>
+    ExceptionRecognizerTranslate.create();
 ----
 <1> ensures an Apache Isis session/transaction running for each test
 <2> sets up a JMock context (using Apache Isis' extension to JMock as described in xref:../ugtst/ugtst.adoc#_ugtst_unit-test-support_jmock-extensions[JMock Extensions].
@@ -52,25 +102,8 @@ Although not mandatory, this provides a number of helper/convenience methods and
 
 All of these rules could be inlined in your own base class; as we say, they are a convenience.
 
-The `IntegrationTestAbstract2` also provides a number of helper/convenience methods, though most of these have been deprecated because the functionality they expose is now readily accessible through various domain services; most notably these are:
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-api_RepositoryService[`RepositoryService`]
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_FactoryService[`FactoryService`]
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_metadata-api_ServiceRegistry[`ServiceRegistry2`]
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_WrapperFactory[`WrapperFactory`] +
-+
-to wrap objects simulating interaction through the user interface)
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_TransactionService[`TransactionService`] +
-+
-most commonly used to commit changes after the fixture setup) and,
-
-* xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_SessionManagementService[`SessionManagementService`] +
-+
-for tests that check interactions over multiple separate sessions.
+The `IntegrationTestAbstract2` also provides a number of helper/convenience methods, though most of these have been deprecated because the functionality they expose is now readily accessible through various domain services; most notably these are
+xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-api_RepositoryService[`RepositoryService`], xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_FactoryService[`FactoryService`], xref:../rgsvc/rgsvc.adoc#_rgsvc_metadata-api_ServiceRegistry[`ServiceRegistry2`], xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_WrapperFactory[`WrapperFactory`] (to wrap objects simulating interaction through the user interface), xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_TransactionService[`Tran [...]
 
 
 
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java
index 52154f7..a9daa4c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java
@@ -19,11 +19,16 @@
 
 package org.apache.isis.applib;
 
+import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
 public interface AppManifest2 extends AppManifest {
 
+    @Programmatic
+    Module getModule();
+    @Programmatic
     FixtureScript getTeardownFixture();
+    @Programmatic
     FixtureScript getRefDataSetupFixture();
 
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
index f3a49b3..8a540d1 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract.java
@@ -18,17 +18,13 @@
  */
 package org.apache.isis.applib;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
-import java.util.Properties;
 import java.util.Set;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
 
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
@@ -43,9 +39,9 @@ public abstract class AppManifestAbstract implements AppManifest {
     private final List<Class<? extends FixtureScript>> fixtures;
     private final Map<String, String> configurationProperties;
 
-    public AppManifestAbstract(final AppManifestBuilder<?> builder) {
+    public AppManifestAbstract(final BuilderAbstract<?> builder) {
 
-        final List<Class<?>> builderModules = builder.getAllModulesAsClass();
+        final List<Class<?>> builderModules = builder.getAllAdditionalModules();
         overrideModules(builderModules);
         this.modules = builderModules;
 
@@ -63,7 +59,7 @@ public abstract class AppManifestAbstract implements AppManifest {
                 this.fixtures);
     }
 
-    private String determineAuthMechanism(final AppManifestBuilder<?> builder) {
+    private String determineAuthMechanism(final ModuleOrBuilderAbstract<?> builder) {
         final String overriddenAuthMechanism = overrideAuthMechanism();
         if (overriddenAuthMechanism != null) {
             return overriddenAuthMechanism;
@@ -76,7 +72,7 @@ public abstract class AppManifestAbstract implements AppManifest {
         }
     }
 
-    private List<Class<? extends FixtureScript>> determineFixtures(final AppManifestBuilder<?> builder) {
+    private List<Class<? extends FixtureScript>> determineFixtures(final ModuleOrBuilderAbstract<?> builder) {
         final List<Class<? extends FixtureScript>> builderFixtures;
         if(builder instanceof Builder) {
             builderFixtures = ((Builder) builder).fixtures;
@@ -89,14 +85,14 @@ public abstract class AppManifestAbstract implements AppManifest {
 
     private Map<String, String> createConfigurationProperties(
             final List<PropertyResource> propertyResources,
-            final List<ConfigurationProperty> individualConfigProps,
+            final Map<String,String> individualConfigProps,
             final List<Class<? extends FixtureScript>> fixtures) {
         final Map<String, String> props = Maps.newHashMap();
         for (PropertyResource propertyResource : propertyResources) {
             propertyResource.loadPropsInto(props);
         }
-        for (ConfigurationProperty individualConfigProp : individualConfigProps) {
-            individualConfigProp.put(props);
+        for (final Map.Entry<String,String> individualConfigProp : individualConfigProps.entrySet()) {
+            props.put(individualConfigProp.getKey(), individualConfigProp.getValue());
         }
         if(!fixtures.isEmpty()) {
             props.put("isis.persistor.datanucleus.install-fixtures","true");
@@ -197,167 +193,73 @@ public abstract class AppManifestAbstract implements AppManifest {
     }
 
     /**
-     * Used to build an {@link AppManifest} either {@link #build() directly}, or implicitly by passing into
-     * {@link AppManifestAbstract}'s {@link AppManifestAbstract#AppManifestAbstract(AppManifestBuilder) constructor}.
+     * Default implementation of {@link AppManifestAbstract} that is built using a {@link Builder}.
      */
-    public static class Builder implements AppManifestBuilder<Builder> {
-
-        final List<Class<?>> modules = Lists.newArrayList();
-        Set<Class<?>> additionalServices = Sets.newLinkedHashSet();
-        String authMechanism = "shiro";
-        List<Class<? extends FixtureScript>> fixtures = Lists.newArrayList();
-
-        List<ConfigurationProperty> individualConfigProps = Lists.newArrayList();
-        List<PropertyResource> propertyResources = Lists.newArrayList();
-
-        private Map<String,String> configurationProperties = Maps.newHashMap();
-
-        Builder() {}
-
-        /**
-         * Factory method.
-         */
-        public static Builder forModules(final List<Class<?>> modules) {
-            return new Builder().withAdditionalModules(modules);
-        }
-        public static Builder forModules(final Class<?>... modules) {
-            return forModules(Arrays.asList(modules));
+    public static class Default extends AppManifestAbstract {
+        public Default(final AppManifestAbstract.Builder builder) {
+            super(builder);
         }
+    }
 
-        public Builder withAdditionalModules(final Class<?>... modules) {
-            return withAdditionalModules(Arrays.asList(modules));
-        }
+    public static abstract class BuilderAbstract<B extends BuilderAbstract<B>> extends ModuleOrBuilderAbstract<B> {
 
-        public Builder withAdditionalModules(final List<Class<?>> modules) {
-            if(modules == null) {
-                throw new IllegalArgumentException("List of modules must not be null");
-            }
-            this.modules.addAll(modules);
-            return this;
-        }
+        String authMechanism = "shiro";
+        List<Class<? extends FixtureScript>> fixtures = Lists.newArrayList();
 
-        public Builder withAuthMechanism(final String authMechanism) {
+        public B withAuthMechanism(final String authMechanism) {
             this.authMechanism = authMechanism;
-            return this;
-        }
-
-        public Builder withAdditionalServices(final Class<?>... additionalServices) {
-            return withAdditionalServices(Arrays.asList(additionalServices));
+            return (B)this;
         }
 
-        public Builder withAdditionalServices(final List<Class<?>> additionalServices) {
-            if(additionalServices == null) {
-                throw new IllegalArgumentException("List of additional services must not be null");
-            }
-            this.additionalServices = Sets.newLinkedHashSet(additionalServices);
-            return this;
-        }
-
-        public Builder withFixtureScripts(final Class<? extends FixtureScript>... fixtures) {
+        public B withFixtureScripts(final Class<? extends FixtureScript>... fixtures) {
             return withFixtureScripts(Arrays.asList(fixtures));
         }
 
-        public Builder withFixtureScripts(final List<Class<? extends FixtureScript>> fixtures) {
+        public B withFixtureScripts(final List<Class<? extends FixtureScript>> fixtures) {
             if(fixtures == null) {
-                throw new IllegalArgumentException("List of fixtures must not be null");
-            }
-            this.fixtures = Lists.newArrayList(fixtures);
-            return this;
-        }
-
-        public Builder withConfigurationProperties(final Map<String,String> configurationProperties) {
-            this.configurationProperties.putAll(configurationProperties);
-            return this;
-        }
-
-        public Builder withConfigurationPropertiesFile(final String propertiesFile) {
-            return withConfigurationPropertiesFile(getClass(), propertiesFile);
-        }
-
-        public Builder withConfigurationPropertiesFile(
-                final Class<?> propertiesFileContext, final String propertiesFile, final String... furtherPropertiesFiles) {
-            addPropertyResource(propertiesFileContext, propertiesFile);
-            for (final String otherFile : furtherPropertiesFiles) {
-                addPropertyResource(propertiesFileContext, otherFile);
+                return (B)this;
             }
-            return this;
+            this.fixtures.addAll(fixtures);
+            return (B)this;
         }
 
-        private void addPropertyResource(final Class<?> propertiesFileContext, final String propertiesFile) {
-            propertyResources.add(new PropertyResource(propertiesFileContext, propertiesFile));
+        List<Class<?>> getAllAdditionalModules() {
+            return Lists.newArrayList(additionalModules);
         }
 
-        public Builder withConfigurationProperty(final String key, final String value) {
-            individualConfigProps.add(new ConfigurationProperty(key,value));
-            return this;
-        }
-
-        @Override
-        public List<Class<?>> getAllModulesAsClass() {
-            return modules;
-        }
-
-        @Override
-        public Set<Class<?>> getAllAdditionalServices() {
+        Set<Class<?>> getAllAdditionalServices() {
             return additionalServices;
         }
 
-        @Override
-        public List<PropertyResource> getAllPropertyResources() {
-            return propertyResources;
+        List<PropertyResource> getAllPropertyResources() {
+            return getPropertyResources();
         }
 
-        @Override
-        public List<ConfigurationProperty> getAllIndividualConfigProps() {
-            return individualConfigProps;
+        Map<String,String> getAllIndividualConfigProps() {
+            return getIndividualConfigProps();
         }
 
-        public AppManifest build() {
-            return new AppManifestAbstract(this) {};
-        }
+        public abstract AppManifest build();
 
     }
 
-    static class ConfigurationProperty {
-        private final String key;
-        private final String value;
+    public static class Builder extends BuilderAbstract<Builder> {
 
-        ConfigurationProperty(final String key, final String value) {
-            this.key = key;
-            this.value = value;
+        /**
+         * Factory method.
+         */
+        public static AppManifestAbstract.Builder forModules(final List<Class<?>> modules) {
+            return new AppManifestAbstract.Builder().withAdditionalModules(modules);
         }
-
-        void put(final Map<String, String> props) {
-            props.put(key, value);
+        public static AppManifestAbstract.Builder forModules(final Class<?>... modules) {
+            return forModules(Arrays.asList(modules));
         }
-    }
 
-    static class PropertyResource {
-        private final Class<?> propertiesFileContext;
-        private final String propertiesFile;
-
-        PropertyResource(final Class<?> propertiesFileContext, final String propertiesFile) {
-            this.propertiesFileContext = propertiesFileContext;
-            this.propertiesFile = propertiesFile;
+        @Override
+        public AppManifest build() {
+            return new AppManifestAbstract.Default(this);
         }
 
-        void loadPropsInto(
-                final Map<String, String> props) {
-            final Properties properties = new Properties();
-            try {
-                try (final InputStream stream = propertiesFileContext.getResourceAsStream(propertiesFile)) {
-                    properties.load(stream);
-                    for (Object key : properties.keySet()) {
-                        final Object value = properties.get(key);
-                        if (key instanceof String && value instanceof String) {
-                            props.put((String) key, (String) value);
-                        }
-                    }
-                }
-            } catch (IOException e) {
-                throw new RuntimeException(
-                        String.format("Failed to load '%s' file ", this), e);
-            }
-        }
     }
+
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract2.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract2.java
index a5bce36..d762a57 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract2.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/AppManifestAbstract2.java
@@ -21,7 +21,6 @@ package org.apache.isis.applib;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import org.apache.isis.applib.annotation.Programmatic;
@@ -32,161 +31,10 @@ import org.apache.isis.applib.fixturescripts.FixtureScript;
  */
 public abstract class AppManifestAbstract2 extends AppManifestAbstract implements AppManifest2 {
 
-    public static class Default extends AppManifestAbstract2 {
-        public Default(final AppManifestAbstract.Builder builder) {
-            super(builder);
-        }
-    }
-
-    interface ModuleProvider {
-        Module getModule();
-    }
-    public static class Builder extends AppManifestAbstract.Builder implements ModuleProvider {
-
-        public static AppManifestAbstract.Builder forModule(Module module) {
-            return module instanceof ModuleAbstract
-                    ? new BuilderWrappingModuleAbstract((ModuleAbstract)module)
-                    : new Builder(module);
-        }
-
-        private final Module module;
-
-        @Override
-        public Module getModule() {
-            return module;
-        }
-
-        private Builder(Module module) {
-            this.module = module;
-
-            final List<Module> transitiveDependencies = Module.Util.transitiveDependenciesOf(module);
-            final Class[] moduleTransitiveDependencies = asClasses(transitiveDependencies);
-
-            final List<Class<?>> additionalModules = Module.Util.transitiveDependenciesAsClassOf(module);
-            final List<Class<?>> additionalServices = Module.Util.transitiveAdditionalServicesOf(module);
-
-            withAdditionalModules(moduleTransitiveDependencies);
-            withAdditionalModules(additionalModules);
-            withAdditionalServices(additionalServices);
-        }
-
-        private static Class[] asClasses(final List<Module> dependencies) {
-            final List<Class<? extends Module>> list = new ArrayList<>();
-            for (Module dependency : dependencies) {
-                Class<? extends Module> aClass = dependency.getClass();
-                list.add(aClass);
-            }
-            return list.toArray(new Class[] {});
-        }
-
-        @Override
-        public AppManifest build() {
-            return new Default(this);
-        }
-    }
-
-    /**
-     * A {@link AppManifestAbstract.Builder} implementation that delegates to the wrapped {@link ModuleAbstract} for transitive modules,
-     * services and configuration properties, but continues to manage fixture scripts and auth mechanisms.
-     */
-    public static class BuilderWrappingModuleAbstract extends AppManifestAbstract.Builder implements ModuleProvider {
-
-        private final ModuleAbstract moduleAbstract;
-
-        private BuilderWrappingModuleAbstract(ModuleAbstract moduleAbstract) {
-            this.moduleAbstract = moduleAbstract;
-        }
-
-        @Override
-        public Module getModule() {
-            return moduleAbstract;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withAdditionalModules(final Class<?>... modules) {
-            moduleAbstract.withAdditionalModules(modules);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withAdditionalModules(final List<Class<?>> modules) {
-            moduleAbstract.withAdditionalModules(modules);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withAdditionalServices(final Class<?>... additionalServices) {
-            moduleAbstract.withAdditionalServices(additionalServices);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withAdditionalServices(final List<Class<?>> additionalServices) {
-            moduleAbstract.withAdditionalServices(additionalServices);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withConfigurationProperties(final Map<String, String> configurationProperties) {
-            moduleAbstract.withConfigurationProperties(configurationProperties);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withConfigurationPropertiesFile(final String propertiesFile) {
-            moduleAbstract.withConfigurationPropertiesFile(propertiesFile);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withConfigurationPropertiesFile(
-                final Class<?> propertiesFileContext,
-                final String propertiesFile,
-                final String... furtherPropertiesFiles) {
-            moduleAbstract.withConfigurationPropertiesFile(propertiesFileContext, propertiesFile, furtherPropertiesFiles);
-            return this;
-        }
-
-        @Override
-        public AppManifestAbstract.Builder withConfigurationProperty(final String key, final String value) {
-            moduleAbstract.withConfigurationProperty(key, value);
-            return this;
-        }
-
-        @Override
-        public List<Class<?>> getAllModulesAsClass() {
-            return moduleAbstract.getAllModulesAsClass();
-        }
-
-        @Override
-        public Set<Class<?>> getAllAdditionalServices() {
-            return moduleAbstract.getAllAdditionalServices();
-        }
-
-        @Override
-        public List<PropertyResource> getAllPropertyResources() {
-            return moduleAbstract.getAllPropertyResources();
-        }
-
-        @Override
-        public List<ConfigurationProperty> getAllIndividualConfigProps() {
-            return moduleAbstract.getAllIndividualConfigProps();
-        }
-
-        @Override
-        public AppManifest build() {
-            return new Default(this);
-        }
-
-    }
-
     private final Module module;
-    public AppManifestAbstract2(final AppManifestAbstract.Builder builder) {
+    public AppManifestAbstract2(final AppManifestAbstract2.Builder builder) {
         super(builder);
-        if (!(builder instanceof ModuleProvider)) {
-            throw new IllegalArgumentException("Requires a Builder that implements ModuleProvider");
-        }
-        this.module = ((ModuleProvider)builder).getModule();
+        this.module = builder.getModule();
     }
 
     @Programmatic
@@ -228,5 +76,68 @@ public abstract class AppManifestAbstract2 extends AppManifestAbstract implement
     }
 
 
+    /**
+     * Default implementation of {@link AppManifestAbstract2} that is built using a {@link AppManifestAbstract2.Builder}.
+     */
+    public static class Default extends AppManifestAbstract2 {
+        public Default(final AppManifestAbstract2.Builder builder) {
+            super(builder);
+        }
+    }
+
+    public static class Builder extends AppManifestAbstract.BuilderAbstract<Builder> {
+
+        /**
+         * Factory method.
+         */
+        public static AppManifestAbstract2.Builder forModule(Module module) {
+            return new Builder(module);
+        }
+
+        private final Module module;
+
+        private Builder(Module module) {
+            this.module = module;
+            withTransitiveFrom(module);
+        }
+
+        public Module getModule() {
+            return module;
+        }
+
+        public Builder withAdditionalDependency(final Module dependency) {
+            withTransitiveFrom(dependency);
+            return this;
+        }
+
+        public Builder withAdditionalDependencies(final Set<Module> dependencies) {
+            for (final Module dependency : dependencies) {
+                withAdditionalDependency(dependency);
+            }
+            return this;
+        }
+
+        private void withTransitiveFrom(final Module module) {
+            withAdditionalModules(asClasses(Module.Util.transitiveDependenciesOf(module)));
+            withAdditionalModules(Module.Util.transitiveDependenciesAsClassOf(module));
+            withAdditionalServices(Module.Util.transitiveAdditionalServicesOf(module));
+            withConfigurationPropertyResources(Module.Util.transitivePropertyResourcesOf(module));
+            withConfigurationProperties(Module.Util.transitiveIndividualConfigPropsOf(module));
+        }
+
+        private static Class[] asClasses(final List<Module> dependencies) {
+            final List<Class<? extends Module>> list = new ArrayList<>();
+            for (Module dependency : dependencies) {
+                Class<? extends Module> aClass = dependency.getClass();
+                list.add(aClass);
+            }
+            return list.toArray(new Class[] {});
+        }
+
+        @Override
+        public AppManifest2 build() {
+            return new Default(this);
+        }
+    }
 
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifestBuilder.java b/core/applib/src/main/java/org/apache/isis/applib/AppManifestBuilder.java
deleted file mode 100644
index fe1431b..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifestBuilder.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *        http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package org.apache.isis.applib;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-interface AppManifestBuilder<T> {
-
-    T withAdditionalModules(final Class<?>... modules);
-
-    T withAdditionalModules(final List<Class<?>> modules);
-
-    T withAdditionalServices(final Class<?>... additionalServices);
-
-    T withAdditionalServices(final List<Class<?>> additionalServices);
-
-    T withConfigurationProperties(final Map<String,String> configurationProperties);
-
-    T withConfigurationPropertiesFile(final String propertiesFile);
-
-    T withConfigurationPropertiesFile(
-            final Class<?> propertiesFileContext, final String propertiesFile, final String... furtherPropertiesFiles);
-
-    T withConfigurationProperty(final String key, final String value);
-
-
-    List<Class<?>> getAllModulesAsClass();
-
-    Set<Class<?>> getAllAdditionalServices();
-
-    List<AppManifestAbstract.PropertyResource> getAllPropertyResources();
-
-    List<AppManifestAbstract.ConfigurationProperty> getAllIndividualConfigProps();
-}
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/Module.java b/core/applib/src/main/java/org/apache/isis/applib/Module.java
index ce3542b..285d70b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/Module.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/Module.java
@@ -18,20 +18,55 @@
  */
 package org.apache.isis.applib;
 
-import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 
+import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
+/**
+ * Represents a collection of entities and domain services that provide a set of coherent functionality under a
+ * single package (or subpackages therein), with the module itself residing at the top-level package.
+ *
+ * <p>
+ *     Moreover, each module can indicate its immediate dependencies (using {@link #getDependencies()}); from this the
+ *     framework can compute the full set of modules (and therefore entities and domain services) that make up the
+ *     application.
+ * </p>
+ *
+ * <p>
+ *     Each module can also optionally define {@link #getAdditionalModules() additional (legacy) modules},
+ *     {@link #getAdditionalServices() additional (non-module) services} and also any additional
+ *     {@link #getIndividualConfigProps() configuration} {@link #getPropertyResources() properties} that should be
+ *     contributed to the overall set of config properties used to bootstrap the application.
+ * </p>
+ *
+ * <p>
+ *     Finally, each module can also optionally define a {@link #getRefDataSetupFixture() reference-data fixture} (for
+ *     reference data entities of the module) and also a {@link #getTeardownFixture() tear-down fixture} (for all
+ *     entities of the module).  These are executed automatically (and in the correct order) within integration tests,
+ *     simplifying setup and teardown of such tests.
+ * </p>
+ *
+ * <p>
+ *     <b>IMPORTANT</b>: implementations are expected to have value-semantics. This allows each {@link Module} to define
+ *     its respective {@link #getDependencies() dependencies} simply by instantiating the {@link Module}s on which
+ *     it depends.  The framework relies on value semantics to remove any duplicates from the computed graph of
+ *     all depenencies for the entire running application.  The easiest way to simply inherit from
+ *     {@link ModuleAbstract}.
+ * </p>
+ */
 public interface Module {
 
     /**
-     * As per Maven's &lt;dependencies&gt;&lt;/dependencies&gt; element; in the future might be derived (code generated?) from java 9's <code>module-info.java</code> metadata
+     * As per Maven's &lt;dependencies&gt;&lt;/dependencies&gt; element; in the future might be derived
+     * (code generated?) from java 9's <code>module-info.java</code> metadata
      *
      * <p>
      *     We use Set (rather than List) because we rely on {@link Module} being a value type based solely on its
@@ -44,14 +79,40 @@ public interface Module {
     /**
      * Support for "legacy" modules that do not implement {@link Module}.
      */
-    Set<Class<?>> getDependenciesAsClass();
+    Set<Class<?>> getAdditionalModules();
 
+    /**
+     * Optionally each module can define a {@link FixtureScript} which holds immutable "reference data".
+     * These are automatically executed whenever running integration tests (but are ignored when bootstrapping the
+     * runtime as a webapp).
+     */
     FixtureScript getRefDataSetupFixture();
 
+    /**
+     * Optionally each module can define a tear-down {@link FixtureScript}, used to remove the contents of <i>all</i>
+     * entities (both reference data and operational/transactional data).
+     * These are automatically executed whenever running integration tests (but are ignored when bootstrapping the
+     * runtime as a webapp).
+     */
     FixtureScript getTeardownFixture();
 
+    /**
+     * Optionally each module can define additional "legacy" domain services that have not been defined within modules,
+     * or that have not been annotated with &#64;{@link DomainService}
+     */
     Set<Class<?>> getAdditionalServices();
 
+    /**
+     * Optionally each module can define additional configuration properties.
+     */
+    Map<String,String> getIndividualConfigProps();
+
+    /**
+     * Optionally each module can define additional configuration properties, specified in terms of
+     * {@link PropertyResource} (a configuration file laoded relative to a base class on the class path).
+     */
+    List<PropertyResource> getPropertyResources();
+
     class Util {
         private Util(){}
 
@@ -62,7 +123,7 @@ public interface Module {
          *     The dependencies are returned in order, with this (the top-most) module last.
          * </p>
          */
-        public static List<Module> transitiveDependenciesOf(Module module) {
+        static List<Module> transitiveDependenciesOf(Module module) {
             final List<Module> ordered = Lists.newArrayList();
             final List<Module> visited = Lists.newArrayList();
             appendDependenciesTo(ordered, module, visited);
@@ -71,18 +132,18 @@ public interface Module {
         }
 
         /**
-         * Obtain the {@link Module#getDependenciesAsClass()} of this module and all its
+         * Obtain the {@link Module#getAdditionalModules()} of this module and all its
          * {@link Module.Util#transitiveDependenciesOf(Module) transitive dependencies}.
          *
          * <p>
          *     No guarantees are made as to the order of these additional module classes.
          * </p>
          */
-        public static List<Class<?>> transitiveDependenciesAsClassOf(Module module) {
+        static List<Class<?>> transitiveDependenciesAsClassOf(Module module) {
             final Set<Class<?>> modules = Sets.newHashSet();
             final List<Module> transitiveDependencies = transitiveDependenciesOf(module);
             for (Module transitiveDependency : transitiveDependencies) {
-                final Set<Class<?>> additionalModules = transitiveDependency.getDependenciesAsClass();
+                final Set<Class<?>> additionalModules = transitiveDependency.getAdditionalModules();
                 if(additionalModules != null && !additionalModules.isEmpty()) {
                     modules.addAll(additionalModules);
                 }
@@ -98,7 +159,7 @@ public interface Module {
          *     No guarantees are made as to the order of these additional service classes.
          * </p>
          */
-        public static List<Class<?>> transitiveAdditionalServicesOf(Module module) {
+        static List<Class<?>> transitiveAdditionalServicesOf(Module module) {
             final Set<Class<?>> services = Sets.newHashSet();
             final List<Module> transitiveDependencies = Util.transitiveDependenciesOf(module);
             for (Module transitiveDependency : transitiveDependencies) {
@@ -136,32 +197,26 @@ public interface Module {
             }
         }
 
-        public static AppManifestAbstract.Builder builderFor(final Module module) {
-            final List<Module> transitiveDependencies = Module.Util.transitiveDependenciesOf(module);
-            final Class[] moduleTransitiveDependencies = asClasses(transitiveDependencies);
-
-            final List<Class<?>> additionalModules = Module.Util.transitiveDependenciesAsClassOf(module);
-            final List<Class<?>> additionalServices = Module.Util.transitiveAdditionalServicesOf(module);
-
-            final AppManifestAbstract.Builder builder =
-                    AppManifestAbstract.Builder
-                            .forModules(moduleTransitiveDependencies)
-                            .withAdditionalModules(additionalModules)
-                            .withAdditionalServices(additionalServices);
-
-            return builder;
-        }
+        static Map<String, String> transitiveIndividualConfigPropsOf(final Module module) {
+            final Map<String,String> transitiveIndividualConfigProps = Maps.newLinkedHashMap();
 
-        private static Class[] asClasses(final List<Module> dependencies) {
-            final List<Class<? extends Module>> list = new ArrayList<>();
-            for (Module dependency : dependencies) {
-                Class<? extends Module> aClass = dependency.getClass();
-                list.add(aClass);
+            final List<Module> transitiveDependencies = transitiveDependenciesOf(module);
+            for (Module transitiveDependency : transitiveDependencies) {
+                transitiveIndividualConfigProps.putAll(transitiveDependency.getIndividualConfigProps());
             }
-            return list.toArray(new Class[] {});
+            return transitiveIndividualConfigProps;
         }
 
+        static List<PropertyResource> transitivePropertyResourcesOf(final Module module) {
+            final List<PropertyResource> transitivePropertyResources = Lists.newArrayList();
 
+            final List<Module> transitiveDependencies = transitiveDependenciesOf(module);
+            for (Module transitiveDependency : transitiveDependencies) {
+                transitivePropertyResources.addAll(transitiveDependency.getPropertyResources());
+            }
+
+            return transitivePropertyResources;
+        }
     }
 
 }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/ModuleAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/ModuleAbstract.java
index eaa9911..44a2284 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/ModuleAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/ModuleAbstract.java
@@ -18,36 +18,27 @@
  */
 package org.apache.isis.applib;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
-import java.util.List;
-import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 
 import javax.xml.bind.annotation.XmlAttribute;
-import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlTransient;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-
 import org.apache.isis.applib.fixturescripts.FixtureScript;
 
-public abstract class ModuleAbstract implements Module, AppManifestBuilder<ModuleAbstract> {
+/**
+ * Adapter for {@link Module} which has a default no-op implementation.
+ *
+ * <p>
+ *     Subclasses can either override the methods, or can use the various {@link #withAdditionalModules(Class[])}.
+ * </p>
+ */
+public abstract class ModuleAbstract
+        extends ModuleOrBuilderAbstract<ModuleAbstract>
+        implements Module {
 
 
-    /**
-     * As per Maven's &lt;dependencies&gt;&lt;/dependencies&gt; element; in the future might be derived (code generated?) from java 9's <code>module-info.java</code> metadata
-     *
-     * <p>
-     *     We use Set (rather than List) because we rely on {@link Module} being a value type based solely on its
-     *     class.  What this means is that each module can simply instantiate its dependencies, and the framework will
-     *     be able to eliminate duplicates.
-     * </p>
-     */
     @Override
     @XmlTransient
     public Set<Module> getDependencies() {
@@ -59,8 +50,8 @@ public abstract class ModuleAbstract implements Module, AppManifestBuilder<Modul
      */
     @Override
     @XmlTransient
-    public Set<Class<?>> getDependenciesAsClass() {
-        return modules;
+    public Set<Class<?>> getAdditionalModules() {
+        return additionalModules;
     }
 
     @Override
@@ -75,7 +66,6 @@ public abstract class ModuleAbstract implements Module, AppManifestBuilder<Modul
         return null;
     }
 
-
     @Override
     @XmlTransient
     public Set<Class<?>> getAdditionalServices() {
@@ -93,141 +83,6 @@ public abstract class ModuleAbstract implements Module, AppManifestBuilder<Modul
     }
 
 
-    @XmlElement(name = "module", required = true)
-    private Set<ModuleAbstract> getModuleDependencies() {
-        return (Set) getDependencies();
-    }
-
-
-
-
-    private final Set<Class<?>> modules = Sets.newLinkedHashSet();
-    private final Set<Class<?>> additionalServices  = Sets.newLinkedHashSet();
-
-    private final List<AppManifestAbstract.ConfigurationProperty> individualConfigProps = Lists.newArrayList();
-    private final List<AppManifestAbstract.PropertyResource> propertyResources = Lists.newArrayList();
-
-    private Map<String,String> configurationProperties = Maps.newHashMap();
-
-    public ModuleAbstract withAdditionalModules(final Class<?>... modules) {
-        return withAdditionalModules(Arrays.asList(modules));
-    }
-
-    public ModuleAbstract withAdditionalModules(final List<Class<?>> modules) {
-        if(modules == null) {
-            throw new IllegalArgumentException("List of modules must not be null");
-        }
-        this.modules.addAll(modules);
-        return this;
-    }
-
-    public ModuleAbstract withAdditionalServices(final Class<?>... additionalServices) {
-        return withAdditionalServices(Arrays.asList(additionalServices));
-    }
-
-    public ModuleAbstract withAdditionalServices(final List<Class<?>> additionalServices) {
-        if(additionalServices == null) {
-            throw new IllegalArgumentException("List of additional services must not be null");
-        }
-        this.additionalServices.addAll(additionalServices);
-        return this;
-    }
-
-    public ModuleAbstract withConfigurationProperties(final Map<String,String> configurationProperties) {
-        this.configurationProperties.putAll(configurationProperties);
-        return this;
-    }
-
-    public ModuleAbstract withConfigurationPropertiesFile(final String propertiesFile) {
-        return withConfigurationPropertiesFile(getClass(), propertiesFile);
-    }
-
-    public ModuleAbstract withConfigurationPropertiesFile(
-            final Class<?> propertiesFileContext, final String propertiesFile, final String... furtherPropertiesFiles) {
-        addPropertyResource(propertiesFileContext, propertiesFile);
-        for (final String otherFile : furtherPropertiesFiles) {
-            addPropertyResource(propertiesFileContext, otherFile);
-        }
-        return this;
-    }
-
-    private void addPropertyResource(final Class<?> propertiesFileContext, final String propertiesFile) {
-        propertyResources.add(new AppManifestAbstract.PropertyResource(propertiesFileContext, propertiesFile));
-    }
-
-    public ModuleAbstract withConfigurationProperty(final String key, final String value) {
-        individualConfigProps.add(new AppManifestAbstract.ConfigurationProperty(key,value));
-        return this;
-    }
-
-
-    @XmlTransient
-    @Override
-    public List<Class<?>> getAllModulesAsClass() {
-
-        final List<Class<?>> modules = Lists.newArrayList();
-
-        final List<Module> transitiveDependencies = Module.Util.transitiveDependenciesOf(this);
-        final List<Class<? extends Module>> moduleTransitiveDependencies = asClasses(transitiveDependencies);
-        modules.addAll(moduleTransitiveDependencies);
-
-        final List<Class<?>> additionalModules = Module.Util.transitiveDependenciesAsClassOf(this);
-        modules.addAll(additionalModules);
-
-        return modules;
-    }
-
-
-    private static List<Class<? extends Module>> asClasses(final List<Module> dependencies) {
-        final List<Class<? extends Module>> list = new ArrayList<>();
-        for (Module dependency : dependencies) {
-            Class<? extends Module> aClass = dependency.getClass();
-            list.add(aClass);
-        }
-        return list;
-    }
-
-    @Override
-    @XmlTransient
-    public final Set<Class<?>> getAllAdditionalServices() {
-        final List<Class<?>> additionalServices = Module.Util.transitiveAdditionalServicesOf(this);
-        return Sets.newLinkedHashSet(additionalServices);
-    }
-
-    @XmlTransient
-    @Override
-    public final List<AppManifestAbstract.PropertyResource> getAllPropertyResources() {
-
-        List<AppManifestAbstract.PropertyResource> transitivePropertyResources = Lists.newArrayList();
-
-        final List<Module> transitiveDependencies = Module.Util.transitiveDependenciesOf(this);
-        for (Module transitiveDependency : transitiveDependencies) {
-            if(transitiveDependency instanceof ModuleAbstract) {
-                ModuleAbstract moduleAbstract = (ModuleAbstract) transitiveDependency;
-                transitivePropertyResources.addAll(moduleAbstract.propertyResources);
-            }
-        }
-
-        return transitivePropertyResources;
-    }
-
-    @XmlTransient
-    @Override
-    public List<AppManifestAbstract.ConfigurationProperty> getAllIndividualConfigProps() {
-        List<AppManifestAbstract.ConfigurationProperty> transitiveIndividualConfigProps = Lists.newArrayList();
-
-        final List<Module> transitiveDependencies = Module.Util.transitiveDependenciesOf(this);
-        for (Module transitiveDependency : transitiveDependencies) {
-            if(transitiveDependency instanceof ModuleAbstract) {
-                ModuleAbstract moduleAbstract = (ModuleAbstract) transitiveDependency;
-                transitiveIndividualConfigProps.addAll(moduleAbstract.individualConfigProps);
-            }
-        }
-        return transitiveIndividualConfigProps;
-    }
-
-
-
 
     @Override
     public String toString() {
@@ -249,4 +104,5 @@ public abstract class ModuleAbstract implements Module, AppManifestBuilder<Modul
         return getFullName().hashCode();
     }
 
+
 }
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/ModuleOrBuilderAbstract.java b/core/applib/src/main/java/org/apache/isis/applib/ModuleOrBuilderAbstract.java
new file mode 100644
index 0000000..e138f06
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/ModuleOrBuilderAbstract.java
@@ -0,0 +1,128 @@
+/*
+ *  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.applib;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.bind.annotation.XmlTransient;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+/**
+ * Factors out the commonality between {@link AppManifestAbstract.Builder} and {@link ModuleAbstract}.
+ *
+ * @param <B>
+ */
+abstract class ModuleOrBuilderAbstract<B extends ModuleOrBuilderAbstract> {
+
+    final Set<Class<?>> additionalModules = Sets.newLinkedHashSet();
+    final Set<Class<?>> additionalServices  = Sets.newLinkedHashSet();
+
+    final Map<String,String> individualConfigProps = Maps.newLinkedHashMap();
+    final List<PropertyResource> propertyResources = Lists.newArrayList();
+
+    ModuleOrBuilderAbstract() {}
+
+    public B withAdditionalModules(final Class<?>... modules) {
+        return withAdditionalModules(Arrays.asList(modules));
+    }
+
+    public B withAdditionalModules(final List<Class<?>> modules) {
+        if(modules == null) {
+            return (B)this;
+        }
+        this.additionalModules.addAll(modules);
+        return (B)this;
+    }
+
+    public B withAdditionalServices(final Class<?>... additionalServices) {
+        return withAdditionalServices(Arrays.asList(additionalServices));
+    }
+
+    public B withAdditionalServices(final List<Class<?>> additionalServices) {
+        if(additionalServices == null) {
+            return (B)this;
+        }
+        this.additionalServices.addAll(additionalServices);
+        return (B)this;
+    }
+
+    public B withConfigurationProperties(final Map<String,String> configurationProperties) {
+        for (Map.Entry<String, String> keyValue : configurationProperties.entrySet()) {
+            withConfigurationProperty(keyValue.getKey(), keyValue.getValue());
+        }
+        return (B)this;
+    }
+
+    public B withConfigurationPropertiesFile(final String propertiesFile) {
+        return withConfigurationPropertiesFile(getClass(), propertiesFile);
+    }
+
+    public B withConfigurationPropertyResources(final List<PropertyResource> propertyResources) {
+        for (PropertyResource propertyResource : propertyResources) {
+            withConfigurationPropertyResource(propertyResource);
+        }
+        return (B)this;
+    }
+
+    public B withConfigurationPropertyResource(final PropertyResource propertyResource) {
+        addPropertyResource(propertyResource);
+        return (B)this;
+    }
+
+    public B withConfigurationPropertiesFile(
+            final Class<?> propertiesFileContext,
+            final String propertiesFile,
+            final String... furtherPropertiesFiles) {
+        addPropertyResource(propertiesFileContext, propertiesFile);
+        for (final String otherFile : furtherPropertiesFiles) {
+            addPropertyResource(propertiesFileContext, otherFile);
+        }
+        return (B)this;
+    }
+
+    private void addPropertyResource(final Class<?> propertiesFileContext, final String propertiesFile) {
+        addPropertyResource(new PropertyResource(propertiesFileContext, propertiesFile));
+    }
+
+    private void addPropertyResource(final PropertyResource propertyResource) {
+        propertyResources.add(propertyResource);
+    }
+
+    public B withConfigurationProperty(final String key, final String value) {
+        individualConfigProps.put(key, value);
+        return (B)this;
+    }
+
+    @XmlTransient
+    public Map<String,String> getIndividualConfigProps() {
+        return individualConfigProps;
+    }
+
+    @XmlTransient
+    public List<PropertyResource> getPropertyResources() {
+        return propertyResources;
+    }
+
+}
diff --git a/core/applib/src/main/java/org/apache/isis/applib/PropertyResource.java b/core/applib/src/main/java/org/apache/isis/applib/PropertyResource.java
new file mode 100644
index 0000000..4f1c687
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/PropertyResource.java
@@ -0,0 +1,61 @@
+/*
+ *  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.applib;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+
+public class PropertyResource {
+    private final Class<?> propertiesFileContext;
+    private final String propertiesFile;
+
+    PropertyResource(final Class<?> propertiesFileContext, final String propertiesFile) {
+        this.propertiesFileContext = propertiesFileContext;
+        this.propertiesFile = propertiesFile;
+    }
+
+    Class<?> getPropertiesFileContext() {
+        return propertiesFileContext;
+    }
+
+    String getPropertiesFile() {
+        return propertiesFile;
+    }
+
+    void loadPropsInto(
+            final Map<String, String> props) {
+        final Properties properties = new Properties();
+        try {
+            try (final InputStream stream = propertiesFileContext.getResourceAsStream(propertiesFile)) {
+                properties.load(stream);
+                for (Object key : properties.keySet()) {
+                    final Object value = properties.get(key);
+                    if (key instanceof String && value instanceof String) {
+                        props.put((String) key, (String) value);
+                    }
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(
+                    String.format("Failed to load '%s' file ", this), e);
+        }
+    }
+}
diff --git a/core/applib/src/test/java/org/apache/isis/applib/modules/Module_Util_transitiveDependenciesOf_Test.java b/core/applib/src/test/java/org/apache/isis/applib/Module_Util_transitiveDependenciesOf_Test.java
similarity index 96%
rename from core/applib/src/test/java/org/apache/isis/applib/modules/Module_Util_transitiveDependenciesOf_Test.java
rename to core/applib/src/test/java/org/apache/isis/applib/Module_Util_transitiveDependenciesOf_Test.java
index ce0bf06..7cc24c4 100644
--- a/core/applib/src/test/java/org/apache/isis/applib/modules/Module_Util_transitiveDependenciesOf_Test.java
+++ b/core/applib/src/test/java/org/apache/isis/applib/Module_Util_transitiveDependenciesOf_Test.java
@@ -1,4 +1,4 @@
-package org.apache.isis.applib.modules;
+package org.apache.isis.applib;
 
 import java.util.Arrays;
 import java.util.Collections;
@@ -12,9 +12,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
 
-import org.apache.isis.applib.Module;
-import org.apache.isis.applib.ModuleAbstract;
-
 import static org.junit.Assert.assertTrue;
 
 public class Module_Util_transitiveDependenciesOf_Test {
@@ -47,7 +44,7 @@ public class Module_Util_transitiveDependenciesOf_Test {
             withAdditionalServices(ServiceX.class);
         }
         @Override
-        public Set<Class<?>> getDependenciesAsClass() {
+        public Set<Class<?>> getAdditionalModules() {
             return Sets.<Class<?>>newHashSet(ModuleP.class);
         }
     };
@@ -62,7 +59,7 @@ public class Module_Util_transitiveDependenciesOf_Test {
             return Sets.newHashSet(moduleE, moduleD);
         }
         @Override
-        public Set<Class<?>> getDependenciesAsClass() {
+        public Set<Class<?>> getAdditionalModules() {
             return Sets.newHashSet(ModuleQ.class, ModuleR.class);
         }
         {
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract3.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract3.java
index dc362e4..c8def8a 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract3.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract3.java
@@ -38,12 +38,14 @@ import org.apache.isis.applib.Module;
 import org.apache.isis.applib.NonRecoverableException;
 import org.apache.isis.applib.RecoverableException;
 import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
-import org.apache.isis.core.integtestsupport.logging.LogConfig;
+import org.apache.isis.core.runtime.headless.logging.LogConfig;
+import org.apache.isis.core.runtime.headless.HeadlessWithBootstrappingAbstract;
+import org.apache.isis.core.runtime.headless.IsisSystem;
 
 /**
  * Reworked base class for integration tests, uses a {@link Module} to bootstrap, rather than an {@link AppManifest}.
  */
-public abstract class IntegrationTestAbstract3 extends IntegrationBootstrapAbstract {
+public abstract class IntegrationTestAbstract3 extends HeadlessWithBootstrappingAbstract {
 
     private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestAbstract3.class);
 
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
index d45c0de..5ddf1d0 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemForTest.java
@@ -44,6 +44,8 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelInvalidExcep
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
 import org.apache.isis.core.runtime.fixtures.FixturesInstallerDelegate;
+import org.apache.isis.core.runtime.headless.IsisComponentProviderDefault;
+import org.apache.isis.core.runtime.headless.IsisSystem;
 import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ObjectFactoryForIntegration.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ObjectFactoryForIntegration.java
index 5740214..9fd3a62 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ObjectFactoryForIntegration.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ObjectFactoryForIntegration.java
@@ -6,7 +6,7 @@ import java.util.Map;
 import com.google.common.collect.Maps;
 
 import org.apache.isis.applib.services.registry.ServiceRegistry2;
-import org.apache.isis.core.integtestsupport.IsisSystem;
+import org.apache.isis.core.runtime.headless.IsisSystem;
 
 import cucumber.api.java.ObjectFactory;
 import cucumber.runtime.CucumberException;
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
index fbc9151..a8b216f 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
+++ b/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ScenarioExecutionForIntegration.java
@@ -19,7 +19,7 @@ package org.apache.isis.core.integtestsupport.scenarios;
 import org.apache.isis.applib.fixtures.InstallableFixture;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.core.commons.authentication.AuthenticationSession;
-import org.apache.isis.core.integtestsupport.IntegrationBootstrapAbstract;
+import org.apache.isis.core.runtime.headless.HeadlessWithBootstrappingAbstract;
 import org.apache.isis.core.integtestsupport.IsisSystemForTest;
 import org.apache.isis.core.specsupport.scenarios.ScenarioExecution;
 import org.apache.isis.core.specsupport.scenarios.ScenarioExecutionScope;
@@ -34,7 +34,7 @@ import org.apache.isis.core.specsupport.scenarios.ScenarioExecutionScope;
  * and of {@link #beginTran() begin} and {@link #endTran(boolean) end} (
  * for transaction management.
  *
- * @deprecated - subclass glue from {@link IntegrationBootstrapAbstract} instead, and inject services into glue
+ * @deprecated - subclass glue from {@link HeadlessWithBootstrappingAbstract} instead, and inject services into glue
  */
 @Deprecated
 public class ScenarioExecutionForIntegration extends ScenarioExecution  {
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
similarity index 95%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationAbstract.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
index fd96657..d8978d1 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import javax.inject.Inject;
 
@@ -39,10 +39,13 @@ import org.apache.isis.applib.services.wrapper.WrapperFactory;
 import org.apache.isis.applib.services.xactn.TransactionService;
 
 /**
- * Reworked base class for integration tests or BDD spec glue.
+ * Reworked base class for headless access.
+ *
+ * <p>
+ *     The most common cases are integration tests or BDD spec glue.
+ * </p>
  */
-public abstract class IntegrationAbstract {
-
+public abstract class HeadlessAbstract {
 
 
     protected void runFixtureScript(final FixtureScript... fixtureScriptList) {
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationBootstrapAbstract.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
similarity index 77%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationBootstrapAbstract.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
index c53cafb..e9bb689 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationBootstrapAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import java.io.PrintStream;
 
@@ -31,12 +31,21 @@ import org.slf4j.event.Level;
 import org.apache.isis.applib.Module;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.core.commons.factory.InstanceUtil;
-import org.apache.isis.core.integtestsupport.logging.LogConfig;
-import org.apache.isis.core.integtestsupport.logging.LogStream;
+import org.apache.isis.core.runtime.headless.logging.LogConfig;
+import org.apache.isis.core.runtime.headless.logging.LogStream;
 
-public abstract class IntegrationBootstrapAbstract extends IntegrationAbstract {
+/**
+ * Provides headless access to the system, first bootstrapping the system if required.
+ *
+ * <p>
+ *     This acts as a common superclass from which framework-provided adapter classes for integration tests
+ *     (<tt>IntegrationTestAbstract3</tt>) and for BDD spec glue (<tt>CukeGlueIntegrationScopeAbstract</tt> inherit,
+ *     to bootstrap the system with a given module for headless access.
+ * </p>
+ */
+public abstract class HeadlessWithBootstrappingAbstract extends HeadlessAbstract {
 
-    private static final Logger LOG = LoggerFactory.getLogger(IntegrationBootstrapAbstract.class);
+    private static final Logger LOG = LoggerFactory.getLogger(HeadlessWithBootstrappingAbstract.class);
 
     private final LogConfig logConfig;
     protected static PrintStream logPrintStream(Level level) {
@@ -52,13 +61,13 @@ public abstract class IntegrationBootstrapAbstract extends IntegrationAbstract {
 
     protected Long t0;
 
-    protected IntegrationBootstrapAbstract(
+    protected HeadlessWithBootstrappingAbstract(
             final Module module,
             final Class... additionalModuleClasses) {
         this(new LogConfig(Level.INFO), module, additionalModuleClasses);
     }
 
-    protected IntegrationBootstrapAbstract(
+    protected HeadlessWithBootstrappingAbstract(
             final LogConfig logConfig,
             final Module module,
             final Class... additionalModuleClasses) {
@@ -72,7 +81,10 @@ public abstract class IntegrationBootstrapAbstract extends IntegrationAbstract {
             t0 = System.currentTimeMillis();
         }
 
-        final String moduleFqcn = System.getProperty("isis.integTest.module");
+        String moduleFqcn = System.getProperty("isis.headless.module");
+        if(moduleFqcn == null) {
+            moduleFqcn = System.getProperty("isis.integTest.module"); // to deprecate
+        }
 
         final Module moduleToUse;
         final Class[] additionalModuleClassesToUse;
@@ -92,7 +104,8 @@ public abstract class IntegrationBootstrapAbstract extends IntegrationAbstract {
 
     protected void bootstrapAndSetupIfRequired() {
 
-        System.setProperty("isis.integTest", "true");
+        System.setProperty("isis.headless", "true");
+        System.setProperty("isis.integTest", "true"); // to deprecate
 
         isisSystemBootstrapper.bootstrapIfRequired(t0);
         isisSystemBootstrapper.injectServicesInto(this);
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisComponentProviderDefault.java
similarity index 96%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisComponentProviderDefault.java
index 87518b2..4631d78 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisComponentProviderDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisComponentProviderDefault.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import org.apache.isis.applib.AppManifest;
 import org.apache.isis.core.commons.config.IsisConfiguration;
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystem.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
similarity index 99%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystem.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
index e5f790b..b57e97b 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystem.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystem.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import java.util.Set;
 
@@ -38,6 +38,7 @@ import org.apache.isis.core.metamodel.specloader.validator.MetaModelInvalidExcep
 import org.apache.isis.core.runtime.authentication.AuthenticationManager;
 import org.apache.isis.core.runtime.authentication.AuthenticationRequest;
 import org.apache.isis.core.runtime.fixtures.FixturesInstallerDelegate;
+import org.apache.isis.core.runtime.headless.auth.AuthenticationRequestNameOnly;
 import org.apache.isis.core.runtime.logging.IsisLoggingConfigurer;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
@@ -47,7 +48,6 @@ import org.apache.isis.core.runtime.system.transaction.IsisTransaction;
 import org.apache.isis.core.runtime.system.transaction.IsisTransaction.State;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
 import org.apache.isis.core.runtime.systemusinginstallers.IsisComponentProvider;
-import org.apache.isis.core.security.authentication.AuthenticationRequestNameOnly;
 
 
 /**
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
similarity index 95%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
index 70ca04e..9e5c546 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import java.util.List;
 import java.util.UUID;
@@ -28,7 +28,6 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.AppManifest;
 import org.apache.isis.applib.AppManifest2;
-import org.apache.isis.applib.AppManifestAbstract;
 import org.apache.isis.applib.AppManifestAbstract2;
 import org.apache.isis.applib.Module;
 import org.apache.isis.applib.clock.TickingFixtureClock;
@@ -37,7 +36,7 @@ import org.apache.isis.applib.fixturescripts.FixtureScripts;
 import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
 import org.apache.isis.applib.services.metamodel.MetaModelService4;
 import org.apache.isis.applib.services.registry.ServiceRegistry2;
-import org.apache.isis.core.integtestsupport.logging.LogConfig;
+import org.apache.isis.core.runtime.headless.logging.LogConfig;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.session.IsisSessionFactory;
 import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegTests;
@@ -68,11 +67,10 @@ public class IsisSystemBootstrapper {
 
     public void bootstrapIfRequired(final Long t0) {
 
-        final AppManifestAbstract.Builder builder =
-                AppManifestAbstract2.Builder.forModule(module);
+        final AppManifestAbstract2.Builder builder = AppManifestAbstract2.Builder.forModule(module);
         builder.withAdditionalModules(additionalModuleClasses); // eg fake module, as passed into constructor
 
-        final AppManifestAbstract2 appManifest = (AppManifestAbstract2) builder.build();
+        final AppManifest2 appManifest = builder.build();
 
         bootstrapUsing(appManifest, t0);
     }
diff --git a/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/auth/AuthenticationRequestNameOnly.java
similarity index 73%
copy from core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java
copy to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/auth/AuthenticationRequestNameOnly.java
index 52154f7..425cd4b 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/AppManifest2.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/auth/AuthenticationRequestNameOnly.java
@@ -16,14 +16,14 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
+package org.apache.isis.core.runtime.headless.auth;
 
-package org.apache.isis.applib;
+import org.apache.isis.core.runtime.authentication.AuthenticationRequestAbstract;
 
-import org.apache.isis.applib.fixturescripts.FixtureScript;
+public class AuthenticationRequestNameOnly extends AuthenticationRequestAbstract {
 
-public interface AppManifest2 extends AppManifest {
-
-    FixtureScript getTeardownFixture();
-    FixtureScript getRefDataSetupFixture();
+    public AuthenticationRequestNameOnly(String name) {
+        super(name);
+    }
 
 }
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogConfig.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogConfig.java
similarity index 98%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogConfig.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogConfig.java
index 143d2ac..1731ed3 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogConfig.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogConfig.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport.logging;
+package org.apache.isis.core.runtime.headless.logging;
 
 import java.io.PrintStream;
 
diff --git a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogStream.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogStream.java
similarity index 97%
rename from core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogStream.java
rename to core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogStream.java
index 022d066..e3616a6 100644
--- a/core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/logging/LogStream.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/logging/LogStream.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport.logging;
+package org.apache.isis.core.runtime.headless.logging;
 
 import java.io.OutputStream;
 import java.io.PrintStream;
diff --git a/core/integtestsupport/src/test/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper_haveSameModules_Test.java b/core/runtime/src/test/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper_haveSameModules_Test.java
similarity index 97%
rename from core/integtestsupport/src/test/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper_haveSameModules_Test.java
rename to core/runtime/src/test/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper_haveSameModules_Test.java
index 0a2cbb2..e25377c 100644
--- a/core/integtestsupport/src/test/java/org/apache/isis/core/integtestsupport/IsisSystemBootstrapper_haveSameModules_Test.java
+++ b/core/runtime/src/test/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper_haveSameModules_Test.java
@@ -16,7 +16,7 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-package org.apache.isis.core.integtestsupport;
+package org.apache.isis.core.runtime.headless;
 
 import org.junit.Test;
 
diff --git a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueIntegrationScopeAbstract.java
similarity index 63%
copy from example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java
copy to core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueIntegrationScopeAbstract.java
index f7515f4..f25e5cd 100644
--- a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/specs/CukeGlueIntegrationScopeAbstract.java
@@ -14,18 +14,23 @@ O *  Licensed to the Apache Software Foundation (ASF) under one or more
  *  See the License for the specific language governing permissions and
  *  limitations under the License.
  */
-package domainapp.application.bdd.specglue;
+package org.apache.isis.core.specsupport.specs;
 
-import org.apache.isis.core.integtestsupport.IntegrationBootstrapAbstract;
+import org.apache.isis.applib.Module;
+import org.apache.isis.core.runtime.headless.HeadlessWithBootstrappingAbstract;
 
 import cucumber.api.java.After;
 import cucumber.api.java.Before;
-import domainapp.application.DomainAppApplicationModule;
 
-public class BootstrappingGlue extends IntegrationBootstrapAbstract {
+/**
+ * For BDD spec using headless access, there needs to be (at least) one BDD spec glue that inherits from this adapter
+ * class, specifying the {@link Module} to use to bootstrap the system.
+ */
+public abstract class CukeGlueIntegrationScopeAbstract extends HeadlessWithBootstrappingAbstract {
 
-    public BootstrappingGlue() {
-        super(new DomainAppApplicationModule());
+    protected CukeGlueIntegrationScopeAbstract(final Module module,
+            final Class... additionalModuleClasses) {
+        super(module, additionalModuleClasses);
     }
 
     @Before(order=100)
diff --git a/example/application/helloworld/src/main/java/domainapp/application/HelloWorldAppManifest.java b/example/application/helloworld/src/main/java/domainapp/application/HelloWorldAppManifest.java
index 98d4f62..30f5774 100644
--- a/example/application/helloworld/src/main/java/domainapp/application/HelloWorldAppManifest.java
+++ b/example/application/helloworld/src/main/java/domainapp/application/HelloWorldAppManifest.java
@@ -18,17 +18,17 @@
  */
 package domainapp.application;
 
-import org.apache.isis.applib.AppManifestAbstract;
+import org.apache.isis.applib.AppManifestAbstract2;
 
 import domainapp.dom.HelloWorldModule;
 
 /**
  * Bootstrap the application.
  */
-public class HelloWorldAppManifest extends AppManifestAbstract {
+public class HelloWorldAppManifest extends AppManifestAbstract2 {
 
     public static final Builder BUILDER = Builder
-            .forModules(HelloWorldModule.class)
+            .forModule(new HelloWorldModule())
             .withConfigurationPropertiesFile(HelloWorldAppManifest.class, "isis.properties")
             .withAuthMechanism("shiro");
 
diff --git a/example/application/helloworld/src/main/java/domainapp/dom/HelloWorldModule.java b/example/application/helloworld/src/main/java/domainapp/dom/HelloWorldModule.java
index d6ee8d9..c2c6600 100644
--- a/example/application/helloworld/src/main/java/domainapp/dom/HelloWorldModule.java
+++ b/example/application/helloworld/src/main/java/domainapp/dom/HelloWorldModule.java
@@ -18,6 +18,8 @@
  */
 package domainapp.dom;
 
-public final class HelloWorldModule {
-    private HelloWorldModule(){}
+import org.apache.isis.applib.ModuleAbstract;
+
+public class HelloWorldModule extends ModuleAbstract {
+
 }
diff --git a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java b/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java
index f7515f4..9eeb747 100644
--- a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java
+++ b/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/BootstrappingGlue.java
@@ -16,26 +16,14 @@ O *  Licensed to the Apache Software Foundation (ASF) under one or more
  */
 package domainapp.application.bdd.specglue;
 
-import org.apache.isis.core.integtestsupport.IntegrationBootstrapAbstract;
+import org.apache.isis.core.specsupport.specs.CukeGlueIntegrationScopeAbstract;
 
-import cucumber.api.java.After;
-import cucumber.api.java.Before;
 import domainapp.application.DomainAppApplicationModule;
 
-public class BootstrappingGlue extends IntegrationBootstrapAbstract {
+public class BootstrappingGlue extends CukeGlueIntegrationScopeAbstract {
 
     public BootstrappingGlue() {
         super(new DomainAppApplicationModule());
     }
 
-    @Before(order=100)
-    public void beforeScenario() {
-        super.bootstrapAndSetupIfRequired();
-    }
-
-    @After
-    public void afterScenario(cucumber.api.Scenario sc) {
-        super.tearDownAllModules();
-    }
-
 }
diff --git a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/CatalogOfFixturesGlue.java b/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/CatalogOfFixturesGlue.java
index 0fb8a81..2de699a 100644
--- a/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/CatalogOfFixturesGlue.java
+++ b/example/application/simpleapp/application/src/test/java/domainapp/application/bdd/specglue/CatalogOfFixturesGlue.java
@@ -19,12 +19,12 @@ package domainapp.application.bdd.specglue;
 import javax.inject.Inject;
 
 import org.apache.isis.applib.fixturescripts.FixtureScripts;
-import org.apache.isis.core.integtestsupport.IntegrationAbstract;
+import org.apache.isis.core.runtime.headless.HeadlessAbstract;
 
 import cucumber.api.java.Before;
 import domainapp.application.fixture.scenarios.DomainAppDemo;
 
-public class CatalogOfFixturesGlue extends IntegrationAbstract {
+public class CatalogOfFixturesGlue extends HeadlessAbstract {
 
     @Before(value={"@DomainAppDemo"}, order=20000)
     public void integrationFixtures() throws Throwable {
diff --git a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModuleManifest.java b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModuleManifest.java
index 32396fa..43875e9 100644
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModuleManifest.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/SimpleModuleManifest.java
@@ -18,15 +18,14 @@
  */
 package domainapp.modules.simple;
 
-import org.apache.isis.applib.AppManifestAbstract;
-import org.apache.isis.applib.Module;
+import org.apache.isis.applib.AppManifestAbstract2;
 
 /**
  * Used by <code>isis-maven-plugin</code> (build-time validation of the module) and also by module-level integration tests.
  */
-public class SimpleModuleManifest extends AppManifestAbstract {
+public class SimpleModuleManifest extends AppManifestAbstract2 {
 
-    public static final Builder BUILDER = Module.Util.builderFor(new SimpleModule());
+    public static final Builder BUILDER = Builder.forModule(new SimpleModule());
 
     public SimpleModuleManifest() {
         super(BUILDER);
diff --git a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
index 66816fb..0b6345a 100644
--- a/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
+++ b/example/application/simpleapp/module-simple/src/test/java/domainapp/modules/simple/specglue/SimpleObjectMenuGlue.java
@@ -21,7 +21,7 @@ import java.util.UUID;
 
 import javax.inject.Inject;
 
-import org.apache.isis.core.integtestsupport.IntegrationAbstract;
+import org.apache.isis.core.runtime.headless.HeadlessAbstract;
 
 import cucumber.api.java.en.Given;
 import cucumber.api.java.en.When;
@@ -30,7 +30,7 @@ import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 
-public class SimpleObjectMenuGlue extends IntegrationAbstract {
+public class SimpleObjectMenuGlue extends HeadlessAbstract {
 
     @Given("^there are.* (\\d+) simple objects$")
     public void there_are_N_simple_objects(int n) throws Throwable {

-- 
To stop receiving notification emails like this one, please contact
"commits@isis.apache.org" <co...@isis.apache.org>.