You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2018/02/12 11:44:44 UTC

[isis] 01/02: ISIS-1585: extends to support derivation of choices for both scalar and collection parameters.

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

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

commit f8a5a2eea74a72eda0b2a4911e25f01b19d9c80b
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Feb 12 11:43:40 2018 +0000

    ISIS-1585: extends to support derivation of choices for both scalar and collection parameters.
    
    Also:
    - extends @Action with associateWithSequence
    - deprecates bulk actions (documentation and API)
    - moves PostProcessor impl to new package
    - fixes rebuildMetaModel to call the PostProcessor
    - updates docs.
---
 .../main/asciidoc/guides/rgant/_rgant-Action.adoc  | 15 ++++-
 .../guides/rgant/_rgant-Action_associateWith.adoc  | 18 ++++--
 ...lication-layer-api_ActionInvocationContext.adoc |  8 ++-
 ...plication-layer-api_BulkInteractionContext.adoc |  2 +-
 .../org/apache/isis/applib/annotation/Action.java  | 30 ++++++++-
 .../org/apache/isis/applib/annotation/Bulk.java    | 73 +++++++++++++++++-----
 .../apache/isis/applib/annotation/InvokeOn.java    | 12 ++++
 .../apache/isis/applib/annotation/MemberOrder.java |  2 +-
 .../services/actinvoc/ActionInvocationContext.java | 36 +++++++++++
 .../action/ActionAnnotationFacetFactory.java       |  6 +-
 ...nParameterDefaultsAndChoicesPostProcessor.java} | 70 +++++++++++++++++----
 ...arameterChoicesFacetFromParentedCollection.java | 60 ++++++++++++++++++
 ...ameterDefaultsFacetFromParentedCollection.java} |  6 +-
 .../metamodel/MetaModelServiceDefault.java         |  1 +
 .../core/metamodel/spec/feature/ObjectAction.java  |  4 ++
 .../spec/feature/ObjectActionParameter.java        | 53 +++++++++++++++-
 .../metamodel/specloader/SpecificationLoader.java  |  6 +-
 .../dflt/ProgrammingModelFacetsJava5.java          |  4 +-
 .../linkandlabel/ActionLinkFactoryAbstract.java    |  6 +-
 19 files changed, 355 insertions(+), 57 deletions(-)

diff --git a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action.adoc b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action.adoc
index bac04b4..cd2e309 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action.adoc
@@ -19,7 +19,12 @@ The table below summarizes the annotation's attributes.
 
 
 |xref:../rgant/rgant.adoc#_rgant-Action_associateWith[`associateWith()`]
-|_name:sequence_ +
+|_memberId_ +
+("")
+|associates an action with another property or collection of the action.
+
+|xref:../rgant/rgant.adoc#_rgant-Action_associateWith[`associateWith-Sequence()`]
+|_memberId_ +
 ("")
 |associates an action with another property or collection of the action.
 
@@ -65,7 +70,9 @@ post-execute).
 |xref:../rgant/rgant.adoc#_rgant-Action_invokeOn[`invokeOn()`]
 |`OBJECT_ONLY`, `COLLECTION_ONLY`, `OBJECT_AND_COLLECTION` +
 (`OBJECT_ONLY`)
-|whether an action can be invoked on a single object and/or on many objects in a collection.
+|(deprecated - use view models and associated actions instead).
+
+whether an action can be invoked on a single object and/or on many objects in a collection.
 
 Currently this is only supported for no-arg actions.
 
@@ -78,7 +85,9 @@ Currently this is only supported for no-arg actions.
 |`publishing-` +
 `PayloadFactory()`
 |subtype of `PublishingPayloadFactory-` `ForAction` (none)
-|specifies that a custom implementation of `PublishingPayloadFactoryForAction` be used to create the (payload of the) published event representing the action invocation
+|(deprecated).
+
+specifies that a custom implementation of `PublishingPayloadFactoryForAction` be used to create the (payload of the) published event representing the action invocation
 
 |xref:../rgant/rgant.adoc#_rgant-Action_restrictTo[`restrictTo()`]
 |`NO_RESTRICTIONS`,`PROTOTYPING` +
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_associateWith.adoc b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_associateWith.adoc
index 38d0c94..814a7df 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_associateWith.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgant/_rgant-Action_associateWith.adoc
@@ -8,6 +8,7 @@
 
 
 The `associateWith` attribute allows an action to be associated with other properties or collections of the same domain object.
+The optional `associateWithSequence` attribute specifies the order of the action in the UI.
 
 For example, an `Order` could have a collection of ``OrderItem``s, and might provide actions to add and remove items:
 
@@ -18,10 +19,10 @@ public class Order {
     @Collection
     SortedSet<OrderItem> getItems() { ... }
 
-    @Action(associateWith="items:1")
+    @Action(associateWith="items", associateWithSequence="1")
     public Order addItem(Product p, int quantity) { ... }
 
-    @Action(associateWith="items:2")
+    @Action(associateWith="items", associateWithSequence="2")
     public Order removeItem(OrderItem item) { ... }
     ...
 }
@@ -37,9 +38,15 @@ The same effect can be accomplished using `@MemberOrder` or with the `.layout.xm
 ====
 
 
-== Collection Parameters
+== Inferred Defaults and Choices
 
-If the action that has collection parameters is associated with a collection, then the Wicket viewer will render the collection with checkboxes, and these checkboxes can be used to select the items of the action parameter.
+If an action is associated with a collection, then any scalar or collection parameter of the action that is the same type as that collection will automatically have a list of choices provided for it, being the items of the associated collection.
+
+This is only done provided that there isn't already an explicit `choicesNXxx()` or `autoCompleteNXxx()` supporting method.
+However, this list of choices _does_ take priority over any choices that are inferred from the parameter type itself (as per either an `@DomainObject(autoCompleteRepository=...)` or `@DomainObject(bounded=...)`).
+
+In addition, if the action has a collection parameter of the same type as the associated collection, then the Wicket viewer will render the collection with checkboxes.
+The user can use these checkboxes can be used to select the items of the action parameter.
 
 For example, suppose we have a "removeItems(...)" action:
 
@@ -52,9 +59,8 @@ public class Order {
 
     ...
 
-    @Action(associateWith="items:2")
+    @Action(associateWith="items", associateWithSequence="2")
     public Order removeItems(SortedSet<OrderItem> items) { ... }
-    public SortedSet<OrderItem> choices0RemoveItems() { return getItems(); }
 }
 ----
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_ActionInvocationContext.adoc b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_ActionInvocationContext.adoc
index e484afa..9df3e19 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_ActionInvocationContext.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_ActionInvocationContext.adoc
@@ -1,5 +1,5 @@
 [[_rgsvc_application-layer-api_ActionInvocationContext]]
-= `ActionInvocationContext`
+= `ActionInvocationContext` (deprecated)
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :_basedir: ../../
 :_imagesdir: images/
@@ -9,6 +9,12 @@ The `ActionInvocationContext` domain service is a xref:../rgant/rgant.adoc#_rgan
 
 When an action is invoked in this way, this service allows each object instance to "know where it is" in the collection; it acts a little like an iterator.  In particular, an object can determine if it is the last object to be called, and so can perform special processing, eg to return a summary calculated result.
 
+[WARNING]
+====
+Bulk actions are now deprecated, which means that this service is also deprecated.
+
+Instead, the recommended technique is to define a view model to wrap around the collection, and then to use an action on the view model, associated with the collection and with a collection parameter), to act upon the selected items of the collection.
+====
 
 == API & Implementation
 
diff --git a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BulkInteractionContext.adoc b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BulkInteractionContext.adoc
index 7cee49c..2cb45df 100644
--- a/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BulkInteractionContext.adoc
+++ b/adocs/documentation/src/main/asciidoc/guides/rgsvc/_rgsvc_application-layer-api_BulkInteractionContext.adoc
@@ -1,5 +1,5 @@
 [[_rgsvc_application-layer-api_BulkInteractionContext]]
-= `BulkInteractionContext`
+= `BulkInteractionContext` (deprecated)
 :Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at. http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or ag [...]
 :_basedir: ../../
 :_imagesdir: images/
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
index a415185..044ff96 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Action.java
@@ -121,7 +121,10 @@ public @interface Action {
      * <p>
      * Has no meaning if annotated on an action of a domain service.
      * </p>
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     InvokeOn invokeOn() default InvokeOn.OBJECT_ONLY;
 
     // //////////////////////////////////////
@@ -212,18 +215,39 @@ public @interface Action {
 
 
     /**
-     * Associates this action with a property or collection, specifying its id and optionally the order in the UI.
+     * Associates this action with a property or collection, specifying its id.
      *
      * <p>
      *     This is an alternative to using {@link MemberOrder#name()}.  To specify the order (equivalent to
-     *     {@link MemberOrder#sequence()}}) add a suffix <code>:XXX</code>.
+     *     {@link MemberOrder#sequence()}}), use {@link #associateWithSequence()}.
      * </p>
      *
      * <p>
-     *     For example <code>@Action(associateWith="items:2.1")</code>
+     *     For example <code>@Action(associateWith="items", associateWithSequence="2.1")</code>
+     * </p>
+     *
+     * <p>
+     *     If an action is associated with a collection, then any matching parameters will have
+     *     their choices automatically inferred from the collection (if not otherwise specified)
+     *     and any collection parameter defaults can be specified using checkboxes
+     *     (in the Wicket UI, at least).
      * </p>
      */
     String associateWith() default "";
 
+    /**
+     * Specifies the sequence/order in the UI for an action that's been associated with a property or collection.
+     *
+     * <p>
+     *     This is an alternative to using {@link MemberOrder#sequence()}, but is ignored if
+     *     {@link Action#associateWith()} isn't also specified.
+     * </p>
+     *
+     * <p>
+     *     For example <code>@Action(associateWith="items", associateWithSequence="2.1")</code>
+     * </p>
+     */
+    String associateWithSequence();
+
 
 }
\ No newline at end of file
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
index b202668..3919a9e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Bulk.java
@@ -26,7 +26,9 @@ import java.util.List;
 import javax.enterprise.context.RequestScoped;
 
 /**
- * @deprecated - use {@link Action#invokeOn()} instead.
+ * Superceded by {@link Action#invokeOn()}.
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
  */
 @Inherited
 @Target({ ElementType.METHOD })
@@ -35,29 +37,39 @@ import javax.enterprise.context.RequestScoped;
 public @interface Bulk {
 
     /**
-     * @deprecated - see {@link InvokeOn}
+     * Superceded by {@link InvokeOn}
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
     @Deprecated
     public static enum AppliesTo {
         /**
-         * @deprecated - see {@link InvokeOn#OBJECT_AND_COLLECTION}
+         * Superceded by {@link InvokeOn#OBJECT_AND_COLLECTION}
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         BULK_AND_REGULAR,
         /**
-         * @deprecated - see {@link InvokeOn#COLLECTION_ONLY}
+         * Superceded by {@link InvokeOn#COLLECTION_ONLY}
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         BULK_ONLY,
         /**
-         * @deprecated - see {@link InvokeOn#OBJECT_ONLY}
+         * Superceded by {@link InvokeOn#OBJECT_ONLY}
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         REGULAR_ONLY
     }
 
     /**
-     * @deprecated - see {@link Action#invokeOn()}.
+     * Superceded by {@link Action#invokeOn()}.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
     @Deprecated
     AppliesTo value() default AppliesTo.BULK_AND_REGULAR;
@@ -66,7 +78,9 @@ public @interface Bulk {
     // //////////////////////////////////////
 
     /**
-     * @deprecated - see {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext}.
+     * Superceded by {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext}.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
     @Deprecated
     @DomainService(
@@ -90,17 +104,23 @@ public @interface Bulk {
         // //////////////////////////////////////
 
         /**
-         * @deprecated - use {@link InvokedOn} instead.
+         * Superceded by {@link InvokedOn} instead.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         public static enum InvokedAs {
             /**
-             * @deprecated - use {@link InvokedOn#COLLECTION} instead.
+             * Superceded by {@link InvokedOn#COLLECTION} instead.
+             *
+             * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
              */
             @Deprecated
             BULK,
             /**
-             * @deprecated - use {@link InvokedOn#OBJECT} instead.
+             * Superceded by {@link InvokedOn#OBJECT} instead.
+             *
+             * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
              */
             @Deprecated
             REGULAR;
@@ -138,7 +158,9 @@ public @interface Bulk {
 
 
         /**
-         * @deprecated - see {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onObject(Object)}.
+         * Superceded by  {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onObject(Object)}.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         public static InteractionContext regularAction(Object domainObject) {
@@ -146,7 +168,9 @@ public @interface Bulk {
         }
 
         /**
-         * @deprecated - see {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onCollection(Object...)}.
+         * Superceded by {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onCollection(Object...)}.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         public static InteractionContext bulkAction(Object... domainObjects) {
@@ -154,7 +178,9 @@ public @interface Bulk {
         }
 
         /**
-         * @deprecated - see {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onCollection(java.util.List)}.
+         * Superceded by  {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext#onCollection(java.util.List)}.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         public static InteractionContext bulkAction(List<Object> domainObjects) {
@@ -170,7 +196,9 @@ public @interface Bulk {
         private int index;
 
         /**
-         * @deprecated - see {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext ()}.
+         * Superceded by {@link org.apache.isis.applib.services.actinvoc.ActionInvocationContext ()}.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         public InteractionContext() {
@@ -220,6 +248,8 @@ public @interface Bulk {
          * Whether this particular {@link org.apache.isis.applib.annotation.Bulk.InteractionContext} was applied as a {@link InvokedOn#COLLECTION bulk} action
          * (against each domain object in a list of domain objects) or as a {@link InvokedOn#OBJECT regular}
          * action (against a single domain object).
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
         @Deprecated
         @Programmatic
@@ -229,7 +259,10 @@ public @interface Bulk {
 
         /**
          * The list of domain objects which are being acted upon.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
+        @Deprecated
         @Programmatic
         public List<Object> getDomainObjects() {
             return domainObjects;
@@ -237,7 +270,10 @@ public @interface Bulk {
 
         /**
          * The number of {@link #domainObjects domain objects} being acted upon.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
+        @Deprecated
         @Programmatic
         public int getSize() {
             return domainObjects.size();
@@ -248,7 +284,10 @@ public @interface Bulk {
          *
          * <p>
          * Will be a value in range [0, {@link #getSize() size}).
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
+        @Deprecated
         @Programmatic
         public int getIndex() {
             return index;
@@ -256,7 +295,10 @@ public @interface Bulk {
 
         /**
          * Whether this object being acted upon is the first such.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
+        @Deprecated
         @Programmatic
         public boolean isFirst() {
             return this.index == 0;
@@ -264,7 +306,10 @@ public @interface Bulk {
 
         /**
          * Whether this object being acted upon is the last such.
+         *
+         * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
          */
+        @Deprecated
         @Programmatic
         public boolean isLast() {
             return this.index == (getSize()-1);
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
index ca52a9b..be84512 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/InvokeOn.java
@@ -20,11 +20,17 @@ package org.apache.isis.applib.annotation;
 
 /**
  * Whether an action can be invoked on a single object and/or on many objects in a collection.
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
  */
+@Deprecated
 public enum InvokeOn {
     /**
      * The action can only be invoked on a single object.  This is the default.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     OBJECT_ONLY,
     /**
      * The action can be invoked either on a single object or on a collection of objects (each in turn).
@@ -32,7 +38,10 @@ public enum InvokeOn {
      * <p>
      *     Corresponds to (the deprecated) <code>@Bulk(appliesTo=BULK_AND_REGULAR)</code> annotation.
      * </p>
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     OBJECT_AND_COLLECTION,
     /**
      * The action is intended to be invoked only on a collection of objects (each in turn).
@@ -40,7 +49,10 @@ public enum InvokeOn {
      * <p>
      *     Corresponds to (the deprecated) <code>@Bulk(appliesTo=BULK_ONLY)</code> annotation.
      * </p>
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     COLLECTION_ONLY;
 
     @Deprecated
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/MemberOrder.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/MemberOrder.java
index 7de0e87..82db30e 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/MemberOrder.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/MemberOrder.java
@@ -29,7 +29,7 @@ import java.lang.annotation.Target;
  * Indicates the position a method should be placed in.
  *
  * <p>
- *     An alternative is to use the <code>Xxx.layout.json</code> file, where <code>Xxx</code> is the domain object name.
+ *     An alternative is to use the <code>Xxx.layout.xml</code> file, where <code>Xxx</code> is the domain object name.
  * </p>
  */
 @Inherited
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java b/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
index a75edb5..86060cc 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/actinvoc/ActionInvocationContext.java
@@ -22,6 +22,8 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import javax.enterprise.context.RequestScoped;
+
+import org.apache.isis.applib.annotation.Action;
 import org.apache.isis.applib.annotation.DomainService;
 import org.apache.isis.applib.annotation.InvokedOn;
 import org.apache.isis.applib.annotation.NatureOfService;
@@ -35,7 +37,10 @@ import org.apache.isis.applib.annotation.Programmatic;
  * with {@link org.apache.isis.applib.annotation.DomainService}.  This means that it is automatically registered
  * and available for use; no further configuration is required.
  * </p>
+ *
+ * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
  */
+@Deprecated
 @DomainService(
         nature = NatureOfService.DOMAIN,
         menuOrder = "" + Integer.MAX_VALUE
@@ -45,21 +50,30 @@ public class ActionInvocationContext {
 
     /**
      * Intended only to support unit testing.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     public static ActionInvocationContext onObject(final Object domainObject) {
         return new ActionInvocationContext(InvokedOn.OBJECT, Collections.singletonList(domainObject));
     }
 
     /**
      * Intended only to support unit testing.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     public static ActionInvocationContext onCollection(final Object... domainObjects) {
         return onCollection(Arrays.asList(domainObjects));
     }
 
     /**
      * Intended only to support unit testing.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     public static ActionInvocationContext onCollection(final List<Object> domainObjects) {
         return new ActionInvocationContext(InvokedOn.COLLECTION, domainObjects);
     }
@@ -74,6 +88,10 @@ public class ActionInvocationContext {
 
     // //////////////////////////////////////
 
+    /**
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
+     */
+    @Deprecated
     public ActionInvocationContext() {
     }
 
@@ -127,7 +145,10 @@ public class ActionInvocationContext {
      * Whether this particular {@link ActionInvocationContext} was applied as a {@link InvokedOn#COLLECTION bulk} action
      * (against each domain object in a list of domain objects) or as a {@link InvokedOn#OBJECT regular}
      * action (against a single domain object).
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public InvokedOn getInvokedOn() {
         return invokedOn;
@@ -136,7 +157,10 @@ public class ActionInvocationContext {
 
     /**
      * The list of domain objects which are being acted upon.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public List<Object> getDomainObjects() {
         return domainObjects;
@@ -144,7 +168,10 @@ public class ActionInvocationContext {
 
     /**
      * The number of {@link #domainObjects domain objects} being acted upon.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public int getSize() {
         return domainObjects.size();
@@ -155,7 +182,10 @@ public class ActionInvocationContext {
      *
      * <p>
      * Will be a value in range [0, {@link #getSize() size}).
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public int getIndex() {
         return index;
@@ -163,7 +193,10 @@ public class ActionInvocationContext {
 
     /**
      * Whether this object being acted upon is the first such.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public boolean isFirst() {
         return this.index == 0;
@@ -171,7 +204,10 @@ public class ActionInvocationContext {
 
     /**
      * Whether this object being acted upon is the last such.
+     *
+     * @deprecated - instead of bulk actions, use view models with collection parameters and {@link Action#associateWith()}.
      */
+    @Deprecated
     @Programmatic
     public boolean isLast() {
         return this.index == (getSize()-1);
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
index a57b8ef..3c9cb6f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/ActionAnnotationFacetFactory.java
@@ -470,9 +470,9 @@ public class ActionAnnotationFacetFactory extends FacetFactoryAbstract
         final Action action = Annotations.getAnnotation(method, Action.class);
         if (action != null) {
             final String associateWith = action.associateWith();
-            final NameAndSequence ns = NameAndSequence.parse(associateWith);
-            if(ns != null) {
-                memberOrderFacet = new MemberOrderFacetForActionAnnotation(ns.name, ns.sequence, holder);
+            if(!Strings.isNullOrEmpty(associateWith)) {
+                final String associateWithSequence = action.associateWithSequence();
+                memberOrderFacet = new MemberOrderFacetForActionAnnotation(associateWith, associateWithSequence, holder);
             }
         }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxesPostProcessor.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionCollectionParameterDefaultsAndChoicesPostProcessor.java
similarity index 53%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxesPostProcessor.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionCollectionParameterDefaultsAndChoicesPostProcessor.java
index e43cefe..a3d1c20 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxesPostProcessor.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionCollectionParameterDefaultsAndChoicesPostProcessor.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.core.metamodel.facets.param.defaults.togglebox;
+package org.apache.isis.core.metamodel.postprocessors.param;
 
 import java.util.List;
 
@@ -26,27 +26,36 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.filter.Filters;
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
 import org.apache.isis.core.metamodel.deployment.DeploymentCategoryProvider;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetUtil;
+import org.apache.isis.core.metamodel.facets.param.autocomplete.ActionParameterAutoCompleteFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacet;
+import org.apache.isis.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacet;
 import org.apache.isis.core.metamodel.progmodel.ObjectSpecificationPostProcessor;
 import org.apache.isis.core.metamodel.services.ServicesInjector;
 import org.apache.isis.core.metamodel.services.ServicesInjectorAware;
+import org.apache.isis.core.metamodel.services.persistsession.PersistenceSessionServiceInternal;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
 import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 
 /**
  * Sets up all the {@link Facet}s for an action in a single shot.
  */
-public class ActionParameterDefaultsFacetViaToggleBoxesPostProcessor implements ObjectSpecificationPostProcessor,
+public class ActionCollectionParameterDefaultsAndChoicesPostProcessor implements ObjectSpecificationPostProcessor,
         ServicesInjectorAware {
 
     private DeploymentCategoryProvider deploymentCategoryProvider;
+    private SpecificationLoader specificationLoader;
+    private AuthenticationSessionProvider authenticationSessionProvider;
+    private PersistenceSessionServiceInternal adapterManager;
 
     @Override
     public void postProcess(final ObjectSpecification objectSpecification) {
@@ -66,41 +75,76 @@ public class ActionParameterDefaultsFacetViaToggleBoxesPostProcessor implements
             //
             // eg Order#getItems() and Order#removeItems(List<OrderItem>)
             //
-            final String collectionId = otma.getId();
             final ObjectSpecification specification = otma.getSpecification();
-            final ImmutableList<ObjectAction> actions = FluentIterable.from(objectActions)
-                    .filter(
-                        ObjectAction.Predicates.associatedWithAndWithCollectionParameterFor(collectionId, specification))
-                    .toList();
 
-            //
-            // ... for the matching actions, install the default facet populated using toggle boxes
-            //
             final ObjectActionParameter.Predicates.CollectionParameter whetherCollectionParamOfType =
                     new ObjectActionParameter.Predicates.CollectionParameter(specification);
-            for (final ObjectAction action : actions) {
+
+            for (final ObjectAction action : objectActions) {
+
                 final List<ObjectActionParameter> parameters = action.getParameters();
+
+                // for collection parameters, install an defaults facet (if there isn't one already)
+                // this will cause the UI to render the collection with toggleboxes
+                // with a thread-local used to provide the selected objects
                 final ImmutableList<ObjectActionParameter> collectionParams = FluentIterable.from(parameters)
                         .filter(whetherCollectionParamOfType).toList();
                 for (final ObjectActionParameter collectionParam : collectionParams) {
-                    FacetUtil.addFacet(new ActionParameterDefaultsFacetViaToggleBoxes(collectionParam));
+                    final ActionParameterDefaultsFacet defaultsFacet = collectionParam
+                            .getFacet(ActionParameterDefaultsFacet.class);
+                    if (existsAndNotDerived(defaultsFacet)) {
+                        // don't overwrite existing facet
+                    } else {
+                        FacetUtil.addFacet(new ActionParameterDefaultsFacetFromParentedCollection(collectionParam));
+                    }
+                }
+
+                // for both scalar and collection parameters, install a choices facet (if there isn't one already)
+                // using the associated collection for its values.
+                for (final ObjectActionParameter scalarOrCollectionParam : parameters) {
+
+                    final ActionParameterChoicesFacet choicesFacet = scalarOrCollectionParam
+                            .getFacet(ActionParameterChoicesFacet.class);
+                    final ActionParameterAutoCompleteFacet autoCompleteFacet = scalarOrCollectionParam
+                            .getFacet(ActionParameterAutoCompleteFacet.class);
+                    if (existsAndNotDerived(choicesFacet) || existsAndNotDerived(autoCompleteFacet)) {
+                        // don't overwrite existing choices or autoComplete facet
+                    } else {
+                        FacetUtil.addFacet(
+                                new ActionParameterChoicesFacetFromParentedCollection(
+                                        scalarOrCollectionParam, otma,
+                                        getDeploymentCategory(), specificationLoader,
+                                        authenticationSessionProvider, adapterManager ));
+                    }
                 }
             }
         }
     }
 
+    private static boolean existsAndNotDerived(final Facet facet) {
+        return facet != null && !facet.isNoop() && !facet.isNoop();
+    }
+
     private List<ActionType> inferActionTypes() {
         final List<ActionType> actionTypes = Lists.newArrayList();
         actionTypes.add(ActionType.USER);
-        final DeploymentCategory deploymentCategory = deploymentCategoryProvider.getDeploymentCategory();
+        final DeploymentCategory deploymentCategory = getDeploymentCategory();
         if ( !deploymentCategory.isProduction()) {
             actionTypes.add(ActionType.PROTOTYPE);
         }
         return actionTypes;
     }
 
+    private DeploymentCategory getDeploymentCategory() {
+        return deploymentCategoryProvider.getDeploymentCategory();
+    }
+
     @Override
     public void setServicesInjector(final ServicesInjector servicesInjector) {
         deploymentCategoryProvider = servicesInjector.getDeploymentCategoryProvider();
+        specificationLoader = servicesInjector.getSpecificationLoader();
+        authenticationSessionProvider = servicesInjector.getAuthenticationSessionProvider();
+        adapterManager = servicesInjector.getPersistenceSessionServiceInternal();
     }
+
 }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
new file mode 100644
index 0000000..3515f67
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterChoicesFacetFromParentedCollection.java
@@ -0,0 +1,60 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.metamodel.postprocessors.param;
+
+import java.util.List;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSessionProvider;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.consent.InteractionInitiatedBy;
+import org.apache.isis.core.metamodel.deployment.DeploymentCategory;
+import org.apache.isis.core.metamodel.facetapi.FacetHolder;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.core.metamodel.facets.param.choices.ActionParameterChoicesFacetAbstract;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
+
+public class ActionParameterChoicesFacetFromParentedCollection extends ActionParameterChoicesFacetAbstract {
+
+    private final OneToManyAssociation otma;
+
+    public ActionParameterChoicesFacetFromParentedCollection(
+            final FacetHolder holder,
+            final OneToManyAssociation otma,
+            final DeploymentCategory deploymentCategory,
+            final SpecificationLoader specificationLoader,
+            final AuthenticationSessionProvider authenticationSessionProvider,
+            final AdapterManager adapterManager) {
+        super(holder, deploymentCategory, specificationLoader, authenticationSessionProvider, adapterManager);
+        this.otma = otma;
+    }
+
+    @Override
+    public Object[] getChoices(
+            final ObjectAdapter target,
+            final List<ObjectAdapter> arguments,
+            final InteractionInitiatedBy interactionInitiatedBy) {
+        final ObjectAdapter objectAdapter = otma.get(target, interactionInitiatedBy);
+        final List<ObjectAdapter> objectAdapters = CollectionFacet.Utils.convertToAdapterList(objectAdapter);
+        return ObjectAdapter.Util.unwrap(objectAdapters.toArray(new ObjectAdapter[0]));
+    }
+
+}
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxes.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterDefaultsFacetFromParentedCollection.java
similarity index 88%
rename from core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxes.java
rename to core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterDefaultsFacetFromParentedCollection.java
index f9ad50e..3093c83 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/param/defaults/togglebox/ActionParameterDefaultsFacetViaToggleBoxes.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/postprocessors/param/ActionParameterDefaultsFacetFromParentedCollection.java
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-package org.apache.isis.core.metamodel.facets.param.defaults.togglebox;
+package org.apache.isis.core.metamodel.postprocessors.param;
 
 import java.io.Serializable;
 import java.util.Collections;
@@ -29,7 +29,7 @@ import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.param.defaults.ActionParameterDefaultsFacetAbstract;
 
-public class ActionParameterDefaultsFacetViaToggleBoxes extends ActionParameterDefaultsFacetAbstract {
+public class ActionParameterDefaultsFacetFromParentedCollection extends ActionParameterDefaultsFacetAbstract {
 
     private static ThreadLocal<List<Object>> selectedPojos = new ThreadLocal<List<Object>>() {
         @Override protected List<Object> initialValue() {
@@ -50,7 +50,7 @@ public class ActionParameterDefaultsFacetViaToggleBoxes extends ActionParameterD
         }
     }
 
-    public ActionParameterDefaultsFacetViaToggleBoxes(final FacetHolder holder) {
+    public ActionParameterDefaultsFacetFromParentedCollection(final FacetHolder holder) {
         super(holder);
     }
 
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
index fb306b6..342589f 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/metamodel/MetaModelServiceDefault.java
@@ -92,6 +92,7 @@ public class MetaModelServiceDefault implements MetaModelService5 {
         // ensure the spec is fully rebuilt
         objectSpecification.getObjectActions(Contributed.INCLUDED);
         objectSpecification.getAssociations(Contributed.INCLUDED);
+        specificationLookup.postProcess(objectSpecification);
     }
 
     // //////////////////////////////////////
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
index e2b8bd1..bbdbeb4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectAction.java
@@ -418,6 +418,10 @@ public interface ObjectAction extends ObjectMember {
             return org.apache.isis.applib.filter.Filters.asPredicate(Filters.memberOrderOf(association));
         }
 
+        public static Predicate<ObjectAction> associatedWith(final String collectionName) {
+            return new AssociatedWith(collectionName);
+        }
+
         public static Predicate<ObjectAction> associatedWithAndWithCollectionParameterFor(
                 final String collectionName,
                 final ObjectSpecification collectionTypeOfSpec) {
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
index fce2438..df26433 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/spec/feature/ObjectActionParameter.java
@@ -163,6 +163,23 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
     public static class Predicates {
         private Predicates(){}
 
+        /**
+         * A predicate for action parameters that checks that the parameter collection element type
+         * is the same as assignable (that is, the same or a supertype of, supporting co-variance) the
+         * {@link ObjectSpecification element type} provided in the constructor.
+         *
+         * <p>
+         *     For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
+         *     into the constructor.  An action with signature <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on
+         *     its (first) parameter.
+         * </p>
+         *
+         * <p>
+         *     For example, a parented collection of <tt>LeaseTermForServiceCharge</tt>s provides an elementSpec
+         *     of <tt>LeaseTermForServiceCharge</tt> into the constructor.  An action with signature
+         *     <tt>removeTerms(List&lt;LeaseTerm>)</tt> would match on its (first) parameter.
+         * </p>
+         */
         public static class CollectionParameter implements Predicate<ObjectActionParameter> {
 
             private final ObjectSpecification elementSpecification;
@@ -179,9 +196,39 @@ public interface ObjectActionParameter extends ObjectFeature, CurrentHolder {
 
                 final OneToManyActionParameter otmap =
                         (OneToManyActionParameter) objectActionParameter;
-                final ObjectSpecification specification = otmap.getSpecification();
-                final ObjectSpecification typeOfSpecification = this.elementSpecification;
-                return specification == typeOfSpecification;
+                final ObjectSpecification paramElementSpecification = otmap.getSpecification();
+                return this.elementSpecification.isOfType(paramElementSpecification);
+            }
+        }
+
+        /**
+         * A predicate for action parameters that checks that the parameter collection element type
+         * is exactly the same as the {@link ObjectSpecification element type} (no co/contra-variance) provided in the constructor.
+         *
+         * <p>
+         *     For example, a parented collection of <tt>LeaseTerm</tt>s provides an elementSpec of <tt>LeaseTerm</tt>
+         *     into the constructor.  An action with signature <tt>addTerm(LeaseTerm)</tt> would match on
+         *     its (first) parameter.
+         * </p>
+         */
+        public static class ScalarParameter implements Predicate<ObjectActionParameter> {
+
+            private final ObjectSpecification specification;
+
+            public ScalarParameter(final ObjectSpecification specification) {
+                this.specification = specification;
+            }
+
+            @Override
+            public boolean apply(@Nullable final ObjectActionParameter objectActionParameter) {
+                if (!(objectActionParameter instanceof OneToOneActionParameter)) {
+                    return false;
+                }
+
+                final OneToOneActionParameter otoap =
+                        (OneToOneActionParameter) objectActionParameter;
+                final ObjectSpecification paramSecification = otoap.getSpecification();
+                return paramSecification == this.specification;
             }
         }
     }
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
index cab0987..df881cb 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/SpecificationLoader.java
@@ -467,11 +467,15 @@ public class SpecificationLoader implements ApplicationScopedComponent {
 
         final Collection<ObjectSpecification> specs = allSpecifications();
         for (final ObjectSpecification spec : specs) {
-            postProcessor.postProcess(spec);
+            postProcess(spec);
         }
 
     }
 
+    public void postProcess(final ObjectSpecification spec) {
+        postProcessor.postProcess(spec);
+    }
+
     //endregion
 
     //region > allSpecifications
diff --git a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
index a81b930..9c616d1 100644
--- a/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
+++ b/core/metamodel/src/main/java/org/apache/isis/progmodels/dflt/ProgrammingModelFacetsJava5.java
@@ -137,7 +137,7 @@ import org.apache.isis.core.metamodel.facets.param.choices.method.ActionChoicesF
 import org.apache.isis.core.metamodel.facets.param.choices.methodnum.ActionParameterChoicesFacetViaMethodFactory;
 import org.apache.isis.core.metamodel.facets.param.defaults.fromtype.ActionParameterDefaultFacetDerivedFromTypeFactory;
 import org.apache.isis.core.metamodel.facets.param.defaults.methodnum.ActionParameterDefaultsFacetViaMethodFactory;
-import org.apache.isis.core.metamodel.facets.param.defaults.togglebox.ActionParameterDefaultsFacetViaToggleBoxesPostProcessor;
+import org.apache.isis.core.metamodel.postprocessors.param.ActionCollectionParameterDefaultsAndChoicesPostProcessor;
 import org.apache.isis.core.metamodel.facets.param.describedas.annotderived.DescribedAsFacetOnParameterAnnotationElseDerivedFromTypeFactory;
 import org.apache.isis.core.metamodel.facets.param.layout.ParameterLayoutFacetFactory;
 import org.apache.isis.core.metamodel.facets.param.mandatory.dflt.MandatoryFacetOnParametersDefaultFactory;
@@ -550,7 +550,7 @@ public final class ProgrammingModelFacetsJava5 extends ProgrammingModelAbstract
     @Override
     public List<ObjectSpecificationPostProcessor> getPostProcessors() {
         return Lists.<ObjectSpecificationPostProcessor>newArrayList(
-            new ActionParameterDefaultsFacetViaToggleBoxesPostProcessor()
+            new ActionCollectionParameterDefaultsAndChoicesPostProcessor()
         );
     }
 }
diff --git a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
index e705eba..5b37e9e 100644
--- a/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
+++ b/core/viewer-wicket-ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/widgets/linkandlabel/ActionLinkFactoryAbstract.java
@@ -37,7 +37,7 @@ import org.apache.wicket.request.cycle.RequestCycle;
 import org.apache.isis.applib.annotation.PromptStyle;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.facets.param.defaults.togglebox.ActionParameterDefaultsFacetViaToggleBoxes;
+import org.apache.isis.core.metamodel.postprocessors.param.ActionParameterDefaultsFacetFromParentedCollection;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.SpecificationLoader;
 import org.apache.isis.core.runtime.system.context.IsisContext;
@@ -121,9 +121,9 @@ public abstract class ActionLinkFactoryAbstract implements ActionLinkFactory {
                                     .filter(Predicates.notNull())
                                     .toList();
 
-                            final ActionPrompt actionPrompt = ActionParameterDefaultsFacetViaToggleBoxes.withSelected(
+                            final ActionPrompt actionPrompt = ActionParameterDefaultsFacetFromParentedCollection.withSelected(
                                     selectedPojos,
-                                    new ActionParameterDefaultsFacetViaToggleBoxes.SerializableRunnable<ActionPrompt>() {
+                                    new ActionParameterDefaultsFacetFromParentedCollection.SerializableRunnable<ActionPrompt>() {
                                         public ActionPrompt call() {
                                             return performOnClick(target);
                                         }

-- 
To stop receiving notification emails like this one, please contact
danhaywood@apache.org.