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 2021/02/01 09:09:13 UTC

[isis] 01/04: ISIS-2444: splits tooling into two commands

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

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

commit 4e54b03a41d9ef0ebeb889049795b77cc858936c
Author: danhaywood <da...@haywood-associates.co.uk>
AuthorDate: Sun Jan 31 14:16:38 2021 +0000

    ISIS-2444: splits tooling into two commands
---
 .run/isis-tooling-cli (overview).run.xml           |  42 ++++
 .../components/docs/modules/ROOT/pages/about.adoc  |  79 +++----
 antora/components/system/antora.yml                |   4 +
 .../modules/generated/pages/system-overview.adoc   | 111 +++++++--
 antora/playbooks/site-mappings.yml                 |   2 +-
 antora/playbooks/site-tooling.yml                  |   9 +
 antora/playbooks/site.yml                          |   4 +-
 antora/supplemental-ui/css/site-custom.css         |   6 +
 core/adoc/modules/ROOT/pages/about.adoc            |  11 +-
 .../adoc/modules/config/pages/sections/Other.adoc  |  35 +++
 .../modules/config/pages/sections/isis.applib.adoc | 139 +++++-------
 .../pages/sections/isis.core.meta-model.adoc       |   2 +-
 .../isis.core.meta-model.introspector.adoc         |   4 +-
 .../sections/isis.core.meta-model.validator.adoc   |  38 +---
 .../pages/sections/isis.core.runtime-services.adoc |  29 ++-
 .../config/pages/sections/isis.extensions.adoc     |  29 ++-
 .../sections/isis.persistence.jdo-datanucleus.adoc |   4 +-
 .../isis.persistence.jdo-datanucleus.impl.adoc     |  33 +--
 .../config/pages/sections/isis.value-types.adoc    |  26 +--
 .../pages/sections/isis.viewer.restfulobjects.adoc |  24 +-
 .../config/pages/sections/isis.viewer.wicket.adoc  |  54 +++--
 .../modules/config/pages/sections/resteasy.adoc    |   2 +-
 isis-tooling.yml                                   |  85 +++++--
 .../adoc/modules/ROOT/partials/component-nav.adoc  |   8 +-
 .../adoc/antora.yml                                |   0
 .../adoc/modules/outbox-publisher/nav.adoc         |   0
 .../adoc/modules/outbox-publisher/pages/about.adoc |   0
 .../outbox-publisher/partials/module-nav.adoc      |   0
 preview.sh                                         |  13 +-
 .../regressiontests/partials/module-nav.adoc       |   2 +-
 .../{_adoc-gen-index.sh => _adoc-gen-tooling.sh}   |   7 +-
 scripts/ci/_build-site.sh                          |   9 +-
 .../adoc/modules/ROOT/partials/component-nav.adoc  |   7 +-
 .../adoc/modules/ROOT/partials/component-nav.adoc  |  12 +-
 tooling/adoc/modules/ROOT/pages/about.adoc         |  15 +-
 .../adoc/modules/ROOT/partials/component-nav.adoc  |  23 +-
 tooling/cli/adoc/antora.yml                        |   2 +-
 .../modules/tooling-cli/examples/isis-tooling.yml  |   2 +-
 .../cli/adoc/modules/tooling-cli/pages/about.adoc  |  35 +--
 .../modules/tooling-cli/partials/module-nav.adoc   |   2 +-
 .../main/java/org/apache/isis/tooling/cli/Cli.java |  69 ++++--
 .../isis/tooling/cli/CliCommandAbstract.java       |   8 +-
 .../org/apache/isis/tooling/cli/CliConfig.java     |  74 +++---
 .../cli/adocfix/OrphanedIncludeStatementFixer.java |   4 +-
 .../isis/tooling/cli/projdoc/ProjectDocModel.java  | 247 +++++++++++++++------
 .../isis/tooling/cli/projdoc/ProjectDocWriter.java | 136 +++++++-----
 .../isis/tooling/cli/test/CliConfigTest.java       |  15 +-
 .../apache/isis/tooling/cli/test/isis-tooling.yml  | 101 ++++++---
 48 files changed, 987 insertions(+), 576 deletions(-)

diff --git a/.run/isis-tooling-cli (overview).run.xml b/.run/isis-tooling-cli (overview).run.xml
new file mode 100644
index 0000000..4dafc48
--- /dev/null
+++ b/.run/isis-tooling-cli (overview).run.xml	
@@ -0,0 +1,42 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="isis-tooling-cli (overview)" type="Application" factoryName="Application">
+    <option name="ALTERNATIVE_JRE_PATH" value="C:\Program Files\OpenJDK\openjdk-11.0.7_10" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+    <option name="MAIN_CLASS_NAME" value="org.apache.isis.tooling.cli.Cli" />
+    <module name="isis-tooling-cli" />
+    <option name="PROGRAM_PARAMETERS" value="-p . -o antora/components/system/modules/generated overview" />
+    <extension name="net.ashald.envfile">
+      <option name="IS_ENABLED" value="false" />
+      <option name="IS_SUBST" value="false" />
+      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
+      <option name="IS_IGNORE_MISSING_FILES" value="false" />
+      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
+      <ENTRIES>
+        <ENTRY IS_ENABLED="true" PARSER="runconfig" />
+      </ENTRIES>
+    </extension>
+    <method v="2">
+      <option name="Make" enabled="true" />
+    </method>
+  </configuration>
+  <configuration default="false" name="isis-tooling-cli (overview)" type="Application" factoryName="Application">
+    <option name="ALTERNATIVE_JRE_PATH" value="C:\Program Files\OpenJDK\openjdk-11.0.7_10" />
+    <option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
+    <option name="MAIN_CLASS_NAME" value="org.apache.isis.tooling.cli.Cli" />
+    <module name="isis-tooling-cli" />
+    <option name="PROGRAM_PARAMETERS" value="-p . -o antora/components/system/modules/generated overview" />
+    <extension name="net.ashald.envfile">
+      <option name="IS_ENABLED" value="false" />
+      <option name="IS_SUBST" value="false" />
+      <option name="IS_PATH_MACRO_SUPPORTED" value="false" />
+      <option name="IS_IGNORE_MISSING_FILES" value="false" />
+      <option name="IS_ENABLE_EXPERIMENTAL_INTEGRATIONS" value="false" />
+      <ENTRIES>
+        <ENTRY IS_ENABLED="true" PARSER="runconfig" />
+      </ENTRIES>
+    </extension>
+    <method v="2">
+      <option name="Make" enabled="true" />
+    </method>
+  </configuration>
+</component>
\ No newline at end of file
diff --git a/antora/components/docs/modules/ROOT/pages/about.adoc b/antora/components/docs/modules/ROOT/pages/about.adoc
index 139c9a5..7c30f5d 100644
--- a/antora/components/docs/modules/ROOT/pages/about.adoc
+++ b/antora/components/docs/modules/ROOT/pages/about.adoc
@@ -25,9 +25,9 @@
 _Starter Apps_
 
 * xref:docs:starters:helloworld.adoc[HelloWorld]
-(link:https://helloworld.isis.incode.work[preview])
+(link:https://helloworld.isis.incode.work[online])
 * xref:docs:starters:simpleapp.adoc[SimpleApp]
-(link:https://simpleapp.isis.incode.work[preview])
+(link:https://simpleapp.isis.incode.work[online])
 
 _POMs_
 
@@ -36,11 +36,11 @@ _POMs_
 
 |
 [discrete]
-== Demos & Tutorial
+== Demos
 
 * xref:docs:demo:about.adoc[Demo App]
-(link:https://demo-wicket.isis.incode.work[preview])
-* link:https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html[Petclinic (v1.16.2)]
+(link:https://demo-wicket.isis.incode.work[online])
+//* link:https://danhaywood.gitlab.io/isis-petclinic-tutorial-docs/petclinic/1.16.2/intro.html[Petclinic (v1.16.2)]
 
 [discrete]
 == Resources
@@ -85,10 +85,6 @@ _Other_
 [discrete]
 == Components
 
-_Overview_
-
-* xref:system:generated:system-overview.adoc[System Overview]
-
 _Viewers_
 
 * xref:vw:ROOT:about.adoc[Wicket UI]
@@ -133,18 +129,26 @@ _Nightly Builds (not ASF)_
 [discrete]
 == Framework
 
+_Process_
+
 * xref:conguide:ROOT:about.adoc[Contributors' Guide]
 * xref:comguide:ROOT:about.adoc[Committers' Guide]
-* xref:core:ROOT:about.adoc[Design Docs]
-* xref:more-thanks/more-thanks.adoc[Acknowledgements]
+** xref:tooling:ROOT:about.adoc[Tooling]
 
+_Design_
 
+* xref:system:generated:system-overview.adoc[System Overview]
+* xref:core:ROOT:about.adoc[Core Framework]
 
 _Analysis_
 
 * link:https://sonarcloud.io/dashboard?id=apache_isis[SonarCloud.io]
 * link:https://fisheye.apache.org/browse/~br=master/isis-git/[ASF Fisheye]
 
+_Thanks_
+
+* xref:more-thanks/more-thanks.adoc[Acknowledgements]
+
 
 |
 [discrete]
@@ -166,38 +170,37 @@ _Academia_
 
 
 
-|
-[discrete]
-== Real-world Apps
-
-* https://github.com/estatio/estatio[Estatio]
-* https://github.com/incodehq/contactapp[ContactApp]
-* https://github.com/incodehq/ecpcrm[ECP CRM]
-
-_Example Apps_
-
-* https://github.com/apache/isis-app-todoapp[TodoApp]
-* https://github.com/isisaddons/isis-app-kitchensink[Kitchensink]
-* https://github.com/isisaddons/isis-app-quickstart[Quickstart]
-
-_Experiments_
+//|
+//[discrete]
+//== Real-world Apps
+//
+//* https://github.com/estatio/estatio[Estatio]
+//* https://github.com/incodehq/contactapp[ContactApp]
+//* https://github.com/incodehq/ecpcrm[ECP CRM]
 
-* https://github.com/isisaddons/isis-app-neoapp[Neo4J Example]
-* https://github.com/isisaddons/isis-app-simpledsl[Isis DSL Example]
+//_Example Apps_
 
+//* https://github.com/apache/isis-app-todoapp[TodoApp]
+//* https://github.com/isisaddons/isis-app-kitchensink[Kitchensink]
+//* https://github.com/isisaddons/isis-app-quickstart[Quickstart]
 
-|
-[discrete]
-== 3rd party
-
-_Restful Objects viewers_
+//_Experiments_
+//
+//* https://github.com/isisaddons/isis-app-neoapp[Neo4J Example]
+//* https://github.com/isisaddons/isis-app-simpledsl[Isis DSL Example]
 
-* link:https://github.com/sebastianslutzky/AngularViewerCLI[AngularViewer]
-* link:https://github.com/sebastianslutzky/rob[ROB]
-* link:https://github.com/joerg-rade/kroviz[Kroviz]
 
-|
-[discrete]
+//|
+//[discrete]
+//== 3rd party
+//
+//_Restful Objects viewers_
+//
+//* link:https://github.com/sebastianslutzky/AngularViewerCLI[AngularViewer]
+//* link:https://github.com/sebastianslutzky/rob[ROB]
+//
+//|
+//[discrete]
 
 
 
diff --git a/antora/components/system/antora.yml b/antora/components/system/antora.yml
index 851f1ee..6e4ac78 100644
--- a/antora/components/system/antora.yml
+++ b/antora/components/system/antora.yml
@@ -20,3 +20,7 @@ title: "System Overview"
 version: latest
 start_page: generated:system-overview.adoc
 
+nav:
+- modules/generated/nav.adoc
+
+
diff --git a/antora/components/system/modules/generated/pages/system-overview.adoc b/antora/components/system/modules/generated/pages/system-overview.adoc
index 4613a68..82fbe17 100644
--- a/antora/components/system/modules/generated/pages/system-overview.adoc
+++ b/antora/components/system/modules/generated/pages/system-overview.adoc
@@ -499,7 +499,7 @@ Folder: \core\runtime
 
 _Components_
 
-* o.a.i.core.runtime.events.AppLifecycleEventService
+* o.a.i.core.runtime.events.MetamodelEventService
 * o.a.i.core.runtime.events.TransactionEventEmitter
 
 _Dependencies_
@@ -528,12 +528,11 @@ _Components_
 * o.a.i.core.runtimeservices.confmenu.ConfigurationViewServiceDefault
 * o.a.i.core.runtimeservices.email.EmailServiceDefault
 * o.a.i.core.runtimeservices.eventbus.EventBusServiceSpring
-* o.a.i.core.runtimeservices.exceprecog.ExceptionRecognizerServiceDefault
 * o.a.i.core.runtimeservices.executor.MemberExecutorServiceDefault
 * o.a.i.core.runtimeservices.factory.FactoryServiceDefault
 * o.a.i.core.runtimeservices.homepage.HomePageResolverServiceDefault
 * o.a.i.core.runtimeservices.i18n.po.TranslationServicePo
-* o.a.i.core.runtimeservices.ixn.InteractionDtoServiceInternalDefault
+* o.a.i.core.runtimeservices.interaction.InteractionDtoServiceInternalDefault
 * o.a.i.core.runtimeservices.jaxb.JaxbServiceDefault
 * o.a.i.core.runtimeservices.menubars.MenuBarsLoaderServiceDefault
 * o.a.i.core.runtimeservices.menubars.bootstrap3.MenuBarsServiceBS3
@@ -543,17 +542,23 @@ _Components_
 * o.a.i.core.runtimeservices.publish.EntityPropertyChangePublisherDefault
 * o.a.i.core.runtimeservices.publish.ExecutionPublisherDefault
 * o.a.i.core.runtimeservices.queryresultscache.QueryResultsCacheDefault
+* o.a.i.core.runtimeservices.recognizer.ExceptionRecognizerServiceDefault
+* o.a.i.core.runtimeservices.recognizer.dae.impl.ExceptionRecognizerForDataAlreadyExists
+* o.a.i.core.runtimeservices.recognizer.dae.impl.ExceptionRecognizerForObjectNotFound
+* o.a.i.core.runtimeservices.recognizer.dae.impl.ExceptionRecognizerForOtherDataAccessProblem
+* o.a.i.core.runtimeservices.recognizer.dae.impl.ExceptionRecognizerForRelatedDataExists
+* o.a.i.core.runtimeservices.recognizer.dae.impl.ExceptionRecognizerForUnableToSaveData
 * o.a.i.core.runtimeservices.repository.RepositoryServiceDefault
 * o.a.i.core.runtimeservices.routing.RoutingServiceDefault
 * o.a.i.core.runtimeservices.scratchpad.ScratchpadDefault
 * o.a.i.core.runtimeservices.session.InteractionFactoryDefault
 * o.a.i.core.runtimeservices.sudo.SudoServiceDefault
+* o.a.i.core.runtimeservices.transaction.TransactionServiceSpring
 * o.a.i.core.runtimeservices.urlencoding.UrlEncodingServiceWithCompression
 * o.a.i.core.runtimeservices.user.UserServiceDefault
 * o.a.i.core.runtimeservices.userprof.UserProfileServiceDefault
 * o.a.i.core.runtimeservices.userreg.EmailNotificationServiceDefault
 * o.a.i.core.runtimeservices.wrapper.WrapperFactoryDefault
-* o.a.i.core.runtimeservices.xactn.TransactionServiceSpring
 * o.a.i.core.runtimeservices.xml.XmlServiceDefault
 * o.a.i.core.runtimeservices.xmlsnapshot.XmlSnapshotServiceDefault
 
@@ -1237,10 +1242,9 @@ _Components_
 * o.a.i.persistence.jdo.datanucleus.config.DnEntityDiscoveryListener
 * o.a.i.persistence.jdo.datanucleus.config.DnSettings
 * o.a.i.persistence.jdo.datanucleus.entities.DnEntityStateProvider
-* o.a.i.persistence.jdo.datanucleus.exceptions.recognizers.ExceptionRecognizerForJDODataStoreException
-* o.a.i.persistence.jdo.datanucleus.exceptions.recognizers.ExceptionRecognizerForJDODataStoreExceptionIntegrityConstraintViolationForeignKeyNoActionException
-* o.a.i.persistence.jdo.datanucleus.exceptions.recognizers.ExceptionRecognizerForJDOObjectNotFoundException
-* o.a.i.persistence.jdo.datanucleus.exceptions.recognizers.ExceptionRecognizerForSQLIntegrityConstraintViolationUniqueOrIndexException
+* o.a.i.persistence.jdo.datanucleus.jdosupport.JdoSupportServiceDefault
+* o.a.i.persistence.jdo.datanucleus.metamodel.JdoDataNucleusProgrammingModel
+* o.a.i.persistence.jdo.datanucleus.schema.JdoSchemaService
 
 _Dependencies_
 
@@ -1269,12 +1273,6 @@ Folder: \persistence\jdo\integration
 ----
 |JDO Integration (powered by DataNucleus)
 
-_Components_
-
-* o.a.i.persistence.jdo.integration.jdosupport.IsisJdoSupportDN5
-* o.a.i.persistence.jdo.integration.metamodel.JdoIntegrationProgrammingModel
-* o.a.i.persistence.jdo.integration.schema.JdoSchemaService
-
 _Dependencies_
 
 * org.apache.isis.commons:isis-commons:jar:<managed>
@@ -1426,6 +1424,10 @@ Folder: \persistence\jpa\metamodel
 ----
 |JPA Metamodel Facets / Programming Model
 
+_Components_
+
+* o.a.i.persistence.jpa.metamodel.JpaProgrammingModel
+
 _Dependencies_
 
 * org.apache.isis.core:isis-core-internaltestsupport:jar:<managed>
@@ -2925,12 +2927,12 @@ skinparam rectangle<<31>> {
   FontColor #fffffe
   BorderColor #2E6295
 }
-skinparam rectangle<<10>> {
+skinparam rectangle<<32>> {
   BackgroundColor #438dd5
   FontColor #fffffe
   BorderColor #2E6295
 }
-skinparam rectangle<<32>> {
+skinparam rectangle<<10>> {
   BackgroundColor #438dd5
   FontColor #fffffe
   BorderColor #2E6295
@@ -3528,7 +3530,15 @@ Artifact: isis-extensions-secman-persistence-jpa
 Type: jar
 Folder: \extensions\security\secman\persistence-jpa
 ----
-|_Dependencies_
+|_Components_
+
+* o.a.i.extensions.secman.jpa.dom.permission.ApplicationPermissionRepository
+* o.a.i.extensions.secman.jpa.dom.role.ApplicationRoleRepository
+* o.a.i.extensions.secman.jpa.dom.tenancy.ApplicationTenancyRepository
+* o.a.i.extensions.secman.jpa.dom.user.ApplicationUserRepository
+* o.a.i.extensions.secman.jpa.seed.SeedSecurityModuleService
+
+_Dependencies_
 
 * org.apache.isis.core:isis-core-runtime:jar:<managed>
 * org.apache.isis.extensions:isis-extensions-secman-api:jar:<managed>
@@ -3604,12 +3614,12 @@ skinparam rectangle<<11>> {
   FontColor #fffffe
   BorderColor #2E6295
 }
-skinparam rectangle<<23>> {
+skinparam rectangle<<12>> {
   BackgroundColor #438dd5
   FontColor #fffffe
   BorderColor #2E6295
 }
-skinparam rectangle<<12>> {
+skinparam rectangle<<23>> {
   BackgroundColor #438dd5
   FontColor #fffffe
   BorderColor #2E6295
@@ -5081,3 +5091,66 @@ _Dependencies_
 * org.apache.isis.viewer:isis-viewer-wicket-ui:jar:<managed>
 * org.datanucleus:javax.jdo:jar:<managed>
 |===
+
+== Other
+
+[plantuml,Other,svg]
+----
+@startuml(id=Other)
+title Other - Containers
+caption Artifact Hierarchy (Maven)
+
+skinparam {
+  shadowing false
+  arrowFontSize 10
+  defaultTextAlignment center
+  wrapWidth 200
+  maxMessageSize 100
+}
+hide stereotype
+skinparam rectangle<<2>> {
+  BackgroundColor #438dd5
+  FontColor #fffffe
+  BorderColor #2E6295
+}
+skinparam rectangle<<3>> {
+  BackgroundColor #438dd5
+  FontColor #fffffe
+  BorderColor #2E6295
+}
+package "Other\n[Software System]" {
+  rectangle "==Apache Isis Starter Parent\n<size:10>[Container: packaging: pom]</size>" <<2>> as 2
+  rectangle "==Apache Isis Supplemental - Legal Info\n<size:10>[Container: packaging: jar]</size>" <<3>> as 3
+}
+@enduml
+----
+.Projects/Modules (Other)
+[cols="3a,5a", options="header"]
+|===
+|Coordinates |Description 
+
+|Apache Isis Starter Parent
+[source,yaml]
+----
+Group: org.apache.isis.app
+Artifact: isis-app-starter-parent
+Type: pom
+Folder: \starters
+----
+|Parent pom providing dependency and plugin management for Apache Isis applications
+		built with Maven.  Builds on top of spring-boot-starter-parent.
+
+|Apache Isis Supplemental - Legal Info
+[source,yaml]
+----
+Group: org.apache.isis
+Artifact: supplemental-model
+Type: jar
+Folder: \supplemental-model
+----
+|For example, the templates used by many Apache distributions assemble a listing of project dependencies 
+  	according to their organization name (and URL), along with the URL each project's website. When dependency 
+  	POMs are missing this information, the dependency notice file that the Remote Resources Plugin renders can 
+  	be invalid.
+	To compensate for incomplete dependency POMs, we use the supplemental models support.
+|===
diff --git a/antora/playbooks/site-mappings.yml b/antora/playbooks/site-mappings.yml
index 3b0d2e0..7d478a9 100644
--- a/antora/playbooks/site-mappings.yml
+++ b/antora/playbooks/site-mappings.yml
@@ -44,7 +44,7 @@ content:
       start_path: mappings/minio/adoc # mappings
       branches: HEAD
     - url: .
-      start_path: mappings/publisher/adoc # mappings
+      start_path: mappings/outbox-publisher/adoc # mappings
       branches: HEAD
     - url: .
       start_path: mappings/restclient/adoc # mappings
diff --git a/antora/playbooks/site-tooling.yml b/antora/playbooks/site-tooling.yml
index 3384db2..e32af13 100644
--- a/antora/playbooks/site-tooling.yml
+++ b/antora/playbooks/site-tooling.yml
@@ -30,6 +30,15 @@ content:
     - url: .
       start_path: antora/components/comguide # comguide
       branches: HEAD
+    - url: .
+      start_path: antora/components/system # system
+      branches: HEAD
+
+# core
+    - url: .
+      start_path: core/adoc # core (design docs)
+      branches: HEAD
+
 # examples
     - url: .
       start_path: examples/demo/domain/src/main/adoc # docs
diff --git a/antora/playbooks/site.yml b/antora/playbooks/site.yml
index 67c3d45..9ecf72e 100644
--- a/antora/playbooks/site.yml
+++ b/antora/playbooks/site.yml
@@ -59,7 +59,7 @@ content:
 
 # core
     - url: .
-      start_path: core/adoc # core
+      start_path: core/adoc  # core (design docs)
       branches: HEAD
     - url: .
       start_path: core/codegen-bytebuddy/src/main/adoc # core
@@ -198,7 +198,7 @@ content:
       start_path: mappings/minio/adoc # mappings
       branches: HEAD
     - url: .
-      start_path: mappings/publisher/adoc # mappings
+      start_path: mappings/outbox-publisher/adoc # mappings
       branches: HEAD
     - url: .
       start_path: mappings/restclient/adoc # mappings
diff --git a/antora/supplemental-ui/css/site-custom.css b/antora/supplemental-ui/css/site-custom.css
index 11b8a16..362e9fb 100644
--- a/antora/supplemental-ui/css/site-custom.css
+++ b/antora/supplemental-ui/css/site-custom.css
@@ -49,3 +49,9 @@ div.paragraph code {
     padding-left: 1rem;
 }
 
+input#algolia-search-layout {
+    min-width: 23em;
+    padding: 5px;
+    border: 2px solid #87a83f;
+    border-radius: 5px;
+}
diff --git a/core/adoc/modules/ROOT/pages/about.adoc b/core/adoc/modules/ROOT/pages/about.adoc
index 06416f6..e6c0129 100644
--- a/core/adoc/modules/ROOT/pages/about.adoc
+++ b/core/adoc/modules/ROOT/pages/about.adoc
@@ -3,9 +3,12 @@
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
-This guide documents the design and implementation of the core framework.
+This section documents the design and implementation of the core framework.
 
-There is documentation for most, though not all, of the core framework.
-The ones that are missing - for example the `core/applib` module - instead contribute to the end-user documentation set.
-They will therefore be found in either the xref:userguide:ROOT:about.adoc[user guide], xref:refguide:ROOT:about.adoc[reference guide], xref:security:ROOT:about.adoc[security guide] or xref:testing:ROOT:about.adoc[testing guide].
+We also include some design documentation - where it provides useful context - in the end-user documentation set:
+
+* xref:userguide:ROOT:about.adoc[user guide]
+* xref:refguide:ROOT:about.adoc[reference guide]
+* xref:security:ROOT:about.adoc[security guide]
+* xref:testing:ROOT:about.adoc[testing guide].
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/Other.adoc b/core/config/src/main/adoc/modules/config/pages/sections/Other.adoc
index 369e82c..8e2eded 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/Other.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/Other.adoc
@@ -19,6 +19,41 @@ isis.as-map
 | null
 
 
+|
+[[isis.persistence.jpa.additional-orm-files]]
+isis.persistence.jpa. +
+additional-orm-files
+
+| 
+| Does lookup additional "mapping-files" in META-INF/orm-_name_.xml (equivalent to "mapping-file" entries in persistence.xml) and adds these to those that are already configured the _Spring Data_ way (if any).
+
+
+|
+[[isis.persistence.jpa.auto-create-schemas]]
+isis.persistence.jpa. +
+auto-create-schemas
+
+| 
+| List of additional schemas to be auto-created.
+
+Explicitly creates given list of schemas by using the specified ``#getCreateSchemaSqlTemplate()`` to generate the actual SQL statement against the configured data-source.
+
+This configuration mechanism does not consider any schema-auto-creation configuration (if any), that independently is provided the standard JPA way.
+
+
+|
+[[isis.persistence.jpa.create-schema-sql-template]]
+isis.persistence.jpa. +
+create-schema-sql-template
+
+| 
+| SQL syntax to create a DB schema.
+
+This template is passed through schemaName) to make the actual SQL statement thats to be used against the configured data-source.
+
+Default template is \{@literal CREATE SCHEMA IF NOT EXISTS %S} with the schema name converted to upper-case.
+
+
 
 |===
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.applib.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.applib.adoc
index 9f0ea2b..e679f8a 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.applib.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.applib.adoc
@@ -6,8 +6,6 @@
 
 include::../section-hooks/isis.applib~pre.adoc[]
 
-WARNING: TODO, outdated due to changes in Nov '20 ... the table below should rather be auto-generated from IsisConfiguration's java-doc.  
-
 [cols="3a,2a,5a", options="header"]
 |===
 |Property
@@ -41,14 +39,14 @@ The CSS class for individual actions can be overridden using ``ActionLayout#cssC
 
 
 |
-[[isis.applib.annotation.action.command]]
+[[isis.applib.annotation.action.command-publishing]]
 isis.applib.annotation.action. +
-command
+command-publishing
 
 | 
-| The default for whether action invocations should be reified as a ``Command``, to be sent to any registered ``CommandServiceListener``s, either for auditing or for replayed against a secondary system, eg for regression testing.
+| TODO[2464] semantic renaming audit/dispatch -> publishing The default for whether action invocations should be reified as a ``Command``, to be sent to any registered ``CommandSubscriber``s, either for auditing or for replayed against a secondary system, eg for regression testing.
 
-This setting can be overridden on a case-by-case basis using ``Action#command()``.
+This setting can be overridden on a case-by-case basis using ``Action#commandPublishing()``.
 
 
 |
@@ -56,7 +54,7 @@ This setting can be overridden on a case-by-case basis using ``Action#command()`
 isis.applib.annotation.action. +
 domain-event.post-for-default
 
-|  true
+| 
 | Influences whether an ``ActionDomainEvent`` should be published (on the internal ``EventBusService``) whenever an action is being interacted with.
 
 Up to five different events can be fired during an interaction, with the event's phase determining which (hide, disable, validate, executing and executed). Subscribers can influence the behaviour at each of these phases.
@@ -69,25 +67,25 @@ The algorithm for determining whether (and what type of) an event is actually se
 
 
 |
-[[isis.applib.annotation.action.explicit]]
+[[isis.applib.annotation.action.execution-publishing]]
 isis.applib.annotation.action. +
-explicit
+execution-publishing
 
 | 
-| Whether or not a public method needs to be annotated with @``Action`` in order to be picked up as an action in the metamodel.
+| TODO[2464] semantic renaming audit/dispatch -> publishing The default for whether action invocations should be sent through to the ``ExecutionSubscriber`` for publishing.
+
+The service's publish method is called only once per transaction, with ``Execution`` collecting details of the identity of the target object, the action invoked, the action arguments and the returned object (if any).
+
+This setting can be overridden on a case-by-case basis using ``Action#executionDispatch()``.
 
 
 |
-[[isis.applib.annotation.action.publishing]]
+[[isis.applib.annotation.action.explicit]]
 isis.applib.annotation.action. +
-publishing
+explicit
 
 | 
-| The default for whether action invocations should be sent through to the ``PublisherService`` for publishing.
-
-The service's publish method is called only once per transaction, with ``Execution`` collecting details of the identity of the target object, the action invoked, the action arguments and the returned object (if any).
-
-This setting can be overridden on a case-by-case basis using ``Action#publishing()``.
+| Whether or not a public method needs to be annotated with @``Action`` in order to be picked up as an action in the metamodel.
 
 
 |
@@ -106,7 +104,7 @@ The value of this can be overridden on a case-by-case basis using ``CollectionLa
 isis.applib.annotation. +
 collection-layout.paged
 
-|  12
+| 
 | Defines the default number of objects that are shown in a "parented" collection of a domain object, result of invoking an action.
 
 This can be overridden on a case-by-case basis using ``CollectionLayout#paged()``.
@@ -117,7 +115,7 @@ This can be overridden on a case-by-case basis using ``CollectionLayout#paged()`
 isis.applib.annotation.collection. +
 domain-event.post-for-default
 
-|  true
+| 
 | Influences whether an ``CollectionDomainEvent`` should be published (on the internal ``EventBusService``) whenever a collection is being interacted with.
 
 Up to two different events can be fired during an interaction, with the event's phase determining which (hide, disable)Subscribers can influence the behaviour at each of these phases.
@@ -191,7 +189,7 @@ The default is ``false``, because otherwise the mere presence of ``@DomainObject
 isis.applib.annotation. +
 domain-object-layout.paged
 
-|  25
+| 
 | Defines the default number of objects that are shown in a "standalone" collection obtained as the result of invoking an action.
 
 This can be overridden on a case-by-case basis using ``DomainObjectLayout#paged()``.
@@ -216,26 +214,13 @@ The default is ``false``, because otherwise the mere presence of ``@DomainObject
 
 
 |
-[[isis.applib.annotation.domain-object.auditing]]
-isis.applib.annotation. +
-domain-object.auditing
-
-| 
-| The default for whether _domain entities_ should be audited or not (meaning that any changes are sent through to the ``AuditerService``.
-
-This setting can be overridden on a case-by-case basis using ``DomainObject#auditing()`` DomainObject#getAuditing()}
-
-Note: this applies only to domain entities, not view models.
-
-
-|
 [[isis.applib.annotation.domain-object.created-lifecycle-event.post-for-default]]
 isis.applib.annotation. +
 domain-object. +
 created-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectCreatedEvent`` should be published (on the internal ``EventBusService``) whenever a domain object has been created using ``FactoryService``.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(createdLifecycleEvent=...) for the domain object in question.
@@ -257,13 +242,27 @@ This setting can be overridden on a case-by-case basis using DomainObject#getEdi
 
 
 |
+[[isis.applib.annotation.domain-object.entity-change-publishing]]
+isis.applib.annotation. +
+domain-object. +
+entity-change-publishing
+
+| 
+| TODO[2464] semantic renaming audit/dispatch -> publishing The default for whether _domain entities_ should be audited or not (meaning that any changes are sent through to ``EntityChangesSubscriber``s and sent through to ``EntityPropertyChangeSubscriber``.
+
+This setting can be overridden on a case-by-case basis using ``DomainObject#entityChangePublishing()``
+
+Note: this applies only to domain entities, not view models.
+
+
+|
 [[isis.applib.annotation.domain-object.loaded-lifecycle-event.post-for-default]]
 isis.applib.annotation. +
 domain-object. +
 loaded-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectLoadedEvent`` should be published (on the internal ``EventBusService``) whenever a domain _entity_ has been loaded from the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(loadedLifecycleEvent=...) for the domain object in question.
@@ -282,7 +281,7 @@ domain-object. +
 persisted-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectPersistedEvent`` should be published (on the internal ``EventBusService``) whenever a domain _entity_ has been persisted (for the first time) to the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(persistedLifecycleEvent=...) for the domain object in question.
@@ -301,7 +300,7 @@ domain-object. +
 persisting-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectPersistingEvent`` should be published (on the internal ``EventBusService``) whenever a domain _entity_ is about to be persisting (for the first time) to the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(persistingLifecycleEvent=...) for the domain object in question.
@@ -314,26 +313,13 @@ Note: this applies only to domain entities, not to view models.
 
 
 |
-[[isis.applib.annotation.domain-object.publishing]]
-isis.applib.annotation. +
-domain-object.publishing
-
-| 
-| The default for whether the identities of changed objects should be sent through to the ``PublisherService`` for publishing.
-
-The service's publish method is called only once per transaction, with ``PublishedObjects`` collecting details of all changed domain objects.
-
-This setting can be overridden on a case-by-case basis using ``DomainObject#publishing()``.
-
-
-|
 [[isis.applib.annotation.domain-object.removing-lifecycle-event.post-for-default]]
 isis.applib.annotation. +
 domain-object. +
 removing-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectRemovingEvent`` should be published (on the internal ``EventBusService``) whenever a persistent domain _entity_ is about to be removed (that is, deleted) from the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(removingLifecycleEvent=...) for the domain object in question.
@@ -354,7 +340,7 @@ domain-object. +
 updated-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectUpdatedEvent`` should be published (on the internal ``EventBusService``) whenever a persistent domain _entity_ has been updated in the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(updatedLifecycleEvent=...) for the domain object in question.
@@ -373,7 +359,7 @@ domain-object. +
 updating-lifecycle-event. +
 post-for-default
 
-|  true
+| 
 | Influences whether an ``ObjectUpdatingEvent`` should be published (on the internal ``EventBusService``) whenever a persistent domain _entity_ is about to be updated in the persistence store.
 
 The algorithm for determining whether (and what type of) an event is sent depends on the value of the @DomainObject(updatingLifecycleEvent=...) for the domain object in question.
@@ -412,14 +398,14 @@ If left as ``LabelPosition#NOT_SPECIFIED`` and not overridden, then the position
 
 
 |
-[[isis.applib.annotation.property.command]]
+[[isis.applib.annotation.property.command-publishing]]
 isis.applib.annotation.property. +
-command
+command-publishing
 
 | 
-| The default for whether property edits should be reified as a ``Command``, to be sent to any registered ``CommandServiceListener``s, either for auditing or for replayed against a secondary system, eg for regression testing.
+| TODO[2464] semantic renaming audit/dispatch -> publishing The default for whether property edits should be reified as a ``Command``, to be sent to any registered ``CommandSubscriber``s, either for auditing or for replayed against a secondary system, eg for regression testing.
 
-This setting can be overridden on a case-by-case basis using ``Property#command()``.
+This setting can be overridden on a case-by-case basis using ``Property#commandDispatch()``.
 
 
 |
@@ -427,7 +413,7 @@ This setting can be overridden on a case-by-case basis using ``Property#command(
 isis.applib.annotation.property. +
 domain-event.post-for-default
 
-|  true
+| 
 | Influences whether an ``PropertyDomainEvent`` should be published (on the internal ``EventBusService``) whenever an property is being interacted with.
 
 Up to five different events can be fired during an interaction, with the event's phase determining which (hide, disable, validate, executing and executed). Subscribers can influence the behaviour at each of these phases.
@@ -440,12 +426,12 @@ The algorithm for determining whether (and what type of) an event is actually se
 
 
 |
-[[isis.applib.annotation.property.publishing]]
+[[isis.applib.annotation.property.execution-publishing]]
 isis.applib.annotation.property. +
-publishing
+execution-publishing
 
 | 
-| The default for whether property edits should be sent through to the ``PublisherService`` for publishing.
+| TODO[2464] semantic renaming audit/dispatch -> publishing The default for whether property edits should be sent through to the ``ExecutionSubscriber`` for publishing.
 
 The service's publish method is called only once per transaction, with ``Execution`` collecting details of the identity of the target object, the property edited, and the new value of the property.
 
@@ -459,11 +445,10 @@ view-model-layout. +
 css-class-ui-event. +
 post-for-default
 
-|  true
-| Influences whether an ``CssClassUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @DomainObject(nature=VIEW_MODEL)) is about to be rendered in the UI - thereby allowing subscribers to optionally ``CssClassUiEvent#setCssClass(String)`` change) the CSS classes that are used.
+| 
+| Influences whether an ``CssClassUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @ViewModel) is about to be rendered in the UI - thereby allowing subscribers to optionally ``CssClassUiEvent#setCssClass(String)`` change) the CSS classes that are used.
 
-(TODO: ViewModel and ViewModelLayout have been removed) 
-The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``DomainObjectLayout#cssClassUiEvent()`` @DomainObjectLayout(cssClassEvent=...)} for the domain object in question:
+The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``ViewModelLayout#cssClassUiEvent()`` @ViewModelLayout(cssClassEvent=...)} for the domain object in question:
 
 * If set to some subtype of CssClassUiEvent.Noop, then _no_ event is sent.
 * If set to some subtype of CssClassUiEvent.Default, then an event is sent _if and only if_ this configuration setting is set.
@@ -476,11 +461,10 @@ isis.applib.annotation. +
 view-model-layout.icon-ui-event. +
 post-for-default
 
-|  true
-| Influences whether an ``IconUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @DomainObject(nature=VIEW_MODEL)) is about to be rendered in the UI - thereby allowing subscribers to optionally ``IconUiEvent#setIconName(String)`` change) the icon that is used.
+| 
+| Influences whether an ``IconUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @ViewModel) is about to be rendered in the UI - thereby allowing subscribers to optionally ``IconUiEvent#setIconName(String)`` change) the icon that is used.
 
-(TODO: ViewModel and ViewModelLayout have been removed)
-The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``DomainObjectLayout#iconUiEvent()`` @DomainObjectLayout(iconEvent=...)} for the domain object in question:
+The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``ViewModelLayout#iconUiEvent()`` @ViewModelLayout(iconEvent=...)} for the domain object in question:
 
 * If set to some subtype of IconUiEvent.Noop, then _no_ event is sent.
 * If set to some subtype of IconUiEvent.Default, then an event is sent _if and only if_ this configuration setting is set.
@@ -493,13 +477,12 @@ isis.applib.annotation. +
 view-model-layout.layout-ui-event. +
 post-for-default
 
-|  true
-| Influences whether an ``LayoutUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @DomainObject(nature=VIEW_MODEL)) is about to be rendered in the UI - thereby allowing subscribers to optionally ``LayoutUiEvent#setLayout(String)`` change) the layout that is used.
+| 
+| Influences whether an ``LayoutUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @ViewModel) is about to be rendered in the UI - thereby allowing subscribers to optionally ``LayoutUiEvent#setLayout(String)`` change) the layout that is used.
 
-(TODO: ViewModel and ViewModelLayout have been removed)
 If a different layout value has been set, then a layout in the form ``xml`` use used (where ``zzz`` is the name of the layout).
 
-The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``DomainObjectLayout#layoutUiEvent()`` @DomainObjectLayout(layoutEvent=...)} for the domain object in question:
+The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``ViewModelLayout#layoutUiEvent()`` @ViewModelLayout(layoutEvent=...)} for the domain object in question:
 
 * If set to some subtype of LayoutUiEvent.Noop, then _no_ event is sent.
 * If set to some subtype of LayoutUiEvent.Default, then an event is sent _if and only if_ this configuration setting is set.
@@ -512,11 +495,10 @@ isis.applib.annotation. +
 view-model-layout.title-ui-event. +
 post-for-default
 
-|  true
-| Influences whether an ``TitleUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @DomainObject(nature=VIEW_MODEL)) is about to be rendered in the UI - thereby allowing subscribers to optionally ``TitleUiEvent#setTitle(String)`` change) the title that is used.
+| 
+| Influences whether an ``TitleUiEvent`` should be published (on the internal ``EventBusService``) whenever a view model (annotated with @ViewModel) is about to be rendered in the UI - thereby allowing subscribers to optionally ``TitleUiEvent#setTitle(String)`` change) the title that is used.
 
-(TODO: ViewModel and ViewModelLayout have been removed)
-The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``DomainObjectLayout#titleUiEvent()`` @DomainObjectLayout(titleEvent=...)} for the domain object in question:
+The algorithm for determining whether (and what type of) an event is sent depends on the value of the ``ViewModelLayout#titleUiEvent()`` @ViewModelLayout(titleEvent=...)} for the domain object in question:
 
 * If set to some subtype of TitleUiEvent.Noop, then _no_ event is sent.
 * If set to some subtype of TitleUiEvent.Default, then an event is sent _if and only if_ this configuration setting is set.
@@ -530,8 +512,7 @@ validation.semantic-checking. +
 enable
 
 | 
-| (TODO: ViewModel and ViewModelLayout have been removed) 
-Whether to check for inconsistencies between the usage of ``DomainObject``, ``ViewModel``, ``DomainObjectLayout`` and ``ViewModelLayout``.
+| Whether to check for inconsistencies between the usage of ``DomainObject``, ``ViewModel``, ``DomainObjectLayout`` and ``ViewModelLayout``.
 
 
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.adoc
index a194ad1..a2dcbfe 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.adoc
@@ -16,7 +16,7 @@ include::../section-hooks/isis.core.meta-model~pre.adoc[]
 isis.core.meta-model. +
 filter-visibility
 
-|  true
+| 
 | Whether domain objects to which the current user does not have visibility access should be rendered within collections or drop-down choices/autocompletes.
 
 One reason this filtering may be necessary is for multi-tenanted applications, whereby an end-user should only be able to "see" what data that they own. For efficiency, the application should only query for objects that the end-user owns. This configuration property acts as a safety net to prevent the end-user from viewing domain objects _even if_ those domain objects were rehydrated from the persistence store.
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.introspector.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.introspector.adoc
index d288d75..a55b77f 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.introspector.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.introspector.adoc
@@ -16,7 +16,7 @@ include::../section-hooks/isis.core.meta-model.introspector~pre.adoc[]
 isis.core.meta-model.introspector. +
 lock-after-full-introspection
 
-|  true
+| 
 | If true, then no new specifications will be allowed to be loaded once introspection has been complete.
 
 Only applies if the introspector is configured to perform full introspection up-front (either because of ``IntrospectionMode#FULL`` or ``IntrospectionMode#LAZY_UNLESS_PRODUCTION`` when in production); otherwise is ignored.
@@ -49,7 +49,7 @@ For now this is _experimental_. Leave this disabled (the default).
 isis.core.meta-model.introspector. +
 validate-incrementally
 
-|  true
+| 
 | If true, then metamodel validation is performed after any new specification has been loaded (after the initial bootstrapping).
 
 This does _not_ apply if the introspector is configured to perform full introspection up-front AND when the metamodel is locked after initial bootstrapping (because in that case the lock check will simply prevent any new specs from being loaded). But it will apply otherwise.
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.validator.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.validator.adoc
index 34b4a40..468b40d 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.validator.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.meta-model.validator.adoc
@@ -17,7 +17,7 @@ isis.core.meta-model.validator. +
 action-collection-parameter- +
 choices
 
-|  true
+| 
 | Whether to validate that any actions that accept action parameters have either a corresponding choices or auto-complete for that action parameter, or are associated with a collection of the appropriate type.
 
 
@@ -26,7 +26,7 @@ choices
 isis.core.meta-model.validator. +
 allow-deprecated
 
-|  true
+| 
 | This setting is used to determine whether the use of such deprecated features is allowed.
 
 If not allowed, then metamodel validation errors will be flagged.
@@ -39,7 +39,7 @@ Note that this settings has no effect if the programming model has been configur
 isis.core.meta-model.validator. +
 ensure-unique-object-types
 
-|  true
+| 
 | Whether to ensure that the object type of all objects (which can be set either explicitly using ``DomainObject#objectType()`` or ``DomainService#objectType()``, or can be inferred implicitly using a variety of mechanisms) must be unique with respect to all other object types.
 
 It is _highly advisable_ to leave this set as enabled (the default), and to also use explicit types (see ``#isExplicitObjectType()``.
@@ -62,7 +62,7 @@ isis.core.meta-model.validator. +
 jaxb-view-model. +
 date-time-type-adapter
 
-|  true
+| 
 | If set, then ensures that for all properties of JAXB-style view models where the property's type is a date or time, then that property has been correctly annotated with @``XmlJavaTypeAdapter`` (so that the property's value can be converted into a serializable form).
 
 
@@ -80,7 +80,7 @@ jaxb-view-model.no-arg-constructor
 isis.core.meta-model.validator. +
 jaxb-view-model.not-abstract
 
-|  true
+| 
 | If set, then ensures that all JAXB-style view models are concrete classes, not abstract.
 
 
@@ -89,7 +89,7 @@ jaxb-view-model.not-abstract
 isis.core.meta-model.validator. +
 jaxb-view-model.not-inner-class
 
-|  true
+| 
 | If set, then ensures that all JAXB-style view models are either top-level classes or nested static classes (in other words, checks that they are not anonymous, local nor nested non-static classes).
 
 
@@ -99,7 +99,7 @@ isis.core.meta-model.validator. +
 jaxb-view-model. +
 reference-type-adapter
 
-|  true
+| 
 | If set, then ensures that for all properties of JAXB-style view models where the property's type is an entity, then that entity's type has been correctly annotated with @``XmlJavaTypeAdapter`` (so that the property's value can be converted into a serializable form).
 
 
@@ -108,7 +108,7 @@ reference-type-adapter
 isis.core.meta-model.validator. +
 jdoql.from-clause
 
-|  true
+| 
 | If set, then ensures that the 'FROM' clause within any JDOQL ``@Query``s annotations relates to a known entity type, and moreover that that type is compatible with the type on which the annotation appears: meaning its either a supertype of or the same type as the annotated type.
 
 
@@ -117,7 +117,7 @@ jdoql.from-clause
 isis.core.meta-model.validator. +
 jdoql.variables-clause
 
-|  true
+| 
 | If set, then ensures that the 'VARIABLES' clause within any JDOQL ``@Query``s relates to a known entity type.
 
 
@@ -139,28 +139,10 @@ Note that this aspect of the programming model relates to the ``hideXxx`` and ``
 isis.core.meta-model.validator. +
 parallelize
 
-|  true
+| 
 | Whether to perform metamodel validation in parallel.
 
 
-|
-[[isis.core.meta-model.validator.mixins-only]]
-isis.core.meta-model.validator. +
-mixins-only
-
-|  true
-| If set, then domain services actions are not contributed to domain objects. @deprecated - in that in the future the programming model will simply not support contributed actions from domain services.
-
-
-|
-[[isis.core.meta-model.validator.service-actions-only]]
-isis.core.meta-model.validator. +
-service-actions-only
-
-|  true
-| If set, checks that any domain services have only actions associated with them, not properties or collections. @deprecated - in that in the future the programming model will simply not search for properties or collections of domain services.
-
-
 
 |===
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.runtime-services.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.runtime-services.adoc
index 23be405..1451ea6 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.core.runtime-services.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.core.runtime-services.adoc
@@ -52,7 +52,7 @@ override.to
 isis.core.runtime-services.email. +
 port
 
-|  587
+| 
 | The port to use for sending email.
 
 
@@ -107,7 +107,7 @@ If not specified, then the sender's email address will be used instead.
 isis.core.runtime-services.email. +
 socket-connection-timeout
 
-|  2000
+| 
 | The maximum number of millseconds to wait to obtain a socket connection before timing out.
 
 
@@ -116,7 +116,7 @@ socket-connection-timeout
 isis.core.runtime-services.email. +
 socket-timeout
 
-|  2000
+| 
 | The maximum number of millseconds to wait to obtain a socket before timing out.
 
 
@@ -125,7 +125,7 @@ socket-timeout
 isis.core.runtime-services.email. +
 throw-exception-on-fail
 
-|  true
+| 
 | If an email fails to send, whether to propagate the exception (meaning that potentially the end-user might see the exception), or whether instead to just indicate failure through the return value of the method (List, List, String, String, DataSource...) that's being called.
 
 
@@ -134,17 +134,17 @@ throw-exception-on-fail
 isis.core.runtime-services.email. +
 tls.enabled
 
-|  true
+| 
 | Whether TLS encryption should be started (that is, ``STARTTLS``).
 
 
 |
-[[isis.core.runtime-services.exception-recognizer.jdo.disable]]
+[[isis.core.runtime-services.exception-recognizer.dae.disable]]
 isis.core.runtime-services. +
-exception-recognizer.jdo.disable
+exception-recognizer.dae.disable
 
 | 
-| Whether the ``ExceptionRecognizer`` implementation for JDO/DataNucleus object store - which attempts to sanitize any exceptions arising from that object store - should be disabled (meaning that exceptions will potentially propagate as more serious to the end user).
+| Whether the ``ExceptionRecognizer`` implementation for Spring's DataAccessException - which attempts to sanitize any exceptions arising from object stores - should be disabled (meaning that exceptions will potentially propagate as more serious to the end user).
 
 
 |
@@ -176,6 +176,19 @@ There are three modes:
 * The disabled performs no translation and simply returns the original string unchanged. Unlike the write mode, it does _not_ keep track of translation requests.
 
 
+|
+[[isis.core.runtime-services.translation.resource-location]]
+isis.core.runtime-services. +
+translation.resource-location
+
+| 
+| Specifies the relative resource path to look for translation files.
+
+If \{@code null} uses \{@code servletContext.getResource("/WEB-INF/")}.
+
+Replaces the former Servlet context parameter 'isis.config.dir';
+
+
 
 |===
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.extensions.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.extensions.adoc
index 6ec6bfe..6a0fe5a 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.extensions.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.extensions.adoc
@@ -16,7 +16,7 @@ include::../section-hooks/isis.extensions~pre.adoc[]
 isis.extensions.command-replay. +
 analyser.exception.enabled
 
-|  true
+| 
 | null
 
 
@@ -25,7 +25,7 @@ analyser.exception.enabled
 isis.extensions.command-replay. +
 analyser.result.enabled
 
-|  true
+| 
 | null
 
 
@@ -34,7 +34,7 @@ analyser.result.enabled
 isis.extensions.command-replay. +
 batch-size
 
-|  10
+| 
 | null
 
 
@@ -80,7 +80,7 @@ isis.extensions.command-replay. +
 quartz-replicate-and-replay-job. +
 repeat-interval
 
-|  10000
+| 
 | Number of milliseconds before running again.
 
 
@@ -90,7 +90,7 @@ isis.extensions.command-replay. +
 quartz-replicate-and-replay-job. +
 start-delay
 
-|  15000
+| 
 | Number of milliseconds before starting the job.
 
 
@@ -99,8 +99,7 @@ start-delay
 isis.extensions.command-replay. +
 quartz-session.roles
 
-|  isisModuleExtCommandReplaySecondar +
-yRole
+| 
 | null
 
 
@@ -109,8 +108,7 @@ yRole
 isis.extensions.command-replay. +
 quartz-session.user
 
-|  isisModuleExtCommandReplaySecondar +
-yUser
+| 
 | The user that runs the replay session secondary.
 
 
@@ -124,6 +122,15 @@ secondary-access.base-url-wicket
 
 
 |
+[[isis.extensions.cors.allow-credentials]]
+isis.extensions.cors. +
+allow-credentials
+
+| 
+| TODO missing java-doc
+
+
+|
 [[isis.extensions.cors.allowed-headers]]
 isis.extensions.cors. +
 allowed-headers
@@ -150,7 +157,7 @@ For more information, check the usage of the ``methods`` init parameter for http
 isis.extensions.cors. +
 allowed-origins
 
-|  *
+| 
 | Which origins are allowed to make CORS requests.
 
 The default is the wildcard ("*") but this can be made more restrictive if necessary.
@@ -163,7 +170,7 @@ For more information, check the usage of the ``origins`` init parameter for http
 isis.extensions.cors. +
 exposed-headers
 
-|  Authorization
+| 
 | Which HTTP headers are exposed in a CORS request.
 
 For more information, check the usage of the ``headers`` init parameter for https://github.com/eBay/cors-filter[EBay CORSFilter].
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.adoc
index 496e236..b5745c5 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.adoc
@@ -16,9 +16,7 @@ include::../section-hooks/isis.persistence.jdo-datanucleus~pre.adoc[]
 isis.persistence.jdo-datanucleus. +
 class-metadata-loaded-listener
 
-|  org.apache.isis.persistence.jdo. +
-datanucleus5.datanucleus. +
-CreateSchemaObjectFromClassMetadata
+| 
 | null
 
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.impl.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.impl.adoc
index 986e28a..307b8d7 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.impl.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.persistence.jdo-datanucleus.impl.adoc
@@ -65,7 +65,7 @@ impl.datanucleus.cache.level2.mode
 isis.persistence.jdo-datanucleus. +
 impl.datanucleus.cache.level2.type
 
-|  none
+| 
 | Name of the type of Level 2 Cache to use.
 
 Can be used to interface with external caching products. Use "none" to turn off L2 caching.
@@ -131,36 +131,12 @@ impl.datanucleus.identifier.case
 
 
 |
-[[isis.persistence.jdo-datanucleus.impl.datanucleus.object-provider.class-name]]
-isis.persistence.jdo-datanucleus. +
-impl.datanucleus.object-provider. +
-class-name
-
-|  org.apache.isis.persistence.jdo. +
-datanucleus5.datanucleus. +
-JDOStateManagerForIsis
-| Enables dependency injection into entities
-
-See also ``json`` (camelCasing instead of kebab-casing).
-
-
-|
-[[isis.persistence.jdo-datanucleus.impl.datanucleus.objectProvider.className]]
-isis.persistence.jdo-datanucleus. +
-impl.datanucleus.objectProvider. +
-className
-
-| 
-| null
-
-
-|
 [[isis.persistence.jdo-datanucleus.impl.datanucleus.persistence-unit-load-classes]]
 isis.persistence.jdo-datanucleus. +
 impl.datanucleus. +
 persistence-unit-load-classes
 
-|  true
+| 
 | Used when we have specified the persistence-unit name for a PMF/EMF and where we want the datastore "tables" for all classes of that persistence-unit loading up into the StoreManager.
 
 Defaults to true, which is the opposite of DataNucleus' own default. (The reason that DN defaults to false is because some databases are slow so such an operation would slow down the startup process).
@@ -236,7 +212,7 @@ isis.persistence.jdo-datanucleus. +
 impl.datanucleus.schema. +
 validate-all
 
-|  true
+| 
 | See also ``json`` (camelCasing instead of kebab-casing).
 
 NOTE: this config property isn't used by the framework, but is provided as a convenience for IDE autocomplete.
@@ -399,8 +375,7 @@ isis.persistence.jdo-datanucleus. +
 impl.javax.jdo. +
 persistence-manager-factory-class
 
-|  org.datanucleus.api.jdo. +
-JDOPersistenceManagerFactory
+| 
 | See also ``json`` (camelCasing instead of kebab-casing).
 
 NOTE: changing this property from its default is used to enable the flyway extension (in combination with ``Schema#isAutoCreateAll()``
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.value-types.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.value-types.adoc
index a026acc..6bc178e 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.value-types.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.value-types.adoc
@@ -88,7 +88,7 @@ big-integer.format
 isis.value-types.java-sql.date. +
 format
 
-|  medium
+| 
 | Configures the formats understood by ``JavaSqlDateValueSemanticsProvider``. @deprecated
 
 
@@ -97,7 +97,7 @@ format
 isis.value-types.java-sql.time. +
 format
 
-|  short
+| 
 | Configures the formats understood by ``JavaSqlTimeValueSemanticsProvider``. @deprecated
 
 
@@ -106,7 +106,7 @@ format
 isis.value-types.java-sql. +
 timestamp.format
 
-|  short
+| 
 | Configures the formats understood by ``JavaSqlTimeStampValueSemanticsProvider``. @deprecated
 
 
@@ -115,7 +115,7 @@ timestamp.format
 isis.value-types.java-time. +
 local-date-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``LocalDateTimeValueSemanticsProvider``. @deprecated
 
 
@@ -124,7 +124,7 @@ local-date-time.format
 isis.value-types.java-time. +
 local-date.format
 
-|  medium
+| 
 | Configures the formats understood by ``LocalDateValueSemanticsProvider``. @deprecated
 
 
@@ -133,7 +133,7 @@ local-date.format
 isis.value-types.java-time. +
 local-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``LocalTimeValueSemanticsProvider``. @deprecated
 
 
@@ -142,7 +142,7 @@ local-time.format
 isis.value-types.java-time. +
 offset-date-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``OffsetDateTimeValueSemanticsProvider``. @deprecated
 
 
@@ -151,7 +151,7 @@ offset-date-time.format
 isis.value-types.java-time. +
 offset-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``OffsetTimeValueSemanticsProvider``. @deprecated
 
 
@@ -160,7 +160,7 @@ offset-time.format
 isis.value-types.java-time. +
 zoned-date-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``ZonedDateTimeValueSemanticsProvider``. @deprecated
 
 
@@ -169,7 +169,7 @@ zoned-date-time.format
 isis.value-types.java-util.date. +
 format
 
-|  medium
+| 
 | Configures the formats understood by ``JavaUtilDateValueSemanticsProvider``. @deprecated
 
 
@@ -178,7 +178,7 @@ format
 isis.value-types.joda.date-time. +
 format
 
-|  medium
+| 
 | Configures the formats understood by ``JodaDateTimeValueSemanticsProvider``. @deprecated
 
 
@@ -187,7 +187,7 @@ format
 isis.value-types.joda. +
 local-date-time.format
 
-|  medium
+| 
 | Configures the formats understood by ``JodaLocalDateTimeValueSemanticsProvider``. @deprecated
 
 
@@ -196,7 +196,7 @@ local-date-time.format
 isis.value-types.joda.local-date. +
 format
 
-|  medium
+| 
 | Configures the formats understood by ``JodaLocalDateValueSemanticsProvider``. @deprecated
 
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.restfulobjects.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.restfulobjects.adoc
index 4754fd6..b0933aa 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.restfulobjects.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.restfulobjects.adoc
@@ -16,7 +16,7 @@ include::../section-hooks/isis.viewer.restfulobjects~pre.adoc[]
 isis.viewer.restfulobjects. +
 base-uri
 
-|
+| 
 | If left unset (the default), then the RO viewer will use the ``UriInfo`` (injected using ``Context``) to figure out the base Uri (used to render ``href``s).
 
 This will be correct much of the time, but will almost certainly be wrong if there is a reverse proxy.
@@ -29,7 +29,7 @@ If set, eg ``com/``, then this value will be used instead.
 isis.viewer.restfulobjects. +
 honor-ui-hints
 
-|
+| 
 | Whether to enable the ``x-ro-follow-links`` support, to minimize round trips.
 
 The RO viewer provides the capability for the client to set the optional ``x-ro-follow-links`` query parameter, as described in section 34.4 of the RO spec v1.0. If used, the resultant representation includes the result of following the associated link, but through a server-side "join", somewhat akin to GraphQL.
@@ -42,7 +42,7 @@ By default this functionality is disabled, this configuration property enables t
 isis.viewer.restfulobjects. +
 object-property-values-only
 
-|
+| 
 | When rendering domain objects, if set the representation returned is stripped back to a minimal set, excluding links to actions and collections and with a simplified representation of an object's properties.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
@@ -53,7 +53,7 @@ This is disabled by default. If enabled, then the representations returned are n
 isis.viewer.restfulobjects. +
 strict-accept-checking
 
-|
+| 
 | If set, then any unrecognised ``Accept`` headers will result in an HTTP _Not Acceptable_ response code (406).
 
 
@@ -62,7 +62,7 @@ strict-accept-checking
 isis.viewer.restfulobjects. +
 suppress-described-by-links
 
-|
+| 
 | If set, then the representations returned will omit any links to the formal domain-type representations.
 
 
@@ -71,7 +71,7 @@ suppress-described-by-links
 isis.viewer.restfulobjects. +
 suppress-member-disabled-reason
 
-|
+| 
 | If set, then - should there be an interaction with an action, property or collection that is disabled - then this will prevent the ``disabledReason`` reason from being added to the returned representation.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
@@ -82,7 +82,7 @@ This is disabled by default. If enabled, then the representations returned are n
 isis.viewer.restfulobjects. +
 suppress-member-extensions
 
-|
+| 
 | If set, then the ``x-isis-format`` key (under ``extensions``) for properties will be suppressed.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
@@ -93,8 +93,8 @@ This is disabled by default. If enabled, then the representations returned are n
 isis.viewer.restfulobjects. +
 suppress-member-id
 
-|
-| If set, then the ``id`` key for all pathsToInclude will be suppressed.
+| 
+| If set, then the ``id`` key for all members will be suppressed.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
 
@@ -104,8 +104,8 @@ This is disabled by default. If enabled, then the representations returned are n
 isis.viewer.restfulobjects. +
 suppress-member-links
 
-|
-| If set, then the detail link (in other words ``]``) for all pathsToInclude will be suppressed.
+| 
+| If set, then the detail link (in other words ``]``) for all members will be suppressed.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
 
@@ -115,7 +115,7 @@ This is disabled by default. If enabled, then the representations returned are n
 isis.viewer.restfulobjects. +
 suppress-update-link
 
-|
+| 
 | If set, then the update link (in other words `` ]`` to perform a bulk update of an object) will be suppressed.
 
 This is disabled by default. If enabled, then the representations returned are non-standard with respect to the RO Spec v1.0.
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.wicket.adoc b/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.wicket.adoc
index bd7ce2a..69b0e77 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.wicket.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/isis.viewer.wicket.adoc
@@ -23,9 +23,7 @@ isis.viewer.wicket.ajax-debug-mode
 [[isis.viewer.wicket.app]]
 isis.viewer.wicket.app
 
-|  org.apache.isis.viewer.wicket. +
-viewer.wicketapp. +
-IsisWicketApplication
+| 
 | Specifies the subclass of ``IsisWicketApplication`` that is used to bootstrap Wicket.
 
 There is usually very little reason to change this from its default.
@@ -107,7 +105,7 @@ A typical value is ``js``. This will result in this file being read from the ``s
 isis.viewer.wicket.application. +
 menubars-layout-xml
 
-|  menubars.layout.xml
+| 
 | Specifies the file name containing the menubars.
 
 This is expected to be a local resource.
@@ -118,7 +116,7 @@ This is expected to be a local resource.
 isis.viewer.wicket.application. +
 name
 
-|  Apache Isis â„¢
+| 
 | Identifies the application on the sign-in page (unless a sign-in image is configured) and on top-left in the header (unless a header image is configured).
 
 
@@ -137,7 +135,7 @@ If present, then this will be shown in the footer on every page as well as on th
 [[isis.viewer.wicket.base-path]]
 isis.viewer.wicket.base-path
 
-|  /wicket/
+| 
 | The base path at which the Wicket viewer is mounted.
 
 
@@ -146,7 +144,7 @@ isis.viewer.wicket.base-path
 isis.viewer.wicket. +
 bookmarked-pages.max-size
 
-|  15
+| 
 | Specifies the maximum number of bookmarks to show.
 
 These are aged out on an MRU-LRU basis.
@@ -157,7 +155,7 @@ These are aged out on an MRU-LRU basis.
 isis.viewer.wicket. +
 bookmarked-pages.show-chooser
 
-|  true
+| 
 | Whether the panel providing linsk to previously visited object should be accessible from the top-left of the header.
 
 
@@ -167,7 +165,7 @@ isis.viewer.wicket. +
 bookmarked-pages. +
 show-drop-down-on-footer
 
-|  true
+| 
 | Whether the drop-down list of previously visited objects should be shown in the footer.
 
 
@@ -176,7 +174,7 @@ show-drop-down-on-footer
 isis.viewer.wicket.breadcrumbs. +
 enabled
 
-|  true
+| 
 | Whether to enable the 'where am i' feature, in other words the breadcrumbs.
 
 
@@ -185,7 +183,7 @@ enabled
 isis.viewer.wicket.breadcrumbs. +
 max-parent-chain-length
 
-|  64
+| 
 | null
 
 
@@ -216,7 +214,7 @@ NOTE: For further discussion, see for example https://stackoverflow.com/question
 [[isis.viewer.wicket.date-pattern]]
 isis.viewer.wicket.date-pattern
 
-|  dd-MM-yyyy
+| 
 | The pattern used for rendering and parsing dates.
 
 Each Date scalar panel will use ``#getDatePattern()`` or ``#getDateTimePattern()`` depending on its date type. In the case of panels with a date picker, the pattern will be dynamically adjusted so that it can be used by the https://github.com/Eonasdan/bootstrap-datetimepicker[Bootstrap Datetime Picker] component (which uses http://momentjs.com/docs/#/parsing/string-format/[Moment.js formats], rather than those of regular Java code).
@@ -227,7 +225,7 @@ Each Date scalar panel will use ``#getDatePattern()`` or ``#getDateTimePattern()
 isis.viewer.wicket.date-picker. +
 max-date
 
-|  2100-01-01T00:00:00.000Z
+| 
 | Defines the first date available in the date picker.
 
 As per http://eonasdan.github.io/bootstrap-datetimepicker/Options/#maxdate, in ISO format (per https://github.com/moment/moment/issues/1407).
@@ -238,7 +236,7 @@ As per http://eonasdan.github.io/bootstrap-datetimepicker/Options/#maxdate, in I
 isis.viewer.wicket.date-picker. +
 min-date
 
-|  1900-01-01T00:00:00.000Z
+| 
 | Defines the first date available in the date picker.
 
 As per http://eonasdan.github.io/bootstrap-datetimepicker/Options/#maxdate, in ISO format (per https://github.com/moment/moment/issues/1407).
@@ -249,7 +247,7 @@ As per http://eonasdan.github.io/bootstrap-datetimepicker/Options/#maxdate, in I
 isis.viewer.wicket. +
 date-time-pattern
 
-|  dd-MM-yyyy HH:mm
+| 
 | The pattern used for rendering and parsing date/times.
 
 Each Date scalar panel will use ``#getDatePattern()`` or ``#getDateTimePattern()`` depending on its date type. In the case of panels with a date time picker, the pattern will be dynamically adjusted so that it can be used by the https://github.com/Eonasdan/bootstrap-datetimepicker[Bootstrap Datetime Picker] component (which uses http://momentjs.com/docs/#/parsing/string-format/[Moment.js formats], rather than those of regular Java code).
@@ -322,7 +320,7 @@ tables
 isis.viewer.wicket. +
 max-title-length-in-tables
 
-|  12
+| 
 | The maximum number of characters to use to render the title of a domain object (alongside the icon) in any table, if not otherwise overridden by either ``#getMaxTitleLengthInParentedTables()`` or ``#getMaxTitleLengthInStandaloneTables()``.
 
 If truncated, then the remainder of the title will be replaced with ellipses (...).
@@ -334,7 +332,7 @@ isis.viewer.wicket. +
 prevent-double-click-for-form- +
 submit
 
-|  true
+| 
 | Whether to disable a form submit button after it has been clicked, to prevent users causing an error if they do a double click. This behaviour is enabled by default, but can be disabled using this flag.
 
 
@@ -344,7 +342,7 @@ isis.viewer.wicket. +
 prevent-double-click-for-no-arg- +
 action
 
-|  true
+| 
 | Whether to disable a no-arg action button after it has been clicked, to prevent users causing an error if they do a double click.
 
 This behaviour is enabled by default, but can be disabled using this flag.
@@ -378,7 +376,7 @@ This behaviour is disabled by default; the viewer will update the existing page
 isis.viewer.wicket.remember-me. +
 cookie-key
 
-|  isisWicketRememberMe
+| 
 | If the "remember me" feature is available, specifies the key to hold the encrypted credentials in the cookie.
 
 
@@ -414,7 +412,7 @@ isis.viewer.wicket. +
 replace-disabled-tag-with-readonly- +
 tag
 
-|  true
+| 
 | In Firefox and more recent versions of Chrome 54+, cannot copy out of disabled fields; instead we use the readonly attribute (https://www.w3.org/TR/2014/REC-html5-20141028/forms.html#the-readonly-attribute)
 
 This behaviour is enabled by default but can be disabled using this flag
@@ -424,7 +422,7 @@ This behaviour is enabled by default but can be disabled using this flag
 [[isis.viewer.wicket.show-footer]]
 isis.viewer.wicket.show-footer
 
-|  true
+| 
 | Whether to show the footer menu bar.
 
 This is enabled by default.
@@ -435,7 +433,7 @@ This is enabled by default.
 isis.viewer.wicket. +
 strip-wicket-tags
 
-|  true
+| 
 | Whether Wicket tags should be stripped from the markup.
 
 By default this is enabled, in other words Wicket tags are stripped. Please be aware that if tags are _not_ stripped, then this may break CSS rules on some browsers.
@@ -475,7 +473,7 @@ isis.viewer.wicket.themes.enabled
 [[isis.viewer.wicket.themes.initial]]
 isis.viewer.wicket.themes.initial
 
-|  Flatly
+| 
 | The initial theme to use.
 
 Expected to be in the list of ``#getEnabled()`` themes.
@@ -485,9 +483,7 @@ Expected to be in the list of ``#getEnabled()`` themes.
 [[isis.viewer.wicket.themes.provider]]
 isis.viewer.wicket.themes.provider
 
-|  org.apache.isis.viewer.wicket.ui. +
-components.widgets.themepicker. +
-IsisWicketThemeSupportDefault
+| 
 | Specifies an implementation of ``IsisWicketThemeSupport``
 
 
@@ -505,7 +501,7 @@ show-chooser
 isis.viewer.wicket. +
 use-indicator-for-form-submit
 
-|  true
+| 
 | Whether to show an indicator for a form submit button that it has been clicked.
 
 This behaviour is enabled by default.
@@ -516,7 +512,7 @@ This behaviour is enabled by default.
 isis.viewer.wicket. +
 use-indicator-for-no-arg-action
 
-|  true
+| 
 | Whether to show an indicator for a no-arg action button that it has been clicked.
 
 This behaviour is enabled by default.
@@ -546,7 +542,7 @@ This behaviour is disabled by default. Please be aware that enabloing it can sub
 isis.viewer.wicket. +
 timestamp-pattern
 
-|  yyyy-MM-dd HH:mm:ss.SSS
+| 
 | @deprecated - seemingly unused
 
 
diff --git a/core/config/src/main/adoc/modules/config/pages/sections/resteasy.adoc b/core/config/src/main/adoc/modules/config/pages/sections/resteasy.adoc
index 984e90f..9526703 100644
--- a/core/config/src/main/adoc/modules/config/pages/sections/resteasy.adoc
+++ b/core/config/src/main/adoc/modules/config/pages/sections/resteasy.adoc
@@ -48,7 +48,7 @@ resteasy.jaxrs.app.registration
 [[resteasy.jaxrs.default-path]]
 resteasy.jaxrs.default-path
 
-|  /restful
+| 
 | The path at which the RO viewer should be mounted.
 
 Note that this is used rather than ``prefix`` because there is _NO_ implementation of ``Application``, so we rely on it being automatically created.
diff --git a/isis-tooling.yml b/isis-tooling.yml
index 57d0451..77fba0f 100644
--- a/isis-tooling.yml
+++ b/isis-tooling.yml
@@ -17,35 +17,84 @@
 #  under the License.
 #
 
-projectDoc:
-  description: "These tables summarize all Maven artifacts available with _Apache Isis_."
-  fixOrphanedAdocIncludeStatements: true
+global:
   namespacePartsSkipCount: 3
-  artifactGroups:
-    Base: org.apache.isis
+
+  sections:
+    App: org.apache.isis.app.*
+    Mavendeps: org.apache.isis.mavendeps.*
+    Testing: org.apache.isis.testing.*
+    Examples: org.apache.isis.examples.*
+
+    Root: org.apache.isis
     Commons: org.apache.isis.commons.*
+
     Core: org.apache.isis.core.*
-    App: org.apache.isis.app.*
 
-    Mavendeps: org.apache.isis.mavendeps.*
-    Mappings: org.apache.isis.mappings.*
+    Persistence: org.apache.isis.persistence
+    JDO: "org.apache.isis.persistence:isis-persistence-jdo.*"
+    JPA: "org.apache.isis.persistence:isis-persistence-jpa.*"
+
+    Security: org.apache.isis.security
+    Bypass: "org.apache.isis.security:isis-security-bypass.*"
+    Keycloak: "org.apache.isis.security:isis-security-keycloak.*"
+    Shiro: "org.apache.isis.security:isis-security-shiro.*"
 
-    Persistence: org.apache.isis.persistence.*
-    Security: org.apache.isis.security.*
+    Viewer: org.apache.isis.viewer
+    "Restful Objects": "org.apache.isis.viewer:isis-viewer-restfulobjects.*"
+    Wicket: "org.apache.isis.viewer:isis-viewer-wicket.*"
 
     Valuetypes: org.apache.isis.valuetypes.*
-    Viewer: org.apache.isis.viewer.*
 
-    Testing: org.apache.isis.testing.*
-    Regression Tests: org.apache.isis.regressiontests.*
+    Mappings: org.apache.isis.mappings
+    #"Outbox Publisher": org.apache.isis.mappings:isis-mappings-jaxrsclient.*
+    "JAX-RS Client Library": "org.apache.isis.mappings:isis-mappings-jaxrsclient.*"
+    #Minio: "org.apache.isis.mappings:isis-mappings-minio.*"
+    "REST Client": "org.apache.isis.mappings:isis-mappings-restclient.*"
+    #"Slack Library": "org.apache.isis.mappings:isis-mappings-slack.*"
 
-    Extensions: org.apache.isis.extensions.*
-    Subdomains: org.apache.isis.subdomains.*
+    Extensions: org.apache.isis.extensions
+    "Core: Command Log": "org.apache.isis.extensions:isis-extensions-command-log.*"
+    "Core: Command Replay": "org.apache.isis.extensions:isis-extensions-command-replay.*"
+    "Core: Flyway": "org.apache.isis.extensions:isis-extensions-flyway.*"
+    "Core: Model Annotation": "org.apache.isis.extensions:isis-extensions-modelannotation.*"
+    "Core: Quartz": "org.apache.isis.extensions:isis-extensions-quartz.*"
+    #"Security: Audit Trail": "org.apache.isis.security:isis-extensions-audit-trail.*"
+    "Security: Secman": "org.apache.isis.security:isis-extensions-secman.*"
+    #"Security: Session Log": "org.apache.isis.security:isis-extensions-session-log.*"
+    "Security: Shiro LDAP Realm": "org.apache.isis.security:isis-extensions-shiro-realm-ldap.*"
+    "RO Viewer: CORS": "org.apache.isis.security:isis-extensions-cors.*"
+    "Wicket Viewer: Excel Download": "org.apache.isis.security:isis-extensions-exceldownload.*"
+    "Wicket Viewer: Full Calendar": "org.apache.isis.security:isis-extensions-fullcalendar.*"
+    #"Wicket Viewer: Gmap3": "org.apache.isis.security:isis-extensions-gmap3.*"
+    "Wicket Viewer: Pdf.js": "org.apache.isis.security:isis-extensions-fullcalendar.*"
 
-    Tooling: org.apache.isis.tooling.*
+    Subdomains: org.apache.isis.subdomains
+    "Base": "org.apache.isis.subdomains:isis-subdomains-base.*"
+    #"docx": "org.apache.isis.subdomains:isis-subdomains-docx.*"
+    "Excel": "org.apache.isis.subdomains:isis-subdomains-excel.*"
+    #"Freemarker": "org.apache.isis.subdomains:isis-subdomains-freemarker.*"
+    #"OGNL": "org.apache.isis.subdomains:isis-subdomains-ognl.*"
+    #"PDF Box": "org.apache.isis.subdomains:isis-subdomains-pdfbox.*"
+    "Spring": "org.apache.isis.subdomains:isis-subdomains-spring.*"
+    "XDocReport": "org.apache.isis.subdomains:isis-subdomains-xdocreport.*"
+    #"Zip": "org.apache.isis.subdomains:isis-subdomains-zip.*"
 
-    Examples: org.apache.isis.examples.*
+    "Tooling": org.apache.isis.tooling.*
+    "Regression Tests": org.apache.isis.regressiontests.*
+
+    Incubator: org.apache.isis.incubator
+    "Kroviz Client": "org.apache.isis.incubator.clients:isis-client-kroviz.*"
+    "JavaFX Viewer": "org.apache.isis.incubator.viewer:isis-viewer-javafx.*"
+    "Vaadin Viewer": "org.apache.isis.incubator.viewer:isis-viewer-vaadin.*"
 
-    Incubator: org.apache.isis.incubator.*
     Legacy: org.apache.isis.legacy.*
 
+
+commands:
+  overview:
+    description: "These tables summarize all Maven artifacts available with _Apache Isis_."
+
+  index:
+    fixOrphanedAdocIncludeStatements: true
+
diff --git a/mappings/adoc/modules/ROOT/partials/component-nav.adoc b/mappings/adoc/modules/ROOT/partials/component-nav.adoc
index bdbfece..666b9ae 100644
--- a/mappings/adoc/modules/ROOT/partials/component-nav.adoc
+++ b/mappings/adoc/modules/ROOT/partials/component-nav.adoc
@@ -1,7 +1,9 @@
 include::mappings:ROOT:partial$module-nav.adoc[]
 
-include::outbox-publisher:partial$module-nav.adoc[]
+// commented out the libraries that have not yet been brought over from incode-platform
+
+//include::outbox-publisher:partial$module-nav.adoc[]
 include::mappings:jaxrsclient:partial$module-nav.adoc[]
-include::mappings:minio:partial$module-nav.adoc[]
+//include::mappings:minio:partial$module-nav.adoc[]
 include::mappings:restclient:partial$module-nav.adoc[]
-include::mappings:slack:partial$module-nav.adoc[]
+//include::mappings:slack:partial$module-nav.adoc[]
diff --git a/mappings/publisher/adoc/antora.yml b/mappings/outbox-publisher/adoc/antora.yml
similarity index 100%
rename from mappings/publisher/adoc/antora.yml
rename to mappings/outbox-publisher/adoc/antora.yml
diff --git a/mappings/publisher/adoc/modules/outbox-publisher/nav.adoc b/mappings/outbox-publisher/adoc/modules/outbox-publisher/nav.adoc
similarity index 100%
rename from mappings/publisher/adoc/modules/outbox-publisher/nav.adoc
rename to mappings/outbox-publisher/adoc/modules/outbox-publisher/nav.adoc
diff --git a/mappings/publisher/adoc/modules/outbox-publisher/pages/about.adoc b/mappings/outbox-publisher/adoc/modules/outbox-publisher/pages/about.adoc
similarity index 100%
rename from mappings/publisher/adoc/modules/outbox-publisher/pages/about.adoc
rename to mappings/outbox-publisher/adoc/modules/outbox-publisher/pages/about.adoc
diff --git a/mappings/publisher/adoc/modules/outbox-publisher/partials/module-nav.adoc b/mappings/outbox-publisher/adoc/modules/outbox-publisher/partials/module-nav.adoc
similarity index 100%
rename from mappings/publisher/adoc/modules/outbox-publisher/partials/module-nav.adoc
rename to mappings/outbox-publisher/adoc/modules/outbox-publisher/partials/module-nav.adoc
diff --git a/preview.sh b/preview.sh
index 2a1b005..374bea9 100644
--- a/preview.sh
+++ b/preview.sh
@@ -14,13 +14,15 @@ export SKIP_INDEX_GENERATION=true
 
 PLAYBOOK_FILE=antora/playbooks/site.yml
 
-while getopts 'ECIAKSeciaksxyhf:' opt
+while getopts 'ECWIAKSecwiaksxyhf:' opt
 do
   case $opt in
     E) export SKIP_EXAMPLES=false
        forcing=true ;;
     C) export SKIP_CONFIGS=false
        forcing=true ;;
+    W) export SKIP_OVERVIEW_GENERATION=false
+       forcing=true ;;
     I) export SKIP_INDEX_GENERATION=false
        forcing=true ;;
     A) export SKIP_ANTORA_GENERATION=false
@@ -34,6 +36,7 @@ do
 
     e) export SKIP_EXAMPLES=true ;;
     c) export SKIP_CONFIGS=true ;;
+    w) export SKIP_OVERVIEW_GENERATION=true ;;
     i) export SKIP_INDEX_GENERATION=true ;;
     a) export SKIP_ANTORA_GENERATION=true
        export SKIP_CLEAR_CACHE=true
@@ -52,6 +55,7 @@ do
        echo "  -e skip examples"
        echo "  -k skip stale example check"
        echo "  -c skip config doc generation"
+       echo "  -w skip system overview generation"
        echo "  -i skip index generation"
        echo "  -a skip Antora generation"
        echo "  -s skip serving generated site"
@@ -60,6 +64,7 @@ do
        echo "  -E force examples"
        echo "  -K force stale example check"
        echo "  -C force config doc generation"
+       echo "  -W force system overview generation"
        echo "  -I force index generation"
        echo "  -A force Antora generation"
        echo "  -S force serving generated site"
@@ -80,6 +85,9 @@ if [ "$forcing" = "true" ]; then
     if [ -z "$SKIP_CONFIGS" ]; then
       export SKIP_CONFIGS=true
     fi
+    if [ -z "$SKIP_OVERVIEW_GENERATION" ]; then
+      export SKIP_OVERVIEW_GENERATION=true
+    fi
     if [ -z "$SKIP_INDEX_GENERATION" ]; then
       export SKIP_INDEX_GENERATION=true
     fi
@@ -99,6 +107,7 @@ fi
 echo ""
 echo "SKIP_EXAMPLES              : $SKIP_EXAMPLES"
 echo "SKIP_STALE_EXAMPLE_CHECK   : $SKIP_STALE_EXAMPLE_CHECK"
+echo "SKIP_OVERVIEW_GENERATION   : $SKIP_OVERVIEW_GENERATION"
 echo "SKIP_INDEX_GENERATION      : $SKIP_INDEX_GENERATION"
 echo "SKIP_CONFIGS               : $SKIP_CONFIGS"
 echo "SKIP_ANTORA_GENERATION     : $SKIP_ANTORA_GENERATION"
@@ -135,7 +144,7 @@ if [[ "$SKIP_SERVE" == "true" ]]; then
   echo "skipping serving"
 else
   echo ""
-  echo "http://localhost:5000"
+  echo "http://localhost:5000/docs/latest/about.html"
   echo ""
 
   serve -S -p 5000 $ANTORA_TARGET_SITE
diff --git a/regressiontests/adoc/modules/regressiontests/partials/module-nav.adoc b/regressiontests/adoc/modules/regressiontests/partials/module-nav.adoc
index eaf53ea..2d1ef6f 100644
--- a/regressiontests/adoc/modules/regressiontests/partials/module-nav.adoc
+++ b/regressiontests/adoc/modules/regressiontests/partials/module-nav.adoc
@@ -1,4 +1,4 @@
 
-* xref:regressiontests:about.adoc[Regression Rests]
+* xref:regressiontests:about.adoc[Regression Tests]
 
 
diff --git a/scripts/ci/_adoc-gen-index.sh b/scripts/ci/_adoc-gen-tooling.sh
similarity index 85%
rename from scripts/ci/_adoc-gen-index.sh
rename to scripts/ci/_adoc-gen-tooling.sh
index 6b52515..d128117 100644
--- a/scripts/ci/_adoc-gen-index.sh
+++ b/scripts/ci/_adoc-gen-tooling.sh
@@ -34,10 +34,11 @@ if [ -z "$REVISION" ]; then
 fi
 
 
+MODE=$1
 
 
 ##
-## run groovy
+## run java
 ##
 JAVA_CMD=$(command -v java)
 
@@ -47,9 +48,9 @@ echo ""
 
 # for now meant to run with nightly builds only
 if [ -z "${JAVA_CMD}" ]; then
-  echo "doc gen: no java, skipping"
+  echo "tooling gen: no java, skipping"
 else
-  java $PROJECT_ROOT_PATH/tooling/cli/target/isis-tooling-cli.jar -p $PROJECT_ROOT_PATH projdoc -o $PROJECT_ROOT_PATH/antora/components/system/modules/generated
+  java -jar "${PROJECT_ROOT_PATH}/tooling/cli/target/isis-tooling-cli.jar" -p "${PROJECT_ROOT_PATH}" -o "${PROJECT_ROOT_PATH}/antora/components/system/modules/generated" $MODE
 fi
 
 
diff --git a/scripts/ci/_build-site.sh b/scripts/ci/_build-site.sh
index ac10e29..6412864 100644
--- a/scripts/ci/_build-site.sh
+++ b/scripts/ci/_build-site.sh
@@ -40,10 +40,17 @@ else
 fi
 
 
+if [[ "$SKIP_OVERVIEW_GENERATION" == "true" ]]; then
+  echo "skipping overview generation"
+else
+  bash $SCRIPT_DIR/_adoc-gen-tooling.sh overview
+fi
+
+
 if [[ "$SKIP_INDEX_GENERATION" == "true" ]]; then
   echo "skipping index generation"
 else
-  bash $SCRIPT_DIR/_adoc-gen-index.sh
+  bash $SCRIPT_DIR/_adoc-gen-tooling.sh index
 fi
 
 
diff --git a/security/adoc/modules/ROOT/partials/component-nav.adoc b/security/adoc/modules/ROOT/partials/component-nav.adoc
index e3d48c8..80307c6 100644
--- a/security/adoc/modules/ROOT/partials/component-nav.adoc
+++ b/security/adoc/modules/ROOT/partials/component-nav.adoc
@@ -8,7 +8,10 @@ include::security:keycloak:partial$module-nav.adoc[]
 include::security:ROOT:partial$module-nav-end.adoc[]
 
 * Extensions
-include::security:audit-trail:partial$module-nav.adoc[]
+
+// commented out the libraries that have not yet been brought over from incode-platform
+
+//include::security:audit-trail:partial$module-nav.adoc[]
 include::security:shiro-realm-ldap:partial$module-nav.adoc[]
 include::security:secman:partial$module-nav.adoc[]
-include::security:session-log:partial$module-nav.adoc[]
+//include::security:session-log:partial$module-nav.adoc[]
diff --git a/subdomains/adoc/modules/ROOT/partials/component-nav.adoc b/subdomains/adoc/modules/ROOT/partials/component-nav.adoc
index a98ab5d..5fd1e23 100644
--- a/subdomains/adoc/modules/ROOT/partials/component-nav.adoc
+++ b/subdomains/adoc/modules/ROOT/partials/component-nav.adoc
@@ -1,12 +1,14 @@
 include::subdomains:ROOT:partial$module-nav.adoc[]
 
+// commented out the libraries that have not yet been brought over from incode-platform
+
 include::subdomains:base:partial$module-nav.adoc[]
-include::subdomains:docx:partial$module-nav.adoc[]
+//include::subdomains:docx:partial$module-nav.adoc[]
 include::subdomains:excel:partial$module-nav.adoc[]
-include::subdomains:freemarker:partial$module-nav.adoc[]
+//include::subdomains:freemarker:partial$module-nav.adoc[]
+//include::subdomains:ognl:partial$module-nav.adoc[]
+//include::subdomains:pdfbox:partial$module-nav.adoc[]
 include::subdomains:spring:partial$module-nav.adoc[]
-include::subdomains:ognl:partial$module-nav.adoc[]
-include::subdomains:pdfbox:partial$module-nav.adoc[]
 include::subdomains:xdocreport:partial$module-nav.adoc[]
-include::subdomains:zip:partial$module-nav.adoc[]
+//include::subdomains:zip:partial$module-nav.adoc[]
 
diff --git a/tooling/adoc/modules/ROOT/pages/about.adoc b/tooling/adoc/modules/ROOT/pages/about.adoc
index 049b713..7147eaa 100644
--- a/tooling/adoc/modules/ROOT/pages/about.adoc
+++ b/tooling/adoc/modules/ROOT/pages/about.adoc
@@ -1,18 +1,11 @@
-= Extensions Catalog
+= Tooling
 
 
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :page-partial:
 
-This catalog lists a number of extensions to the framework.
-These typically are for use directly within by the domain application itself.
+This chapter describes the command line tooling used to automatically generate documentation from the program sources (eg `.java` source code and Maven `pom.xml` project files).
 
-For convenience, some of the extensions catalogued here are incorporated in other guides:
+The tooling itself is accessed through a xref:tooling:tooling-cli:about.adoc[command line interface (CLI)] tool.
 
-* in the xref:security:ROOT:about.adoc[security] guide, and the xref:vw:ROOT:about.adoc[wicket viewer] guide).
-+
-These extensions extend the capability of those components, or provide alternative implementations
-
-* in the xref:testing:ROOT:about.adoc[testing] guide
-+
-The extensions here _are_ for use by the domain application, but only for testing or prototyping (eg fixtures) rather than in the business logic itself.
+The tools are used both during the xref:comguide:ROOT:cutting-a-release.adoc[release process] and on an adhoc basis.
diff --git a/tooling/adoc/modules/ROOT/partials/component-nav.adoc b/tooling/adoc/modules/ROOT/partials/component-nav.adoc
index bcba06e..ab1fd97 100644
--- a/tooling/adoc/modules/ROOT/partials/component-nav.adoc
+++ b/tooling/adoc/modules/ROOT/partials/component-nav.adoc
@@ -1,24 +1,3 @@
 include::tooling:ROOT:partial$module-nav.adoc[]
 
-* CLI
-
-include::security:session-log:partial$module-nav.adoc[]
-include::extensions:command-log:partial$module-nav.adoc[]
-include::extensions:command-replay:partial$module-nav.adoc[]
-include::userguide:flyway:partial$module-nav.adoc[]
-include::extensions:model-annotation:partial$module-nav.adoc[]
-
-* Security
-include::security:shiro-realm-ldap:partial$module-nav.adoc[]
-include::security:secman:partial$module-nav.adoc[]
-
-* Restful Objects Viewer
-
-include::vro:cors:partial$module-nav.adoc[]
-
-* Wicket Viewer
-
-include::vw:exceldownload:partial$module-nav.adoc[]
-include::vw:fullcalendar:partial$module-nav.adoc[]
-include::vw:gmap3:partial$module-nav.adoc[]
-include::vw:pdfjs:partial$module-nav.adoc[]
+include::tooling:tooling-cli:partial$module-nav.adoc[]
diff --git a/tooling/cli/adoc/antora.yml b/tooling/cli/adoc/antora.yml
index f59b33f..d2f65ab 100644
--- a/tooling/cli/adoc/antora.yml
+++ b/tooling/cli/adoc/antora.yml
@@ -15,5 +15,5 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-name: extensions
+name: tooling
 version: latest
diff --git a/tooling/cli/adoc/modules/tooling-cli/examples/isis-tooling.yml b/tooling/cli/adoc/modules/tooling-cli/examples/isis-tooling.yml
index 523a205..57d0451 100644
--- a/tooling/cli/adoc/modules/tooling-cli/examples/isis-tooling.yml
+++ b/tooling/cli/adoc/modules/tooling-cli/examples/isis-tooling.yml
@@ -18,9 +18,9 @@
 #
 
 projectDoc:
+  description: "These tables summarize all Maven artifacts available with _Apache Isis_."
   fixOrphanedAdocIncludeStatements: true
   namespacePartsSkipCount: 3
-  description: "These tables summarize all Maven artifacts available with _Apache Isis_."
   artifactGroups:
     Base: org.apache.isis
     Commons: org.apache.isis.commons.*
diff --git a/tooling/cli/adoc/modules/tooling-cli/pages/about.adoc b/tooling/cli/adoc/modules/tooling-cli/pages/about.adoc
index 133b079..25b26af 100644
--- a/tooling/cli/adoc/modules/tooling-cli/pages/about.adoc
+++ b/tooling/cli/adoc/modules/tooling-cli/pages/about.adoc
@@ -5,8 +5,6 @@
 
 Command Line Interface for the _Apache Isis Tooling_ ecosystem, to generate documentation from program sources (`.java` files, `pom.xml`, etc).
 
-WARNING: This is work-in-progress.
-Regard the following text as an early draft.
 
 
 == Prerequisites
@@ -21,7 +19,7 @@ mvn install -D module-tooling -Dskip.essential
 This will generate the command line CLI as an executable jar in its target directory (`tooling/cli/target`).
 
 
-== Usage
+== Available Commands
 
 Use the help command to see a list of available commands:
 
@@ -31,38 +29,49 @@ Use the help command to see a list of available commands:
 java -jar tooling/cli/target/isis-tooling-cli.jar --help
 ----
 
-which (currently) generates the folloing:
+which (currently) generates the following:
 
 [source]
 ----
-Usage: cli [-hV] [-p=<projectRootPath>] [COMMAND]
+Usage: cli [-hV] [-o=<outputPath>] [-p=<projectRootPath>] [COMMAND]
 CLI for the Apache Isis Tooling Ecosystem
   -h, --help      Show this help message and exit.
+  -o, --output=<outputPath>
+                  path to the output file (default: NONE = write to std.out)
   -p, --project=<projectRootPath>
                   path to the (multi-module) project root (default: current dir)
   -V, --version   Print version information and exit.
 Commands:
-  projdoc  Writes a System Overview document (AsciiDoc) to given output.
+  overview  Writes a System Overview document (AsciiDoc) to given output.
+  index     Writes a Global Index (AsciiDoc) to given output.
 ----
 
-NOTE: there is currently only one subcommand, namely "projdoc".
+By default, the current directory is used as the target to perform commands in.
 
-By default, the current directory is used as the target to perform sub-commands in.
 
-Default options can be overruled by specifying a configuration file located at the root of the repo:
+=== Configuration File
+
+The `isis-tooling.yml` configuration file (found in the root of the repo) provides default options for each command, as well as global defaults applicable to all commands:
 
 [source,yml]
 .isis-tooling.yml
 ----
-projectDoc: # <.>
+global: # <.>
   option ...
   option ...
+command:
+  overview: # <.>
+    ...
+  index:    # <.>
+    ...
 ----
 
-<.> eg. configuration for sub-command `projdoc`
+<.> configuration applicable to all commands
+<.> configuration for the "overview" command
+<.> configuration for the "index" command
 
-This configuration file is mapped onto the `CLIConfig` bean.
-Look it up in the java sources for more detailed information.
+TIP: This configuration file is mapped onto the `CLIConfig` bean.
+Inspect its https://github.com/apache/isis/blob/master/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java#L31[source code] for more detailed information.
 
 
 == Commands
diff --git a/tooling/cli/adoc/modules/tooling-cli/partials/module-nav.adoc b/tooling/cli/adoc/modules/tooling-cli/partials/module-nav.adoc
index 814560b..9b2d812 100644
--- a/tooling/cli/adoc/modules/tooling-cli/partials/module-nav.adoc
+++ b/tooling/cli/adoc/modules/tooling-cli/partials/module-nav.adoc
@@ -1,4 +1,4 @@
 
-** xref:tooling-cli:about.adoc[Tooling CLI]
+* xref:tooling-cli:about.adoc[Tooling CLI]
 
 
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
index ef1d621..aeaab1a 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/Cli.java
@@ -33,19 +33,26 @@ import picocli.CommandLine.Command;
 import picocli.CommandLine.Option;
 
 @Command(
-        name = "cli", 
-        mixinStandardHelpOptions = true, 
+        name = "cli",
+        mixinStandardHelpOptions = true,
         version = "0.1",
         description = "CLI for the Apache Isis Tooling Ecosystem",
         subcommands = {
-                Cli.ProjectDocCommand.class})
+                Cli.SystemOverviewCommand.class,
+                Cli.GlobalIndexCommand.class,
+        })
 class Cli implements Callable<Integer> {
 
     @Option(
-            names = {"-p", "--project"}, 
+            names = {"-p", "--project"},
             description = "path to the (multi-module) project root (default: current dir)")
     private String projectRootPath;
 
+    @Option(
+            names = {"-o", "--output"},
+            description = "path to the output file (default: NONE = write to std.out)")
+    private String outputPath;
+
     private _Lazy<CliConfig> configRef = _Lazy.threadSafe(()->CliConfig
             .read(projectRootPath!=null
                     ? new File(projectRootPath, "isis-tooling.yml")
@@ -54,15 +61,21 @@ class Cli implements Callable<Integer> {
     public CliConfig getConfig() {
         return configRef.get();
     }
-    
+
     public  File getProjectRoot() {
         return projectRootPath!=null
                 ? new File(projectRootPath)
                 : new File(".");
     }
 
+    public  File getOutputPath() {
+        return outputPath !=null
+                ? new File(outputPath)
+                : new File(".");
+    }
+
     @Override
-    public Integer call() throws Exception { 
+    public Integer call() throws Exception {
         // not used
         return 0;
     }
@@ -70,38 +83,52 @@ class Cli implements Callable<Integer> {
     // -- SUB COMMANDS
 
     @Command(
-            name = "projdoc",
+            name = "overview",
             description = "Writes a System Overview document (AsciiDoc) to given output.")
-    static class ProjectDocCommand extends CliCommandAbstract {
+    static class SystemOverviewCommand extends CliCommandAbstract {
 
         @Option(
-                names = {"-o", "--output"}, 
+                names = {"-o", "--output"},
                 description = "path to the output file (default: NONE = write to std.out)")
         private String outputFilePath;
 
         @Override
         public Integer call() throws Exception {
 
-            if(outputFilePath!=null) {
-                getConfig().getProjectDoc().setOutputRootFolder(new File(outputFilePath));
+            if(getOutputPath()!=null) {
+                getConfig().getGlobal().setOutputRootFolder(getOutputPath());
+            }
+
+            val projTree = ProjectNodeFactory.maven(getProjectRoot());
+            val projectDocModel = new ProjectDocModel(projTree);
+            projectDocModel.generateAsciiDoc(getConfig(), ProjectDocModel.Mode.OVERVIEW);
+            return 0;
+        }
+    }
+
+    @Command(
+            name = "index",
+            description = "Writes a Global Index (AsciiDoc) to given output.")
+    static class GlobalIndexCommand extends CliCommandAbstract {
+
+
+        @Override
+        public Integer call() throws Exception {
+
+            if(getOutputPath() !=null) {
+                getConfig().getGlobal().setOutputRootFolder(getOutputPath());
             }
-            
+
             val projTree = ProjectNodeFactory.maven(getProjectRoot());
             val projectDocModel = new ProjectDocModel(projTree);
-            projectDocModel.generateAsciiDoc(getConfig());
+            projectDocModel.generateAsciiDoc(getConfig(), ProjectDocModel.Mode.INDEX);
             return 0;
         }
     }
-    
+
     //TODO mvn2gradle
     //description = "Detects differences between Maven and Gradle (multi-module) projects.",
-    
 
-    //    @Command
-    //    int shout() {
-    //        System.out.println("HI! " + getConfig());
-    //        return 0;
-    //    }
 
     // -- ENTRY POINT
 
@@ -115,4 +142,4 @@ class Cli implements Callable<Integer> {
     // -- HELPER
 
 
-}
\ No newline at end of file
+}
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliCommandAbstract.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliCommandAbstract.java
index 4e3168b..c2956f9 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliCommandAbstract.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliCommandAbstract.java
@@ -28,10 +28,14 @@ abstract class CliCommandAbstract implements Callable<Integer> {
     public CliConfig getConfig() {
         return _Context.getElseFail(Cli.class).getConfig();
     }
-    
+
     public File getProjectRoot() {
         return _Context.getElseFail(Cli.class).getProjectRoot();
     }
 
-    
+    public File getOutputPath() {
+        return _Context.getElseFail(Cli.class).getOutputPath();
+    }
+
+
 }
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
index caee899..fb9e84e 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/CliConfig.java
@@ -30,54 +30,76 @@ import lombok.NonNull;
 @Data
 public class CliConfig {
 
-    private ProjectDoc projectDoc = new ProjectDoc();
+    private Global global = new Global();
 
     @Data
-    public static class ProjectDoc {
-        private String description = "These tables summarize all Maven artifacts available with this project.";
+    public static class Global {
+
+        private File outputRootFolder = null; // where to write to (overridden by -o flag)
+
         private String licenseHeader =
                 "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.";
-        private LinkedHashMap<String, String> artifactGroups = new LinkedHashMap<>();
-
-        private File outputRootFolder = null; // where to write eg. system-overview.adoc
+                        + "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.";
 
         private String documentPagesPath = "pages";
-        private String documentGlobalIndexPath = "pages/index";
-        private String documentGlobalIndexXrefPageIdFormat = "system:generated:index/%s.adoc";
-
-        private boolean fixOrphanedAdocIncludeStatements = false;
-
-        private String systemOverviewFilename = "system-overview.adoc";
 
         // when 3 eg. skips first three parts of the package names 'org.apache.isis'
         private int namespacePartsSkipCount = 0;
 
+        private LinkedHashMap<String, String> sections = new LinkedHashMap<>();
+
         public boolean isDryRun() {
             return getOutputRootFolder() == null;
         }
 
-        public File getDocumentIndexFolder() {
-            return Optional.ofNullable(getOutputRootFolder())
-                    .map(root->new File(root, getDocumentGlobalIndexPath()))
-                    .orElse(null);
-        }
-
         public File getDocumentPagesFolder() {
             return Optional.ofNullable(getOutputRootFolder())
                     .map(root->new File(root, getDocumentPagesPath()))
                     .orElse(null);
         }
+    }
+
+    private Commands commands = new Commands();
+
+    @Data
+    public static class Commands {
+
+        private Overview overview = new Overview();
+
+        @Data
+        public static class Overview {
+            private String systemOverviewFilename = "system-overview.adoc";
+
+            private String description = "These tables summarize all Maven artifacts available with this project.";
+        }
+
+        private Index index = new Index();
+
+        @Data
+        public static class Index {
+
+            private String documentGlobalIndexPath = "pages/index";
+            private String documentGlobalIndexXrefPageIdFormat = "system:generated:index/%s.adoc";
+
+            private boolean fixOrphanedAdocIncludeStatements = false;
+
+            public File getDocumentIndexFolder(File outputRootFolder) {
+                return Optional.ofNullable(outputRootFolder)
+                        .map(root->new File(root, getDocumentGlobalIndexPath()))
+                        .orElse(null);
+            }
+        }
 
     }
 
+
     // -- LOADING
 
     public static CliConfig read(final @NonNull File file) {
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
index 6ac54e3..4565613 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/adocfix/OrphanedIncludeStatementFixer.java
@@ -41,12 +41,12 @@ public final class OrphanedIncludeStatementFixer {
             final @NonNull CliConfig cliConfig,
             final @NonNull J2AdocContext j2aContext) {
 
-        if(cliConfig.getProjectDoc().isDryRun()) {
+        if(cliConfig.getGlobal().isDryRun()) {
             System.out.println("IncludeStatementFixer: skip (dry-run)");
             return;
         }
 
-        if(!cliConfig.getProjectDoc().isFixOrphanedAdocIncludeStatements()) {
+        if(!cliConfig.getCommands().getIndex().isFixOrphanedAdocIncludeStatements()) {
             System.out.println("IncludeStatementFixer: skip (disabled via config, fixOrphandedAdocIncludeStatements=false)");
             return;
         }
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
index a6663e4..74bc655 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocModel.java
@@ -20,6 +20,8 @@ package org.apache.isis.tooling.cli.projdoc;
 
 import java.io.File;
 import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Optional;
@@ -28,6 +30,7 @@ import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.annotation.Nullable;
 
@@ -60,6 +63,7 @@ import static org.apache.isis.tooling.model4adoc.AsciiDocFactory.row;
 import static org.apache.isis.tooling.model4adoc.AsciiDocFactory.table;
 
 import lombok.EqualsAndHashCode;
+import lombok.Getter;
 import lombok.NonNull;
 import lombok.RequiredArgsConstructor;
 import lombok.val;
@@ -84,45 +88,114 @@ public class ProjectDocModel {
         this.projTree = projTree;
     }
 
-    public void generateAsciiDoc(final @NonNull CliConfig cliConfig) {
-        
+    public enum Mode {
+        OVERVIEW,
+        INDEX
+    }
+
+    public void generateAsciiDoc(final @NonNull CliConfig cliConfig, final @NonNull Mode mode) {
+
         modules = new TreeSet<ProjectNode>();
         projTree.depthFirst(modules::add);
-        
+
         final SortedSet<File> asciiDocFiles = new TreeSet<>();
 
         val j2aContext = J2AdocContext
                 //.compactFormat()
                 .javaSourceWithFootnotesFormat()
-                .licenseHeader(cliConfig.getProjectDoc().getLicenseHeader())
-                .xrefPageIdFormat(cliConfig.getProjectDoc().getDocumentGlobalIndexXrefPageIdFormat())
-                .namespacePartsSkipCount(cliConfig.getProjectDoc().getNamespacePartsSkipCount())
+                .licenseHeader(cliConfig.getGlobal().getLicenseHeader())
+                .xrefPageIdFormat(cliConfig.getCommands().getIndex().getDocumentGlobalIndexXrefPageIdFormat())
+                .namespacePartsSkipCount(cliConfig.getGlobal().getNamespacePartsSkipCount())
                 .build();
-        
+
         val doc = doc();
         doc.setTitle("System Overview");
 
-        _Strings.nonEmpty(cliConfig.getProjectDoc().getLicenseHeader())
+        _Strings.nonEmpty(cliConfig.getGlobal().getLicenseHeader())
         .ifPresent(notice->AsciiDocFactory.attrNotice(doc, notice));
-        
-        _Strings.nonEmpty(cliConfig.getProjectDoc().getDescription())
+
+        _Strings.nonEmpty(cliConfig.getCommands().getOverview().getDescription())
         .ifPresent(block(doc)::setSource);
 
-        cliConfig.getProjectDoc().getArtifactGroups().forEach((section, groupId)->{
-            createSection(doc, section, groupId, j2aContext, asciiDocFiles::add);
+        // partition modules into sections
+        val sections = new ArrayList<Section>();
+        cliConfig.getGlobal().getSections().forEach((section, groupIdArtifactIdPattern)->{
+            createSections(modules, section, groupIdArtifactIdPattern, sections::add);
         });
 
+        // ensure that each module is referenced only by a single section,
+        // preferring to be owned by a non-group section (ie more specific)
+        val modulesReferencedByNonGroupSections =
+            sections.stream()
+                .filter(Section::isNotGroupLevelOnly)
+                .flatMap(Section::streamMatchingProjectNodes)
+                .collect(Collectors.toList());
+
+        sections.stream()
+                .filter(Section::isGroupLevelOnly)
+                .forEach(section -> section.removeProjectNodes(modulesReferencedByNonGroupSections));
+
+        // any remaining modules go into an 'Other' section
+        sections.forEach(section -> modules.removeAll(section.getMatchingProjectNodes()));
         if(!modules.isEmpty()) {
-            createSection(doc, "Other", null, j2aContext, asciiDocFile->{ /* don't collect*/});
+            final Section other = new Section("Other", null, false);
+            modules.forEach(other::addProjectNode);
+            sections.add(other);
+            modules.clear();
         }
-        
-        ProjectDocWriter.write(cliConfig, doc, j2aContext);
-        
+
+        // now generate the overview or index
+        writeSections(sections, doc, j2aContext, mode, asciiDocFiles::add);
+
+        if (mode == Mode.OVERVIEW) {
+            ProjectDocWriter.write(cliConfig, doc, j2aContext, mode);
+        }
+
         // update include statements ...
         OrphanedIncludeStatementFixer.fixIncludeStatements(asciiDocFiles, cliConfig, j2aContext);
 
     }
 
+    @RequiredArgsConstructor
+    public static class Section {
+        @Getter
+        private final String sectionName;
+        @Getter
+        private final String groupIdArtifactIdPattern;
+        @Getter
+        private final boolean addAdocFiles;
+
+        private final List<ProjectNode> matchingProjectNodes = new ArrayList<>();
+
+        public List<ProjectNode> getMatchingProjectNodes() {
+            return Collections.unmodifiableList(matchingProjectNodes);
+        }
+
+        public Stream<ProjectNode> streamMatchingProjectNodes() {
+            return matchingProjectNodes.stream();
+        }
+
+        void addProjectNode(ProjectNode projectNode) {
+            matchingProjectNodes.add(projectNode);
+        }
+
+        boolean isGroupLevelOnly() {
+            return ! isNotGroupLevelOnly();
+        }
+        boolean isNotGroupLevelOnly() {
+            return groupIdArtifactIdPattern.contains(":");
+        }
+
+        void removeProjectNodes(Collection<ProjectNode> projectNodes) {
+            matchingProjectNodes.removeAll(projectNodes);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("%s (%s): %d modules", sectionName, isGroupLevelOnly() ? "group" : "non-group", getMatchingProjectNodes().size());
+        }
+    }
+
     // -- HELPER
 
     @RequiredArgsConstructor(staticName = "of")
@@ -131,11 +204,11 @@ public class ProjectDocModel {
         final ProjectNode projectNode;
         @EqualsExclude final Container container;
     }
-    
+
     private static class GroupDiagram {
-        
+
         private final C4 c4;
-        private final List<ProjectNode> projectNodes = new ArrayList<>(); 
+        private final List<ProjectNode> projectNodes = new ArrayList<>();
 
         public GroupDiagram(C4 c4) {
             this.c4 = c4;
@@ -159,8 +232,8 @@ public class ProjectDocModel {
                 return ProjectAndContainerTuple.of(projectNode, container);
             });
 
-            
-            final _Graph<ProjectAndContainerTuple> adjMatrix = 
+
+            final _Graph<ProjectAndContainerTuple> adjMatrix =
                     _Graph.of(tuples, (a, b)->a.projectNode.getChildren().contains(b.projectNode));
 
             tuples.forEach(tuple->{
@@ -183,19 +256,52 @@ public class ProjectDocModel {
 
             return AsciiDocFactory.SourceFactory.plantuml(toPlantUml(softwareSystemName), key, null);
         }
+    }
+
+    private void createSections(
+            final @NonNull SortedSet<ProjectNode> projectNodes,
+            final @NonNull String sectionName,
+            final @Nullable String pattern,
+            final @NonNull Consumer<Section> sectionConsumer) {
+
+        val section = new Section(sectionName, pattern, true);
+
+        projectNodes.stream()
+                .filter(module->matchesGroupId(module, pattern))
+                .forEach(section::addProjectNode);
 
+        sectionConsumer.accept(section);
     }
 
-    private void createSection(
-            final @NonNull Document doc, 
-            final @NonNull String sectionName, 
-            final @Nullable String groupIdPattern, 
+    private void writeSections(
+            final @NonNull List<Section> sections,
+            final @NonNull Document doc,
             final @NonNull J2AdocContext j2aContext,
+            final @NonNull Mode mode,
             final @NonNull Consumer<File> onAdocFile) {
 
+        sections.forEach(section -> {
+            writeSection(section, doc, j2aContext, mode, onAdocFile);
+        });
+    }
+
+    private void writeSection(
+            final @NonNull Section section,
+            final @NonNull Document doc,
+            final @NonNull J2AdocContext j2aContext,
+            final @NonNull Mode mode,
+            final @NonNull Consumer<File> onAdocFile) {
+
+        val sectionName = section.getSectionName();
+        val groupIdPattern = section.getGroupIdArtifactIdPattern();
+
         val titleBlock = block(doc);
 
-        titleBlock.setSource(String.format("== %s", sectionName));
+        val headingLevel =
+                (groupIdPattern == null || !groupIdPattern.contains(":"))
+                        ? "=="
+                        : "===";
+        titleBlock.setSource(String.format("%s %s", headingLevel, sectionName));
 
         val descriptionBlock = block(doc);
         val groupDiagram = new GroupDiagram(C4.of(sectionName, null));
@@ -213,54 +319,59 @@ public class ProjectDocModel {
         val projRoot = _Files.canonicalPath(projTree.getProjectDirectory())
                 .orElseThrow(()->_Exceptions.unrecoverable("cannot resolve project root"));
 
-        Set<ProjectNode> modulesWritten = new HashSet<>();
-
-        modules.stream()
-        .filter(module->matchesGroupId(module, groupIdPattern))
-        .forEach(module->{
-            gatherAdocFiles(module.getProjectDirectory(), onAdocFile);
+        section.getMatchingProjectNodes()
+                .forEach(module -> {
+                    if(mode == Mode.INDEX) {
+                        gatherAdocFiles(module.getProjectDirectory(), onAdocFile);
+                    }
 
-            val projPath = _Files.canonicalPath(module.getProjectDirectory()).get();
-            val projRelativePath = 
-                    Optional.ofNullable(
-                            _Strings.emptyToNull(
-                                    _Files.toRelativePath(projRoot, projPath)))
-                    .orElse("/");
+                    val projPath = _Files.canonicalPath(module.getProjectDirectory()).get();
+                    val projRelativePath =
+                            Optional.ofNullable(
+                                    _Strings.emptyToNull(
+                                            _Files.toRelativePath(projRoot, projPath)))
+                                    .orElse("/");
 
-            modulesWritten.add(module);
-            groupDiagram.collect(module);
+                    groupDiagram.collect(module);
 
-            val row = row(table);
-            cell(table, row, coordinates(module, projRelativePath));
-            cell(table, row, details(module, j2aContext));
-        });
+                    val row = row(table);
+                    cell(table, row, coordinates(module, projRelativePath));
+                    cell(table, row, details(module, j2aContext));
+                });
 
         descriptionBlock.setSource(groupDiagram.toAsciiDoc(sectionName));
-
-        modules.removeAll(modulesWritten);
-
     }
 
     private boolean matchesGroupId(ProjectNode module, String groupIdPattern) {
-        if(_Strings.isNullOrEmpty(module.getArtifactCoordinates().getGroupId())) {
+        val moduleCoords = module.getArtifactCoordinates();
+
+        if(_Strings.isNullOrEmpty(moduleCoords.getGroupId())) {
             return false; // never match on missing data
         }
         if(_Strings.isNullOrEmpty(groupIdPattern)) {
             return true; // no groupIdPattern, always matches
         }
-        if(groupIdPattern.equals(module.getArtifactCoordinates().getGroupId())) {
+        if(groupIdPattern.equals(moduleCoords.getGroupId())) {
             return true; // exact match
         }
         if(groupIdPattern.endsWith(".*")) {
             val groupIdPrefix = groupIdPattern.substring(0, groupIdPattern.length()-2);
-            if(groupIdPrefix.equals(module.getArtifactCoordinates().getGroupId())) {
-                return true; // exact match
-            }
-            if(groupIdPrefix.equals(module.getArtifactCoordinates().getGroupId())) {
-                return true; // exact prefix match
-            }
-            if(module.getArtifactCoordinates().getGroupId().startsWith(groupIdPrefix+".")) {
-                return true; // prefix match
+            if(groupIdPattern.contains(":")) {
+                final String[] split = groupIdPrefix.split(":");
+                val groupId = split[0];
+                val artifactIdPrefix = split[1];
+                if(groupId.equals(moduleCoords.getGroupId())) {
+                    if(moduleCoords.getArtifactId().startsWith(artifactIdPrefix)) {
+                        return true; // match on artifactId
+                    }
+                }
+            } else {
+                if(groupIdPrefix.equals(moduleCoords.getGroupId())) {
+                    return true; // exact prefix match
+                }
+                if(moduleCoords.getGroupId().startsWith(groupIdPrefix+".")) {
+                    return true; // prefix match
+                }
             }
         }
         return false;
@@ -283,11 +394,11 @@ public class ProjectDocModel {
                 module.getName(),
                 AsciiDocFactory.SourceFactory.yaml(coors.toString(), null));
     }
-    
+
     private void appendKeyValue(StringBuilder sb, String key, String value) {
         sb.append(String.format("%s: %s\n", key, value));
     }
-    
+
     private String details(ProjectNode module, J2AdocContext j2aContext) {
         val description = module.getDescription().trim();
         val dependencyList = module.getDependencies()
@@ -303,7 +414,7 @@ public class ProjectDocModel {
                 .map(ProjectDocModel::toAdocListItem)
                 .collect(Collectors.joining())
                 .trim();
-        
+
         val indexEntriesCompactList = gatherGlobalDocIndexXrefs(module.getProjectDirectory(), j2aContext)
                 .stream()
                 .collect(Collectors.joining(", "))
@@ -322,7 +433,7 @@ public class ProjectDocModel {
         if(!dependencyList.isEmpty()) {
             sb.append(toAdocSection("Dependencies", dependencyList));
         }
-        
+
         if(!indexEntriesCompactList.isEmpty()) {
             sb.append(toAdocSection("Document Index Entries", indexEntriesCompactList));
         }
@@ -333,23 +444,23 @@ public class ProjectDocModel {
     private static String toAdocSection(String title, String content) {
         return String.format("_%s_\n\n%s\n\n", title, content);
     }
-    
+
     private static String toAdocListItem(String element) {
         return String.format("* %s\n", element);
     }
 
     private SortedSet<String> gatherGlobalDocIndexXrefs(File projDir, J2AdocContext j2aContext) {
-        
+
         val analyzerConfig = AnalyzerConfigFactory.maven(projDir, Language.JAVA).main();
 
         final SortedSet<String> docIndexXrefs = analyzerConfig.getSources(JAVA).stream()
         .flatMap(j2aContext::add)
         .map(unit->unit.getAsciiDocXref(j2aContext))
         .collect(Collectors.toCollection(TreeSet::new));
-        
+
         return docIndexXrefs;
     }
-    
+
     private SortedSet<String> gatherSpringComponents(File projDir) {
 
         val analyzerConfig = AnalyzerConfigFactory.maven(projDir, Language.JAVA).main();
@@ -367,16 +478,16 @@ public class ProjectDocModel {
 
         return components;
     }
-    
+
     private void gatherAdocFiles(File projDir, Consumer<File> onFile) {
-    
+
         val analyzerConfig = AnalyzerConfigFactory.maven(projDir, Language.ADOC).main();
 
         analyzerConfig.getSources(Language.ADOC)
                 .stream()
                 .forEach(onFile::accept);
     }
-                
+
 
 }
 
diff --git a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
index 66ac7ec..a457abd 100644
--- a/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
+++ b/tooling/cli/src/main/java/org/apache/isis/tooling/cli/projdoc/ProjectDocWriter.java
@@ -38,91 +38,107 @@ final class ProjectDocWriter {
 
     @SneakyThrows
     static void write(
-            final @NonNull CliConfig cliConfig, 
-            final @NonNull Document systemSummaryAdoc, 
-            final @NonNull J2AdocContext j2aContext) {
-        
-        final BiConsumer<Document, File> docWriter = cliConfig.getProjectDoc().isDryRun()
+            final @NonNull CliConfig cliConfig,
+            final @NonNull Document systemSummaryAdoc,
+            final @NonNull J2AdocContext j2aContext,
+            final @NonNull ProjectDocModel.Mode mode) {
+
+        final BiConsumer<Document, File> docWriter = cliConfig.getGlobal().isDryRun()
                 ? (doc, file)->AsciiDocWriter.print(doc) // print to system out only (dry run)
                 : AsciiDocWriter::writeToFile;
 
         val currentUnit = _Refs.<J2AdocUnit>objectRef(null);
-        val projectDoc = cliConfig.getProjectDoc();
-            
-        val rootFolder = projectDoc.getOutputRootFolder();
-        val pagesFolder = projectDoc.getDocumentPagesFolder();
-        
+        val global = cliConfig.getGlobal();
+        val overview = cliConfig.getCommands().getOverview();
+        val index = cliConfig.getCommands().getIndex();
+
+        val rootFolder = global.getOutputRootFolder();
+        val pagesFolder = global.getDocumentPagesFolder();
+
         val deleteCount = _Refs.intRef(0);
         int writeCount = 0;
-        
+
         try {
 
-            // delete all generated documents 
-            _Files.searchFiles(rootFolder, dir->true, file->file.getName().endsWith(".adoc"))
-            .stream()
-            .peek(adocFile->System.out.println(String.format("deleting file: %s", adocFile.getName())))
-            .peek(__->deleteCount.inc())
-            .forEach(_Files::deleteFile);
-            
-            // write system overview
-            val sysovFile = new File(pagesFolder, projectDoc.getSystemOverviewFilename()); 
-            System.out.println(String.format("writing system overview: %s", sysovFile.getName()));
-            docWriter.accept(systemSummaryAdoc, sysovFile);
-            ++writeCount;
-            
-            // write document index
-            for(val unit : j2aContext.getUnitIndex().values()) {
-            
-                currentUnit.setValue(unit);
-                         
-                val adocIndexFile = adocDestinationFileForUnit(unit, projectDoc);
-                
-                System.out.println(String.format("writing file: %s", adocIndexFile.getName()));
-                
-                docWriter.accept(
-                        unit.toAsciiDoc(j2aContext), 
-                        adocIndexFile);
-                
+            // TODO: should split this out into two separate methods etc.
+            if (mode == ProjectDocModel.Mode.OVERVIEW) {
+
+                // write system overview
+                val overviewFile = new File(pagesFolder, overview.getSystemOverviewFilename());
+                System.out.printf("writing system overview: %s%n", overviewFile.getName());
+                docWriter.accept(systemSummaryAdoc, overviewFile);
                 ++writeCount;
             }
-            
-            // summary
-            System.out.println(
-                    String.format("ProjectDocWriter: all done. (deleted: %d, written: %d)", 
-                            deleteCount.getValue(),
-                            writeCount));
-            
+
+            if(mode == ProjectDocModel.Mode.INDEX) {
+
+                // delete all generated documents in the index
+                _Files.searchFiles(pagesFolder, dir->true, file-> {
+                    val fileName = file.getName();
+                    return  fileName.endsWith(".adoc") &&
+                           !fileName.equals(overview.getSystemOverviewFilename());
+                })
+                .stream()
+                .peek(adocFile->System.out.printf("deleting file: %s%n", adocFile.getName()))
+                .peek(__->deleteCount.inc())
+                .forEach(_Files::deleteFile);
+
+
+                // write document index
+                for(val unit : j2aContext.getUnitIndex().values()) {
+
+                    currentUnit.setValue(unit);
+
+                    val adocIndexFile = adocDestinationFileForUnit(unit, global, overview, index);
+
+                    System.out.printf("writing file: %s%n", adocIndexFile.getName());
+
+                    docWriter.accept(
+                            unit.toAsciiDoc(j2aContext),
+                            adocIndexFile);
+
+                    ++writeCount;
+                }
+
+                // summary
+                System.out.printf(
+                        "ProjectDocWriter: all done. (deleted: %d, written: %d)%n",
+                        deleteCount.getValue(), writeCount);
+            }
+
         } catch (Exception e) {
-            System.err.println(String.format(
-                    "failed to write adoc for unit %s", 
-                    currentUnit.getValue().map(J2AdocUnit::getCanonicalName).orElse("none")));
+            System.err.printf(
+                    "failed to write adoc for unit %s%n",
+                    currentUnit.getValue().map(J2AdocUnit::getCanonicalName).orElse("none"));
             e.printStackTrace();
             System.exit(1);
-        } 
-        
+        }
     }
-    
+
     // generate output file based on unit's namespace and unit's name
     private static File adocDestinationFileForUnit(
             final @NonNull J2AdocUnit unit,
-            final @NonNull CliConfig.ProjectDoc projectDoc) {
-        
-        val indexFolder = projectDoc.getDocumentIndexFolder();
-     
+            final @NonNull CliConfig.Global global,
+            final @NonNull CliConfig.Commands.Overview overview,
+            final @NonNull CliConfig.Commands.Index index
+            ) {
+
+        val indexFolder = index.getDocumentIndexFolder(global.getOutputRootFolder());
+
         val destFolderBuilder = _Refs.<File>objectRef(indexFolder);
-        
+
         unit.getNamespace().stream()
-        .skip(projectDoc.getNamespacePartsSkipCount()) 
+        .skip(global.getNamespacePartsSkipCount())
         .forEach(subDir->destFolderBuilder.update(currentDir->new File(currentDir, subDir)));
-        
+
         val destFolder = destFolderBuilder.getValueElseDefault(indexFolder);
         destFolder.mkdirs();
-        
+
         return new File(
                 destFolder,
                 unit.getCanonicalName()+ ".adoc");
-        
+
     }
 
-    
+
 }
diff --git a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/CliConfigTest.java b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/CliConfigTest.java
index fbddcbb..10f2a92 100644
--- a/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/CliConfigTest.java
+++ b/tooling/cli/src/test/java/org/apache/isis/tooling/cli/test/CliConfigTest.java
@@ -53,14 +53,15 @@ class CliConfigTest {
 
     private void assertConfigIsPopulated(CliConfig config) {
         assertNotNull(config);
-        assertNotNull(config.getProjectDoc());
-        assertEquals("These tables summarize all Maven artifacts available with _Apache Isis_.", config.getProjectDoc().getDescription());
-        assertNotNull(config.getProjectDoc().getArtifactGroups());
-        assertTrue(config.getProjectDoc().getArtifactGroups().size()>5);
+        assertNotNull(config.getGlobal());
+        assertNotNull(config.getCommands().getOverview());
+        assertNotNull(config.getCommands().getIndex());
+        assertEquals("These tables summarize all Maven artifacts available with _Apache Isis_.", config.getCommands().getOverview().getDescription());
+        assertNotNull(config.getGlobal().getSections());
+        assertTrue(config.getGlobal().getSections().size()>5);
 
-
-        assertEquals(true, config.getProjectDoc().isFixOrphanedAdocIncludeStatements());
-        assertEquals(3, config.getProjectDoc().getNamespacePartsSkipCount());
+        assertTrue(config.getCommands().getIndex().isFixOrphanedAdocIncludeStatements());
+        assertEquals(3, config.getGlobal().getNamespacePartsSkipCount());
     }
 
 }
diff --git a/tooling/cli/src/test/resources/org/apache/isis/tooling/cli/test/isis-tooling.yml b/tooling/cli/src/test/resources/org/apache/isis/tooling/cli/test/isis-tooling.yml
index 503a7b4..77fba0f 100644
--- a/tooling/cli/src/test/resources/org/apache/isis/tooling/cli/test/isis-tooling.yml
+++ b/tooling/cli/src/test/resources/org/apache/isis/tooling/cli/test/isis-tooling.yml
@@ -17,35 +17,84 @@
 #  under the License.
 #
 
-projectDoc:
-  fixOrphanedAdocIncludeStatements: true
+global:
   namespacePartsSkipCount: 3
-  description: "These tables summarize all Maven artifacts available with _Apache Isis_."
-  artifactGroups:
-    Base: org.apache.isis
-    Commons: org.apache.isis.commons.*
-    Core: org.apache.isis.core.*
+
+  sections:
     App: org.apache.isis.app.*
-    
     Mavendeps: org.apache.isis.mavendeps.*
-    Mappings: org.apache.isis.mappings.*
-    
-    Persistence: org.apache.isis.persistence.*
-    Security: org.apache.isis.security.*
-    
-    Valuetypes: org.apache.isis.valuetypes.*
-    Viewer: org.apache.isis.viewer.*
-
     Testing: org.apache.isis.testing.*
-    Regression Tests: org.apache.isis.regressiontests.*
-    
-    Extensions: org.apache.isis.extensions.*
-    Subdomains: org.apache.isis.subdomains.*
-    
-    Tooling: org.apache.isis.tooling.*
-    
     Examples: org.apache.isis.examples.*
-    
-    Incubator: org.apache.isis.incubator.*
+
+    Root: org.apache.isis
+    Commons: org.apache.isis.commons.*
+
+    Core: org.apache.isis.core.*
+
+    Persistence: org.apache.isis.persistence
+    JDO: "org.apache.isis.persistence:isis-persistence-jdo.*"
+    JPA: "org.apache.isis.persistence:isis-persistence-jpa.*"
+
+    Security: org.apache.isis.security
+    Bypass: "org.apache.isis.security:isis-security-bypass.*"
+    Keycloak: "org.apache.isis.security:isis-security-keycloak.*"
+    Shiro: "org.apache.isis.security:isis-security-shiro.*"
+
+    Viewer: org.apache.isis.viewer
+    "Restful Objects": "org.apache.isis.viewer:isis-viewer-restfulobjects.*"
+    Wicket: "org.apache.isis.viewer:isis-viewer-wicket.*"
+
+    Valuetypes: org.apache.isis.valuetypes.*
+
+    Mappings: org.apache.isis.mappings
+    #"Outbox Publisher": org.apache.isis.mappings:isis-mappings-jaxrsclient.*
+    "JAX-RS Client Library": "org.apache.isis.mappings:isis-mappings-jaxrsclient.*"
+    #Minio: "org.apache.isis.mappings:isis-mappings-minio.*"
+    "REST Client": "org.apache.isis.mappings:isis-mappings-restclient.*"
+    #"Slack Library": "org.apache.isis.mappings:isis-mappings-slack.*"
+
+    Extensions: org.apache.isis.extensions
+    "Core: Command Log": "org.apache.isis.extensions:isis-extensions-command-log.*"
+    "Core: Command Replay": "org.apache.isis.extensions:isis-extensions-command-replay.*"
+    "Core: Flyway": "org.apache.isis.extensions:isis-extensions-flyway.*"
+    "Core: Model Annotation": "org.apache.isis.extensions:isis-extensions-modelannotation.*"
+    "Core: Quartz": "org.apache.isis.extensions:isis-extensions-quartz.*"
+    #"Security: Audit Trail": "org.apache.isis.security:isis-extensions-audit-trail.*"
+    "Security: Secman": "org.apache.isis.security:isis-extensions-secman.*"
+    #"Security: Session Log": "org.apache.isis.security:isis-extensions-session-log.*"
+    "Security: Shiro LDAP Realm": "org.apache.isis.security:isis-extensions-shiro-realm-ldap.*"
+    "RO Viewer: CORS": "org.apache.isis.security:isis-extensions-cors.*"
+    "Wicket Viewer: Excel Download": "org.apache.isis.security:isis-extensions-exceldownload.*"
+    "Wicket Viewer: Full Calendar": "org.apache.isis.security:isis-extensions-fullcalendar.*"
+    #"Wicket Viewer: Gmap3": "org.apache.isis.security:isis-extensions-gmap3.*"
+    "Wicket Viewer: Pdf.js": "org.apache.isis.security:isis-extensions-fullcalendar.*"
+
+    Subdomains: org.apache.isis.subdomains
+    "Base": "org.apache.isis.subdomains:isis-subdomains-base.*"
+    #"docx": "org.apache.isis.subdomains:isis-subdomains-docx.*"
+    "Excel": "org.apache.isis.subdomains:isis-subdomains-excel.*"
+    #"Freemarker": "org.apache.isis.subdomains:isis-subdomains-freemarker.*"
+    #"OGNL": "org.apache.isis.subdomains:isis-subdomains-ognl.*"
+    #"PDF Box": "org.apache.isis.subdomains:isis-subdomains-pdfbox.*"
+    "Spring": "org.apache.isis.subdomains:isis-subdomains-spring.*"
+    "XDocReport": "org.apache.isis.subdomains:isis-subdomains-xdocreport.*"
+    #"Zip": "org.apache.isis.subdomains:isis-subdomains-zip.*"
+
+    "Tooling": org.apache.isis.tooling.*
+    "Regression Tests": org.apache.isis.regressiontests.*
+
+    Incubator: org.apache.isis.incubator
+    "Kroviz Client": "org.apache.isis.incubator.clients:isis-client-kroviz.*"
+    "JavaFX Viewer": "org.apache.isis.incubator.viewer:isis-viewer-javafx.*"
+    "Vaadin Viewer": "org.apache.isis.incubator.viewer:isis-viewer-vaadin.*"
+
     Legacy: org.apache.isis.legacy.*
-     
+
+
+commands:
+  overview:
+    description: "These tables summarize all Maven artifacts available with _Apache Isis_."
+
+  index:
+    fixOrphanedAdocIncludeStatements: true
+