You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2021/01/22 17:16:33 UTC

[isis] 04/04: Collection instroduced, version updsate for Kotlin, kotlinx.serialization and KVision

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

joergrade pushed a commit to branch ISIS-2465_Kroviz-Demo_Menu_Actions_Show_No_Output
in repository https://gitbox.apache.org/repos/asf/isis.git

commit db1ca839f67f32afe0af5204ba4df4056047538f
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Fri Jan 22 18:15:27 2021 +0100

    Collection instroduced, version updsate for Kotlin, kotlinx.serialization and KVision
---
 incubator/clients/kroviz/build.gradle.kts          |  5 +-
 incubator/clients/kroviz/gradle.properties         |  6 +-
 .../kroviz/core/aggregator/ActionDispatcher.kt     | 18 ++---
 .../kroviz/core/aggregator/ObjectAggregator.kt     | 25 +++++--
 .../kroviz/core/aggregator/RestfulDispatcher.kt    |  3 +-
 .../isis/client/kroviz/core/event/LogEntry.kt      | 17 ++---
 .../apache/isis/client/kroviz/core/model/ListDM.kt |  2 +-
 .../isis/client/kroviz/handler/ActionHandler.kt    |  4 +-
 .../{ActionHandler.kt => CollectionHandler.kt}     | 12 ++--
 .../client/kroviz/handler/DomainTypesHandler.kt    |  5 +-
 .../isis/client/kroviz/handler/HttpErrorHandler.kt |  5 +-
 .../isis/client/kroviz/handler/LayoutHandler.kt    |  5 +-
 .../isis/client/kroviz/handler/PlainHandlers.kt    | 33 +++++----
 .../isis/client/kroviz/handler/ResponseHandler.kt  |  4 +-
 .../isis/client/kroviz/handler/RestfulHandler.kt   |  5 +-
 .../client/kroviz/handler/ResultListHandler.kt     |  5 +-
 .../client/kroviz/handler/ResultObjectHandler.kt   |  5 +-
 .../client/kroviz/handler/ResultValueHandler.kt    |  5 +-
 .../kroviz/to/{TransferObject.kt => Collection.kt} | 14 ++--
 .../org/apache/isis/client/kroviz/to/Link.kt       | 79 ++++++++++++++++++++--
 .../isis/client/kroviz/to/PlainTransferObjects.kt  | 64 ------------------
 .../org/apache/isis/client/kroviz/to/TObject.kt    |  4 ++
 .../apache/isis/client/kroviz/to/TransferObject.kt | 35 +++++-----
 .../org/apache/isis/client/kroviz/to/Value.kt      | 60 ++++++++--------
 .../apache/isis/client/kroviz/ui/EventLogDetail.kt |  5 +-
 .../isis/client/kroviz/ui/builder/ColBuilder.kt    | 10 +--
 .../isis/client/kroviz/ui/builder/RowBuilder.kt    | 12 ++--
 .../org/apache/isis/client/kroviz/ui/kv/RoTable.kt | 31 ++++++++-
 .../apache/isis/client/kroviz/ui/kv/UiManager.kt   |  3 +-
 .../org/apache/isis/client/kroviz/utils/Utils.kt   |  4 +-
 .../apache/isis/client/kroviz/IntegrationTest.kt   |  2 -
 .../apache/isis/client/kroviz/PumlBuilderTest.kt   |  2 -
 .../org/apache/isis/client/kroviz/TestUtil.kt      |  2 +-
 .../kroviz/core/aggregator/ActionDispatcherTest.kt |  2 -
 .../kroviz/core/aggregator/ListAggregatorTest.kt   |  2 -
 .../kroviz/core/aggregator/ObjectAggregatorTest.kt |  2 -
 .../client/kroviz/core/event/EventStoreTest.kt     |  2 -
 .../client/kroviz/core/model/DisplayListTest.kt    |  2 -
 .../isis/client/kroviz/core/model/ExposerTest.kt   |  2 -
 .../client/kroviz/core/model/FixtureResultTest.kt  |  5 +-
 .../client/kroviz/handler/PropertyHandlerTest.kt   |  2 -
 .../client/kroviz/handler/ResponseHandlerTest.kt   |  2 -
 .../client/kroviz/handler/RestfulHandlerTest.kt    |  2 -
 .../apache/isis/client/kroviz/layout/LayoutTest.kt |  2 -
 .../snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt    | 73 ++++++++++++++++++++
 .../isis/client/kroviz/snapshots/sample.json       | 45 ++++++------
 .../kroviz/snapshots/simpleapp1_16_0/UrlsTest.kt   |  2 -
 .../org/apache/isis/client/kroviz/to/ActionTest.kt |  2 -
 .../kroviz/to/{LinkTest.kt => CollectionTest.kt}   | 48 ++++++-------
 .../apache/isis/client/kroviz/to/DomainTypeTest.kt |  6 +-
 .../isis/client/kroviz/to/FeaturedTypesTest.kt     |  2 -
 .../apache/isis/client/kroviz/to/HttpErrorTest.kt  |  2 -
 .../org/apache/isis/client/kroviz/to/LinkTest.kt   | 41 ++++++++++-
 .../org/apache/isis/client/kroviz/to/MemberTest.kt |  4 +-
 .../apache/isis/client/kroviz/to/PropertyTest.kt   |  2 -
 .../apache/isis/client/kroviz/to/ResultListTest.kt |  2 -
 .../isis/client/kroviz/to/ResultObjectTest.kt      |  2 -
 .../isis/client/kroviz/to/ResultValueTest.kt       |  2 -
 .../apache/isis/client/kroviz/to/ServiceTest.kt    |  2 -
 .../apache/isis/client/kroviz/to/TObjectTest.kt    |  2 -
 .../org/apache/isis/client/kroviz/to/UserTest.kt   |  2 -
 .../apache/isis/client/kroviz/to/VersionTest.kt    |  2 -
 .../isis/client/kroviz/to/mb/MenubarsTest.kt       |  2 -
 63 files changed, 426 insertions(+), 333 deletions(-)

diff --git a/incubator/clients/kroviz/build.gradle.kts b/incubator/clients/kroviz/build.gradle.kts
index 6aa80a0..a7af57b 100644
--- a/incubator/clients/kroviz/build.gradle.kts
+++ b/incubator/clients/kroviz/build.gradle.kts
@@ -95,9 +95,6 @@ kotlin {
     }
     sourceSets["main"].dependencies {
         implementation(kotlin("stdlib-js"))
-        implementation(npm("po2json"))
-        implementation(npm("grunt"))
-        implementation(npm("grunt-pot"))
 
         implementation("pl.treksoft:kvision:$kvisionVersion")
         implementation("pl.treksoft:kvision-bootstrap:$kvisionVersion")
@@ -127,7 +124,7 @@ kotlin {
 }
 
 fun getNodeJsBinaryExecutable(): String {
-    val nodeDir = NodeJsRootPlugin.apply(project).nodeJsSetupTask.destination
+    val nodeDir = NodeJsRootPlugin.apply(project).nodeJsSetupTaskProvider.get().destination
     val isWindows = System.getProperty("os.name").toLowerCase().contains("windows")
     val nodeBinDir = if (isWindows) nodeDir else nodeDir.resolve("bin")
     val command = NodeJsRootPlugin.apply(project).nodeCommand
diff --git a/incubator/clients/kroviz/gradle.properties b/incubator/clients/kroviz/gradle.properties
index 3e22a52..1ae047d 100644
--- a/incubator/clients/kroviz/gradle.properties
+++ b/incubator/clients/kroviz/gradle.properties
@@ -20,7 +20,7 @@
 
 javaVersion=1.8
 #Plugins
-systemProp.kotlinVersion=1.3.72
-serializationVersion=0.20.0
+systemProp.kotlinVersion=1.4.21
+serializationVersion=1.0.1
 #Dependencies
-systemProp.kvisionVersion=3.11.0
+systemProp.kvisionVersion=3.19.1
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
index 5599c60..fc1e3cf 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcher.kt
@@ -23,6 +23,7 @@ import org.apache.isis.client.kroviz.core.event.RoXmlHttpRequest
 import org.apache.isis.client.kroviz.to.Action
 import org.apache.isis.client.kroviz.to.Link
 import org.apache.isis.client.kroviz.to.Method
+import org.apache.isis.client.kroviz.to.Relation
 import org.apache.isis.client.kroviz.ui.kv.ActionPrompt
 import org.apache.isis.client.kroviz.utils.Point
 import org.apache.isis.client.kroviz.utils.Utils
@@ -35,10 +36,7 @@ class ActionDispatcher(private val at: Point = Point(100, 100)) : BaseAggregator
             if (link.isInvokeAction()) {
                 when (link.method) {
                     Method.GET.name -> process(action, link)
-                    Method.POST.name -> {
-                        val title = Utils.deCamel(action.id)
-                        process(action, link, ObjectAggregator(title))
-                    }
+                    Method.POST.name -> invoke(action, link)
                     Method.PUT.name -> process(action, link)
                 }
             }
@@ -48,19 +46,21 @@ class ActionDispatcher(private val at: Point = Point(100, 100)) : BaseAggregator
     private fun process(action: Action, link: Link, aggregator: BaseAggregator = this) {
         when {
             link.hasArguments() -> ActionPrompt(action = action).open(at)
-            link.rel.contains("invoke") -> {
-                val title = Utils.deCamel(action.id)
-                RoXmlHttpRequest().invoke(link, ObjectAggregator(title))
-            }
+            link.relation() == Relation.INVOKE -> invoke(action, link)
             else -> RoXmlHttpRequest().invoke(link, aggregator)
         }
     }
 
+    private fun invoke(action: Action, link: Link) {
+        val title = Utils.deCamel(action.id)
+        RoXmlHttpRequest().invoke(link, ObjectAggregator(title))
+    }
+
     /**
      *  link.rel should neither be: (self | up | describedBy )
      */
     private fun Link.isInvokeAction(): Boolean {
-        return rel.contains("invoke") && rel.contains("action")
+        return relation() == Relation.INVOKE && rel.contains("action")
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
index 3a64a16..83b1228 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregator.kt
@@ -22,10 +22,7 @@ import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.RoXmlHttpRequest
 import org.apache.isis.client.kroviz.core.model.ObjectDM
 import org.apache.isis.client.kroviz.layout.Layout
-import org.apache.isis.client.kroviz.to.HttpError
-import org.apache.isis.client.kroviz.to.Property
-import org.apache.isis.client.kroviz.to.ResultObject
-import org.apache.isis.client.kroviz.to.TObject
+import org.apache.isis.client.kroviz.to.*
 import org.apache.isis.client.kroviz.to.bs3.Grid
 import org.apache.isis.client.kroviz.ui.ErrorDialog
 import org.apache.isis.client.kroviz.ui.kv.Constants
@@ -43,12 +40,16 @@ class ObjectAggregator(val actionTitle: String) : BaseAggregator() {
             is TObject -> handleObject(obj)
             is ResultObject -> handleResultObject(obj)
             is Property -> handleProperty(obj)
+            is Collection -> handleCollection(obj)
             is Layout -> handleLayout(obj)
             is Grid -> handleGrid(obj)
             is HttpError -> ErrorDialog(logEntry).open()
             else -> log(logEntry)
         }
 
+        console.log("[ObjectAggregator.update]")
+        console.log(logEntry.getTransferObject())
+
         if (dpm.canBeDisplayed()) {
             UiManager.openObjectView(this)
         }
@@ -58,13 +59,21 @@ class ObjectAggregator(val actionTitle: String) : BaseAggregator() {
         dpm.addData(obj)
         val l = obj.getLayoutLink()!!
         // Json.Layout is invoked first
-        RoXmlHttpRequest().invoke(l,this)
+        RoXmlHttpRequest().invoke(l, this)
         // then Xml.Layout is to be invoked as well
-        RoXmlHttpRequest().invoke(l,this, Constants.subTypeXml)
+        RoXmlHttpRequest().invoke(l, this, Constants.subTypeXml)
+    }
+
+    fun handleCollection(obj: Collection) {
+        // TODO dsp.addData(obj)
+        console.log("[ObjectAggregator.handleCollection] TODO")
+        console.log(obj)
     }
 
     fun handleResultObject(obj: ResultObject) {
         // TODO dsp.addData(obj)
+        console.log("[ObjectAggregator.handleResultObject] TODO")
+        console.log(obj)
     }
 
     override fun getObject(): TObject? {
@@ -73,6 +82,8 @@ class ObjectAggregator(val actionTitle: String) : BaseAggregator() {
 
     private fun handleProperty(property: Property) {
         //TODO  yet to be implemented
+        console.log("[ObjectAggregator.handleProperty] TODO")
+        console.log(property)
     }
 
     private fun handleLayout(layout: Layout) {
@@ -84,7 +95,7 @@ class ObjectAggregator(val actionTitle: String) : BaseAggregator() {
                 val isDn = l.href.contains("datanucleus")
                 if (isDn) {
                     //invoking DN links leads to an error
-                    RoXmlHttpRequest().invoke(l,this)
+                    RoXmlHttpRequest().invoke(l, this)
                 }
             }
         }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/RestfulDispatcher.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/RestfulDispatcher.kt
index 6d4ab0c..970f585 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/RestfulDispatcher.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/RestfulDispatcher.kt
@@ -21,6 +21,7 @@ package org.apache.isis.client.kroviz.core.aggregator
 import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.RoXmlHttpRequest
 import org.apache.isis.client.kroviz.to.Link
+import org.apache.isis.client.kroviz.to.Relation
 import org.apache.isis.client.kroviz.to.Restful
 
 class RestfulDispatcher() : BaseAggregator() {
@@ -30,7 +31,7 @@ class RestfulDispatcher() : BaseAggregator() {
         restful.links.forEach {
             when {
                 it.rel.endsWith("/menuBars") -> invokeNavigation(it)
-                it.rel == "self" -> {}
+                it.relation() == Relation.SELF -> {}
                 it.rel.endsWith("/services") -> {}
                 else -> invokeSystem(it)
             }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
index 6279542..09955ae 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntry.kt
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.client.kroviz.core.event
 
-import kotlinx.serialization.ContextualSerialization
+import kotlinx.serialization.Contextual
 import kotlinx.serialization.Serializable
 import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.core.aggregator.BaseAggregator
@@ -52,7 +52,7 @@ data class LogEntry(
         val method: String? = "",
         val request: String = "",
         val subType: String = Constants.subTypeJson,
-        @ContextualSerialization val createdAt: Date = Date()) {
+        @Contextual val createdAt: Date = Date()) {
     var state = EventState.INITIAL
     var title: String = ""
     var requestLength: Int = 0 // must be accessible (public) for LogEntryTable
@@ -61,26 +61,27 @@ data class LogEntry(
 
     init {
         state = EventState.RUNNING
-        title = stripHostPort(url)
+        title = url // stripHostPort(url)
         requestLength = request.length
     }
 
-    @ContextualSerialization
+    @Contextual
     var updatedAt: Date? = null
 
-    @ContextualSerialization
+    @Contextual
     private var lastAccessedAt: Date? = null
 
     private var fault: String? = null
 
-    @ContextualSerialization
+    @Contextual
     var duration: Int = 0
 
     var cacheHits = 0
-    val aggregators by lazy { mutableListOf<BaseAggregator>() }
+
+    val aggregators = mutableListOf<@Contextual BaseAggregator>()
     var nOfAggregators: Int = 0 // must be accessible (public) for LogEntryTable
 
-    @ContextualSerialization
+    @Contextual
     var obj: Any? = null
 
     // alternative constructor for UI events (eg. from user interaction)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ListDM.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ListDM.kt
index dd2c0dc..6bd3080 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ListDM.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/model/ListDM.kt
@@ -30,7 +30,7 @@ class ListDM(override val title: String) : DisplayModelWithLayout() {
         if (!rawData.contains(obj)) {
             rawData.add(obj)
             val exo = Exposer(obj as TObject)
-            data.add(exo.dynamise())  //if exposer is not dynamised, data access in tables won't work
+            data.add(exo)  //if exposer is not dynamised, data access in tables won't work   .dynamise()
         }
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
index 00a112a..2e86e98 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.to.Action
@@ -26,9 +25,8 @@ import org.apache.isis.client.kroviz.to.TransferObject
 
 class ActionHandler : BaseHandler() {
 
-    @UnstableDefault
     override fun parse(response: String): TransferObject {
-        return Json.parse(Action.serializer(), response)
+        return Json.decodeFromString(Action.serializer(), response)
     }
 
     override fun doHandle() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
similarity index 76%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
copy to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
index 00a112a..c8ead08 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ActionHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/CollectionHandler.kt
@@ -18,21 +18,19 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
-import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
-import org.apache.isis.client.kroviz.to.Action
+import org.apache.isis.client.kroviz.to.Collection
 import org.apache.isis.client.kroviz.to.TransferObject
 
-class ActionHandler : BaseHandler() {
+class CollectionHandler : BaseHandler() {
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Action.serializer(), response)
+        return Json.decodeFromString(Collection.serializer(), response)
     }
 
     override fun doHandle() {
-        logEntry.addAggregator(ActionDispatcher())
+        //logEntry.addAggregator(ActionDispatcher())
         update()
     }
 
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/DomainTypesHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/DomainTypesHandler.kt
index 6b69341..f31cf1e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/DomainTypesHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/DomainTypesHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.DomainTypesAggregator
 import org.apache.isis.client.kroviz.to.DomainTypes
@@ -27,9 +26,9 @@ import org.apache.isis.client.kroviz.ui.kv.UiManager
 
 class DomainTypesHandler : org.apache.isis.client.kroviz.handler.BaseHandler() {
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(DomainTypes.serializer(), response)
+        return Json.decodeFromString(DomainTypes.serializer(), response)
     }
 
     override fun doHandle() {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/HttpErrorHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/HttpErrorHandler.kt
index f53020d..c37b56c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/HttpErrorHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/HttpErrorHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.ErrorDispatcher
 import org.apache.isis.client.kroviz.to.HttpError
@@ -31,8 +30,8 @@ class HttpErrorHandler : BaseHandler() {
         update()
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(HttpError.serializer(), response)
+        return Json.decodeFromString(HttpError.serializer(), response)
     }
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/LayoutHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/LayoutHandler.kt
index 319eef5..72fa0f7 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/LayoutHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/LayoutHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.layout.Layout
 import org.apache.isis.client.kroviz.to.TransferObject
@@ -35,9 +34,9 @@ class LayoutHandler : org.apache.isis.client.kroviz.handler.BaseHandler() {
         return false
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Layout.serializer(), response)
+        return Json.decodeFromString(Layout.serializer(), response)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
index 1824e5d..f94f48c 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/PlainHandlers.kt
@@ -19,7 +19,6 @@
 
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.to.*
 import org.apache.isis.client.kroviz.to.mb.Menubars
@@ -29,57 +28,57 @@ import org.apache.isis.client.kroviz.to.mb.Menubars
  */
 
 class DomainTypeHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(DomainType.serializer(), response)
+        return Json.decodeFromString(DomainType.serializer(), response)
     }
 }
 
 class MemberHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Member.serializer(), response)
+        return Json.decodeFromString(Member.serializer(), response)
     }
 }
 
 class MenuBarsHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Menubars.serializer(), response)
+        return Json.decodeFromString(Menubars.serializer(), response)
     }
 }
 
 class PropertyHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Property.serializer(), response)
+        return Json.decodeFromString(Property.serializer(), response)
     }
 }
 
 class ServiceHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Service.serializer(), response)
+        return Json.decodeFromString(Service.serializer(), response)
     }
 }
 
 class TObjectHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(TObject.serializer(), response)
+        return Json.decodeFromString(TObject.serializer(), response)
     }
 }
 
 class UserHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(User.serializer(), response)
+        return Json.decodeFromString(User.serializer(), response)
     }
 }
 
 class VersionHandler : BaseHandler() {
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Version.serializer(), response)
+        return Json.decodeFromString(Version.serializer(), response)
     }
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
index f2fe458..316cc47 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandler.kt
@@ -39,6 +39,7 @@ object ResponseHandler {
     private var _6 = LayoutHandler()
     private var _6a = LayoutXmlHandler()
     private var _7 = PropertyHandler()
+    private var _7a = CollectionHandler()
     private var _8 = MemberHandler()
     private var _9 = HttpErrorHandler()
     private var _10 = UserHandler()
@@ -60,7 +61,8 @@ object ResponseHandler {
         _5.successor = _6
         _6.successor = _6a
         _6a.successor = _7
-        _7.successor = _8
+        _7.successor = _7a
+        _7a.successor = _8
         _8.successor = _9
         _9.successor = _10
         _10.successor = _11
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandler.kt
index 3ecfe44..e184534 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.RestfulDispatcher
 import org.apache.isis.client.kroviz.to.Restful
@@ -31,9 +30,9 @@ class RestfulHandler : BaseHandler() {
         update()
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(Restful.serializer(), response)
+        return Json.decodeFromString(Restful.serializer(), response)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultListHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultListHandler.kt
index 9a5c92b..592ebf7 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultListHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultListHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.ListAggregator
 import org.apache.isis.client.kroviz.to.ResultList
@@ -31,9 +30,9 @@ class ResultListHandler : BaseHandler() {
         update()
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(ResultList.serializer(), response)
+        return Json.decodeFromString(ResultList.serializer(), response)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultObjectHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultObjectHandler.kt
index a788ed9..cefa8f8 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultObjectHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultObjectHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.ObjectAggregator
 import org.apache.isis.client.kroviz.to.ResultObject
@@ -31,9 +30,9 @@ class ResultObjectHandler : BaseHandler() {
         update()
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(ResultObject.serializer(), response)
+        return Json.decodeFromString(ResultObject.serializer(), response)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultValueHandler.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultValueHandler.kt
index 8641a27..dcc5417 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultValueHandler.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/handler/ResultValueHandler.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.core.aggregator.DownloadDispatcher
 import org.apache.isis.client.kroviz.to.ResultValue
@@ -31,9 +30,9 @@ class ResultValueHandler : BaseHandler() {
         update()
     }
 
-    @UnstableDefault
+    
     override fun parse(response: String): TransferObject {
-        return Json.parse(ResultValue.serializer(), response)
+        return Json.decodeFromString(ResultValue.serializer(), response)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Collection.kt
similarity index 68%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt
copy to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Collection.kt
index c1aa5f1..31f8848 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Collection.kt
@@ -16,11 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-
 package org.apache.isis.client.kroviz.to
 
-/*
- * @See: https://martinfowler.com/eaaCatalog/dataTransferObject.html
- */
+import kotlinx.serialization.Serializable
 
-interface TransferObject
+@Serializable
+data class Collection(val id: String,
+                      val memberType: String,
+                      override val links: List<Link> = emptyList(),
+                      val extensions: Extensions,
+                      val value: List<Link> = emptyList(),
+                      val disabledReason: String = ""
+) : TransferObject, HasLinks {}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
index b04f009..d5d076b 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Link.kt
@@ -69,10 +69,10 @@ data class Link(val rel: String = "",
     }
 
     fun relation(): Relation {
-        val prefix = "urn:org.restfulobjects:rels/"
-        console.log("[Link.relation()]")
-        console.log(this)
-        var raw = rel.replace(prefix, "")
+        val roPrefix = "urn:org.apache.isis.restfulobjects:rels/"
+        var raw = rel.replace(roPrefix, "")
+        val isisPrefix = "urn:org.restfulobjects:rels/"
+        raw = raw.replace(isisPrefix, "")
         if (raw.contains(";")) {
             raw = raw.split(";").first()  //TODO handle args=value separated by ;
         }
@@ -80,7 +80,7 @@ data class Link(val rel: String = "",
         return Relation.find(raw)!!
     }
 
-    private fun representation(): Represention {
+    fun representation(): Represention {
         val prefix = "application/json;profile=\"urn:org.restfulobjects:repr-types/"
         var raw = type.replace(prefix, "")
         raw = raw.replace("\"", "")
@@ -88,3 +88,72 @@ data class Link(val rel: String = "",
     }
 
 }
+
+/**
+ * RO SPEC restfulobject-spec.pdf §2.7.1
+ * extends ->
+ * IANA SPEC http://www.iana.org/assignments/link-relations/link-relations.xml
+ */
+enum class Relation(val type: String) {
+    ACTION("action"),
+    DESCRIBED_BY("describedby"), //ISIS. IANA:"describedBy"
+    DETAILS("details"),
+    DOMAIN_TYPE("domain-type"),
+    DOMAIN_TYPES("domain-types"),
+    ELEMENT("element"),
+    HELP("help"),               //IANA
+    ICON("icon"),               //IANA
+    INVOKE("invoke"),
+    LOGOUT("logout"),
+    MENU_BARS("menuBars"),
+    MODIFY("modify"),
+    NEXT("next"),               //IANA
+    OBJECT_ICON("object-icon"),
+    OBJECT_LAYOUT("object-layout"),
+    PREVIOUS("previous"),       //IANA
+    PROPERTY("property"),
+    RETURN_TYPE("return-type"),
+    SELF("self"),               //IANA
+    SERVICE("service"),         //specified in both IANA & RO
+    SERVICES("services"),
+    UP("up"),                   //IANA
+    UPDATE("update"),
+    USER("user"),
+    VALUE("value"),
+    VERSION("version");
+
+    companion object {
+        fun find(value: String): Relation? = Relation.values().find { it.type == value }
+    }
+}
+
+/**
+ * RO SPEC restfulobject-spec.pdf §2.4.1
+ */
+enum class Represention(val type: String) {
+    ACTION("action"),                      // missing in RO SPEC ???
+    ACTION_DESCRIPTION("action-description"),
+    ACTION_RESULT("action-result"),
+    ACTION_PARAM_DESCRIPTION("action-param-description"),
+    COLLECTION_DESCRIPTION("collection-description"),
+    DOMAIN_TYPE("domain-type"),
+    ERROR("error"),
+    HOMEPAGE("homepage"),
+    LIST("list"),
+    OBJECT("object"),
+    OBJECT_ACTION("object-action"),
+    OBJECT_COLLECTION("object-collection"),
+    OBJECT_LAYOUT_BS3("object-layout-bs3"), // missing in RO SPEC ???
+    OBJECT_PROPERTY("object-property"),
+    PROPERTY_DESCRIPTION("property-description"),
+    SELF("self"),
+    TYPE_LIST("type-list"),
+    TYPE_ACTION_RESULT("type-action-result"),
+    USER("user"),
+    VERSION("version");
+
+    companion object {
+        fun find(value: String): Represention? = Represention.values().find { it.type == value }
+    }
+
+}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
index ace446c..1aca714 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/PlainTransferObjects.kt
@@ -110,70 +110,6 @@ data class Property(val id: String = "",
                     val maxLength: Int = 0
 ) : TransferObject, HasLinks
 
-
-/**
- * RO SPEC restfulobject-spec.pdf §2.7.1
- * extends ->
- * IANA SPEC http://www.iana.org/assignments/link-relations/link-relations.xml
- */
-enum class Relation(val type:String) {
-    ACTION("action"),
-    DESCRIBED_BY("describedBy"),  //IANA
-    DETAILS("details"),
-    DOMAIN_TYPE("domain-type"),
-    ELEMENT("element"),
-    HELP("help"),               //IANA
-    ICON("icon"),               //IANA
-    INVOKE("invoke"),
-    MODIFY("modify"),
-    NEXT("next"),               //IANA
-    PREVIOUS("previous"),       //IANA
-    PROPERTY("property"),
-    RETURN_TYPE("return-type"),
-    SELF("self"),               //IANA
-    SERVICE("service"),         //specified in both IANA & RO
-    SERVICES("services"),
-    UP("up"),                   //IANA
-    UPDATE("update"),
-    USER("user"),
-    VALUE("value"),
-    VERSION("version");
-
-    companion object {
-        fun find(value: String): Relation? = Relation.values().find { it.type == value }
-    }
-}
-
-/**
- * RO SPEC restfulobject-spec.pdf §2.4.1
- */
-enum class Represention(val type: String) {
-    ACTION("action"),                      // missing in RO SPEC ???
-    ACTION_DESCRIPTION("action-description"),
-    ACTION_RESULT("action-result"),
-    ACTION_PARAM_DESCRIPTION("action-param-description"),
-    COLLECTION_DESCRIPTION("collection-description"),
-    DOMAIN_TYPE("domain-type"),
-    ERROR("error"),
-    HOMEPAGE("homepage"),
-    LIST("list"),
-    OBJECT("object"),
-    OBJECT_ACTION("object-action"),
-    OBJECT_COLLECTION("object-collection"),
-    OBJECT_LAYOUT_BS3("object-layout-bs3"), // missing in RO SPEC ???
-    OBJECT_PROPERTY("object-property"),
-    PROPERTY_DESCRIPTION("property-description"),
-    TYPE_LIST("type-list"),
-    TYPE_ACTION_RESULT("type-action-result"),
-    USER("user"),
-    VERSION("version");
-
-    companion object {
-        fun find(value: String): Represention? = Represention.values().find { it.type == value }
-    }
-
-}
-
 @Serializable
 data class Restful(override val links: List<Link> = emptyList(),
                    val extensions: Extensions
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TObject.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TObject.kt
index c1cfbc0..e4f2bb8 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TObject.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TObject.kt
@@ -37,6 +37,10 @@ data class TObject(override val links: List<Link> = emptyList(),
         return getMembersOfType(MemberType.ACTION.type)
     }
 
+    fun getCollections(): MutableList<Member> {
+        return getMembersOfType(MemberType.COLLECTION.type)
+    }
+
     private fun getMembersOfType(type: String): MutableList<Member> {
         val result = mutableListOf<Member>()
         members.forEach {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt
index c1aa5f1..0cbcb00 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/TransferObject.kt
@@ -1,26 +1,23 @@
 /*
- *  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
+ * 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
+ *       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.
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
  */
 
 package org.apache.isis.client.kroviz.to
 
-/*
- * @See: https://martinfowler.com/eaaCatalog/dataTransferObject.html
- */
-
-interface TransferObject
+interface TransferObject {
+}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Value.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Value.kt
index 1dcb938..242e9a7 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Value.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/to/Value.kt
@@ -20,10 +20,11 @@ package org.apache.isis.client.kroviz.to
 
 import kotlinx.serialization.*
 import kotlinx.serialization.builtins.nullable
+import kotlinx.serialization.encoding.Decoder
 import kotlinx.serialization.json.Json
 import kotlinx.serialization.json.JsonElement
-import kotlinx.serialization.json.JsonException
-import kotlinx.serialization.json.content
+import kotlinx.serialization.json.JsonObject
+import kotlinx.serialization.json.jsonPrimitive
 
 /**
  *  Custom data structure to handle 'untyped' value in Member, Property, Parameter
@@ -37,48 +38,47 @@ import kotlinx.serialization.json.content
 @Serializable
 data class Value(
         //IMPROVE: make content immutable (again) and handle property edits eg. via a wrapper
-        @ContextualSerialization @SerialName("value") var content: Any? = null
+        @Contextual @SerialName("value") var content: Any? = null
 ) : TransferObject {
 
+    @ExperimentalSerializationApi
     @Serializer(forClass = Value::class)
     companion object : KSerializer<Value> {
-        override fun serialize(encoder: Encoder, obj: Value) {
-            // Not required yet
-        }
-
-        override val descriptor: SerialDescriptor = SerialDescriptor("Value")
 
-        @UnstableDefault
+        @ExperimentalSerializationApi
         override fun deserialize(decoder: Decoder): Value {
-            var result: Value
-            var jse: JsonElement? = null
-            try {
-                val nss = JsonElement.serializer().nullable
-                jse = decoder.decode(nss)!!
-                val jsct = jse.content
-                when {
-                    jse.isNull -> result = Value(null)
-                    isLong(jsct) -> result = Value(jsct.toLong())
-                    else -> result = Value(jsct)
-                }
-            } catch (je: JsonException) {
-                val linkStr = jse.toString()
-                val link = Json.parse(Link.serializer(), linkStr)
-                result = Value(link)
+            val nss = JsonElement.serializer().nullable
+            val jse: JsonElement? = decoder.decodeNullableSerializableValue(nss)!!
+            val result: Value = when {
+                jse == null -> Value(null)
+                isNumeric(jse) -> Value(jse.jsonPrimitive.content.toLong())
+                jse is JsonObject -> toLink(jse)
+                else -> toString(jse)
             }
             return result
         }
 
-        private fun isLong(raw: String): Boolean {
-            var answer = true
+        private fun toString(jse: JsonElement): Value {
+            val s = jse.jsonPrimitive.content
+            return Value(s)
+        }
+
+        private fun toLink(jse: JsonElement): Value {
+            val linkStr = jse.toString()
+            val link = Json.decodeFromString(Link.serializer(), linkStr)
+            return Value(link)
+        }
+
+        private fun isNumeric(jse: JsonElement): Boolean {
             try {
-                raw.toLong()
+                jse.jsonPrimitive.content.toLong()
+                return true
             } catch (nfe: NumberFormatException) {
-                answer = false
+                return false
+            } catch (ie: IllegalArgumentException) {
+                return false
             }
-            return answer
         }
-
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
index 1258de3..1717264 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/EventLogDetail.kt
@@ -35,7 +35,7 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
         if (jsonStr.isNotEmpty() && logEntry.subType == Constants.subTypeJson) {
             jsonStr = Utils.format(jsonStr)
         }
-        formItems.add(FormItem("Text", ValueType.TEXT_AREA, jsonStr, 10))
+        formItems.add(FormItem("Response", ValueType.TEXT_AREA, jsonStr, 10))
 
         var aggtStr = ""
         logEntry.aggregators.forEach { it ->
@@ -47,7 +47,8 @@ class EventLogDetail(val logEntry: LogEntry) : Command() {
                 caption = "Error :" + logEntry.title,
                 items = formItems,
                 command = this,
-                defaultAction = "Visualize").open()
+                defaultAction = "Visualize",
+                widthPerc = 60).open()
     }
 
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
index d901382..22a50c4 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/ColBuilder.kt
@@ -21,17 +21,19 @@ package org.apache.isis.client.kroviz.ui.builder
 import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.to.bs3.Col
 import org.apache.isis.client.kroviz.ui.kv.RoDisplay
+import pl.treksoft.kvision.core.*
+import pl.treksoft.kvision.core.FlexWrap
 import pl.treksoft.kvision.panel.*
 
 class ColBuilder {
 
     fun create(col: Col, tObject: TObject, dsp: RoDisplay): FlexPanel {
         val result = FlexPanel(
-                FlexDir.COLUMN,
+                FlexDirection.COLUMN,
                 FlexWrap.NOWRAP,
-                FlexJustify.SPACEBETWEEN,
-                FlexAlignItems.CENTER,
-                FlexAlignContent.STRETCH,
+                JustifyContent.SPACEBETWEEN,
+                AlignItems.CENTER,
+                AlignContent.STRETCH,
                 spacing = 10)
         for (tg in col.tabGroupList) {
             val tgCpt = TabGroupBuilder().create(tg, tObject, dsp)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/RowBuilder.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/RowBuilder.kt
index d120509..708eb55 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/RowBuilder.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/builder/RowBuilder.kt
@@ -22,19 +22,19 @@ import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.to.bs3.Row
 import org.apache.isis.client.kroviz.ui.kv.MenuFactory
 import org.apache.isis.client.kroviz.ui.kv.RoDisplay
-import pl.treksoft.kvision.core.CssSize
-import pl.treksoft.kvision.core.UNIT
+import pl.treksoft.kvision.core.*
+import pl.treksoft.kvision.core.FlexWrap
 import pl.treksoft.kvision.panel.*
 
 class RowBuilder {
 
     fun create(row: Row, tObject: TObject, dsp: RoDisplay): SimplePanel {
         val result = FlexPanel(
-                FlexDir.ROW,
+                FlexDirection.ROW,
                 FlexWrap.NOWRAP,
-                FlexJustify.FLEXSTART,
-                FlexAlignItems.FLEXSTART,
-                FlexAlignContent.STRETCH,
+                JustifyContent.FLEXSTART,
+                AlignItems.FLEXSTART,
+                AlignContent.STRETCH,
                 spacing = 10 )
 
         for (c in row.colList) {
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/RoTable.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/RoTable.kt
index 2af92e3..83c10f2 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/RoTable.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/RoTable.kt
@@ -21,6 +21,7 @@ package org.apache.isis.client.kroviz.ui.kv
 import org.apache.isis.client.kroviz.core.model.Exposer
 import org.apache.isis.client.kroviz.core.model.ListDM
 import org.apache.isis.client.kroviz.utils.Utils
+import pl.treksoft.kvision.core.Container
 import pl.treksoft.kvision.core.CssSize
 import pl.treksoft.kvision.core.UNIT
 import pl.treksoft.kvision.panel.SimplePanel
@@ -28,7 +29,7 @@ import pl.treksoft.kvision.table.TableType
 import pl.treksoft.kvision.tabulator.Layout
 import pl.treksoft.kvision.tabulator.Tabulator
 import pl.treksoft.kvision.tabulator.TabulatorOptions
-import pl.treksoft.kvision.tabulator.tabulator
+import pl.treksoft.kvision.utils.set
 
 /**
  * access attributes from dynamic (JS) objects with varying
@@ -64,4 +65,32 @@ class RoTable(displayList: ListDM) : SimplePanel() {
         }
     }
 
+    fun <T : Any> Container.tabulator(
+            data: List<T>? = null,
+            dataUpdateOnEdit: Boolean = true,
+            options: TabulatorOptions<T> = TabulatorOptions(),
+            types: Set<TableType> = setOf(),
+            classes: Set<String>? = null,
+            className: String? = null,
+            init: (Tabulator<T>.() -> Unit)? = null
+    ): Tabulator<T> {
+        val tabulator = create(data, dataUpdateOnEdit, options, types, classes ?: className.set)
+        init?.invoke(tabulator)
+        this.add(tabulator)
+        return tabulator
+    }
+
+    fun <T : Any> create(
+            data: List<T>? = null,
+            dataUpdateOnEdit: Boolean = true,
+            options: TabulatorOptions<T> = TabulatorOptions(),
+            types: Set<TableType> = setOf(),
+            classes: Set<String> = setOf(),
+            init: (Tabulator<T>.() -> Unit)? = null
+    ): Tabulator<T> {
+        val tabulator = Tabulator(data, dataUpdateOnEdit, options, types, classes)
+        init?.invoke(tabulator)
+        return tabulator
+    }
+
 }
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/UiManager.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/UiManager.kt
index 40ad80a..ba7eb96 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/UiManager.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/kv/UiManager.kt
@@ -27,6 +27,7 @@ import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
 import org.apache.isis.client.kroviz.core.model.ListDM
 import org.apache.isis.client.kroviz.core.model.ObjectDM
+import org.apache.isis.client.kroviz.to.Relation
 import org.apache.isis.client.kroviz.to.TObject
 import org.apache.isis.client.kroviz.to.mb.Menubars
 import org.apache.isis.client.kroviz.utils.Utils
@@ -129,7 +130,7 @@ object UiManager {
 
     private fun linkLayout(tObject: TObject, aggregator: ObjectAggregator) {
         val layoutLink = tObject.links.firstOrNull {
-            it.rel.contains("object-layout")
+            it.relation() == Relation.OBJECT_LAYOUT
         }
         val reSpec = ResourceSpecification(layoutLink!!.href)
         val logEntry = EventStore.find(reSpec)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/Utils.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/Utils.kt
index c0271b8..2c64e9e 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/Utils.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/utils/Utils.kt
@@ -21,6 +21,7 @@ package org.apache.isis.client.kroviz.utils
 import org.apache.isis.client.kroviz.to.Argument
 import org.apache.isis.client.kroviz.to.Link
 import org.apache.isis.client.kroviz.to.TObject
+import kotlinx.serialization.json.Json
 
 object Utils {
 
@@ -160,8 +161,7 @@ object Utils {
     }
 
     fun format(jsonStr: String): String {
-        val s1 = JSON.parse<String>(jsonStr)
-        return JSON.stringify(s1, null, 2)
+        return JSON.stringify(jsonStr, null, 2)
     }
 
     fun extractTitle(title: String): String {
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/IntegrationTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/IntegrationTest.kt
index f3418c6..77383d5 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/IntegrationTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/IntegrationTest.kt
@@ -21,7 +21,6 @@ package org.apache.isis.client.kroviz
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.delay
 import kotlinx.coroutines.launch
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.core.aggregator.BaseAggregator
 import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.LogEntry
@@ -36,7 +35,6 @@ import org.w3c.xhr.XMLHttpRequest
 
 // subclasses expect a running backend, here SimpleApp localhost:8080/restful*
 
-@UnstableDefault
 open class IntegrationTest {
 
     fun isAppAvailable(): Boolean {
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/PumlBuilderTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/PumlBuilderTest.kt
index 7b000bc..410ac43 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/PumlBuilderTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/PumlBuilderTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.LogEntry
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
@@ -48,7 +47,6 @@ class PumlBuilderTest {
         UiManager.login(url, user, pw)
     }
 
-    @UnstableDefault
     @Test
     fun testSimpleObject() {
         //given
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/TestUtil.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/TestUtil.kt
index 0cc5e47..1ae740b 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/TestUtil.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/TestUtil.kt
@@ -44,7 +44,7 @@ interface DomSpec : TestSpec {
     override fun afterTest() {
         val div = document.getElementById("pretest")
         div?.remove()
-        jQuery(`object` = ".modal-backdrop").remove()
+//        jQuery(`object` = ".modal-backdrop").remove()
     }
 
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcherTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcherTest.kt
index 30703aa..3e0c99d 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcherTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ActionDispatcherTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.aggregator
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS_INVOKE
@@ -28,7 +27,6 @@ import kotlin.test.Test
 import kotlin.test.assertNotEquals
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class ActionDispatcherTest : IntegrationTest() {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ListAggregatorTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ListAggregatorTest.kt
index 00f0dc4..e4a317d 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ListAggregatorTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ListAggregatorTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.aggregator
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.core.event.EventStore
 import org.apache.isis.client.kroviz.core.event.ResourceSpecification
@@ -30,7 +29,6 @@ import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class ListAggregatorTest : IntegrationTest() {
 
     //@Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregatorTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregatorTest.kt
index d8699b9..0e6b4cb 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregatorTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/aggregator/ObjectAggregatorTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.aggregator
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.ACTION_SO_CREATE
 import org.apache.isis.client.kroviz.to.ResultObject
@@ -26,7 +25,6 @@ import org.apache.isis.client.kroviz.to.ResultType
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class ObjectAggregatorTest : IntegrationTest() {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/EventStoreTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/EventStoreTest.kt
index e980ded..402b64d 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/EventStoreTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/EventStoreTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.event
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.core.aggregator.ListAggregator
 import org.apache.isis.client.kroviz.core.aggregator.ObjectAggregator
@@ -29,7 +28,6 @@ import org.apache.isis.client.kroviz.utils.XmlHelper
 import pl.treksoft.kvision.panel.VPanel
 import kotlin.test.*
 
-@UnstableDefault
 class EventStoreTest : IntegrationTest() {
 
     //@Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/DisplayListTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/DisplayListTest.kt
index 65516ef..9e7bc06 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/DisplayListTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/DisplayListTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.model
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.LayoutHandler
 import org.apache.isis.client.kroviz.handler.LayoutXmlHandler
 import org.apache.isis.client.kroviz.handler.TObjectHandler
@@ -29,7 +28,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class DisplayListTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/ExposerTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/ExposerTest.kt
index f2523bc..e121cfa 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/ExposerTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/ExposerTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.core.model
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.TObjectHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.CFG_1
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_0
@@ -28,7 +27,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 
-@UnstableDefault
 class ExposerTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/FixtureResultTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/FixtureResultTest.kt
index ae8827c..3fe06de 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/FixtureResultTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/model/FixtureResultTest.kt
@@ -18,7 +18,7 @@
  */
 package org.apache.isis.client.kroviz.core.model
 
-import kotlinx.serialization.UnstableDefault
+import kotlinx.serialization.decodeFromString
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.FR_OBJECT_BAZ
 import org.apache.isis.client.kroviz.to.Link
@@ -29,7 +29,6 @@ import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class FixtureResultTest {
 
     @Test
@@ -38,7 +37,7 @@ class FixtureResultTest {
         val jsonStr = FR_OBJECT_BAZ.str
 
         // when
-        val tObj = Json.parse(TObject.serializer(), jsonStr)
+        val tObj = Json.decodeFromString(TObject.serializer(), jsonStr)
         val dynObj = tObj.asDynamic()
 
         // then
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/PropertyHandlerTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/PropertyHandlerTest.kt
index d50bb71..886bde3 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/PropertyHandlerTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/PropertyHandlerTest.kt
@@ -18,13 +18,11 @@
  */
 package org.apache.isis.client.kroviz.handler;
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_PROPERTY
 import org.apache.isis.client.kroviz.to.Property
 import kotlin.test.Test
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class PropertyHandlerTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandlerTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandlerTest.kt
index f14b8f8..e6489ef 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandlerTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/ResponseHandlerTest.kt
@@ -19,13 +19,11 @@
 
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.core.aggregator.ObjectAggregator
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS_INVOKE
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class ResponseHandlerTest : IntegrationTest() {
 
     //@Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandlerTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandlerTest.kt
index 300fd0e..53a9599 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandlerTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/handler/RestfulHandlerTest.kt
@@ -18,14 +18,12 @@
  */
 package org.apache.isis.client.kroviz.handler
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL
 import org.apache.isis.client.kroviz.to.Restful
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class RestfulHandlerTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/layout/LayoutTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/layout/LayoutTest.kt
index 5f75ef9..351ef85 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/layout/LayoutTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/layout/LayoutTest.kt
@@ -18,14 +18,12 @@
  */
 package org.apache.isis.client.kroviz.layout
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.handler.LayoutHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_LAYOUT_JSON
 import kotlin.test.Test
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class LayoutTest : IntegrationTest() {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt
new file mode 100644
index 0000000..760a8ae
--- /dev/null
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/demo2_0_0/COLLECTIONS_ENTITIES.kt
@@ -0,0 +1,73 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.isis.client.kroviz.snapshots.demo2_0_0
+
+import org.apache.isis.client.kroviz.snapshots.Response
+
+object COLLECTIONS_ENTITIES: Response(){
+    override val url = "http://localhost:8080/restful/services/simple.SimpleObjectMenu/actions/findByName"
+    override val str = """
+        {
+          "id": "entities",
+          "memberType": "collection",
+          "links": [
+            {
+              "rel": "self",
+              "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities",
+              "method": "GET",
+              "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-collection\""
+            },
+            {
+              "rel": "up",
+              "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=",
+              "method": "GET",
+              "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
+              "title": "String data type"
+            },
+            {
+              "rel": "describedby",
+              "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStrings/collections/entities",
+              "method": "GET",
+              "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/collection-description\""
+            }
+          ],
+          "extensions": {
+            "collectionSemantics": "list"
+          },
+          "value": [
+            {
+              "rel": "urn:org.restfulobjects:rels/value",
+              "href": "http://localhost:8080/restful/objects/demo.JavaLangStringJdo/1",
+              "method": "GET",
+              "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
+              "title": "StringJDO entity: Hello"
+            },
+            {
+              "rel": "urn:org.restfulobjects:rels/value",
+              "href": "http://localhost:8080/restful/objects/demo.JavaLangStringJdo/2",
+              "method": "GET",
+              "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
+              "title": "StringJDO entity: world"
+            }
+          ],
+          "disabledReason": "Immutable"
+        }
+    """
+}
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
index f444b14..748e11b 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/sample.json
@@ -1,38 +1,45 @@
 {
-  "id": "strings",
-  "memberType": "action",
+  "id": "entities",
+  "memberType": "collection",
   "links": [
     {
       "rel": "self",
-      "href": "https://demo-wicket.isis.incode.work/restful/objects/demo.JavaLangTypesMenu/1/actions/strings",
+      "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=/collections/entities",
       "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\""
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-collection\""
     },
     {
       "rel": "up",
-      "href": "https://demo-wicket.isis.incode.work/restful/objects/demo.JavaLangTypesMenu/1",
+      "href": "http://localhost:8080/restful/objects/demo.JavaLangStrings/PADw_eG1sIHZlcnNpb249IjEuMCIgZW5jb2Rpbmc9IlVURi04IiBzdGFuZGFsb25lPSJ5ZXMiPz4KPERlbW8vPgo=",
       "method": "GET",
       "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
-      "title": "JavaLangTypes"
-    },
-    {
-      "rel": "urn:org.restfulobjects:rels/invoke;action=\"strings\"",
-      "href": "https://demo-wicket.isis.incode.work/restful/objects/demo.JavaLangTypesMenu/1/actions/strings/invoke",
-      "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object-action\"",
-      "arguments": {}
+      "title": "String data type"
     },
     {
       "rel": "describedby",
-      "href": "https://demo-wicket.isis.incode.work/restful/domain-types/demo.JavaLangTypesMenu/actions/strings",
+      "href": "http://localhost:8080/restful/domain-types/demo.JavaLangStrings/collections/entities",
       "method": "GET",
-      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/action-description\""
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/collection-description\""
     }
   ],
   "extensions": {
-    "actionType": "user",
-    "actionSemantics": "safe"
+    "collectionSemantics": "list"
   },
-  "parameters": {
-  }
+  "value": [
+    {
+      "rel": "urn:org.restfulobjects:rels/value",
+      "href": "http://localhost:8080/restful/objects/demo.JavaLangStringJdo/1",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
+      "title": "StringJDO entity: Hello"
+    },
+    {
+      "rel": "urn:org.restfulobjects:rels/value",
+      "href": "http://localhost:8080/restful/objects/demo.JavaLangStringJdo/2",
+      "method": "GET",
+      "type": "application/json;profile=\"urn:org.restfulobjects:repr-types/object\"",
+      "title": "StringJDO entity: world"
+    }
+  ],
+  "disabledReason": "Immutable"
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/simpleapp1_16_0/UrlsTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/simpleapp1_16_0/UrlsTest.kt
index 4e5b8d7..f51e4fc 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/simpleapp1_16_0/UrlsTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/snapshots/simpleapp1_16_0/UrlsTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.core.event.EventStore
@@ -35,7 +34,6 @@ import kotlin.test.assertEquals
  * @item check if the href 'self' can be invoked and
  * @item compare the response of invoking 'self' with what is hardcoded
  */
-@UnstableDefault
 class UrlsTest : IntegrationTest() {
 
     //@Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ActionTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ActionTest.kt
index aca0537..463cfab 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ActionTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ActionTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 import org.apache.isis.client.kroviz.core.aggregator.ActionDispatcher
 import org.apache.isis.client.kroviz.core.event.EventStore
@@ -32,7 +31,6 @@ import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class ActionTest : IntegrationTest() {
 
     // @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
similarity index 55%
copy from incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
copy to incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
index 6037a00..39e2a8f 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/CollectionTest.kt
@@ -18,43 +18,33 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
-import kotlinx.serialization.json.Json
+import org.apache.isis.client.kroviz.IntegrationTest
+import org.apache.isis.client.kroviz.handler.CollectionHandler
+import org.apache.isis.client.kroviz.snapshots.demo2_0_0.COLLECTIONS_ENTITIES
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
-class LinkTest {
+class CollectionTest : IntegrationTest() {
 
     @Test
     fun testParse() {
         //given
-        val jsonStr = """{
-            "rel": "R",
-            "href": "H",
-            "method": "GET",
-            "type": "TY",
-            "title": "TI"
-        }"""
-
-        // when
-        val link = Json.parse(Link.serializer(), jsonStr)
-
-        // then
-        assertEquals("R", link.rel)
-    }
+        val jsonStr = COLLECTIONS_ENTITIES.str
+        //when
+        val collection = CollectionHandler().parse(jsonStr) as Collection
+        //then
+        assertEquals("entities", collection.id)
+        assertEquals("collection", collection.memberType)
 
-    @Test
-    fun testArgumentsCanHaveEmptyKeys() {
-        val href = "href"
-        val arg = Argument(href)
-        val args = mutableMapOf<String, Argument?>()
-        args.put("", arg)
-        val l = Link(arguments = args, href = href)
-        // then
-        val arguments = l.argMap()!!
-        val a = arguments[""]
-        assertEquals("href", a!!.key)
+        val linkList = collection.links
+        assertEquals(3, linkList.size)
+
+        assertEquals("list", collection.extensions.collectionSemantics)
+
+        val valueList = collection.value as List<Link>
+        assertEquals(2, valueList.size)
+
+        assertEquals("Immutable", collection.disabledReason)
     }
 
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
index c2e3182..1519e5a 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/DomainTypeTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_FILE_NODE
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO
@@ -26,7 +25,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class DomainTypeTest {
 
     @Test
@@ -34,7 +32,7 @@ class DomainTypeTest {
         // given
         val jsonStr = SO.str
         // when
-        val domainType = Json.parse(DomainType.serializer(), jsonStr)
+        val domainType = Json.decodeFromString(DomainType.serializer(), jsonStr)
         // then
         val linkList = domainType.links
         assertEquals(2, linkList.size)
@@ -55,7 +53,7 @@ class DomainTypeTest {
         // given
         val jsonStr = DEMO_FILE_NODE.str
         // when
-        val domainType = Json.parse(DomainType.serializer(), jsonStr)
+        val domainType = Json.decodeFromString(DomainType.serializer(), jsonStr)
         // then
         val linkList = domainType.links
         assertEquals(2, linkList.size)
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/FeaturedTypesTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/FeaturedTypesTest.kt
index 0be9573..14e40fc 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/FeaturedTypesTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/FeaturedTypesTest.kt
@@ -18,14 +18,12 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.TObjectHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_PRIMITIVES
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_TEMPORALS
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class FeaturedTypesTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/HttpErrorTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/HttpErrorTest.kt
index cb48ec9..3b30999 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/HttpErrorTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/HttpErrorTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.HttpErrorHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_HTTP_ERROR_500
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.HTTP_ERROR_405
@@ -29,7 +28,6 @@ import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class HttpErrorTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
index 6037a00..f750c95 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/LinkTest.kt
@@ -18,12 +18,12 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
+import org.apache.isis.client.kroviz.handler.RestfulHandler
+import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class LinkTest {
 
     @Test
@@ -38,7 +38,7 @@ class LinkTest {
         }"""
 
         // when
-        val link = Json.parse(Link.serializer(), jsonStr)
+        val link = Json.decodeFromString(Link.serializer(), jsonStr)
 
         // then
         assertEquals("R", link.rel)
@@ -57,4 +57,39 @@ class LinkTest {
         assertEquals("href", a!!.key)
     }
 
+    @Test
+    fun testFindRelation() {
+        //given
+        var rel:Relation?
+        //when
+        rel = Relation.find("menuBars")
+        //then
+        assertEquals(Relation.MENU_BARS, rel)
+
+        //when
+        rel = Relation.find("self")
+        //then
+        assertEquals(Relation.SELF, rel)
+
+        //when
+        rel = Relation.find("services")
+        //then
+        assertEquals(Relation.SERVICES, rel)
+    }
+
+    @Test
+    fun testFindParsedLinkEnums() {
+        //given
+        val jsonStr = RESTFUL.str
+        val ro = RestfulHandler().parse(jsonStr) as Restful
+        val links = ro.links
+        var rel:Relation?
+        //when
+        links.forEach { it ->
+            it.relation()    //TODO
+//            it.representation()
+        }
+        //then
+    }
+
 }
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
index 1ab69f1..98755dd 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/MemberTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import kotlinx.serialization.json.Json
 import org.apache.isis.client.kroviz.handler.MemberHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.FR_PROPERTY_DESCRIPTION
@@ -26,7 +25,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class MemberTest() {
 
     @Test
@@ -78,7 +76,7 @@ class MemberTest() {
     }
 
     private fun parse(jsonStr: String): Member {
-        return Json.parse(Member.serializer(), jsonStr)
+        return Json.decodeFromString(Member.serializer(), jsonStr)
     }
 
     private fun buildJsonWith(value: Any): String {
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/PropertyTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/PropertyTest.kt
index 32960f3..4407187 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/PropertyTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/PropertyTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.PropertyHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_DOMAIN_TYPES_PROPERTY
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_PROPERTY
@@ -29,7 +28,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class PropertyTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultListTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultListTest.kt
index b7d08e3..4393db0 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultListTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultListTest.kt
@@ -18,13 +18,11 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.ResultListHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_LIST_ALL_INVOKE
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class ResultListTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultObjectTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultObjectTest.kt
index 704a1a4..6f02818 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultObjectTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultObjectTest.kt
@@ -18,13 +18,11 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.ResultObjectHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.ACTION_SO_CREATE
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class ResultObjectTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultValueTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultValueTest.kt
index d91e045..e24c7b1 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultValueTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ResultValueTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.IntegrationTest
 
 import org.apache.isis.client.kroviz.core.aggregator.ObjectAggregator
@@ -29,7 +28,6 @@ import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.ACTIONS_OPEN_SWAG
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class ResultValueTest : IntegrationTest() {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ServiceTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ServiceTest.kt
index fb4f35a..1e4f875 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ServiceTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/ServiceTest.kt
@@ -18,14 +18,12 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.ServiceHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.SO_MENU
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class ServiceTest : ToTest() {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/TObjectTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/TObjectTest.kt
index 19eefc8..c075451 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/TObjectTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/TObjectTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.TObjectHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_STRINGS_INVOKE
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.ACTIONS_TEXT_INVOKE
@@ -30,7 +29,6 @@ import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 import kotlin.test.assertTrue
 
-@UnstableDefault
 class TObjectTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/UserTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/UserTest.kt
index ecaed7e..a2ee300 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/UserTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/UserTest.kt
@@ -19,13 +19,11 @@
 package org.apache.isis.client.kroviz.to
 
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.UserHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL_USER
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class UserTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/VersionTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/VersionTest.kt
index 669442f..16bb324 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/VersionTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/VersionTest.kt
@@ -18,13 +18,11 @@
  */
 package org.apache.isis.client.kroviz.to
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.VersionHandler
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL_VERSION
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-@UnstableDefault
 class VersionTest {
 
     @Test
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/mb/MenubarsTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/mb/MenubarsTest.kt
index fc553f6..3bb1c2f 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/mb/MenubarsTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/to/mb/MenubarsTest.kt
@@ -18,7 +18,6 @@
  */
 package org.apache.isis.client.kroviz.to.mb
 
-import kotlinx.serialization.UnstableDefault
 import org.apache.isis.client.kroviz.handler.MenuBarsHandler
 import org.apache.isis.client.kroviz.snapshots.demo2_0_0.DEMO_MENUBARS
 import org.apache.isis.client.kroviz.snapshots.simpleapp1_16_0.RESTFUL_MENUBARS
@@ -26,7 +25,6 @@ import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertNotNull
 
-@UnstableDefault
 class MenubarsTest {
 
     @Test