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 2018/01/05 00:08:05 UTC

[isis] 01/02: Merge branch 'master' into dev/2.0.0/ISIS-1632-meta-annotations

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

danhaywood pushed a commit to branch dev/2.0.0/ISIS-1632-meta-annotations
in repository https://gitbox.apache.org/repos/asf/isis.git

commit c62048b2f82c93aa4d5e05504c8e45ca396d7815
Merge: 16ac24d a3df937
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Thu Jan 4 23:58:58 2018 +0000

    Merge branch 'master' into dev/2.0.0/ISIS-1632-meta-annotations
    
    # Conflicts:
    #	adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgcms/_rgcms_schema-aim.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_ActionInvocationContext.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BackgroundService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_CommandContext.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_InteractionContext.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_MessageService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_TitleService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_TransactionService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_WrapperFactory.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_BackgroundCommandService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_HomePageProviderService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_bootstrapping-spi_ClassDiscoveryService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_ClockService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_ConfigurationService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_DomainObjectContainer.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_EventBusService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_FactoryService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_Scratchpad.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_UserService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_BookmarkService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_EmailService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_JaxbService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_MementoService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_XmlSnapshotService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_ApplicationFeatureRepository.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_ServiceRegistry.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_IsisJdoSupport.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_MetricsService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_QueryResultsCache.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_RepositoryService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_AuditerService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_AuditingService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_EventSerializer.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_PublisherService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_PublishingService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_UserRegistrationService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-api_AcceptHeaderService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-api_DeepLinkService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_EmailNotificationService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_ErrorReportingService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_ExceptionRecognizer.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_GridLoaderService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_GridSystemService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_HintStore.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_LocaleProvider.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TranslationService.adoc
    #	adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TranslationsResolver.adoc
    #	adocs/documentation/src/main/asciidoc/guides/ugodn/_ugodn_configuring_properties.adoc
    #	adocs/documentation/src/main/asciidoc/guides/ugtst/_ugtst_integ-test-support_abstract-class.adoc
    #	adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_extending_replacing-page-elements.adoc
    #	core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
    #	core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
    #	core/mavendeps/intellij/pom.xml
    #	core/mavendeps/testing/pom.xml
    #	core/mavendeps/webapp/pom.xml
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/DefaultViewFacetForCollectionLayoutAnnotation.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/CssClassFacetForDomainObjectLayoutAnnotation.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservicelayout/DomainServiceLayoutFacetFactory.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternalNoop.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
    #	core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilderContext.java
    #	core/metamodel/src/test/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactoryTest.java
    #	core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
    #	core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
    #	core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProvider.java
    #	example/application/simpleapp/pom.xml

 adocs/documentation/pom.xml                        | 149 ++++----
 .../cgcom/_cgcom_asciidoc-publish-procedure.adoc   |   2 +-
 .../guides/cgcom/_cgcom_cutting-a-release.adoc     |  22 +-
 .../cgcom/_cgcom_post-release-successful.adoc      |   2 +-
 .../main/asciidoc/guides/dg/_dg_building-isis.adoc |  13 +-
 .../main/asciidoc/guides/dg/_dg_contributing.adoc  |  17 +-
 .../main/asciidoc/guides/dg/_dg_ide_eclipse.adoc   |  85 ++++-
 .../dg/images/contributing/git-workflow-2.png      | Bin 40826 -> 0 bytes
 .../guides/dg/images/contributing/git-workflow.png | Bin 48331 -> 55066 bytes
 .../dg/images/contributing/git-workflow.pptx       | Bin 68580 -> 39495 bytes
 .../eclipse/2017-oxygen/010-lombok-locate-jar.png  | Bin 0 -> 71407 bytes
 .../020-lombok-install-into-eclipse.png            | Bin 0 -> 41747 bytes
 .../030-datanucleus-install-new-software.png       | Bin 0 -> 60520 bytes
 .../040-datanucleus-specify-repository.png         | Bin 0 -> 8783 bytes
 .../2017-oxygen/050-datanucleus-select-plugin.png  | Bin 0 -> 34002 bytes
 .../060-enable-annotation-processor.png            | Bin 0 -> 31017 bytes
 .../guides/rgant/_rgant-Action_domainEvent.adoc    |   4 +-
 .../asciidoc/guides/rgant/_rgant-Collection.adoc   |   2 +-
 .../rgant/_rgant-Collection_domainEvent.adoc       |   4 +-
 .../guides/rgant/_rgant-Property_domainEvent.adoc  |   4 +-
 .../asciidoc/guides/rgant/_rgant_aaa_main.adoc     |   2 +-
 .../guides/rgcfg/_rgcfg_configuring-core.adoc      | 392 +++++----------------
 .../guides/rgcfg/_rgcfg_specifying-components.adoc |  75 +---
 .../_rgcms_classes_AppManifest-bootstrapping.adoc  |  17 +-
 .../_rgcms_classes_AppManifest2-bootstrapping.adoc | 193 ++++++++++
 ...rgcms_classes_contributee_HasTransactionId.adoc |   3 +-
 .../guides/rgcms/_rgcms_classes_layout.adoc        |   8 +-
 .../guides/rgcms/_rgcms_classes_menubars.adoc      |   2 +-
 .../guides/rgcms/_rgcms_classes_mixins_Object.adoc |  89 +++--
 .../rgcms/_rgcms_classes_mixins_Persistable.adoc   |  19 +-
 .../rgcms/_rgcms_classes_super_FixtureScripts.adoc |   5 +-
 .../_rgcms_classes_utility_ObjectContracts.adoc    |  10 +-
 .../guides/rgcms/_rgcms_classes_value-types.adoc   |   2 +-
 .../rgcms/_rgcms_methods_reserved_validate.adoc    |   3 +-
 .../_rgcms_schema-aim.adoc}                        |  14 +-
 .../asciidoc/guides/rgcms/_rgcms_schema-cmd.adoc   |   6 +-
 ...ce-layer_PersistenceSessionServiceInternal.adoc |   2 +-
 .../guides/rgsvc/_rgsvc_application-layer-api.adoc |  22 +-
 ...lication-layer-api_ActionInvocationContext.adoc |   2 -
 ...vc_application-layer-api_BackgroundService.adoc |  16 +-
 ...rgsvc_application-layer-api_CommandContext.adoc |  20 +-
 ...vc_application-layer-api_DtoMappingHelper.adoc} |  23 +-
 ...c_application-layer-api_InteractionContext.adoc |  27 +-
 ...rgsvc_application-layer-api_MessageService.adoc |   3 -
 .../_rgsvc_application-layer-api_TitleService.adoc |   4 -
 ...c_application-layer-api_TransactionService.adoc |  60 ++--
 ...rgsvc_application-layer-api_WrapperFactory.adoc |   6 -
 ...ication-layer-spi_BackgroundCommandService.adoc |   8 +-
 ...rgsvc_application-layer-spi_CommandService.adoc |  26 +-
 ...lication-layer-spi_HomePageProviderService.adoc |   7 +-
 ...vc_bootstrapping-spi_ClassDiscoveryService.adoc |  30 +-
 .../rgsvc/_rgsvc_core-domain-api_ClockService.adoc |  16 +-
 ...rgsvc_core-domain-api_ConfigurationService.adoc |   2 -
 ...gsvc_core-domain-api_DomainObjectContainer.adoc |   1 -
 .../_rgsvc_core-domain-api_EventBusService.adoc    |  88 +++--
 .../_rgsvc_core-domain-api_FactoryService.adoc     |   1 -
 .../rgsvc/_rgsvc_core-domain-api_Scratchpad.adoc   |   5 +-
 .../rgsvc/_rgsvc_core-domain-api_UserService.adoc  |   2 -
 .../guides/rgsvc/_rgsvc_integration-api.adoc       |  22 --
 .../_rgsvc_integration-api_BookmarkService.adoc    |   2 +-
 .../rgsvc/_rgsvc_integration-api_EmailService.adoc | 136 ++++++-
 .../rgsvc/_rgsvc_integration-api_JaxbService.adoc  |   2 -
 .../_rgsvc_integration-api_MementoService.adoc     |  26 +-
 .../_rgsvc_integration-api_XmlSnapshotService.adoc |   4 -
 ..._metadata-api_ApplicationFeatureRepository.adoc |  34 +-
 .../_rgsvc_metadata-api_MetamodelService.adoc      |  17 +-
 .../rgsvc/_rgsvc_metadata-api_ServiceRegistry.adoc |   3 +-
 ...rgsvc_persistence-layer-api_IsisJdoSupport.adoc |   8 +-
 ...rgsvc_persistence-layer-api_MetricsService.adoc |   3 -
 ...vc_persistence-layer-api_QueryResultsCache.adoc |   2 -
 ...vc_persistence-layer-api_RepositoryService.adoc | 110 +++---
 ...rgsvc_persistence-layer-spi_AuditerService.adoc |  15 +-
 ...gsvc_persistence-layer-spi_AuditingService.adoc |  82 +++++
 ...gsvc_persistence-layer-spi_EventSerializer.adoc |  67 ++++
 ...svc_persistence-layer-spi_PublisherService.adoc |   3 +
 ...vc_persistence-layer-spi_PublishingService.adoc | 190 ++++++++++
 ...sistence-layer-spi_UserRegistrationService.adoc |   3 +-
 .../rgsvc/_rgsvc_presentation-layer-api.adoc       |  81 +++++
 ...resentation-layer-api_AcceptHeaderService.adoc} |   2 +-
 ..._presentation-layer-api_BookmarkUiService.adoc} |  20 +-
 ...vc_presentation-layer-api_DeepLinkService.adoc} |  17 +-
 ..._presentation-layer-api_GuiceBeanProvider.adoc} |   4 +-
 ...esentation-layer-spi_ContentMappingService.adoc |  14 -
 ...ntation-layer-spi_EmailNotificationService.adoc |   4 -
 ...esentation-layer-spi_ErrorReportingService.adoc |   3 +-
 ...presentation-layer-spi_ExceptionRecognizer.adoc |  40 ++-
 ...c_presentation-layer-spi_GridLoaderService.adoc |   3 -
 .../_rgsvc_presentation-layer-spi_GridService.adoc |  13 -
 ...c_presentation-layer-spi_GridSystemService.adoc |   1 -
 .../_rgsvc_presentation-layer-spi_HintStore.adoc   |   1 -
 ...gsvc_presentation-layer-spi_LocaleProvider.adoc |   1 -
 ...esentation-layer-spi_MenuBarsLoaderService.adoc |   2 +-
 ...svc_presentation-layer-spi_MenuBarsService.adoc |   2 +-
 ...entation-layer-spi_TableColumnOrderService.adoc |   7 -
 ..._presentation-layer-spi_TranslationService.adoc |  22 +-
 ...resentation-layer-spi_TranslationsResolver.adoc |   1 -
 ..._presentation-layer-spi_UserProfileService.adoc |   7 +-
 .../main/asciidoc/guides/rgsvc/_rgsvc_testing.adoc |  15 +-
 .../_rgsvc_testing_ExecutionParametersService.adoc |   5 +-
 .../rgsvc/_rgsvc_testing_FixtureScripts.adoc       |  62 ++++
 .../_rgsvc_testing_FixtureScriptsDefault.adoc      |  50 ---
 ...esting_FixtureScriptsSpecificationProvider.adoc |   5 +-
 .../guides/rgsvc/_rgsvc_testing_SudoService.adoc   |  10 -
 .../rgsvc/_rgsvc_testing_SwitchUserService.adoc    |   3 +-
 .../rgsvc/images/reference-services/categories.png | Bin 31453 -> 35572 bytes
 .../images/reference-services/categories.pptx      | Bin 63438 -> 41617 bytes
 .../src/main/asciidoc/guides/rgsvc/rgsvc.adoc      |   1 +
 .../guides/ugbtb/_ugbtb_deployment_neo4j.adoc      |   3 +-
 .../_ugbtb_hints-and-tips_persisted-title.adoc     |   2 +-
 ..._replacing-default-service-implementations.adoc |  19 +-
 .../ugbtb/_ugbtb_programming-model_finetuning.adoc |   7 -
 ...ailable-domain-services_framework-provided.adoc |   8 +-
 .../_ugfun_building-blocks_events_ui-events.adoc   |   2 +-
 .../_ugfun_building-blocks_identifiers_oid.adoc    |   2 +-
 .../ugfun/_ugfun_building-blocks_modules.adoc      |   9 +-
 ..._ugfun_getting-started_simpleapp-archetype.adoc | 192 +++++-----
 ...ming-model_view-models_jaxb_joda-datatypes.adoc |   2 +-
 .../asciidoc/guides/ugodn/_ugodn_configuring.adoc  |   4 +-
 .../guides/ugodn/_ugodn_configuring_bulk-load.adoc |  36 ++
 ...n_configuring_eagerly-registering-entities.adoc |  23 --
 .../ugodn/_ugodn_configuring_properties.adoc       |  61 +++-
 .../asciidoc/guides/ugodn/_ugodn_db-schemas.adoc   |  16 +-
 ..._hints-and-tips_overriding-jdo-annotations.adoc |   2 +-
 ...appings_1-to-m-bidirectional-relationships.adoc |   2 +-
 .../_ugsec_configuring-isis-to-use-shiro.adoc      |  26 +-
 .../guides/ugtst/_ugtst_bdd-spec-support.adoc      |   3 -
 .../ugtst/_ugtst_bdd-spec-support_key-classes.adoc |  59 ----
 ...ugtst_bdd-spec-support_maven-configuration.adoc |  50 ++-
 ..._ugtst_bdd-spec-support_writing-a-bdd-spec.adoc | 119 +++----
 .../guides/ugtst/_ugtst_fixture-scripts.adoc       |  18 +-
 .../_ugtst_fixture-scripts_api-and-usage.adoc      | 327 +++++++++--------
 .../ugtst/_ugtst_fixture-scripts_sudo-service.adoc |   6 +-
 ...tst_fixture-scripts_ticking-clock-fixture.adoc} |  24 +-
 .../_ugtst_integ-test-support_abstract-class.adoc  |  99 +++---
 .../_ugtst_integ-test-support_bootstrapping.adoc   | 207 +----------
 ...nteg-test-support_configuration-properties.adoc |   5 +-
 ...tst_integ-test-support_maven-configuration.adoc |   4 +-
 ...gtst_unit-test-support_maven-configuration.adoc |   4 +-
 .../images/testing/fixture-scripts/prompt.png      | Bin 52869 -> 49181 bytes
 .../testing/fixture-scripts/prototyping-menu.png   | Bin 59183 -> 58104 bytes
 .../result-list-specifying-number.png              | Bin 63100 -> 0 bytes
 .../images/testing/fixture-scripts/result-list.png | Bin 50272 -> 82117 bytes
 .../ugvro/_ugvro_configuration-properties.adoc     |  28 +-
 .../guides/ugvro/_ugvro_layout-resources.adoc      |   4 +-
 .../ugvro/_ugvro_simplified-representations.adoc   |   2 +-
 .../ugvw/_ugvw_configuration-properties.adoc       |  77 +++-
 .../_ugvw_extending_replacing-page-elements.adoc   |  38 +-
 .../asciidoc/guides/ugvw/_ugvw_hints-and-tips.adoc |   1 +
 ..._ugvw_hints-and-tips_highlight-current-row.adoc |  88 +++++
 ...hints-and-tips_i18n-label-in-wicket-viewer.adoc |   9 +-
 .../guides/ugvw/_ugvw_layout_annotation-based.adoc |   2 +-
 .../guides/ugvw/_ugvw_menubars-layout.adoc         |   2 +-
 .../ugvw/_ugvw_menubars-layout_file-based.adoc     |   4 +-
 adocs/documentation/src/main/asciidoc/index.html   |  56 +--
 .../_migration-notes_1.15.0-to-1.16.0.adoc         |  71 ++++
 ...9.0_fixture-scripts-specification-provider.adoc |   2 +-
 .../asciidoc/migration-notes/migration-notes.adoc  |   1 +
 .../src/main/asciidoc/pages/icons/icons.adoc       |   2 +-
 .../release-notes/_release-notes_1.16.0.adoc       | 123 +++++++
 .../main/asciidoc/release-notes/release-notes.adoc |  11 +-
 adocs/template/document.html.erb                   |  26 +-
 .../java/org/apache/isis/applib/AppManifest2.java  |  18 +-
 .../apache/isis/applib/AppManifestAbstract.java    | 201 ++++-------
 .../apache/isis/applib/AppManifestAbstract2.java   | 143 ++++++++
 .../main/java/org/apache/isis/applib/Module.java   | 227 ++++++++++++
 .../org/apache/isis/applib/ModuleAbstract.java     | 132 +++++++
 .../isis/applib/ModuleOrBuilderAbstract.java       | 128 +++++++
 .../org/apache/isis/applib/PropertyResource.java   |  61 ++++
 .../apache/isis/applib/annotation/Constants.java   |  12 +-
 .../isis/applib/annotation/DomainService.java      |   2 +-
 .../applib/annotation/DomainServiceLayout.java     |   2 +-
 .../isis/applib/annotation/Programmatic.java       |   7 +-
 .../java/org/apache/isis/applib/clock/Clock.java   |   3 +-
 .../isis/applib/fixtures/TickingFixtureClock.java  | 172 +++++++++
 .../fixturescripts/BuilderScriptAbstract.java      | 103 ++++++
 .../isis/applib/fixturescripts/FixtureScript.java  | 179 +++++++---
 .../FixtureScriptWithExecutionStrategy.java}       |  13 +-
 .../isis/applib/fixturescripts/FixtureScripts.java |  56 ++-
 .../fixturescripts/PersonaWithBuilderScript.java   |   9 +-
 .../PersonaWithFinder.java}                        |   8 +-
 .../isis/applib/fixturescripts/WithPrereqs.java    |  14 +-
 .../applib/fixturescripts/clock/ClockFixture.java  | 124 +++++++
 .../fixturescripts/clock/TickingClockFixture.java  | 138 ++++++++
 .../setup/PersonaEnumPersistAll.java               |  89 +++++
 .../teardown/TeardownFixtureAbstract.java          |  68 ++++
 .../teardown/TeardownFixtureAbstract2.java         | 152 ++++++++
 .../applib/layout/menubars/MenuBarsAbstract.java   |  18 +
 .../applib/services/acceptheader/package-info.java |   2 +-
 .../BookmarkUiService.java}                        |   6 +-
 .../services/config/ConfigurationProperty.java     |  36 +-
 .../isis/applib/services/dto/DtoMappingHelper.java |  66 ++++
 .../isis/applib/services/error/ErrorDetails.java   |  25 +-
 .../apache/isis/applib/services/error/Ticket.java  |  23 ++
 .../exceprecog/ExceptionRecognizerComposite.java   |   2 +-
 .../fixturespec/FixtureScriptsSpecification.java   |  10 +
 .../isis/applib/services/guice/package-info.java   |   2 +-
 .../applib/services/layout/Object_openRestApi.java |  64 ++++
 .../isis/applib/services/linking/package-info.java |   2 +-
 .../services/metamodel/MetaModelService.java       |  16 +
 .../services/repository/RepositoryService.java     |   9 +-
 .../services/swagger/SwaggerServiceMenu.java       |   4 +-
 .../isis/applib/services/title/package-info.java   |   2 +-
 .../applib/services/urlencoding/package-info.java  |   2 +-
 .../isis/applib/services/xactn/Transaction.java    |  12 +-
 .../applib/services/xactn/TransactionService.java  |  52 ++-
 .../java/org/apache/isis/applib/util/Clause.java   | 122 +++++++
 .../apache/isis/applib/util/ObjectContracts.java   | 132 +------
 .../Module_Util_transitiveDependenciesOf_Test.java | 199 +++++++++++
 .../ConfigurationProperty_isProtected_Test.java    |  66 ++++
 .../integtestsupport/IntegrationTestAbstract.java  |   3 +
 .../integtestsupport/IntegrationTestAbstract2.java |   3 +
 .../integtestsupport/IntegrationTestAbstract3.java | 179 ++++++++++
 .../core/integtestsupport/IsisSystemForTest.java   |   5 +
 .../scenarios/ObjectFactoryForIntegration.java     |  75 ++++
 .../scenarios/ScenarioExecutionForIntegration.java |   5 +-
 .../isis/tool/mavenplugin/IsisMojoAbstract.java    |   2 +-
 .../intellij}/pom.xml                              |  17 +-
 .../testing}/pom.xml                               |   1 +
 .../{mavendeps-webapp => mavendeps/webapp}/pom.xml |  30 +-
 .../isis/core/commons/compare/SequenceCompare.java |   2 +
 .../commons/config/IsisConfigurationDefault.java   |   8 +-
 .../isis/core/commons/lang/StringExtensions.java   |   3 -
 .../layout/CollectionLayoutFacetFactory.java       |   4 +-
 ...aultViewFacetForCollectionLayoutAnnotation.java |   9 +-
 .../DomainObjectAnnotationFacetFactory.java        |   4 +-
 .../auditing/DefaultViewConfiguration.java}        |  34 +-
 ...atableObjectFacetForDomainObjectAnnotation.java |  21 +-
 ...sClassFacetForDomainObjectLayoutAnnotation.java |  12 +
 .../domainservice/DomainServiceMenuOrder.java      |  16 +-
 .../DomainServiceLayoutFacetFactory.java           |   3 +-
 .../RecreatableObjectFacetAbstract.java            |   8 -
 ...ObjectFacetDeclarativeInitializingAbstract.java |   3 +-
 ...ctFacetForRecreatableDomainObjectInterface.java |   2 +-
 ...eObjectFacetForRecreatableObjectAnnotation.java |   2 +-
 ...leObjectFacetForRecreatableObjectInterface.java |   2 +-
 ...creatableObjectFacetForViewModelAnnotation.java |   2 +-
 ...ableObjectFacetForXmlRootElementAnnotation.java |   2 +-
 .../facets/object/viewmodel/ViewModelFacet.java    |  11 -
 .../progmodel/ProgrammingModelAbstract.java        |   8 +-
 .../services/appmanifest/AppManifestProvider.java} |  11 +-
 .../metamodel/MetaModelServiceDefault.java         |  15 +
 .../PersistenceSessionServiceInternal.java         |   3 +
 .../PersistenceSessionServiceInternalNoop.java     |   5 +
 .../services/swagger/internal/Generation.java      |  14 +-
 .../services/xactn/TransactionServiceDefault.java  |  35 +-
 .../core/metamodel/spec/feature/ObjectMember.java  |  38 +-
 .../metamodel/specloader/SpecificationLoader.java  |  21 +-
 .../classsubstitutor/ClassSubstitutor.java         |  15 +
 .../specloader/specimpl/FacetedMethodsBuilder.java |  21 +-
 .../specimpl/FacetedMethodsBuilderContext.java     |   6 +-
 .../specloader/specimpl/ObjectActionDefault.java   |   4 +-
 .../validator/MetaModelValidatorVisiting.java      |   7 +-
 .../facets/object/query/JdoNamedQuery.java         |  21 +-
 .../query/JdoQueryAnnotationFacetFactory.java      | 125 +------
 .../object/query/VisitorForClauseAbstract.java     |  99 ++++++
 .../facets/object/query/VisitorForFromClause.java  |  62 ++++
 .../object/query/VisitorForVariablesClause.java    |  58 +++
 .../config/IsisConfigurationDefault_safe_Test.java |  12 +-
 .../metamodel/facets/AbstractFacetFactoryTest.java |   3 +
 ...etForCollectionLayoutAnnotationFactoryTest.java |  14 +-
 .../DomainObjectAnnotationFacetFactoryTest.java    |  12 -
 .../DefaultViewConfiguration_parseValue_Test.java  |  48 +++
 ...tTest.java => DomainServiceMenuOrder_Test.java} |   2 +-
 .../DomainServiceLayoutFacetFactoryTest.java       |  12 +-
 .../services/menubars/menubars.layout.xml          |  18 +
 core/pom.xml                                       |   8 +-
 .../core/runtime/headless/HeadlessAbstract.java    | 141 ++++++++
 .../HeadlessWithBootstrappingAbstract.java         | 158 +++++++++
 .../headless}/IsisComponentProviderDefault.java    |   2 +-
 .../isis/core/runtime/headless/IsisSystem.java}    | 343 ++++--------------
 .../runtime/headless/IsisSystemBootstrapper.java   | 236 +++++++++++++
 .../auth/AuthenticationRequestNameOnly.java}       |  12 +-
 .../core/runtime/headless/logging/LogConfig.java   |  81 +++++
 .../core/runtime/headless/logging/LogStream.java   |  87 +++++
 .../changes/ChangedObjectsServiceInternal.java     |   6 +-
 .../runtime/services/changes/PreAndPostValues.java |  12 +-
 .../menubars/bootstrap3/MenuBarsServiceBS3.java    |   3 +
 .../menubars/bootstrap3/ServiceAndAction.java      |  18 +
 .../PersistenceSessionServiceInternalDefault.java  |   7 +-
 .../userprof/UserProfileServiceDefault.java}       |  17 +-
 .../system/persistence/PersistenceSession.java     | 158 ++++++++-
 .../runtime/system/session/IsisSessionFactory.java |  14 +-
 .../system/session/IsisSessionFactoryBuilder.java  |   1 +
 .../system/transaction/IsisTransaction.java        |  21 +-
 .../IsisComponentProvider.java                     |  94 ++++-
 ...sistenceQueryFindUsingApplibQueryProcessor.java |  13 +-
 ...sisSystemBootstrapper_haveSameModules_Test.java |  54 +++
 .../runtime/services/DeweyOrderComparatorTest.java |   8 +
 .../changes/PreAndPostValues_shouldAudit_Test.java |  65 ++++
 .../IsisComponentProvider_within_Test.java         |  48 +++
 .../fixture/budget/SomeServiceToInclude.java}      |   6 +-
 .../budgetassignment/SomeServiceNotToInclude.java  |   5 +-
 .../scenarios/DomainServiceProvider.java           |   7 +-
 .../scenarios/DomainServiceProviderMockery.java    |   4 +
 .../core/specsupport/scenarios/InMemoryDB.java     |   3 +
 .../specsupport/scenarios/ScenarioExecution.java   |   3 +
 .../scenarios/ScenarioExecutionForUnit.java        |   3 +
 .../scenarios/ScenarioExecutionScope.java          |   3 +
 .../core/specsupport/specs/CukeGlueAbstract.java   |   3 +
 .../core/specsupport/specs/CukeGlueAbstract2.java  |  23 +-
 .../specs/CukeGlueBootstrappingAbstract.java       |  28 +-
 .../core/specsupport/specs/CukeSpecsAbstract.java  |   3 +
 .../restfulobjects/applib/Rel_getName_Test.java    |  18 +
 .../rendering/domainobjects/JsonValueEncoder.java  |   2 +-
 .../server/RestfulObjectsApplication.java          |   9 +-
 .../RestfulObjectsApplicationExceptionMapper.java  | 116 ------
 .../RestfulObjectsApplicationExceptionPojo.java    |  88 -----
 .../server/mappers/ExceptionMapperAbstract.java    | 120 +++++++
 .../mappers/ExceptionMapperForObjectNotFound.java  |  19 +-
 ...xceptionMapperForRestfulObjectsApplication.java |  18 +-
 .../ExceptionMapperForRuntimeException.java}       |  36 +-
 .../entity/ExceptionDetail.java}                   |  72 ++--
 .../server/mappers/entity/ExceptionPojo.java       |  55 +++
 .../server/mappers/entity/package-info.java}       |  12 +-
 .../resources/DomainObjectResourceServerside.java  |  12 +-
 .../IsisTransactionFilterForRestfulObjects.java    |   6 +-
 ...stfulObjectsApplicationExceptionMapperTest.java |  29 +-
 .../integration/wicket/WebRequestCycleForIsis.java |  88 ++++-
 .../viewer/services/BookmarkUiServiceWicket.java   |  29 +-
 .../model/mementos/ObjectAdapterMemento.java       |  13 +-
 .../viewer/wicket/model/models/ActionModel.java    |   5 +
 .../wicket/model/models/BookmarkedPagesModel.java  |   1 +
 .../wicket/model/models/EntityCollectionModel.java |  46 ++-
 .../viewer/wicket/model/models/FormExecutor.java   |   2 +-
 .../wicket/model/models/FormExecutorContext.java   |  12 +
 .../viewer/wicket/model/models/ScalarModel.java    |   5 +
 .../wicket/model/models/ServiceActionsModel.java   |   3 +-
 .../entityactions/AdditionalLinksPanel.java        |   5 +-
 .../entityactions/EntityActionLinkFactory.java     |  26 +-
 .../serviceactions/ServiceActionUtil.java          |   5 +-
 .../actions/ActionFormExecutorStrategy.java        |   5 +-
 .../CollectionContentsAsAjaxTablePanel.java        |   6 +-
 .../CollectionContentsSortableDataProvider.java    |  16 +-
 .../columns/ObjectAdapterPropertyColumn.java       |  10 +-
 .../components/entity/fieldset/PropertyGroup.java  |  43 ++-
 .../wicket/ui/components/header/HeaderPanel.java   |   6 +-
 .../components/scalars/ScalarPanelAbstract2.java   |   2 +-
 .../widgets/breadcrumbs/BreadcrumbModel.java       |  23 +-
 .../widgets/linkandlabel/ActionLink.java           |  38 +-
 .../linkandlabel/ActionLinkFactoryAbstract.java    |   2 +-
 .../viewer/wicket/ui/errors/ExceptionModel.java    |  28 +-
 .../wicket/ui/errors/ExceptionStackTracePanel.html |   9 +-
 .../wicket/ui/errors/ExceptionStackTracePanel.java |  36 +-
 .../viewer/wicket/ui/pages/error/ErrorPage.java    |  24 +-
 .../isis/viewer/wicket/ui/pages/home/HomePage.java |   8 +-
 .../wicket/ui/pages/jquery.isis.wicket.viewer.js   |   6 +-
 .../wicket/ui/panels/FormExecutorDefault.java      |  10 +-
 .../wicket/ui/panels/PromptFormAbstract.java       |  16 +-
 example/application/helloworld/pom.xml             |  69 +++-
 .../application/HelloWorldAppManifest.java         |   8 +-
 ...sis.properties => isis-non-changing.properties} |  10 +-
 .../java/domainapp/application/menubars.layout.xml |  18 +
 .../main/java/domainapp/dom/HelloWorldModule.java  |   6 +-
 .../src/main/webapp/WEB-INF/isis.properties        |  22 +-
 .../src/main/webapp/WEB-INF/logging.properties     |  26 +-
 .../src/main/webapp/swagger-ui/index.html          |   6 +-
 .../application/simpleapp/application/.gitignore   |   1 +
 .../simpleapp/application/lib/.gitignore           |   5 -
 ...arDown.java => DomainAppApplicationModule.java} |  17 +-
 ...mainAppFixtureScriptsSpecificationProvider.java |   1 -
 .../fixture/scenarios/DomainAppDemo.java           |  25 +-
 .../application/manifest/DomainAppAppManifest.java |  21 +-
 .../manifest/DomainAppAppManifestWithFixtures.java |   7 +-
 .../application/manifest/menubars.layout.xml       |  18 +
 .../services/homepage/HomePageViewModel.java       |   6 +-
 .../services/homepage/HomePageViewModel.layout.xml |   1 +
 ...sis.properties => isis-non-changing.properties} |  16 +-
 .../manifest/persistor_datanucleus.properties      |  10 +-
 .../bdd/specglue/BootstrappingGlue.java            |  20 +-
 .../bdd/specglue/CatalogOfFixturesGlue.java        |  12 +-
 .../{RunIntegBddSpecs.java => RunBddSpecs.java}    |   5 +-
 .../SimpleObjectSpec_listAllAndCreate.feature      |   5 +-
 .../integtests/DomainAppIntegTestAbstract.java     |  13 +-
 .../application/integtests/Smoke_IntegTest.java    |  21 +-
 .../src/test/resources/cucumber.properties         |   1 +
 .../application/simpleapp/module-simple/.gitignore |   3 +-
 ...leModuleDomSubmodule.java => SimpleModule.java} |  21 +-
 .../modules/simple/SimpleModuleManifest.java       |  15 +-
 .../modules/simple/dom/impl/SimpleObject.java      |   1 -
 .../simple/dom/impl/SimpleObjectRepository.java    |  59 ----
 .../{SimpleObjectMenu.java => SimpleObjects.java}  |  38 +-
 ...pleObjectData.java => SimpleObjectBuilder.java} |  51 +--
 ...leObjectData.java => SimpleObject_persona.java} |  28 +-
 .../fixture/scenario/CreateSimpleObjects.java      |  77 ----
 ...epository_Test.java => SimpleObjects_Test.java} |  23 +-
 .../integtests/SimpleModuleIntegTestAbstract.java  |  14 +-
 .../tests/SimpleObjectMenu_IntegTest.java          |  56 +--
 .../integtests/tests/SimpleObject_IntegTest.java   |  40 +--
 .../simple/specglue/SimpleObjectMenuGlue.java      |  24 +-
 example/application/simpleapp/pom.xml              |  21 +-
 example/application/simpleapp/webapp/pom.xml       |   5 -
 .../webapp/src/main/webapp/WEB-INF/isis.properties |  25 +-
 .../src/main/webapp/WEB-INF/logging.properties     |  26 +-
 .../webapp/src/main/webapp/swagger-ui/index.html   |   6 +-
 394 files changed, 8554 insertions(+), 3805 deletions(-)

diff --cc adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
index 0b35d85,36606b9..332dedc
--- a/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgcfg/_rgcfg_configuring-core.adoc
@@@ -730,24 -511,59 +511,60 @@@ See xref:../ugbtb/ugbtb.adoc#_ugbtb_pro
  |Fully qualified class names of (new, custom) facet factory classes to be included to the programming model. +
  See xref:../ugbtb/ugbtb.adoc#_ugbtb_programming-model_finetuning[finetuning the programming model] for more details.
  
+ |`isis.reflector.` +
+ `layoutMetadataReaders`
+ |`FQCN`,`FQCN2`,...
+ |Fully qualified class names of classes to be instantiated to read layout metadata, as used in for xref:../ugvw/ugvw.adoc#_ugvw_layout_file-based[file-based layout]s. +
+ 
+ See xref:../ugbtb/ugbtb.adoc#_ugbtb_programming-model_layout-metadata-reader[Layout Metadata Reader] for more information.
  
- |`isis.viewers.` +
- `paged.parented`
- |positive integer (12)
- |Default page size for parented collections (as owned by an object, eg `Customer#getOrders()`)
  
  
- |`isis.viewers.` +
- `paged.standalone`
- |positive integer (25)
- |Default page size for standalone collections (as returned from an action invocation)
+ |===
+ 
+ 
+ 
+ [[__rgcfg_configuring-core_policy]]
+ == Policy
+ 
+ .Runtime Policy Configuration Properties
+ [cols="2a,1,3a", options="header"]
+ |===
+ |Property
+ |Value +
+ (default value)
+ |Description
+ 
+ |`isis.objects.` +
+ `editing`
+ |`true`,`false` +
+ (`true`)
+ |Whether objects' properties and collections can be edited directly (for objects annotated with xref:../rgant/rgant.adoc#_rgant-DomainObject_editing[`@DomainObject#editing()`]); see xref:../rgcfg/rgcfg.adoc#__rgcfg_configuring-core_isis-objects-editing[below] for further discussion.
+ 
+ |`isis.reflector.` +
+ `explicitAnnotations.` +
+ `action`
+ |`true`,`false` +
+ (`false`)
+ |Whether action methods need to be explicitly annotated using `@Action`.
+ 
+ The default is that any non-`@Programmatic` methods that are not otherwise recognised as properties, collections or supporting methods, are assumed to be actions.
+ Setting this property reverses this policy, effectively requiring that all actions need to be annotated with `@Action`.
+ 
+ Note that properties and collections are still implicitly inferred by virtue of being "getters".
+ 
+ 
+ |`isis.reflector.facet.` +
+ `filterVisibility`
+ |`true`,`false` +
+ (`true`)
+ |Whether objects should be filtered for visibility. +
+ 
++
+ See xref:../rgcfg/rgcfg.adoc#__rgcfg_configuring-core_filterVisibility[section below] for further discussion.
+ 
  
  
- |`isis.viewers.` +
- `propertyLayout.labelPosition`
- |`TOP`, `LEFT` +
- (`LEFT`)
- |Default for label position for all properties if not explicitly specified using xref:../rgant/rgant.adoc#_rgant-PropertyLayout_labelPosition[`@PropertyLayout#labelPosition()`]
  
  |===
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BackgroundService.adoc
index 3a4da86,cf00a3f..aaa6dfc
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BackgroundService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BackgroundService.adoc
@@@ -10,13 -11,15 +11,16 @@@ xref:../rgsvc/rgsvc.adoc#_rgsvc_applica
  The `BackgroundService2` is responsible for capturing a memento representing the command in a typesafe way, and persisting it rather than executing it directly.
  
  The default `BackgroundServiceDefault` implementation works by using a proxy wrapper around the target so that it can capture the action to invoke and its arguments.
- (As of `1.13.0`), this is done using xref:../rgfis/rgfis.adoc#_rgfis_application-layer_CommandDtoServiceInternal[`CommandDtoServiceInternal`] (in previous releases it used (a private copy of) xref:../rgsvc/rgsvc.adoc#_rgsvc_integration-api_MementoService[`MementoService`]).
++
+ This is done using xref:../rgfis/rgfis.adoc#_rgfis_application-layer_CommandDtoServiceInternal[`CommandDtoServiceInternal`].
  
  The persistence delegates the persistence of the memento to an appropriate implementation of the companion `BackgroundCommandService2`.
- One such implementation of `BackgroundCommandService` is provided by (non-ASF) link:http://platform.incode.org/spi/command/command.html[Incode Platform's command] module.
+ One such implementation of `BackgroundCommandService` is provided by (non-ASF) http://github.com/isisaddons/isis-module-command[Isis addons' command] module.
  
  The persisting of commands is only half the story; there needs to be a separate process to read the commands and execute them.
- The `BackgroundCommandExecution` abstract class (discussed xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService_BackgroundCommandExecution[below]) provides infrastructure to do this; the concrete implementation of this class depends on the configured `BackgroundCommandService` (in order to query for the persisted (background) ``Command``s.
+ The `BackgroundCommandExecution` abstract class (discussed
+ xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService_BackgroundCommandExecution[below]) provides infrastructure to do this;
+ the concrete implementation of this class depends on the configured `BackgroundCommandService` (in order to query for the persisted (background) ``Command``s.
  
  
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_InteractionContext.adoc
index c50a8f3,bc170e8..1e6d25e
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_InteractionContext.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_InteractionContext.adoc
@@@ -155,28 -167,6 +166,14 @@@ public class PropertyEdit extends Execu
  <1> The object used as the new value of the property.  Could be `null` if the property is being cleared.
  
  
 +=== Alternate Implementations
 +
 +Apache Isis' default
 +implementation of `InteractionContext` class is automatically registered (it is annotated with `@DomainService`).
 +
- To use an alternative implementation, subclass and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
- 
- 
- The framework also takes responsibility for instantiating the `Interaction`, using the
- xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_FactoryService[`FactoryService`].
- 
- [NOTE]
- ====
- Unlike the similar xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] (discussed
- xref:../rgsvc/rgsvc.adoc#__rgsvc_application-layer-api_InteractionContext_Related-Classes[below]) there is no domain service to different
- implementations of `Interaction` to be used.
- If this were to be needed, then a custom implementation of
-  xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_FactoryService[`FactoryService`] could always used).
- ====
 +
 +
 +
  
  == Interacting with the services
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_MessageService.adoc
index 3048cfa,e7d8413..dea60de
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_MessageService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_MessageService.adoc
@@@ -56,8 -61,4 +56,5 @@@ public Order addItem(Product product, @
  
  The core framework provides a default implementation of this service, `o.a.i.core.runtime.services.message.MessageServiceDefault`.
  
 +To use an alternative implementation, implement the `MessageService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
  
- 
- 
- 
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_TransactionService.adoc
index f4fb4ba,0320657..cc8e080
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_TransactionService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_TransactionService.adoc
@@@ -5,8 -5,12 +5,8 @@@
  :_imagesdir: images/
  
  
- The `TransactionService2` provides a small number of methods to allow domain objects to influence user transactions.
+ The `TransactionService3` (and its various supertypes) allows domain objects to influence user transactions.
  
 -[NOTE]
 -====
 -The methods in this service replace similar methods (now deprecated) in xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_DomainObjectContainer[`DomainObjectContainer`].
 -====
  
  
  == API
@@@ -97,4 -120,4 +116,3 @@@ try 
  The core framework provides a default implementation of this service, `o.a.i.core.metamodel.services.xactn.TransactionServiceDefault`.
  
  
- To use an alternative implementation, implement the `TransactionService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
 -
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
index 275d024,9b541bf..b04eef8
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-spi_CommandService.adoc
@@@ -9,18 -9,17 +9,15 @@@
  The `CommandService` service supports the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service such
  that `Command` objects (that reify the invocation of an action/edit of a property on a domain object) can be persisted.
  
- As of `1.13.0`, the primary use case for persistent ``Command``s is in support of background commands; they
- act as a parent to any background commands that can be persisted either explicitly using the
- xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService[`BackgroundService`], or implicitly by way of the
- xref:../rgant/rgant.adoc#_rgant-Action_command[`@Action#command()`] annotation.
+ The primary use case for persistent ``Command``s is in support of background commands; they act as a parent to any background commands that can be persisted either explicitly using the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_BackgroundService[`BackgroundService`], or implicitly by way of the xref:../rgant/rgant.adoc#_rgant-Action_command[`@Action#command()`] annotation.
  
- In previous versions of the framework, persistent ``Command``s also supported a number of other use cases:
+ There are a number of related use cases:
  
  * they enable profiling of the running application (which actions are invoked then most often, what is their response time)
 -* if xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`] or
 -xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublishingService[`PublishingService`] (latter deprecated) is configured, they provide
 +* if xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_PublisherService[`PublisherService`] is configured, they provide
  better traceability as the `Command` is also correlated with any published events, again through the unique
  `transactionId` GUID
 -* if xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuderService[`AuditerService`] or
 -xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuditService[`AuditingService`] (latter deprecated) is configured, they provide better audit
 +* if xref:../rgsvc/rgsvc.adoc#_rgsvc_spi_AuditerService[`AuditerService`](s) are configured, they provide better audit
  information, since the `Command` (the 'cause' of an action) can be correlated to the audit records (the "effect" of
  the action) through the `transactionId` GUID
  
@@@ -57,12 -58,14 +54,11 @@@ public interface CommandService 
  <1> Instantiate the appropriate instance of the `Command` (as defined by the
  xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-api_CommandContext[`CommandContext`] service).  Its members will be populated automatically by
  the framework.
- <2> Set the hint that the `Command` should be persisted if possible (when completed, see below).
- <3> "Complete" the command, typically meaning that the command should be persisted it if its `Command#getPersistence()`
- flag and persistence hint (`Command#isPersistHint()`) indicate that it should be.
- +
- The framework will automatically have set the `completedAt` property of the `Command`.
+ <2> Deprecated and *IS NOT CALLED* by the framework.
+ The framework automatically populates the ``Command``'s `timestamp`, `user` and `transactionId` fields, so there is no need for the service implementation to initialize any of these.
+ In particular, the ``Command`` will already have been initialized with the provided `transactionId` argument.
+ <3> Set the hint that the `Command` should be persisted if possible (when completed, see below).
 -<4> "Complete" the command, typically meaning that the command should be persisted it if its `Command#getPersistence()`
 -flag and persistence hint (`Command#isPersistHint()`) indicate that it should be.  +
 -+
 -The framework will automatically have set the `completedAt` property of the `Command`.
 +
  
  
  == Implementation
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_bootstrapping-spi_ClassDiscoveryService.adoc
index 866fadc,372a582..208f1f0
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_bootstrapping-spi_ClassDiscoveryService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_bootstrapping-spi_ClassDiscoveryService.adoc
@@@ -41,36 -41,10 +41,14 @@@ This implementation is also used to dis
  Currently this logic uses the implementation directly, so is not pluggable.
  ====
  
 +To use an alternative implementation, implement the `ClassDiscoveryService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
 +
 +
 +
  
- == Usage
- 
- The usage will vary depending upon the conventions of the design.
- As of `1.9.0`, the usage of the service has been centralized such that the packages to be scanned are located from the xref:../rgcms/rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping[`AppManifest`]'s `#getModules()` method.
- 
- For example, the xref:../ugfun/ugfun.adoc#_ugfun_getting-started_simpleapp-archetype[SimpleApp archetype]'s app manifest includes:
- 
- [source,java]
- ----
- public class DomainAppAppManifest implements AppManifest {
-     @Override
-     public List<Class<?>> getModules() {
-         return Arrays.asList(
-                 DomainAppDomainModule.class,  // domain (entities and repositories)
-                 DomainAppFixtureModule.class, // fixtures
-                 DomainAppAppModule.class      // home page service etc
-         );
-     }
-     ...
- }
- ----
- 
- where the three module classes in effect define three different package prefixes to search under (for domain services, fixture scripts and persistent entities).
- 
- Other usages of the `ClassDiscoveryService` are likely to work in a similar way, requiring some sort of scope to be specified.
  
+ == Related Services
  
+ The xref:rgsvc.adoc#_rgsvc_testing_FixtureScripts[`FixtureScripts`] domain service uses `ClassDiscoveryService` to discover ``FixtureScript``s implementations to present in the UI.
  
+ Note that the bootstrapping of the framework itself does _not_ use this service (though it does use the same underlying library as the default implementation of this service, namely `org.reflections.Reflections`).
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_DomainObjectContainer.adoc
index 1984691,93de668..0f628ff
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_DomainObjectContainer.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_DomainObjectContainer.adoc
@@@ -32,4 -38,5 +32,3 @@@ include::_rgsvc_core-domain-api_DomainO
  
  The core framework provides a default implementation of this service (`o.a.i.core.metamodel.services.container.DomainObjectContainerDefault`).
  
 -
--
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_EventBusService.adoc
index 658bf23,b747cfc..d0376a1
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_EventBusService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_EventBusService.adoc
@@@ -44,11 -44,9 +44,11 @@@ public abstract class EventBusService 
  <2> allows domain services to register themselves.  This should be done in their xref:../rgant/rgant.adoc#_rgant-PostConstruct[`@PostConstruct`] initialization method (for both singleton and xref:../rgant/rgant.adoc#_rgant-RequestScoped[`@RequestScoped`] domain services.
  <3> exists for symmetry, but need never be called (it is in fact deliberately a no-op).
  
- Isis provides a default implementation of the service, `o.a.i.objectstore.jdo.datanucleus.service.eventbus.EventBusServiceJdo`.
+ 
  
  
 +To use an alternative implementation, implement the `EventBusService` domain service and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
 +
  
  
  
@@@ -371,22 -393,7 +395,8 @@@ isis.services.eventbus.implementation=c
  
  
  
- In addition, there is one further configuration property, whether to allow "late registration":
- 
- [source,ini]
- ----
- isis.services.eventbus.allowLateRegistration=false
- ----
- 
- Late registration refers to the idea that a domain service can register itself with the `EventBusService` after events have been posted.  Since domain services are set up at boot time, this almost certainly constitutes a bug in the code and so by default late registration is _not_ allowed.  Setting the above property to `true` disables this check.
- 
- 
- 
- 
- 
- 
  
 +
  == Related Services
  
  The `EventBusService` is intended for fine-grained publish/subscribe for object-to-object interactions within an Apache Isis domain object model. The event propagation is strictly in-memory, and there are no restrictions on the object acting as the event (it need not be serializable, for example).
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_Scratchpad.adoc
index 083ca18,86287d9..8740fe3
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_Scratchpad.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_core-domain-api_Scratchpad.adoc
@@@ -29,10 -29,9 +29,10 @@@ public class Scratchpad 
  ----
  
  This class (`o.a.i.applib.services.scratchpad.Scratchpad`) is also the implementation.
- The service is just a request-scoped wrapper around a `java.util.Map`.
+ And, as you can see, the service is just a request-scoped wrapper around a `java.util.Map`.
  
  
 +To use an alternative implementation, subclass and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
  
  
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_JaxbService.adoc
index 8eb3586,6545b19..f519fd7
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_JaxbService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_JaxbService.adoc
@@@ -56,5 -54,4 +56,3 @@@ xref:../ugfun/ugfun.adoc#_ugfun_buildin
  exposed in the UI through mixins to xref:../rgcms/rgcms.adoc#_rgcms_classes_mixins_Dto[`Dto`] interface.
  
  
- 
--
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_XmlSnapshotService.adoc
index 4fa00e6,8afedff..883e3ac
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_XmlSnapshotService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_integration-api_XmlSnapshotService.adoc
@@@ -188,14 -189,8 +188,10 @@@ public interface XmlSnapshotService 
  
  
  
 +== Implementation
  
 +The core framework provides an implementation of this service (`o.a.i.core.runtime.services.xmlsnapshot.XmlSnapshotServiceDefault`).
  
- To use an alternative implementation, implement use the `XmlSnapshotService` interface and xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
- 
- 
- 
  
  == Related Services
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
index d81b1af,a7b7813..3b45d42
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_MetamodelService.adoc
@@@ -6,9 -6,10 +6,9 @@@
  
  
  
- The `MetaModelService` service provides access to a number of aspects of Apache Isis' internal metamodel.
+ The `MetaModelService4` service (and its various supertypes) provides access to a number of aspects of Apache Isis' internal metamodel.
  
  
 -
  == API
  
  
@@@ -48,9 -57,9 +56,8 @@@ If an `AppManifest2` was used (from a `
  
  The framework provides a default implementation of this service, `o.a.i.c.m.services.metamodel.MetaModelServiceDefault`.
  
- To use an alternative implementation, implement the `MetamodelService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
  
  
 -
  == Related Services
  
  The `MetaModelServiceMenu` provides a method to download all domain members as a CSV.  Internally
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_ServiceRegistry.adoc
index ceee9e7,c8bc229..f4820d2
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_ServiceRegistry.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_metadata-api_ServiceRegistry.adoc
@@@ -5,8 -5,12 +5,8 @@@
  :_imagesdir: images/
  
  
- The `ServiceRegistry` service collects together methods for injecting or looking up domain services (either provided by the framework or application-specific) currently known to the runtime.
+ The `ServiceRegistry2` domain service (and its various supertypes)collects together methods for injecting or looking up domain services (either provided by the framework or application-specific) currently known to the runtime.
  
 -[NOTE]
 -====
 -The methods in this service replace similar methods (now deprecated) in xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_DomainObjectContainer[`DomainObjectContainer`].
 -====
  
  
  == API
@@@ -54,5 -58,6 +54,4 @@@ The alternative is to use the xref:../r
  
  The core framework provides a default implementation of this service (`o.a.i.core.runtime.services.registry.ServiceRegistryDefault`).
  
- To use an alternative implementation, implement the `ServiceRegistry` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
  
 -
 -
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_RepositoryService.adoc
index 36b8e68,51236d1..0b4633f
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_RepositoryService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-api_RepositoryService.adoc
@@@ -76,9 -96,11 +91,11 @@@ cust.setLastName("Mercury")
  repositoryService.persist(cust);
  ----
  
- You should be aware that by default Apache Isis queues up calls to `#persist()` and `#remove()`.  These are then executed either when the request completes (and the transaction commits), or if the queue is flushed.  This can be done either implicitly by the framework, or as the result of a direct call to `#flush()`.
+ You should be aware that by default Apache Isis queues up calls to `#persist()` and `#remove()`.
+ These are then executed either when the request completes (and the transaction commits), or if the queue is flushed.
+ This can be done either implicitly by the framework, or as the result of a direct call to `#flush()`.
  
 -By default the framework itself will cause `#flush()` to be called whenever a query is executed by way of `#allMatches(Query)`, as documented xref:../rgsvc/rgsvc.adoc#_rgsvc_core-domain-api_DomainObjectContainer_generic-repository-api[above].
 +By default the framework itself will cause `#flush()` to be called whenever a query is executed by way of `#allMatches(Query)`.
  However, this behaviour can be disabled using the  xref:../rgcfg/rgcfg.adoc#_rgcfg_configuring-core[configuration property] `isis.services.container.disableAutoFlush`.
  
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_AuditerService.adoc
index 5629624,3b66a78..3444220
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_AuditerService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_AuditerService.adoc
@@@ -83,19 -88,20 +88,21 @@@ audit entries that occurred in a given 
  another audit entry is displayed.
  
  
 +These services can be activated by updating the `pom.xml` and updating the `AppManifest#getModules()` method.
  
 +If menu items or contributions are not required in the UI, these can be suppressed either using security or by implementing a xref:../ugbtb/ugbtb.adoc#_ugbtb_hints-and-tips_vetoing-visibility[vetoing subscriber].
  
 -== Usage
  
 -The typical way to indicate that an object should be audited is to annotate it with the xref:../rgant/rgant.adoc#_rgant-DomainObject_auditing[`@DomainObject#auditing()`] annotation.
  
 +== Usage
  
 +The typical way to indicate that an object should be audited is to annotate it with the xref:../rgant/rgant.adoc#_rgant-DomainObject_auditing[`@DomainObject#auditing()`] annotation.
  
  
+ == Alternative Implementations
  
 -The (non-ASF) link:http://platform.incode.org[Incode Platform^]'s audit module provides an implementation of this service (`AuditerService`), and also provides a number of related domain services (`AuditingServiceMenu`, `AuditingServiceRepository` and `AuditingServiceContributions`).
  
+ If menu items or contributions are not required in the UI, these can be suppressed either using security or by implementing a xref:../ugbtb/ugbtb.adoc#_ugbtb_hints-and-tips_vetoing-visibility[vetoing subscriber].
  
  
  
@@@ -107,10 -113,10 +114,6 @@@ obtained from the xref:../rgsvc/rgsvc.a
  execution captures the _cause_ of an interaction (an action was invoked, a property was edited), while the
  `AuditerService` audit entries capture the _effect_ of that interaction in terms of changed state.
  
- [NOTE]
- ====
- Prior to `1.13.0` the xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_CommandService[`CommandService`] performed a similar role,
- of capturing the cause.  As of `1.13.0`, ``Command``s are now primarily to capture the _intent_ of an action,
- not the actual action invocation itself.
- ====
+ The xref:../rgsvc/rgsvc.adoc#_rgsvc_application-layer-spi_CommandService[`CommandService`] can also be combined with the auditer service, however
+ ``Command``s are primarily concerned with capture the _intent_ of an action, not the actual action invocation itself.
  
 -The `AuditerService` is intended to replace the (now-deprecated)
 -xref:../rgsvc/rgsvc.adoc#_rgsvc_persistence-layer-spi_AuditingService3[`AuditingService3`], as the latter does not support the concept of multiple
 -transactions within a single interaction.
 -
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_PublisherService.adoc
index 9ffc5e3,84b5e49..815310e
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_PublisherService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_persistence-layer-spi_PublisherService.adoc
@@@ -116,7 -106,12 +116,10 @@@ To indicate that a changed object shoul
  
  
  
+ == Alternative Implementations
+ 
+ The (non-ASF) link:http://platform.incode.org[Incode Platform^];s publishmq module provides an implementation of this service.
  
 -The module also provide services that contribute to the UI.
 -If contributions are not required in the UI, these can be suppressed either using security or by implementing a xref:../ugbtb/ugbtb.adoc#_ugbtb_hints-and-tips_vetoing-visibility[vetoing subscriber].
  
  
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-api_DeepLinkService.adoc
index 7797f2f,1e7a7ef..a272dbb
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-api_DeepLinkService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-api_DeepLinkService.adoc
@@@ -35,11 -36,4 +36,3 @@@ The xref:../rgsvc/rgsvc.adoc#_rgsvc_pre
  
  
  
- == Implementations
- 
- The Wicket viewer core framework provides a default implementation of this API:
- 
- * `org.apache.isis.viewer.wicket.viewer.services.DeepLinkServiceWicket`
- 
--
- To use an alternative implementation, implement the `DeepLinkService` interface use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_EmailNotificationService.adoc
index 53e3d8b,b53479a..5c52319
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_EmailNotificationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_EmailNotificationService.adoc
@@@ -55,13 -55,12 +55,9 @@@ If you wish to write an alternative imp
  This implies a couple of additional constraints:
  
  * first, implementation class should also be annotated with `@com.google.inject.Singleton`
 -* second, there may not be any Apache Isis session running. (If necessary, one can be created on the fly using `IsisContext.doInSession(...)`)
 -
 -To ensure that your alternative implementation takes the place of the default implementation, register it explicitly in `isis.properties`.
 -
  
 +* second, there may not be any Apache Isis session running. (If necessary, one can be created on the fly using `IsisContext.doInSession(...)`)
  
- To use an alternative implementation, implement the `EmailNotificationService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
- 
- 
- 
  
  == Related Services
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_ExceptionRecognizer.adoc
index 3308d43,357ded8..fbb1d0c
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_ExceptionRecognizer.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_ExceptionRecognizer.adoc
@@@ -89,9 -89,46 +89,47 @@@ The framework provides two default impl
  ** `ExceptionRecognizerForJDODataStoreException`
  
  
 -If you want to recognize and handle additional exceptions (for example to capture error messages specific to the JDBC driver you might be using), then create a fine-grained implementation of `ExceptionRecognizer2` for the particular error message (there are some convenience implementations of the interface that you can subclass from if required) and register in `isis.properties`.
 +If you want to recognize and handle additional exceptions (for example to capture error messages specific to the JDBC driver you might be using), then create a fine-grained implementation of `ExceptionRecognizer` for the particular error message (there are some convenience implementations of the interface that you can subclass from if required) and annotated with `@DomainService` in the usual way.
 +Make sure that the service resides under a module registered in `AppManifest`.
  
  
- If the JDO exception recognizers are not required (rather unlikely), then they can be disabled en-masse using the xref:../rgcfg/rgcfg.adoc#_rgcfg_configuring-core[configuration property] `isis.services.ExceptionRecognizerCompositeForJdoObjectStore.disable`.
+ 
+ === Configuration Properties
+ 
+ The following configuration properties are relevant:
+ 
+ [cols="2a,1,3a", options="header"]
+ |===
+ |Property
+ |Value +
+ (default value)
+ |Description
+ 
+ | `isis.services.` +
+ `exceprecog.` +
+ `logRecognized` +
+ `Exceptions` +
+ |`true`,`false` +
+ (`false`)
+ |whether recognized exceptions should also be logged. +
+ 
+ Generally a recognized exception is one that is expected (for example a uniqueness constraint violated in the database) and which does not represent an error condition.
+ This property logs the exception anyway, useful for debugging.
+ 
+ This is recognised by all implementations that subclass `ExceptionRecognizerAbstract`.
+ 
+ | `isis.services.` +
+ `ExceptionRecognizer` +
+ `CompositeFor` +
+ `JdoObjectStore.` +
+ `disable` +
+ |`true`,`false` +
+ (`false`)
+ |whether to disable the default recognizers registered by `ExceptionRecognizerCompositeForJdoObjectStore`. +
+ 
+ This implementation provides a default set of recognizers to convert RDBMS constraints into user-friendly messages.
+ In the (probably remote) chance that this functionality isn't required, they can be disabled through this flag.
+ 
+ 
+ |===
  
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TableColumnOrderService.adoc
index 6405299,36c7b55..18b187e
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TableColumnOrderService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TableColumnOrderService.adoc
@@@ -39,16 -39,4 +39,9 @@@ If all provided implementations return 
  
  The framework provides a fallback implementation of this service, namely `TableColumnOrderService.Default`.
  
 +There can be multiple implementations of `TableColumnOrderService registered.
 +These are checked in turn (chain of responsibility pattern), ordered according to xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
 +The order from the first service that returns a non null value will be used.
 +
 +
  
- == Registering the Services
- 
- Assuming that the `configuration-and-annotation` services installer is configured (implicit if using the
- `AppManifest` to xref:../rgcms/rgcms.adoc#_rgcms_classes_AppManifest-bootstrapping[bootstrap the app]), then the
-  default implementation of `TableColumnOrderService` is automatically registered and injected, and no further
-  configuration is required.
- 
diff --cc adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TranslationService.adoc
index f2ed5d0,eeba5d9..a846227
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TranslationService.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_presentation-layer-spi_TranslationService.adoc
@@@ -57,10 -58,27 +59,28 @@@ If the menu items are not required the
  For more details on the implementation, see xref:../ugbtb/ugbtb.adoc#_ugbtb_i18n[i18n support].
  
  
 +If the menu items are not required then these can be suppressed either using security or by implementing a xref:../ugbtb/ugbtb.adoc#_ugbtb_hints-and-tips_vetoing-visibility[vetoing subscriber].
  
- To use an alternative implementation, implement the `TranslationService` interface and use xref:../rgant/rgant.adoc#_rgant-DomainServiceLayout_menuOrder[`@DomainServiceLayout#menuOrder()`] (as explained in the xref:../rgsvc/rgsvc.adoc#__rgsvc_intro_overriding-the-services[introduction] to this guide).
+ === Configuration Properties
+ 
+ The default implementation of this domain service recognises the following configuration properties:
+ 
+ [cols="2a,1,3a", options="header"]
+ |===
+ |Property
+ |Value +
+ (default value)
+ |Description
+ 
+ |`isis.services.` +
+ `translation.` +
+ `po.mode`
+ | `read`,`write`
+ |Whether to force the `TranslationService` into either read or write mode. +
+ 
+ See xref:../ugbtb/ugbtb.adoc#_ugbtb_i18n[i18n support] to learn more about the translation service.
  
+ |===
  
  
  
diff --cc adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_extending_replacing-page-elements.adoc
index 39fe361,3a98738..56e1b9d
--- a/adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_extending_replacing-page-elements.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/ugvw/_ugvw_extending_replacing-page-elements.adoc
@@@ -122,11 -132,14 +132,13 @@@ public class MyAppApplication extends I
  [[__ugvw_extending_replacing-page-elements_collections]]
  == Additional Views of Collections
  
- As explained above, in most cases Apache Isis' Wicket viewer will search for the first `ComponentFactory` that can render an element, and use it. In the case of (either standalone or parented) collections, though, Apache Isis will show all available views.
+ As explained above, in most cases Apache Isis' Wicket viewer will search for the first `ComponentFactory` that can render an element, and use it.
+ In the case of (either standalone or parented) collections, though, Apache Isis will show all available views.
  
 -For example, out-of-the-box Apache Isis provides a table view, a summary view (totals/sums/averages of any data), and a collapsed view (for `@Render(LAZILY)` collections).
 -These are selected by clicking on the toolbar by each collection.
 +For example, out-of-the-box Apache Isis provides a table view, a summary view (totals/sums/averages of any data), and a collapsed view. These are selected by clicking on the toolbar by each collection.
  
- Additional views though could render the objects in the collection as a variety of ways. Indeed, some third-party implementations in the (non-ASF) link:http://platform.incode.org[Incode Platform^] already exist, including:
+ Additional views though could render the objects in the collection as a variety of ways.
+ Indeed, some third-party implementations in the (non-ASF) link:http://platform.incode.org[Incode Platform^] already exist, including:
  
  * excel component - collection as a downloadable excel spreadsheet
  * gmap3 component - render any objects with a location on a map
diff --cc core/applib/src/main/java/org/apache/isis/applib/fixturescripts/BuilderScriptAbstract.java
index 0000000,addc6cf..d4bf129
mode 000000,100644..100644
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/BuilderScriptAbstract.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/BuilderScriptAbstract.java
@@@ -1,0 -1,103 +1,103 @@@
+ /*
+  *  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.fixturescripts;
+ 
+ import java.util.List;
+ 
+ import com.google.common.collect.Lists;
+ 
+ import org.apache.isis.applib.annotation.Programmatic;
+ 
+ public abstract class BuilderScriptAbstract<T,F extends BuilderScriptAbstract<T,F>>
+         extends FixtureScript implements WithPrereqs<T,F>, FixtureScriptWithExecutionStrategy {
+ 
+     private final FixtureScripts.MultipleExecutionStrategy executionStrategy;
+ 
+     /**
+      * Typically we expect builders to have value semantics, so this is provided as a convenience.
+      */
+     protected BuilderScriptAbstract() {
+         this(FixtureScripts.MultipleExecutionStrategy.EXECUTE_ONCE_BY_VALUE);
+     }
+ 
+     protected BuilderScriptAbstract(final FixtureScripts.MultipleExecutionStrategy executionStrategy) {
+         this.executionStrategy = executionStrategy;
+     }
+ 
+     @Override
+     public FixtureScripts.MultipleExecutionStrategy getMultipleExecutionStrategy() {
+         return executionStrategy;
+     }
+ 
+     @Programmatic
+     public F build(
+             final FixtureScript parentFixtureScript,
+             ExecutionContext executionContext) {
+ 
+         final F onFixture = (F) BuilderScriptAbstract.this;
 -        parentFixtureScript.container.injectServicesInto(onFixture);
++        parentFixtureScript.serviceRegistry.injectServicesInto(onFixture);
+ 
+         execPrereqs(executionContext);
+ 
+         // returns the fixture script that is run
+         // (either this one, or possibly one previously executed).
+         return (F)executionContext.executeChildT(parentFixtureScript, this);
+     }
+ 
+     @Override
+     public void execPrereqs(final ExecutionContext executionContext) {
+         final F onFixture = (F) BuilderScriptAbstract.this;
+         for (final WithPrereqs.Block<T,F> prereq : prereqs) {
+             prereq.execute(onFixture, executionContext);
+         }
+     }
+ 
+     @Override
+     protected abstract void execute(final ExecutionContext executionContext);
+ 
+     public abstract T getObject();
+ 
+     public <P extends PersonaWithBuilderScript<T, F>, T, F extends BuilderScriptAbstract<T,F>> T objectFor(
+             final P persona,
+             final FixtureScript.ExecutionContext ec) {
+         if(persona == null) {
+             return null;
+         }
+         final F fixtureScript = persona.builder();
+         return ec.executeChildT(this, fixtureScript).getObject();
+     }
+ 
+     public <P extends PersonaWithFinder<T>, T> T findUsing(final P persona) {
+         if(persona == null) {
+             return null;
+         }
+         return persona.findUsing(serviceRegistry);
+     }
+ 
+     private final List<WithPrereqs.Block<T,F>> prereqs = Lists.newArrayList();
+ 
+     @Override
+     public F setPrereq(WithPrereqs.Block<T,F> prereq) {
+         prereqs.add(prereq);
+         return (F)this;
+     }
+ 
+ 
+ }
+ 
diff --cc core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
index e4e1316,a9b9725..779ade8
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScript.java
@@@ -541,23 -625,103 +590,92 @@@ public abstract class FixtureScrip
              if(localNameOverride != null) {
                  childFixtureScript.setLocalName(localNameOverride);
              }
 -            callingFixtureScript.getContainer().injectServicesInto(childFixtureScript);
 +            callingFixtureScript.serviceRegistry.injectServicesInto(childFixtureScript);
  
-             executeChildIfNotAlready(childFixtureScript);
+             final T childOrPreviouslyExecuted = executeChildIfNotAlready(childFixtureScript);
  
-             return childFixtureScript;
+             return childOrPreviouslyExecuted;
          }
  
  
          static enum As { EXEC, SKIP }
  
 -        /**
 -         * DO <i>NOT</i> CALL DIRECTLY; instead use {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(org.apache.isis.applib.fixturescripts.FixtureScript, String, org.apache.isis.applib.fixturescripts.FixtureScript)} or {@link org.apache.isis.applib.fixturescripts.FixtureScript.ExecutionContext#executeChild(FixtureScript, FixtureScript)}.
 -         *
 -         * @deprecated - should not be called directly, but has <code>public</code> visibility so there is scope for confusion.  Replaced by method with private visibility.
 -         */
 -        @Deprecated
 -        @Programmatic
 -        public void executeIfNotAlready(final FixtureScript fixtureScript) {
 -            executeChildIfNotAlready(fixtureScript);
 -        }
  
-         private void executeChildIfNotAlready(final FixtureScript fixtureScript) {
-             if(shouldExecute(fixtureScript)) {
-                 trace(fixtureScript, As.EXEC);
-                 fixtureScript.execute(this);
+         private <T extends FixtureScript> T executeChildIfNotAlready(final T childFixtureScript) {
+ 
+             final FixtureScripts.MultipleExecutionStrategy executionStrategy =
+                     determineExecutionStrategy(childFixtureScript);
+ 
+             FixtureScript previouslyExecutedScript;
+             switch (executionStrategy) {
+ 
 -            case IGNORE:
+             case EXECUTE_ONCE_BY_CLASS:
+                 previouslyExecutedScript = fixtureScriptByClass.get(childFixtureScript.getClass());
+                 if (previouslyExecutedScript == null) {
+                     if (childFixtureScript instanceof WithPrereqs) {
+                         final WithPrereqs withPrereqs = (WithPrereqs) childFixtureScript;
+                         withPrereqs.execPrereqs(this);
+                     }
+                 }
+                 // the prereqs might now result in a match, so we check again.
+                 previouslyExecutedScript = fixtureScriptByClass.get(childFixtureScript.getClass());
+                 if (previouslyExecutedScript == null) {
+                     trace(childFixtureScript, As.EXEC);
+                     childFixtureScript.execute(this);
+                     this.previouslyExecuted.add(childFixtureScript);
+                     fixtureScriptByClass.put(childFixtureScript.getClass(), childFixtureScript);
+                     return childFixtureScript;
+                 } else {
+                     trace(childFixtureScript, As.SKIP);
+                     return (T)previouslyExecutedScript;
+                 }
+ 
+             case EXECUTE_ONCE_BY_VALUE:
+                 return executeChildIfNotAlreadyWithValueSemantics(childFixtureScript);
+ 
+             case EXECUTE:
+                 trace(childFixtureScript, As.EXEC);
+                 childFixtureScript.execute(this);
+                 this.previouslyExecuted.add(childFixtureScript);
+                 return childFixtureScript;
+ 
+             default:
+                 throw new IllegalArgumentException("Execution strategy: '" + executionStrategy + "' not recognized");
+             }
+         }
+ 
+         private <T extends FixtureScript> FixtureScripts.MultipleExecutionStrategy determineExecutionStrategy(final T childFixtureScript) {
+             final FixtureScripts.MultipleExecutionStrategy executionStrategy;
+ 
+             if(childFixtureScript instanceof FixtureScriptWithExecutionStrategy) {
+                 final FixtureScriptWithExecutionStrategy fixtureScriptWithExecutionStrategy =
+                         (FixtureScriptWithExecutionStrategy) childFixtureScript;
+                 executionStrategy = fixtureScriptWithExecutionStrategy.getMultipleExecutionStrategy();
              } else {
-                 trace(fixtureScript, As.SKIP);
+                 executionStrategy = fixtureScripts.getMultipleExecutionStrategy();
+             }
+             return executionStrategy;
+         }
+ 
+         private <T extends FixtureScript> T executeChildIfNotAlreadyWithValueSemantics(final T childFixtureScript) {
+             FixtureScript previouslyExecutedScript = fixtureScriptByValue.get(childFixtureScript);
+             if (previouslyExecutedScript == null) {
+                 if (childFixtureScript instanceof WithPrereqs) {
+                     final WithPrereqs withPrereqs = (WithPrereqs) childFixtureScript;
+                     withPrereqs.execPrereqs(this);
+                 }
+             }
+             // the prereqs might now result in a match, so we check again.
+             previouslyExecutedScript = fixtureScriptByValue.get(childFixtureScript);
+             if (previouslyExecutedScript == null) {
+                 trace(childFixtureScript, As.EXEC);
+                 childFixtureScript.execute(this);
+                 this.previouslyExecuted.add(childFixtureScript);
+                 fixtureScriptByValue.put(childFixtureScript, childFixtureScript);
+                 return childFixtureScript;
+             } else {
+                 trace(childFixtureScript, As.SKIP);
+                 return (T)previouslyExecutedScript;
              }
          }
  
diff --cc core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
index 50b9708,4c051d5..a3dde31
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/FixtureScripts.java
@@@ -53,6 -51,6 +54,7 @@@ import org.apache.isis.applib.services.
  import org.apache.isis.applib.services.xactn.TransactionService;
  import org.apache.isis.applib.util.ObjectContracts;
  
++
  /**
   * Rather than subclassing, instead implement
   * {@link org.apache.isis.applib.services.fixturespec.FixtureScriptsSpecificationProvider}.  The framework will
@@@ -274,9 -362,26 +275,27 @@@ public abstract class FixtureScripts ex
          }
      }
  
 +
      //endregion
  
+     //region > fixtureTracing (thread-local)
+ 
+     private final ThreadLocal<PrintStream> fixtureTracing = new ThreadLocal<PrintStream>(){{
+         set(System.out);
+     }};
+ 
+     @Programmatic
+     public PrintStream getFixtureTracing() {
+         return fixtureTracing.get();
+     }
+ 
+     @Programmatic
+     public void setFixtureTracing(PrintStream fixtureTracing) {
+         this.fixtureTracing.set(fixtureTracing);
+     }
+ 
+     //endregion
+ 
      //region > runFixtureScript (prototype action)
  
      /**
@@@ -440,23 -566,17 +491,22 @@@
      MementoService mementoService;
  
      @javax.inject.Inject
 -    TransactionService transactionService;
 +    BookmarkService bookmarkService;
  
      @javax.inject.Inject
 -    ClassDiscoveryService classDiscoveryService;
 +    ServiceRegistry serviceRegistry;
  
      @javax.inject.Inject
 -    ExecutionParametersService executionParametersService;
 +    RepositoryService repositoryService;
  
      @javax.inject.Inject
 -    ServiceRegistry2 serviceRegistry;
 +    TransactionService transactionService;
 +
 +    @javax.inject.Inject
 +    ClassDiscoveryService classDiscoveryService;
  
 +    @javax.inject.Inject
 +    ExecutionParametersService executionParametersService;
- 
      //endregion
  
  }
diff --cc core/applib/src/main/java/org/apache/isis/applib/fixturescripts/PersonaWithFinder.java
index 54d1cd1,95d97d7..d32e749
--- a/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/PersonaWithFinder.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/fixturescripts/PersonaWithFinder.java
@@@ -16,9 -16,13 +16,13 @@@
   *  specific language governing permissions and limitations
   *  under the License.
   */
+ package org.apache.isis.applib.fixturescripts;
  
- package org.apache.isis.applib.services.registry;
 -import org.apache.isis.applib.services.registry.ServiceRegistry2;
++import org.apache.isis.applib.services.registry.ServiceRegistry;
  
- public interface ServiceRegistry2 extends ServiceRegistry {
+ public interface PersonaWithFinder<T> {
+ 
 -    T findUsing(final ServiceRegistry2 serviceRegistry);
++    T findUsing(final ServiceRegistry serviceRegistry);
  
  }
+ 
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_openRestApi.java
index 0000000,e4e203b..1c4e1ef
mode 000000,100644..100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_openRestApi.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/layout/Object_openRestApi.java
@@@ -1,0 -1,64 +1,64 @@@
+ /**
+  *  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.services.layout;
+ 
+ import java.net.MalformedURLException;
+ 
+ import org.apache.isis.applib.annotation.Action;
+ import org.apache.isis.applib.annotation.ActionLayout;
+ import org.apache.isis.applib.annotation.Contributed;
+ import org.apache.isis.applib.annotation.MemberOrder;
+ import org.apache.isis.applib.annotation.Mixin;
+ import org.apache.isis.applib.annotation.RestrictTo;
+ import org.apache.isis.applib.annotation.SemanticsOf;
+ import org.apache.isis.applib.services.bookmark.Bookmark;
 -import org.apache.isis.applib.services.bookmark.BookmarkService2;
++import org.apache.isis.applib.services.bookmark.BookmarkService;
+ 
+ @Mixin(method="act")
+ public class Object_openRestApi {
+ 
+     private final Object object;
+ 
+     public Object_openRestApi(final Object object) {
+         this.object = object;
+     }
+ 
+     public static class ActionDomainEvent extends org.apache.isis.applib.IsisApplibModule.ActionDomainEvent<Object_openRestApi> {}
+ 
+     @Action(
+             domainEvent = ActionDomainEvent.class,
+             semantics = SemanticsOf.SAFE,
+             restrictTo = RestrictTo.PROTOTYPING
+     )
+     @ActionLayout(
+             contributed = Contributed.AS_ACTION,
+             cssClassFa = "fa-external-link",
+             position = ActionLayout.Position.PANEL_DROPDOWN
+     )
+     @MemberOrder(name = "datanucleusIdLong", sequence = "750.1")
+     public java.net.URL act() throws MalformedURLException {
 -        Bookmark bookmark = bookmarkService2.bookmarkFor(object);
++        Bookmark bookmark = bookmarkService.bookmarkFor(object);
+         return new java.net.URL(String.format(
+                 "http:///restful/objects/%s/%s",
+                 bookmark.getObjectType(),
+                 bookmark.getIdentifier()));
+     }
+ 
+     @javax.inject.Inject
 -    BookmarkService2 bookmarkService2;
++    BookmarkService bookmarkService;
+ 
+ }
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
index 3150f8e,3263ba7..589b602
--- a/core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/metamodel/MetaModelService.java
@@@ -20,9 -20,8 +20,11 @@@ package org.apache.isis.applib.services
  
  import java.util.List;
  
++import org.apache.isis.applib.AppManifest;
++import org.apache.isis.applib.AppManifest2;
  import org.apache.isis.applib.annotation.DomainObject;
  import org.apache.isis.applib.annotation.Programmatic;
 +import org.apache.isis.applib.services.bookmark.Bookmark;
  
  /**
   * This service provides a formal API into Isis' metamodel.
@@@ -59,73 -58,5 +61,87 @@@ public interface MetaModelService 
      @Programmatic
      List<DomainMember> export();
  
 +    /**
 +     * @deprecated - use {@link #sortOf(Class, MetaModelService.Mode)}
 +     */
 +    @Deprecated
 +    @Programmatic
 +    Sort sortOf(Class<?> domainType);
 +
 +    /**
 +     * @deprecated - use {@link #sortOf(Bookmark, MetaModelService.Mode)}
 +     */
 +    @Deprecated
 +    @Programmatic
 +    Sort sortOf(Bookmark bookmark);
 +
 +    @Programmatic
 +    Sort sortOf(Class<?> domainType, Mode mode);
 +
 +    @Programmatic
 +    Sort sortOf(Bookmark bookmark, Mode mode);
 +
 +    enum Sort {
 +        VIEW_MODEL,
 +        JDO_ENTITY,
 +        DOMAIN_SERVICE,
 +        MIXIN,
 +        VALUE,
 +        COLLECTION,
 +        UNKNOWN;
 +
 +        public boolean isDomainService() {
 +            return this == DOMAIN_SERVICE;
 +        }
 +
 +        public boolean isMixin() {
 +            return this == MIXIN;
 +        }
 +
 +        public boolean isViewModel() {
 +            return this == VIEW_MODEL;
 +        }
 +
 +        public boolean isValue() {
 +            return this == VALUE;
 +        }
 +
 +        public boolean isCollection() {
 +            return this == COLLECTION;
 +        }
 +
 +        public boolean isJdoEntity() {
 +            return this == JDO_ENTITY;
 +        }
 +
 +        public boolean isUnknown() {
 +            return this == UNKNOWN;
 +        }
 +
 +    }
 +
 +    enum Mode {
 +        /**
 +         * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then throw an exception.
 +         */
 +        STRICT,
 +        /**
 +         * If the {@link #sortOf(Class, Mode) sort of} object type is unknown, then return {@link Sort#UNKNOWN}.
 +         */
 +        RELAXED
 +    }
++
++    /**
++     * @return as {@link #getAppManifest()}, downcasted (else null).
++     */
++    @Programmatic
++    AppManifest2 getAppManifest2();
++
++    /**
++     * @return the {@link AppManifest} used to bootstrap the application.
++     */
++    @Programmatic
++    AppManifest getAppManifest();
++
+ 
  }
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java
index d95a044,d3dc95a..a9857ab
--- a/core/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/xactn/Transaction.java
@@@ -60,4 -65,4 +65,7 @@@ public interface Transaction extends Ha
      @Programmatic
      void clearAbortCause();
  
++    @Programmatic
++    TransactionState getTransactionState();
++
  }
diff --cc core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
index fa4a9e0,42380a6..8631686
--- a/core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/xactn/TransactionService.java
@@@ -39,7 -39,7 +39,7 @@@ public interface TransactionService 
      void flushTransaction();
  
      /**
-      * Intended only for use by fixture scripts and integration tests; commits this transaction and starts a new one.
 -     * See also {@link TransactionService3#nextTransaction(TransactionService3.Policy)} with a {@link TransactionService3.Policy} of {@link TransactionService3.Policy#UNLESS_MARKED_FOR_ABORT}.
++     * See also {@link TransactionService#nextTransaction(TransactionService.Policy)} with a {@link TransactionService.Policy} of {@link TransactionService.Policy#UNLESS_MARKED_FOR_ABORT}.
       */
      @Programmatic
      void nextTransaction();
@@@ -50,4 -50,4 +50,54 @@@
      @Programmatic
      Transaction currentTransaction();
  
++    /**
++     * Generally this is equivalent to using {@link #currentTransaction()} and {@link Transaction#getTransactionState()}.
++     * However, if there is no current transaction, then this will return {@link TransactionState#NONE}.
++     */
++    @Programmatic
++    TransactionState getTransactionState();
++
++
++    /**
++     * Intended only for use by fixture scripts and integration tests.
++     *
++     * <p>
++     *     The behaviour depends on the current state of the transaction, and the specified policy.
++     *     <ul>
++     *         <li>
++     *              If the current transaction is in that it is still in progress, then commits and starts a new one.
++     *         </li>
++     *         <li>
++     *              If the current transaction is complete, in that it is already committed or was rolled back, then simply starts a new one.
++     *         </li>
++     *         <li>
++     *              If the current transaction is marked for abort, then depends on the provided policy:
++     *              <ul>
++     *                  <li>
++     *                      If set to {@link Policy#ALWAYS always}, then rolls back and starts a new transaction
++     *                  </li>
++     *                  <li>
++     *                      But if set to {@link Policy#UNLESS_MARKED_FOR_ABORT marked for abort}, then fails fast by throwing a runtime exception.
++     *                  </li>
++     *              </ul>
++     *         </li>
++     *
++     *     </ul>
++     *     If the current transaction has been marked for abort only, then depends on the provided rolls it back, and (again) starts a new one.
++     * </p>
++     *
++     * <p>
++     *     This is a refinement of the {@link TransactionService#nextTransaction()}, introduced in
++     *     order to improve the error handling of that method in the case of an already must-abort transaction, and
++     *     also to allow the caller to have more control on how to continue.
++     * </p>
++     */
++    @Programmatic
++    void nextTransaction(Policy policy);
++
++    public enum Policy {
++        UNLESS_MARKED_FOR_ABORT,
++        ALWAYS
++    }
++
  }
diff --cc core/applib/src/main/java/org/apache/isis/applib/util/ObjectContracts.java
index c4160fe,e53696c..0c55ff1
--- a/core/applib/src/main/java/org/apache/isis/applib/util/ObjectContracts.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/util/ObjectContracts.java
@@@ -64,6 -59,6 +60,13 @@@ public class ObjectContracts 
      }
  
      private static <T> int compare(final T p, final T q, final Iterable<String> propertyNamesIter) {
++        if(p == null) { return -1;}
++        if(q == null) { return +1;}
++        if(p.getClass() != q.getClass()) {
++            // just sort on the class type
++            return Ordering.natural().onResultOf((Function<Object, String>) o -> o.getClass().getSimpleName()).compare(p, q);
++        }
++
          final Iterable<Clause> clauses = clausesFor(propertyNamesIter);
          ComparisonChain chain = ComparisonChain.start();
          for (final Clause clause : clauses) {
@@@ -84,12 -79,12 +87,7 @@@
      @Deprecated
      @SuppressWarnings("unchecked")
      public static <T> Comparator<T> compareBy(final String propertyNames){
--        return new Comparator<T>() {
--            @Override
--            public int compare(T p, T q) {
--                return ObjectContracts.compare(p, q, propertyNames);
--            }
--        };
++        return (p, q) -> compare(p, q, propertyNames);
      }
      /**
       * Returns a {@link Comparator} to evaluate objects by their property name(s).
@@@ -98,12 -93,12 +96,7 @@@
      @Deprecated
      @SuppressWarnings("unchecked")
      public static <T> Comparator<T> compareBy(final String... propertyNames){
--        return new Comparator<T>() {
--            @Override
--            public int compare(T p, T q) {
--                return ObjectContracts.compare(p, q, propertyNames);
--            }
--        };
++        return (p, q) -> compare(p, q, propertyNames);
      }
      //endregion
  
@@@ -218,12 -213,12 +211,7 @@@
  
      //region > helpers
      private static Iterable<Clause> clausesFor(final Iterable<String> iterable) {
--        return Iterables.transform(iterable, new Function<String, Clause>() {
--            @Override
--            public Clause apply(String input) {
--                return Clause.parse(input);
--            }
--        });
++        return Iterables.transform(iterable, Clause::parse);
      }
  
      private static Iterable<String> csvToIterable(final String propertyNames) {
diff --cc core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/IntegrationTestAbstract3.java
index 0000000,67394ad..f0a3066
mode 000000,100644..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
@@@ -1,0 -1,178 +1,179 @@@
+ /*
+  *  Licensed to the Apache Software Foundation (ASF) under one
+  *  or more contributor license agreements.  See the NOTICE file
+  *  distributed with this work for additional information
+  *  regarding copyright ownership.  The ASF licenses this file
+  *  to you under the Apache License, Version 2.0 (the
+  *  "License"); you may not use this file except in compliance
+  *  with the License.  You may obtain a copy of the License at
+  *
+  *        http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing,
+  *  software distributed under the License is distributed on an
+  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  *  specific language governing permissions and limitations
+  *  under the License.
+  */
+ package org.apache.isis.core.integtestsupport;
+ 
+ import java.util.List;
+ 
+ import com.google.common.base.Throwables;
+ 
+ import org.junit.After;
+ import org.junit.Before;
+ import org.junit.Rule;
+ import org.junit.rules.ExpectedException;
+ import org.junit.rules.MethodRule;
+ import org.junit.runners.model.FrameworkMethod;
+ import org.junit.runners.model.Statement;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.slf4j.event.Level;
+ 
+ import org.apache.isis.applib.AppManifest;
+ 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.applib.services.xactn.TransactionService;
+ 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 HeadlessWithBootstrappingAbstract {
+ 
+     private static final Logger LOG = LoggerFactory.getLogger(IntegrationTestAbstract3.class);
+ 
+     @Rule
+     public ExpectedException expectedExceptions = ExpectedException.none();
+ 
+     /**
+      * this is asymmetric - handles only the teardown of the transaction afterwards, not the initial set up
+      * (which is done instead by the @Before, so that can also bootstrap system the very first time)
+      */
+     @Rule
+     public IntegrationTestAbstract3.IsisTransactionRule isisTransactionRule = new IntegrationTestAbstract3.IsisTransactionRule();
+ 
+     private static class IsisTransactionRule implements MethodRule {
+ 
+         @Override
+         public Statement apply(final Statement base, final FrameworkMethod method, final Object target) {
+ 
+             return new Statement() {
+                 @Override
+                 public void evaluate() throws Throwable {
+ 
+                     // we don't set up the ISFT, because the very first time it won't be there.
+                     // Instead we expect it to be bootstrapped via @Before
+                     try {
+                         base.evaluate();
+                         final IsisSystem isft = IsisSystem.get();
+                         isft.endTran();
+                     } catch(final Throwable e) {
+                         // determine if underlying cause is an applib-defined exception,
+                         final RecoverableException recoverableException =
+                                 determineIfRecoverableException(e);
+                         final NonRecoverableException nonRecoverableException =
+                                 determineIfNonRecoverableException(e);
+ 
+                         if(recoverableException != null) {
+                             try {
+                                 final IsisSystem isft = IsisSystem.get();
 -                                isft.getContainer().flush(); // don't care if npe
++                                isft.getService(TransactionService.class).flushTransaction(); // don't care if npe
+                                 isft.getService(IsisJdoSupport.class).getJdoPersistenceManager().flush();
+                             } catch (Exception ignore) {
+                                 // ignore
+                             }
+                         }
+                         // attempt to close this
+                         try {
+                             final IsisSystem isft = IsisSystem.getElseNull();
+                             isft.closeSession(); // don't care if npe
+                         } catch(Exception ignore) {
+                             // ignore
+                         }
+ 
+                         // attempt to start another
+                         try {
+                             final IsisSystem isft = IsisSystem.getElseNull();
+                             isft.openSession(); // don't care if npe
+                         } catch(Exception ignore) {
+                             // ignore
+                         }
+ 
+ 
+                         // if underlying cause is an applib-defined, then
+                         // throw that rather than Isis' wrapper exception
+                         if(recoverableException != null) {
+                             throw recoverableException;
+                         }
+                         if(nonRecoverableException != null) {
+                             throw nonRecoverableException;
+                         }
+ 
+                         // report on the error that caused
+                         // a problem for *this* test
+                         throw e;
+                     }
+                 }
+ 
+                 NonRecoverableException determineIfNonRecoverableException(final Throwable e) {
+                     NonRecoverableException nonRecoverableException = null;
+                     final List<Throwable> causalChain2 = Throwables.getCausalChain(e);
+                     for (final Throwable cause : causalChain2) {
+                         if(cause instanceof NonRecoverableException) {
+                             nonRecoverableException = (NonRecoverableException) cause;
+                             break;
+                         }
+                     }
+                     return nonRecoverableException;
+                 }
+ 
+                 RecoverableException determineIfRecoverableException(final Throwable e) {
+                     RecoverableException recoverableException = null;
+                     final List<Throwable> causalChain = Throwables.getCausalChain(e);
+                     for (final Throwable cause : causalChain) {
+                         if(cause instanceof RecoverableException) {
+                             recoverableException = (RecoverableException) cause;
+                             break;
+                         }
+                     }
+                     return recoverableException;
+                 }
+             };
+         }
+     }
+ 
+ 
+     protected IntegrationTestAbstract3(final Module module) {
+         this(new LogConfig(Level.INFO), module);
+     }
+ 
+     protected IntegrationTestAbstract3(
+             final LogConfig logConfig,
+             final Module module) {
+         super(logConfig, module);
+     }
+ 
+     @Override
+     @Before
+     public void bootstrapAndSetupIfRequired() {
+ 
+         super.bootstrapAndSetupIfRequired();
+ 
+         log("### TEST: " + this.getClass().getCanonicalName());
+     }
+ 
+     @Override
+     @After
+     public void tearDownAllModules() {
+         super.tearDownAllModules();
+     }
+ 
+ }
diff --cc core/integtestsupport/src/main/java/org/apache/isis/core/integtestsupport/scenarios/ObjectFactoryForIntegration.java
index 0000000,dfe7364..c272afe
mode 000000,100644..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
@@@ -1,0 -1,75 +1,75 @@@
+ /*
+  *  Licensed to the Apache Software Foundation (ASF) under one
+  *  or more contributor license agreements.  See the NOTICE file
+  *  distributed with this work for additional information
+  *  regarding copyright ownership.  The ASF licenses this file
+  *  to you under the Apache License, Version 2.0 (the
+  *  "License"); you may not use this file except in compliance
+  *  with the License.  You may obtain a copy of the License at
+  *
+  *        http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing,
+  *  software distributed under the License is distributed on an
+  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  *  specific language governing permissions and limitations
+  *  under the License.
+  */
+ package org.apache.isis.core.integtestsupport.scenarios;
+ 
+ import java.lang.reflect.Constructor;
+ import java.util.Map;
+ 
+ import com.google.common.collect.Maps;
+ 
 -import org.apache.isis.applib.services.registry.ServiceRegistry2;
++import org.apache.isis.applib.services.registry.ServiceRegistry;
+ import org.apache.isis.core.runtime.headless.IsisSystem;
+ 
+ import cucumber.api.java.ObjectFactory;
+ import cucumber.runtime.CucumberException;
+ 
+ public class ObjectFactoryForIntegration implements ObjectFactory {
+     private final Map<Class<?>, Object> instances = Maps.newHashMap();
+ 
+     public void start() { }
+ 
+     public void stop() {
+         this.instances.clear();
+     }
+ 
+     public boolean addClass(Class<?> clazz) {
+         return true;
+     }
+ 
+     public <T> T getInstance(Class<T> type) {
+         T instance = type.cast(this.instances.get(type));
+         if (instance == null) {
+             instance = this.newInstance(type);
+             IsisSystem isisSystem = IsisSystem.getElseNull();
+             if(isisSystem != null) {
+                 instance = this.cacheInstance(type, instance);
 -                isisSystem.getService(ServiceRegistry2.class).injectServicesInto(instance);
++                isisSystem.getService(ServiceRegistry.class).injectServicesInto(instance);
+             } else {
+                 // don't cache
+             }
+         }
+         return instance;
+     }
+ 
+     private <T> T cacheInstance(Class<T> type, T instance) {
+         this.instances.put(type, instance);
+         return instance;
+     }
+ 
+     private <T> T newInstance(Class<T> type) {
+         try {
+             Constructor<T> constructor = type.getConstructor();
+             return constructor.newInstance();
+         } catch (NoSuchMethodException var4) {
+             throw new CucumberException(String.format("%s doesn't have an empty constructor.", type), var4);
+         } catch (Exception var5) {
+             throw new CucumberException(String.format("Failed to instantiate %s", type), var5);
+         }
+     }
+ }
diff --cc core/mavendeps/intellij/pom.xml
index d18a94c,17b36ca..78e9c14
--- a/core/mavendeps/intellij/pom.xml
+++ b/core/mavendeps/intellij/pom.xml
@@@ -24,7 -24,8 +24,8 @@@
  	<parent>
          <groupId>org.apache.isis.core</groupId>
          <artifactId>isis</artifactId>
 -        <version>1.16.0-SNAPSHOT</version>
 +        <version>2.0.0-SNAPSHOT</version>
+         <relativePath>../../pom.xml</relativePath>
      </parent>
  
      <groupId>org.apache.isis.mavendeps</groupId>
diff --cc core/mavendeps/testing/pom.xml
index 117bd2c,832e0d1..3dbb626
--- a/core/mavendeps/testing/pom.xml
+++ b/core/mavendeps/testing/pom.xml
@@@ -24,7 -24,8 +24,8 @@@
  	<parent>
          <groupId>org.apache.isis.core</groupId>
          <artifactId>isis</artifactId>
 -        <version>1.16.0-SNAPSHOT</version>
 +        <version>2.0.0-SNAPSHOT</version>
+         <relativePath>../../pom.xml</relativePath>
      </parent>
  
      <groupId>org.apache.isis.mavendeps</groupId>
diff --cc core/mavendeps/webapp/pom.xml
index e6392d0,22c1f6a..aa03e2e
--- a/core/mavendeps/webapp/pom.xml
+++ b/core/mavendeps/webapp/pom.xml
@@@ -24,7 -24,8 +24,8 @@@
      <parent>
          <groupId>org.apache.isis.core</groupId>
          <artifactId>isis</artifactId>
 -        <version>1.16.0-SNAPSHOT</version>
 +        <version>2.0.0-SNAPSHOT</version>
+         <relativePath>../../pom.xml</relativePath>
      </parent>
  
      <groupId>org.apache.isis.mavendeps</groupId>
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
index b04599e,1cc6c88..8518a6b
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/CollectionLayoutFacetFactory.java
@@@ -18,9 -18,8 +18,9 @@@
   */
  package org.apache.isis.core.metamodel.facets.collections.layout;
  
--
 +import java.util.List;
  import java.util.Properties;
++
  import org.apache.isis.applib.annotation.CollectionLayout;
  import org.apache.isis.core.metamodel.facetapi.FacetHolder;
  import org.apache.isis.core.metamodel.facetapi.FacetUtil;
@@@ -69,8 -81,10 +69,8 @@@ public class CollectionLayoutFacetFacto
  
  
          // defaultView
 -        DefaultViewFacet defaultViewFacet = DefaultViewFacetOnCollectionFromLayoutProperties.create(properties, holder);
 -        if(defaultViewFacet == null) {
 -            defaultViewFacet = DefaultViewFacetForCollectionLayoutAnnotation.create(collectionLayout, getConfiguration(), holder);
 -        }
 +        DefaultViewFacet defaultViewFacet =
-                 DefaultViewFacetForCollectionLayoutAnnotation.create(collectionLayouts, holder);
++                DefaultViewFacetForCollectionLayoutAnnotation.create(collectionLayouts, getConfiguration(), holder);
          FacetUtil.addFacet(defaultViewFacet);
          
  
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/DefaultViewFacetForCollectionLayoutAnnotation.java
index de17ed5,7d998f9..88109da
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/DefaultViewFacetForCollectionLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/collections/layout/DefaultViewFacetForCollectionLayoutAnnotation.java
@@@ -36,15 -35,15 +38,16 @@@ public class DefaultViewFacetForCollect
      }
  
      public static DefaultViewFacet create(
 -            final CollectionLayout collectionLayout,
 +            final List<CollectionLayout> collectionLayouts,
+             final IsisConfiguration configuration,
              final FacetHolder holder) {
  
-         return collectionLayouts.stream()
 -        String defaultView = Strings.emptyToNull(collectionLayout != null ? collectionLayout.defaultView() : null);
 -        if (defaultView == null) {
 -            final DefaultViewConfiguration setting = DefaultViewConfiguration.parse(configuration);
 -            defaultView = setting.getDefaultView();
 -        }
++        final String defaultView = collectionLayouts.stream()
 +                .map(CollectionLayout::defaultView)
 +                .map(Strings::emptyToNull)
 +                .filter(Objects::nonNull)
 +                .findFirst()
-                 .map(defaultView -> new DefaultViewFacetForCollectionLayoutAnnotation(defaultView, holder))
-                 .orElse(null);
++                .orElseGet(() -> DefaultViewConfiguration.parse(configuration).getDefaultView());
+         return new DefaultViewFacetForCollectionLayoutAnnotation(defaultView, holder);
      }
  }
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
index c5b2810,3a60287..a6c387f
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/DomainObjectAnnotationFacetFactory.java
@@@ -19,10 -19,7 +19,9 @@@
  package org.apache.isis.core.metamodel.facets.object.domainobject;
  
  import java.lang.reflect.Method;
- import java.util.Collection;
 +import java.util.List;
  import java.util.Map;
 +import java.util.stream.Collectors;
  
  import javax.annotation.PostConstruct;
  
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
index 3cf4cb8,17ce65d..c925650
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobject/recreatable/RecreatableObjectFacetForDomainObjectAnnotation.java
@@@ -42,45 -40,32 +42,33 @@@ public class RecreatableObjectFacetForD
              final FacetHolder holder,
              final PostConstructMethodCache postConstructMethodCache) {
  
 -        if(domainObject == null) {
 -            return null;
 -        }
 -
 -        final Nature nature = domainObject.nature();
 -        switch (nature)
 -        {
 -            case NOT_SPECIFIED:
 -            case JDO_ENTITY:
 -            case MIXIN:
 -                // not a recreatable object, so no facet
 -                return null;
 +        return domainObjects.stream()
 +                .map(DomainObject::nature)
 +                .map(nature -> {
 +                    switch (nature) {
 +                    case NOT_SPECIFIED:
 +                    case JDO_ENTITY:
 +                    case MIXIN:
 +                        // not a recreatable object, so no facet
 +                        return null;
  
 -            case VIEW_MODEL:
 -            case EXTERNAL_ENTITY:
 -            case INMEMORY_ENTITY:
 -                final ViewModelFacet existingFacet = holder.getFacet(ViewModelFacet.class);
 -                if (existingFacet != null) {
 -                    return null;
 -                }
 -                return new RecreatableObjectFacetForDomainObjectAnnotation(
 -                        holder,
 -                        specificationLoader, adapterManager, servicesInjector, postConstructMethodCache);
 -        }
 -        // shouldn't happen, the above switch should match all cases.
 -        throw new IllegalArgumentException("nature of '" + nature + "' not recognized");
 +                    case VIEW_MODEL:
++                    case EXTERNAL_ENTITY:
++                    case INMEMORY_ENTITY:
 +                        final ViewModelFacet existingFacet = holder.getFacet(ViewModelFacet.class);
 +                        if (existingFacet != null) {
-                             if (existingFacet.getArchitecturalLayer() == ArchitecturalLayer.APPLICATION) {
-                                 // if compatible existing facet, then just ignore
-                                 return null;
-                             }
-                             // otherwise, we continue through and add the new facet making the existing one the
-                             // underlying.  The metamodel validator on RecreatableObjectFacetFactory will then mark the
-                             // model as invalid because of incompatible semantics.
++                            return null;
 +                        }
 +                        return new RecreatableObjectFacetForDomainObjectAnnotation(
 +                                holder,
-                                 ArchitecturalLayer.APPLICATION,
-                                 specificationLoader, adapterManager, servicesInjector, postConstructMethodCache);
- 
-                     case EXTERNAL_ENTITY:
-                     case INMEMORY_ENTITY:
-                         return new RecreatableObjectFacetForDomainObjectAnnotation(
-                                 holder,
-                                 ArchitecturalLayer.DOMAIN,
 +                                specificationLoader, adapterManager, servicesInjector, postConstructMethodCache);
 +                    }
 +                    // shouldn't happen, the above switch should match all cases.
 +                    throw new IllegalArgumentException("nature of '" + nature + "' not recognized");
 +                })
 +                .filter(Objects::nonNull)
 +                .findFirst()
 +                .orElse(null);
      }
  
      private RecreatableObjectFacetForDomainObjectAnnotation(
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/CssClassFacetForDomainObjectLayoutAnnotation.java
index 1dd69a2,2de276b..faf558d
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/CssClassFacetForDomainObjectLayoutAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainobjectlayout/CssClassFacetForDomainObjectLayoutAnnotation.java
@@@ -28,14 -26,23 +29,25 @@@ import org.apache.isis.core.metamodel.f
  
  public class CssClassFacetForDomainObjectLayoutAnnotation extends CssClassFacetAbstract {
  
 -    public static CssClassFacet create(final DomainObjectLayout domainObjectLayout, final FacetHolder holder) {
 -        if (domainObjectLayout == null) {
 -            return null;
 -        }
 +    public static CssClassFacet create(final List<DomainObjectLayout> domainObjectLayouts, final FacetHolder holder) {
+         CssClassFacet facet = holder.getFacet(CssClassFacet.class);
+         // this is a bit hacky, explicitly checking whether a different implementation is already added.
+         // normally we would just re-order the list of facet factories in ProgrammingModelsFacetJava5, however in
+         // this case @DomainObjectLayout is responsible for two different variations of CssClassFacet, either as
+         // a result of the cssClass attribute, but also as a result of the cssClassUiEvent.  The former has lower
+         // "priority" to the cssClass() method, but the latter has *higher* priority.  Hence the special casing
+         // that is required here.
+         if(facet != null && facet instanceof CssClassFacetMethod) {
+             // don't overwrite
+             return null;
+         }
 -        final String cssClass = Strings.emptyToNull(domainObjectLayout.cssClass());
 -        return cssClass != null ? new CssClassFacetForDomainObjectLayoutAnnotation(cssClass, holder) : null;
 +        return domainObjectLayouts.stream()
 +                .map(DomainObjectLayout::cssClass)
 +                .map(Strings::emptyToNull)
 +                .filter(Objects::nonNull)
 +                .map(cssClass -> new CssClassFacetForDomainObjectLayoutAnnotation(cssClass, holder))
 +                .findFirst()
 +                .orElse(null);
      }
  
      private CssClassFacetForDomainObjectLayoutAnnotation(
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservicelayout/DomainServiceLayoutFacetFactory.java
index 6ddfc35,c920233..13afd70
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservicelayout/DomainServiceLayoutFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/object/domainservicelayout/DomainServiceLayoutFacetFactory.java
@@@ -18,9 -18,6 +18,8 @@@
   */
  package org.apache.isis.core.metamodel.facets.object.domainservicelayout;
  
- 
 +import java.util.List;
 +
  import org.apache.isis.applib.annotation.DomainService;
  import org.apache.isis.applib.annotation.DomainServiceLayout;
  import org.apache.isis.core.metamodel.facetapi.FacetHolder;
@@@ -31,6 -28,7 +30,7 @@@ import org.apache.isis.core.metamodel.f
  import org.apache.isis.core.metamodel.facets.object.domainservicelayout.annotation.DomainServiceLayoutFacetAnnotation;
  
  
++
  public class DomainServiceLayoutFacetFactory extends FacetFactoryAbstract {
  
      public DomainServiceLayoutFacetFactory() {
@@@ -74,10 -60,9 +74,9 @@@
                          facetHolder,
                          menuBar, menuOrder));
  
 -        FacetUtil.addFacet(NamedFacetForDomainServiceLayoutAnnotation.create(domainServiceLayout, facetHolder));
 +        FacetUtil.addFacet(NamedFacetForDomainServiceLayoutAnnotation.create(domainServiceLayouts, facetHolder));
      }
  
- 
      private static String coalesce(final String... reasons) {
          for (final String reason : reasons) {
              if(reason != null) {
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index f89277c,614d1a3..f9c1adc
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@@ -34,8 -36,9 +36,9 @@@ import org.apache.isis.applib.annotatio
  import org.apache.isis.applib.services.bookmark.Bookmark;
  import org.apache.isis.applib.services.grid.GridService;
  import org.apache.isis.applib.services.metamodel.DomainMember;
 -import org.apache.isis.applib.services.metamodel.MetaModelService4;
 +import org.apache.isis.applib.services.metamodel.MetaModelService;
  import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
+ import org.apache.isis.core.metamodel.services.appmanifest.AppManifestProvider;
  import org.apache.isis.core.metamodel.spec.ObjectSpecId;
  import org.apache.isis.core.metamodel.spec.ObjectSpecification;
  import org.apache.isis.core.metamodel.spec.feature.Contributed;
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
index 04a1b42,4d9908b..2a81809
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/persistsession/PersistenceSessionServiceInternal.java
@@@ -112,7 -112,10 +112,10 @@@ public interface PersistenceSessionServ
      void commit();
  
      @Programmatic
+     void abortTransaction();
+ 
+     @Programmatic
 -    Transaction2 currentTransaction();
 +    Transaction currentTransaction();
  
  
      @Programmatic
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
index 4b066d0,68b1fb4..96d92de
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/xactn/TransactionServiceDefault.java
@@@ -21,16 -21,17 +21,17 @@@ package org.apache.isis.core.metamodel.
  
  import org.apache.isis.applib.annotation.DomainService;
  import org.apache.isis.applib.annotation.NatureOfService;
 -import org.apache.isis.applib.services.xactn.Transaction2;
 -import org.apache.isis.applib.services.xactn.TransactionService3;
 +import org.apache.isis.applib.services.xactn.Transaction;
- import org.apache.isis.applib.services.xactn.TransactionService2;
++import org.apache.isis.applib.services.xactn.TransactionService;
  import org.apache.isis.applib.services.xactn.TransactionState;
+ import org.apache.isis.core.commons.exceptions.IsisException;
  import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
  
  @DomainService(
          nature = NatureOfService.DOMAIN,
          menuOrder = "" + Integer.MAX_VALUE
  )
- public class TransactionServiceDefault implements TransactionService2 {
 -public class TransactionServiceDefault implements TransactionService3 {
++public class TransactionServiceDefault implements TransactionService {
  
  
      @Override
@@@ -40,7 -41,34 +41,34 @@@
  
      @Override
      public void nextTransaction() {
-         persistenceSessionServiceInternal.commit();
 -        nextTransaction(TransactionService3.Policy.UNLESS_MARKED_FOR_ABORT);
++        nextTransaction(TransactionService.Policy.UNLESS_MARKED_FOR_ABORT);
+     }
+ 
+     @Override
 -    public void nextTransaction(TransactionService3.Policy policy) {
++    public void nextTransaction(TransactionService.Policy policy) {
+         final TransactionState transactionState = getTransactionState();
+         switch (transactionState) {
+         case NONE:
+             break;
+         case IN_PROGRESS:
+             persistenceSessionServiceInternal.commit();
+             break;
+         case MUST_ABORT:
+             switch (policy) {
+             case UNLESS_MARKED_FOR_ABORT:
+                 throw new IsisException("Transaction is marked to abort");
+             case ALWAYS:
+                 persistenceSessionServiceInternal.abortTransaction();
+                 currentTransaction().clearAbortCause();
+                 break;
+             }
+             break;
+         case COMMITTED:
+             break;
+         case ABORTED:
+             break;
+         }
+ 
          persistenceSessionServiceInternal.beginTran();
      }
  
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
index d9c9c1d,8ff8324..17ff6f2
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectMember.java
@@@ -36,6 -34,10 +36,8 @@@ import org.apache.isis.core.metamodel.f
  import org.apache.isis.core.metamodel.facets.members.order.MemberOrderFacet;
  import org.apache.isis.core.metamodel.layout.memberorderfacet.MemberOrderFacetComparator;
  
 -import com.google.common.base.Function;
+ import com.google.common.base.Predicate;
 -import com.google.common.collect.Maps;
+ 
  /**
   * Provides reflective access to an action or a field on a domain object.
   */
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index 8f80a9b,f4a30ff..702ab74
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@@ -22,6 -22,6 +22,8 @@@ import java.util.List
  import java.util.Map;
  import java.util.Set;
  
++import javax.ws.rs.HEAD;
++
  import com.google.common.base.Function;
  import com.google.common.collect.Lists;
  import com.google.common.collect.Maps;
@@@ -41,8 -41,10 +43,9 @@@ import org.apache.isis.core.metamodel.f
  import org.apache.isis.core.metamodel.facets.FacetFactory;
  import org.apache.isis.core.metamodel.facets.object.autocomplete.AutoCompleteFacet;
  import org.apache.isis.core.metamodel.facets.object.objectspecid.ObjectSpecIdFacet;
 -import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
  import org.apache.isis.core.metamodel.progmodel.ProgrammingModel;
  import org.apache.isis.core.metamodel.services.ServicesInjector;
+ import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
  import org.apache.isis.core.metamodel.spec.FreeStandingList;
  import org.apache.isis.core.metamodel.spec.ObjectSpecId;
  import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@@ -395,9 -403,11 +398,11 @@@ public class SpecificationLoader implem
              return new ObjectSpecificationOnStandaloneList(servicesInjector,
                      facetProcessor);
          } else {
+             final ConfigurationServiceInternal configService = servicesInjector.lookupService(
+                     ConfigurationServiceInternal.class);
              final FacetedMethodsBuilderContext facetedMethodsBuilderContext =
                      new FacetedMethodsBuilderContext(
-                             this, facetProcessor);
 -                            this, facetProcessor, layoutMetadataReaders, configService);
++                            this, facetProcessor, configService);
              return new ObjectSpecificationDefault(cls, facetedMethodsBuilderContext,
                      servicesInjector, facetProcessor, natureOfServiceIfAny);
          }
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
index 52856a7,9665ef4..2b77b34
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilder.java
@@@ -134,7 -142,12 +137,9 @@@ public class FacetedMethodsBuilder 
  
      private final SpecificationLoader specificationLoader;
  
 -    private final List<LayoutMetadataReader> layoutMetadataReaders;
 -    private final Map<LayoutMetadataReader, LayoutMetadataReader2.Support> supportByReader;
 -
  
+     private final boolean explicitAnnotationsForActions;
+ 
      // ////////////////////////////////////////////////////////////////////////////
      // Constructor & finalize
      // ////////////////////////////////////////////////////////////////////////////
@@@ -152,6 -167,19 +159,9 @@@
  
          this.facetProcessor = facetedMethodsBuilderContext.facetProcessor;
          this.specificationLoader = facetedMethodsBuilderContext.specificationLoader;
+ 
 -        this.layoutMetadataReaders = facetedMethodsBuilderContext.layoutMetadataReaders;
+         this.explicitAnnotationsForActions = facetedMethodsBuilderContext.configService.getBoolean("isis.reflector.explicitAnnotations.action");
+ 
 -        this.supportByReader = Maps.newHashMap();
 -        for (LayoutMetadataReader reader : layoutMetadataReaders) {
 -
 -            if(reader instanceof LayoutMetadataReader2) {
 -                final LayoutMetadataReader2 reader2 = (LayoutMetadataReader2) reader;
 -                final LayoutMetadataReader2.Support support = reader2.support();
 -                supportByReader.put(reader, support);
 -            }
 -        }
      }
  
      @Override
diff --cc core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilderContext.java
index e4681db,bd44ea7..8326a88
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilderContext.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/FacetedMethodsBuilderContext.java
@@@ -16,17 -16,26 +16,21 @@@
   */
  package org.apache.isis.core.metamodel.specloader.specimpl;
  
 -import java.util.List;
 -import org.apache.isis.core.metamodel.layoutmetadata.LayoutMetadataReader;
+ import org.apache.isis.core.metamodel.services.configinternal.ConfigurationServiceInternal;
  import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
  import org.apache.isis.core.metamodel.specloader.facetprocessor.FacetProcessor;
  
  public class FacetedMethodsBuilderContext {
      public final SpecificationLoader specificationLoader;
      public final FacetProcessor facetProcessor;
 -    public final List<LayoutMetadataReader> layoutMetadataReaders;
+     public final ConfigurationServiceInternal configService;
  
      public FacetedMethodsBuilderContext(
              final SpecificationLoader specificationLoader,
-             final FacetProcessor facetProcessor) {
+             final FacetProcessor facetProcessor,
 -            final List<LayoutMetadataReader> layoutMetadataReaders,
+             final ConfigurationServiceInternal configService) {
          this.specificationLoader = specificationLoader;
          this.facetProcessor = facetProcessor;
 -        this.layoutMetadataReaders = layoutMetadataReaders;
+         this.configService = configService;
      }
  }
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
index 0000000,9a66503..4aceeb9
mode 000000,100644..100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessAbstract.java
@@@ -1,0 -1,141 +1,141 @@@
+ /*
+  *  Licensed to the Apache Software Foundation (ASF) under one
+  *  or more contributor license agreements.  See the NOTICE file
+  *  distributed with this work for additional information
+  *  regarding copyright ownership.  The ASF licenses this file
+  *  to you under the Apache License, Version 2.0 (the
+  *  "License"); you may not use this file except in compliance
+  *  with the License.  You may obtain a copy of the License at
+  *
+  *        http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing,
+  *  software distributed under the License is distributed on an
+  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  *  specific language governing permissions and limitations
+  *  under the License.
+  */
+ package org.apache.isis.core.runtime.headless;
+ 
+ import javax.inject.Inject;
+ 
+ import org.joda.time.LocalDate;
+ 
+ import org.apache.isis.applib.clock.Clock;
+ import org.apache.isis.applib.fixtures.FixtureClock;
+ import org.apache.isis.applib.fixtures.TickingFixtureClock;
+ import org.apache.isis.applib.fixturescripts.BuilderScriptAbstract;
+ import org.apache.isis.applib.fixturescripts.FixtureScript;
+ import org.apache.isis.applib.fixturescripts.FixtureScripts;
+ import org.apache.isis.applib.fixturescripts.PersonaWithBuilderScript;
+ import org.apache.isis.applib.services.clock.ClockService;
+ import org.apache.isis.applib.services.factory.FactoryService;
 -import org.apache.isis.applib.services.metamodel.MetaModelService4;
 -import org.apache.isis.applib.services.registry.ServiceRegistry2;
++import org.apache.isis.applib.services.metamodel.MetaModelService;
++import org.apache.isis.applib.services.registry.ServiceRegistry;
+ import org.apache.isis.applib.services.repository.RepositoryService;
+ import org.apache.isis.applib.services.sessmgmt.SessionManagementService;
+ import org.apache.isis.applib.services.user.UserService;
+ import org.apache.isis.applib.services.wrapper.WrapperFactory;
 -import org.apache.isis.applib.services.xactn.TransactionService3;
++import org.apache.isis.applib.services.xactn.TransactionService;
+ 
+ /**
+  * Reworked base class for headless access.
+  *
+  * <p>
+  *     The most common cases are integration tests or BDD spec glue.
+  * </p>
+  */
+ public abstract class HeadlessAbstract {
+ 
+ 
+     protected void runFixtureScript(final FixtureScript... fixtureScriptList) {
+         this.fixtureScripts.runFixtureScript(fixtureScriptList);
+     }
+ 
+     protected <T,F extends BuilderScriptAbstract<T,F>> T runBuilderScript(final F fixtureScript) {
+         return this.fixtureScripts.runBuilderScript(fixtureScript);
+     }
+ 
+     protected <P extends PersonaWithBuilderScript<T,F>, T,F extends BuilderScriptAbstract<T,F>> T runBuilderScript(final P persona) {
+         return runBuilderScript(persona.builder());
+     }
+ 
+ 
+     /**
+      * For convenience of subclasses, remove some boilerplate
+      */
+     protected <T> T wrap(final T obj) {
+         return wrapperFactory.wrap(obj);
+     }
+ 
+     /**
+      * For convenience of subclasses, remove some boilerplate
+      */
+     protected <T> T mixin(final Class<T> mixinClass, final Object mixedIn) {
+         return factoryService.mixin(mixinClass, mixedIn);
+     }
+ 
+ 
+     /**
+      * To use instead of {@link #getFixtureClock()}'s {@link FixtureClock#setDate(int, int, int)} ()}.
+      */
+     protected void setFixtureClockDate(final LocalDate date) {
+         if(date == null) {
+             return;
+         }
+         setFixtureClockDate(date.getYear(), date.getMonthOfYear(), date.getDayOfMonth());
+     }
+ 
+     /**
+      * To use instead of {@link #getFixtureClock()}'s {@link FixtureClock#setDate(int, int, int)} ()}.
+      */
+     protected void setFixtureClockDate(final int year, final int month, final int day) {
+         final Clock instance = Clock.getInstance();
+ 
+         if(instance instanceof TickingFixtureClock) {
+             TickingFixtureClock.reinstateExisting();
+             getFixtureClock().setDate(year, month, day);
+             TickingFixtureClock.replaceExisting();
+         }
+ 
+         if(instance instanceof FixtureClock) {
+             getFixtureClock().setDate(year, month, day);
+         }
+     }
+ 
+     /**
+      * If just require the current time, use {@link ClockService}
+      */
+     private FixtureClock getFixtureClock() {
+         return ((FixtureClock)FixtureClock.getInstance());
+     }
+ 
+ 
+     /**
+      * For convenience of subclasses, remove some boilerplate
+      */
+     protected <T> T unwrap(final T obj) {
+         return wrapperFactory.unwrap(obj);
+     }
+ 
+     @Inject
 -    protected MetaModelService4 metaModelService4;
++    protected MetaModelService metaModelService;
+     @Inject
+     protected FixtureScripts fixtureScripts;
+     @Inject
+     protected FactoryService factoryService;
+     @Inject
 -    protected ServiceRegistry2 serviceRegistry;
++    protected ServiceRegistry serviceRegistry;
+     @Inject
+     protected RepositoryService repositoryService;
+     @Inject
+     protected UserService userService;
+     @Inject
+     protected WrapperFactory wrapperFactory;
+     @Inject
 -    protected TransactionService3 transactionService;
++    protected TransactionService transactionService;
+     @Inject
+     protected SessionManagementService sessionManagementService;
+ 
+ }
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
index 0000000,a4027b4..3b40b50
mode 000000,100644..100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/HeadlessWithBootstrappingAbstract.java
@@@ -1,0 -1,158 +1,158 @@@
+ /*
+  *  Licensed to the Apache Software Foundation (ASF) under one
+  *  or more contributor license agreements.  See the NOTICE file
+  *  distributed with this work for additional information
+  *  regarding copyright ownership.  The ASF licenses this file
+  *  to you under the Apache License, Version 2.0 (the
+  *  "License"); you may not use this file except in compliance
+  *  with the License.  You may obtain a copy of the License at
+  *
+  *        http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing,
+  *  software distributed under the License is distributed on an
+  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  *  specific language governing permissions and limitations
+  *  under the License.
+  */
+ package org.apache.isis.core.runtime.headless;
+ 
+ import java.io.PrintStream;
+ 
+ import com.google.common.base.Strings;
+ 
+ import org.apache.log4j.PropertyConfigurator;
+ import org.joda.time.LocalDate;
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ import org.slf4j.event.Level;
+ 
+ import org.apache.isis.applib.Module;
+ import org.apache.isis.applib.clock.Clock;
 -import org.apache.isis.applib.services.xactn.TransactionService3;
++import org.apache.isis.applib.services.xactn.TransactionService;
+ import org.apache.isis.core.commons.factory.InstanceUtil;
+ import org.apache.isis.core.runtime.headless.logging.LogConfig;
+ import org.apache.isis.core.runtime.headless.logging.LogStream;
+ 
+ /**
+  * 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(HeadlessWithBootstrappingAbstract.class);
+ 
+     private final LogConfig logConfig;
+     protected static PrintStream logPrintStream(Level level) {
+         return LogStream.logPrintStream(LOG, level);
+     }
+ 
+     private final static ThreadLocal<Boolean> setupLogging = new ThreadLocal<Boolean>() {{
+         set(false);
+     }};
+ 
+ 
+     private final IsisSystemBootstrapper isisSystemBootstrapper;
+ 
+     protected HeadlessWithBootstrappingAbstract(
+             final Module module) {
+         this(new LogConfig(Level.INFO), module);
+     }
+ 
+     protected HeadlessWithBootstrappingAbstract(
+             final LogConfig logConfig,
+             final Module module) {
+ 
+         this.logConfig = logConfig;
+ 
+         final boolean firstTime = !setupLogging.get();
+         if(firstTime) {
+             PropertyConfigurator.configure(logConfig.getLoggingPropertyFile());
+             setupLogging.set(true);
+         }
+ 
+         final String integTestModuleFqcn = System.getProperty("isis.integTest.module");
+         LOG.info("isis.integTest.module = " + integTestModuleFqcn);
+         String moduleFqcn = integTestModuleFqcn;
+ 
+         if(moduleFqcn == null) {
+             final String headlessModuleFqcn = System.getProperty("isis.headless.module");
+             LOG.info("isis.headless.module = " + headlessModuleFqcn);
+             moduleFqcn = headlessModuleFqcn;
+         }
+ 
+         final Module moduleToUse =
+                 !Strings.isNullOrEmpty(moduleFqcn)
+                         ? InstanceUtil.createInstance(moduleFqcn, Module.class)
+                         : module;
+         this.isisSystemBootstrapper =
+                 new IsisSystemBootstrapper(logConfig, moduleToUse);
+     }
+ 
+ 
+     private LocalDate timeBeforeTest;
+ 
+     protected void bootstrapAndSetupIfRequired() {
+ 
+         System.setProperty("isis.headless", "true");
+         System.setProperty("isis.integTest", "true");
+         System.setProperty("isis.bddSpec", "true");
+ 
+         isisSystemBootstrapper.bootstrapIfRequired();
+         isisSystemBootstrapper.injectServicesInto(this);
+         fixtureScripts.setFixtureTracing(logConfig.getFixtureTracing());
+ 
+         beginTransaction();
+ 
+         isisSystemBootstrapper.setupModuleRefData();
+ 
+         timeBeforeTest = Clock.getTimeAsLocalDate();
+     }
+ 
+     private void beginTransaction() {
+         final IsisSystem isft = IsisSystem.get();
+         isft.beginTran();
+     }
+ 
+     protected void tearDownAllModules() {
+ 
+         final boolean testHealthy = transactionService != null;
+         if(!testHealthy) {
+             // avoid throwing an NPE here if something unexpected has occurred...
+             return;
+         }
+ 
 -        transactionService.nextTransaction(TransactionService3.Policy.ALWAYS);
++        transactionService.nextTransaction(TransactionService.Policy.ALWAYS);
+ 
+         isisSystemBootstrapper.tearDownAllModules();
+ 
+         // reinstate clock
+         setFixtureClockDate(timeBeforeTest);
+     }
+ 
+     protected void log(final String message) {
+         switch (logConfig.getTestLoggingLevel()) {
+         case ERROR:
+             LOG.error(message);
+             break;
+         case WARN:
+             LOG.warn(message);
+             break;
+         case INFO:
+             LOG.info(message);
+             break;
+         case DEBUG:
+             LOG.debug(message);
+             break;
+         case TRACE:
+             LOG.trace(message);
+             break;
+         }
+     }
+ }
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
index 0000000,6a7c0cb..3156b92
mode 000000,100644..100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/headless/IsisSystemBootstrapper.java
@@@ -1,0 -1,236 +1,236 @@@
+ /*
+  *  Licensed to the Apache Software Foundation (ASF) under one
+  *  or more contributor license agreements.  See the NOTICE file
+  *  distributed with this work for additional information
+  *  regarding copyright ownership.  The ASF licenses this file
+  *  to you under the Apache License, Version 2.0 (the
+  *  "License"); you may not use this file except in compliance
+  *  with the License.  You may obtain a copy of the License at
+  *
+  *        http://www.apache.org/licenses/LICENSE-2.0
+  *
+  *  Unless required by applicable law or agreed to in writing,
+  *  software distributed under the License is distributed on an
+  *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  *  specific language governing permissions and limitations
+  *  under the License.
+  */
+ package org.apache.isis.core.runtime.headless;
+ 
+ import java.util.List;
+ import java.util.UUID;
+ 
+ import javax.jdo.PersistenceManagerFactory;
+ 
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+ 
+ import org.apache.isis.applib.AppManifest;
+ import org.apache.isis.applib.AppManifest2;
+ import org.apache.isis.applib.AppManifestAbstract2;
+ import org.apache.isis.applib.Module;
+ import org.apache.isis.applib.fixtures.TickingFixtureClock;
+ import org.apache.isis.applib.fixturescripts.FixtureScript;
+ import org.apache.isis.applib.fixturescripts.FixtureScripts;
+ import org.apache.isis.applib.services.jdosupport.IsisJdoSupport;
 -import org.apache.isis.applib.services.metamodel.MetaModelService4;
 -import org.apache.isis.applib.services.registry.ServiceRegistry2;
++import org.apache.isis.applib.services.metamodel.MetaModelService;
++import org.apache.isis.applib.services.registry.ServiceRegistry;
+ 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;
+ 
+ public class IsisSystemBootstrapper {
+ 
+     private static final Logger LOG = LoggerFactory.getLogger(IsisSystemBootstrapper.class);
+ 
+     /**
+      * The {@link AppManifest2} used to bootstrap the {@link IsisSystem} (on the thread-local)
+      */
+     private static ThreadLocal<AppManifest2> isftAppManifest = new ThreadLocal<>();
+ 
+ 
+     private final LogConfig logConfig;
+     private final AppManifest2 appManifest2;
+ 
+     public IsisSystemBootstrapper(
+             final LogConfig logConfig,
+             final Module module) {
+         this(logConfig, AppManifestAbstract2.Builder.forModule(module).build());
+     }
+ 
+     public IsisSystemBootstrapper(
+             final LogConfig logConfig,
+             final AppManifest2 appManifest2) {
+ 
+         this.logConfig = logConfig;
+         this.appManifest2 = appManifest2;
+     }
+ 
+     public AppManifest2 getAppManifest2() {
+         return appManifest2;
+     }
+ 
+     /**
+      * Corresponding to {@link AppManifest2} provided in {@link #IsisSystemBootstrapper(LogConfig, AppManifest2)}, or
+      * (equivalently) the {@link Module} provided directly in {@link #IsisSystemBootstrapper(LogConfig, Module)}.
+      */
+     public Module getModule() {
+         return appManifest2.getModule();
+     }
+ 
+     public IsisSystem bootstrapIfRequired() {
+         bootstrapUsing(appManifest2);
+ 
+         return IsisSystem.get();
+     }
+ 
+     /**
+      * Expects a transaction to have been started
+      */
+     public void setupModuleRefData() {
 -        MetaModelService4 metaModelService4 = lookupService(MetaModelService4.class);
++        MetaModelService metaModelService4 = lookupService(MetaModelService.class);
+         FixtureScript refDataSetupFixture = metaModelService4.getAppManifest2().getRefDataSetupFixture();
+         runFixtureScript(refDataSetupFixture);
+     }
+ 
+ 
+     private void bootstrapUsing(AppManifest2 appManifest2) {
+ 
+         final SystemState systemState = determineSystemState(appManifest2);
+         switch (systemState) {
+ 
+         case BOOTSTRAPPED_SAME_MODULES:
+             // nothing to do
+             break;
+         case BOOTSTRAPPED_DIFFERENT_MODULES:
+             // TODO: this doesn't work correctly yet; not tearing down HSQLDB correctly.
+             if(false) {
+                 teardownSystem();
+             } else {
+                 throw new RuntimeException("Bootstrapping different modules is not yet supported");
+             }
+             // fall through
+         case NOT_BOOTSTRAPPED:
+ 
+             long t0 = System.currentTimeMillis();
+             setupSystem(appManifest2);
+             long t1 = System.currentTimeMillis();
+ 
+             log("##########################################################################");
+             log("# Bootstrapped in " + (t1- t0) + " millis");
+             log("##########################################################################");
+ 
+             TickingFixtureClock.replaceExisting();
+ 
+             break;
+         }
+     }
+ 
+     private static SystemState determineSystemState(final AppManifest appManifest) {
+         IsisSystem isft = IsisSystem.getElseNull();
+         if (isft == null)
+             return SystemState.NOT_BOOTSTRAPPED;
+ 
+         final AppManifest appManifestFromPreviously = isftAppManifest.get();
+         return haveSameModules(appManifest, appManifestFromPreviously)
+                 ? SystemState.BOOTSTRAPPED_SAME_MODULES
+                 : SystemState.BOOTSTRAPPED_DIFFERENT_MODULES;
+     }
+ 
+     static boolean haveSameModules(
+             final AppManifest m1,
+             final AppManifest m2) {
+         final List<Class<?>> m1Modules = m1.getModules();
+         final List<Class<?>> m2Modules = m2.getModules();
+         return m1Modules.containsAll(m2Modules) && m2Modules.containsAll(m1Modules);
+     }
+ 
+     private static IsisSystem setupSystem(final AppManifest2 appManifest2) {
+ 
+         final IsisConfigurationForJdoIntegTests configuration = new IsisConfigurationForJdoIntegTests();
+         configuration.putDataNucleusProperty("javax.jdo.option.ConnectionURL","jdbc:hsqldb:mem:test-" + UUID.randomUUID().toString());
+         final IsisSystem.Builder isftBuilder =
+                 new IsisSystem.Builder()
+                         .withLoggingAt(org.apache.log4j.Level.INFO)
+                         .with(appManifest2)
+                         .with(configuration);
+ 
+         IsisSystem isft = isftBuilder.build();
+         isft.setUpSystem();
+ 
+         // save both the system and the manifest
+         // used to bootstrap the system onto thread-loca
+         IsisSystem.set(isft);
+         isftAppManifest.set(appManifest2);
+ 
+         return isft;
+     }
+ 
+     public void injectServicesInto(final Object object) {
 -        lookupService(ServiceRegistry2.class).injectServicesInto(object);
++        lookupService(ServiceRegistry.class).injectServicesInto(object);
+     }
+ 
+     enum SystemState {
+         NOT_BOOTSTRAPPED,
+         BOOTSTRAPPED_SAME_MODULES,
+         BOOTSTRAPPED_DIFFERENT_MODULES
+     }
+ 
+     private static void teardownSystem() {
+         final IsisSessionFactory isisSessionFactory = lookupService(IsisSessionFactory.class);
+ 
+         // TODO: this ought to be part of isisSessionFactory's responsibilities
+         final IsisJdoSupport isisJdoSupport = lookupService(IsisJdoSupport.class);
+         final PersistenceManagerFactory pmf =
+                 isisJdoSupport.getJdoPersistenceManager().getPersistenceManagerFactory();
+         isisSessionFactory.destroyServicesAndShutdown();
+         pmf.close();
+ 
+         IsisContext.testReset();
+     }
+ 
+     public void tearDownAllModules() {
 -        final MetaModelService4 metaModelService4 = lookupService(MetaModelService4.class);
++        final MetaModelService metaModelService4 = lookupService(MetaModelService.class);
+ 
+         FixtureScript fixtureScript = metaModelService4.getAppManifest2().getTeardownFixture();
+         runFixtureScript(fixtureScript);
+     }
+ 
+ 
+     private void runFixtureScript(final FixtureScript... fixtureScriptList) {
+         final FixtureScripts fixtureScripts = lookupService(FixtureScripts.class);
+         fixtureScripts.runFixtureScript(fixtureScriptList);
+     }
+ 
+ 
+     private static IsisSystem getIsisSystem() {
+         return IsisSystem.get();
+     }
+ 
+     private static <T> T lookupService(Class<T> serviceClass) {
+         return getIsisSystem().getService(serviceClass);
+     }
+ 
+     private void log(final String message) {
+         switch (logConfig.getTestLoggingLevel()) {
+         case ERROR:
+             LOG.error(message);
+             break;
+         case WARN:
+             LOG.warn(message);
+             break;
+         case INFO:
+             LOG.info(message);
+             break;
+         case DEBUG:
+             LOG.debug(message);
+             break;
+         case TRACE:
+             LOG.trace(message);
+             break;
+         }
+     }
+ 
+ }
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
index 46fbc47,d29662c..91bf672
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/persistsession/PersistenceSessionServiceInternalDefault.java
@@@ -162,7 -162,12 +162,12 @@@ public class PersistenceSessionServiceI
      }
  
      @Override
+     public void abortTransaction() {
+         getTransactionManager().abortTransaction();
+     }
+ 
+     @Override
 -    public Transaction2 currentTransaction() {
 +    public Transaction currentTransaction() {
          return getTransactionManager().getCurrentTransaction();
      }
  
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
index 6a4b474,f26f368..7ac12ff
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
@@@ -30,7 -30,8 +30,8 @@@ import org.slf4j.LoggerFactory
  import org.apache.isis.applib.annotation.Programmatic;
  import org.apache.isis.applib.services.HasTransactionId;
  import org.apache.isis.applib.services.WithTransactionScope;
 -import org.apache.isis.applib.services.xactn.Transaction2;
 +import org.apache.isis.applib.services.xactn.Transaction;
+ import org.apache.isis.applib.services.xactn.TransactionState;
  import org.apache.isis.core.commons.authentication.AuthenticationSession;
  import org.apache.isis.core.commons.authentication.MessageBroker;
  import org.apache.isis.core.commons.components.TransactionScopedComponent;
@@@ -58,9 -58,8 +58,8 @@@ import org.apache.isis.core.runtime.ser
   * the {@link IsisTransactionManager} to ensure that the underlying persistence
   * mechanism (for example, the <tt>ObjectStore</tt>) is also committed.
   */
 -public class IsisTransaction implements TransactionScopedComponent, Transaction2 {
 +public class IsisTransaction implements TransactionScopedComponent, Transaction {
  
- 
      public static class Placeholder {
          public static Placeholder NEW = new Placeholder("[NEW]");
          public static Placeholder DELETED = new Placeholder("[DELETED]");
diff --cc core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
index 3bc818f,9773fa9..890e831
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/systemusinginstallers/IsisComponentProvider.java
@@@ -30,6 -29,8 +30,7 @@@ import javax.jdo.annotations.Persistenc
  
  import com.google.common.base.Function;
  import com.google.common.base.Joiner;
 -import com.google.common.base.Predicate;
+ import com.google.common.collect.FluentIterable;
  import com.google.common.collect.Iterables;
  import com.google.common.collect.Lists;
  import com.google.common.collect.Sets;
@@@ -145,19 -148,62 +147,57 @@@ public abstract class IsisComponentProv
  
          final Set<Class<?>> mixinTypes = Sets.newHashSet();
          mixinTypes.addAll(reflections.getTypesAnnotatedWith(Mixin.class));
+ 
          final Set<Class<?>> domainObjectTypes = reflections.getTypesAnnotatedWith(DomainObject.class);
          mixinTypes.addAll(
 -                Lists.newArrayList(Iterables.filter(domainObjectTypes, new Predicate<Class<?>>() {
 -                    @Override
 -                    public boolean apply(@Nullable final Class<?> input) {
 -                        if(input == null) { return false; }
 -                        final DomainObject annotation = input.getAnnotation(DomainObject.class);
 -                        return annotation.nature() == Nature.MIXIN;
 -                    }
 -                }))
 +                domainObjectTypes.stream()
 +                        .filter(input -> input.getAnnotation(DomainObject.class).nature() == Nature.MIXIN)
 +                        .collect(Collectors.toList())
          );
  
-         registry.setDomainServiceTypes(domainServiceTypes);
-         registry.setPersistenceCapableTypes(persistenceCapableTypes);
-         registry.setFixtureScriptTypes(fixtureScriptTypes);
-         registry.setMixinTypes(mixinTypes);
+         // add in any explicitly registered services...
+         domainServiceTypes.addAll(appManifest.getAdditionalServices());
+ 
+         // Reflections seems to have a bug whereby it will return some classes outside the
+         // set of packages that we want (think this is to do with the fact that it matches based on
+         // the prefix and gets it wrong); so we double check and filter out types outside our
+         // required set of packages.
+ 
+         // for a tiny bit of efficiency, we append a '.' to each package name here, outside the loops
+         List<String> packagesWithDotSuffix =
+             FluentIterable.from(moduleAndFrameworkPackages).transform(new Function<String, String>() {
+                 @Nullable @Override
+                 public String apply(@Nullable final String s) {
+                     return s != null ? s + "." : null;
+                 }
+             }).toList();
+ 
+         registry.setDomainServiceTypes(within(packagesWithDotSuffix, domainServiceTypes));
+         registry.setPersistenceCapableTypes(within(packagesWithDotSuffix, persistenceCapableTypes));
+         registry.setFixtureScriptTypes(within(packagesWithDotSuffix, fixtureScriptTypes));
+         registry.setMixinTypes(within(packagesWithDotSuffix, mixinTypes));
      }
  
+     static <T> Set<Class<? extends T>> within(
+             final List<String> packagesWithDotSuffix,
+             final Set<Class<? extends T>> classes) {
+         Set<Class<? extends T>> classesWithin = Sets.newLinkedHashSet();
+         for (Class<? extends T> clz : classes) {
+             final String className = clz.getName();
+             if(containedWithin(packagesWithDotSuffix, className)) {
+                 classesWithin.add(clz);
+             }
+         }
+         return classesWithin;
+     }
+     static private boolean containedWithin(final List<String> packagesWithDotSuffix, final String className) {
+         for (String packageWithDotSuffix : packagesWithDotSuffix) {
+             if(className.startsWith(packageWithDotSuffix)) {
+                 return true;
+             }
+         }
+         return false;
+     }
  
      private void specifyServicesAndRegisteredEntitiesUsing(final AppManifest appManifest) {
          final Iterable<String> packageNames = modulePackageNamesFrom(appManifest);
diff --cc core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProvider.java
index 0ee22ef,09429d5..a18d39f
--- a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProvider.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProvider.java
@@@ -27,10 -27,15 +27,13 @@@ import org.apache.isis.applib.DomainObj
   * For {@link ScenarioExecution scenario}s with integration-scope, these will be
   * configured services for an end-to-end running system.  For scenarios with
   * unit-scope, these will typically be mocks.
+  * 
+  * @deprecated - with no replacement
   */
+ @Deprecated
  public interface DomainServiceProvider {
  
-     public abstract <T> T getService(Class<T> serviceClass);
 -    DomainObjectContainer getContainer();
 -
+     <T> T getService(Class<T> serviceClass);
  
      /**
       * Replaces the service implementation with some other.
diff --cc core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProviderMockery.java
index 9814a84,cbb6f11..e79a19e
--- a/core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProviderMockery.java
+++ b/core/specsupport/src/main/java/org/apache/isis/core/specsupport/scenarios/DomainServiceProviderMockery.java
@@@ -26,15 -24,16 +26,19 @@@ import org.jmock.Expectations
  import org.jmock.Mockery;
  import org.jmock.api.Action;
  import org.jmock.api.Invocation;
 -import org.apache.isis.applib.DomainObjectContainer;
 +
 +import org.apache.isis.applib.services.factory.FactoryService;
 +import org.apache.isis.applib.services.repository.RepositoryService;
  import org.apache.isis.core.unittestsupport.jmocking.JavassistImposteriser;
  
+ /**
+  * @deprecated - with no replacement
+  */
+ @Deprecated
  class DomainServiceProviderMockery implements DomainServiceProvider {
  
 -    private DomainObjectContainer mockContainer = null;
 +    private RepositoryService mockRepositoryService = null;
 +    private FactoryService mockFactoryService = null;
      private final Map<Class<?>, Object> mocks = Maps.newHashMap();
      
      private Mockery context;
diff --cc core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
index 37e63c9,c5b6349..1554922
--- a/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
+++ b/core/viewer-wicket-impl/src/main/java/org/apache/isis/viewer/wicket/viewer/integration/wicket/WebRequestCycleForIsis.java
@@@ -21,9 -21,12 +21,11 @@@ package org.apache.isis.viewer.wicket.v
  
  import java.lang.reflect.Constructor;
  import java.util.List;
++import java.util.Optional;
  import java.util.Set;
  
  import com.google.common.base.Function;
 -import com.google.common.base.Optional;
+ import com.google.common.base.Throwables;
 -import com.google.common.collect.FluentIterable;
  import com.google.common.collect.Lists;
  
  import org.apache.wicket.Application;
@@@ -46,11 -51,15 +50,14 @@@ import org.slf4j.Logger
  import org.slf4j.LoggerFactory;
  
  import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 -import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer2;
  import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
  import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerForType;
+ import org.apache.isis.applib.services.i18n.TranslationService;
  import org.apache.isis.core.commons.authentication.AuthenticationSession;
+ import org.apache.isis.core.commons.authentication.MessageBroker;
  import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
  import org.apache.isis.core.metamodel.services.ServicesInjector;
+ import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
  import org.apache.isis.core.metamodel.specloader.validator.MetaModelInvalidException;
  import org.apache.isis.core.runtime.system.context.IsisContext;
  import org.apache.isis.core.runtime.system.session.IsisSession;
@@@ -180,6 -190,48 +188,48 @@@ public class WebRequestCycleForIsis ext
              return new RenderPageRequestHandler(new PageProvider(mmvErrorPage), RedirectPolicy.ALWAYS_REDIRECT);
          }
  
+         try {
+ 
+             // adapted from http://markmail.org/message/un7phzjbtmrrperc
+             if(ex instanceof ListenerInvocationNotAllowedException) {
+                 final ListenerInvocationNotAllowedException linaex = (ListenerInvocationNotAllowedException) ex;
+                 if(linaex.getComponent() != null && PromptFormAbstract.ID_CANCEL_BUTTON.equals(linaex.getComponent().getId())) {
+                     // no message.
+                     // this seems to occur when press ESC twice in rapid succession on a modal dialog.
+                 } else {
+                     addMessage(null);
+ 
+                 }
+                 return respondGracefully(cycle);
+             }
+ 
+ 
+             // handle recognised exceptions gracefully also
 -            final List<ExceptionRecognizer2> exceptionRecognizers =
 -                    getServicesInjector().lookupServices(ExceptionRecognizer2.class);
++            final List<ExceptionRecognizer> exceptionRecognizers =
++                    getServicesInjector().lookupServices(ExceptionRecognizer.class);
+             String recognizedMessageIfAny = new ExceptionRecognizerComposite(exceptionRecognizers).recognize(ex);
+             if(recognizedMessageIfAny != null) {
+                 return respondGracefully(cycle);
+             }
+ 
+             final List<Throwable> causalChain = Throwables.getCausalChain(ex);
 -            final Optional<Throwable> hiddenIfAny = FluentIterable.from(causalChain).filter(
 -                    ObjectMember.HiddenException.isInstanceOf()).first();
++            final Optional<Throwable> hiddenIfAny = causalChain.stream()
++                    .filter(ObjectMember.HiddenException.isInstanceOf()::apply).findFirst();
+             if(hiddenIfAny.isPresent()) {
+                 addMessage("hidden");
+                 return respondGracefully(cycle);
+             }
 -            final Optional<Throwable> disabledIfAny = FluentIterable.from(causalChain).filter(
 -                    ObjectMember.DisabledException.isInstanceOf()).first();
++            final Optional<Throwable> disabledIfAny = causalChain.stream()
++                    .filter(ObjectMember.DisabledException.isInstanceOf()::apply).findFirst();
+             if(disabledIfAny.isPresent()) {
+                 addTranslatedMessage(disabledIfAny.get().getMessage());
+                 return respondGracefully(cycle);
+             }
+ 
+         } catch(Exception ignoreFailedAttemptToGracefullyHandle) {
+             // if any of this graceful responding fails, then fall back to original handling
+         }
+ 
          PageProvider errorPageProvider = errorPageProviderFor(ex);
          // avoid infinite redirect loops
          RedirectPolicy redirectPolicy = ex instanceof PageExpiredException
diff --cc example/application/simpleapp/application/src/main/java/domainapp/application/fixture/scenarios/DomainAppDemo.java
index 7f3ce27,8a044aa..09dfe21
--- a/example/application/simpleapp/application/src/main/java/domainapp/application/fixture/scenarios/DomainAppDemo.java
+++ b/example/application/simpleapp/application/src/main/java/domainapp/application/fixture/scenarios/DomainAppDemo.java
@@@ -18,14 -18,13 +18,13 @@@
   */
  package domainapp.application.fixture.scenarios;
  
- import javax.annotation.Nullable;
+ import javax.inject.Inject;
  
+ import org.apache.isis.applib.AppManifest2;
  import org.apache.isis.applib.fixturescripts.FixtureScript;
 -import org.apache.isis.applib.services.metamodel.MetaModelService4;
++import org.apache.isis.applib.services.metamodel.MetaModelService;
  
- import domainapp.application.fixture.teardown.DomainAppTearDown;
- import domainapp.modules.simple.fixture.scenario.CreateSimpleObjects;
- import lombok.Getter;
- import lombok.Setter;
+ import domainapp.modules.simple.fixture.SimpleObject_persona;
  
  public class DomainAppDemo extends FixtureScript {
  
@@@ -33,16 -32,14 +32,14 @@@
          withDiscoverability(Discoverability.DISCOVERABLE);
      }
  
-     @Nullable
-     @Getter @Setter
-     private Integer number;
- 
      @Override
      protected void execute(final ExecutionContext ec) {
- 
-         // execute
-         ec.executeChild(this, new DomainAppTearDown());
-         ec.executeChild(this, new CreateSimpleObjects().setNumber(number));
- 
 -        AppManifest2 appManifest2 = metaModelService4.getAppManifest2();
++        AppManifest2 appManifest2 = metaModelService.getAppManifest2();
+         ec.executeChild(this, appManifest2.getTeardownFixture());
+         ec.executeChild(this, appManifest2.getRefDataSetupFixture());
+         ec.executeChild(this, new SimpleObject_persona.PersistAll());
      }
+ 
+     @Inject
 -    MetaModelService4 metaModelService4;
++    MetaModelService metaModelService;
  }
diff --cc example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
index 8cf4270,33c70fe..034574c
--- a/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
+++ b/example/application/simpleapp/module-simple/src/main/java/domainapp/modules/simple/fixture/SimpleObject_persona.java
@@@ -17,10 -17,15 +17,15 @@@
   *  under the License.
   */
  
- package domainapp.modules.simple.fixture.scenario;
+ package domainapp.modules.simple.fixture;
+ 
+ import org.apache.isis.applib.fixturescripts.PersonaWithBuilderScript;
+ import org.apache.isis.applib.fixturescripts.PersonaWithFinder;
+ import org.apache.isis.applib.fixturescripts.setup.PersonaEnumPersistAll;
 -import org.apache.isis.applib.services.registry.ServiceRegistry2;
++import org.apache.isis.applib.services.registry.ServiceRegistry;
  
  import domainapp.modules.simple.dom.impl.SimpleObject;
- import domainapp.modules.simple.dom.impl.SimpleObjectMenu;
+ import domainapp.modules.simple.dom.impl.SimpleObjects;
  import lombok.AllArgsConstructor;
  
  @AllArgsConstructor
@@@ -39,11 -45,21 +45,19 @@@ public enum SimpleObject_persona implem
  
      private final String name;
  
-     public SimpleObject createWith(final SimpleObjectMenu menu) {
-         return menu.create(name);
 -//    @Override
+     public SimpleObjectBuilder builder() {
+         return new SimpleObjectBuilder().setName(name);
+     }
+ 
 -    //@Override
 -    public SimpleObject findUsing(final ServiceRegistry2 serviceRegistry) {
++    public SimpleObject findUsing(final ServiceRegistry serviceRegistry) {
+         SimpleObjects simpleObjects = serviceRegistry.lookupService(SimpleObjects.class);
+         return simpleObjects.findByNameExact(name);
      }
  
-     public SimpleObject findWith(final SimpleObjectMenu menu) {
-         return menu.findByName(name).get(0);
+     public static class PersistAll
+             extends PersonaEnumPersistAll<SimpleObject_persona, SimpleObject, SimpleObjectBuilder> {
+         public PersistAll() {
+             super(SimpleObject_persona.class);
+         }
      }
  }
diff --cc example/application/simpleapp/pom.xml
index c488ee2,f53bbe5..4dd98c6
--- a/example/application/simpleapp/pom.xml
+++ b/example/application/simpleapp/pom.xml
@@@ -35,12 -35,8 +35,8 @@@
  
      <packaging>pom</packaging>
  
-     <prerequisites>
-         <maven>3.0.4</maven>
-     </prerequisites>
- 
      <properties>
 -        <isis.version>1.16.0-SNAPSHOT</isis.version>
 +        <isis.version>2.0.0-SNAPSHOT</isis.version>
  
          <lombok.version>1.16.18</lombok.version>
  

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