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 2014/02/05 09:45:55 UTC

[1/3] ISIS-667,ISIS-684,ISIS-685: async commands, tidy-up

Updated Branches:
  refs/heads/master 30ee89634 -> 4ce9e812f


http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/webapp/src/main/resources/webapp/scheduler/quartz-config.xml
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/resources/webapp/scheduler/quartz-config.xml b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/resources/webapp/scheduler/quartz-config.xml
index 7518e13..d61b938 100644
--- a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/resources/webapp/scheduler/quartz-config.xml
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/resources/webapp/scheduler/quartz-config.xml
@@ -8,10 +8,10 @@ http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
 
 	<schedule>
 		<job>
-			<name>BackgroundActionExecutionJob</name>
+			<name>BackgroundCommandExecutionJob</name>
 			<group>Isis</group>
 			<description>Poll and execute any background actions persisted by the BackgroundActionServiceJdo domain service</description>
-			<job-class>webapp.scheduler.BackgroundActionExecutionQuartzJob</job-class>
+			<job-class>webapp.scheduler.BackgroundCommandExecutionQuartzJob</job-class>
 			<job-data-map>
 				<entry>
 					<key>webapp.scheduler.user</key>
@@ -30,8 +30,8 @@ http://www.quartz-scheduler.org/xml/job_scheduling_data_1_8.xsd"
 	 	-->
 		<trigger>
 			<cron>
-				<name>BackgroundActionExecutionJobEveryTenSeconds</name>
-				<job-name>BackgroundActionExecutionJob</job-name>
+				<name>BackgroundCommandExecutionJobEveryTenSeconds</name>
+				<job-name>BackgroundCommandExecutionJob</job-name>
 				<job-group>Isis</job-group>
 				<cron-expression>0/10 * * * * ?</cron-expression>
 			</cron>

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
index ae65cab..c57a1b4 100644
--- a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
@@ -195,15 +195,15 @@ isis.services = \
                 org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdoContributions,\
                 org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdoRepository,\
                 \
-                # Core implementation of BackgroundService (depends on: MementoService & BackgroundActionService), \
+                # Core implementation of BackgroundService (depends on: MementoService & BackgroundCommandService & CommandContext service), \
                 org.apache.isis.core.runtime.services.background.BackgroundServiceDefault,\
                 \
-                # JDO implementation of the BackgroundTaskService (depends on: ReifiableActionContext service), \
-                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdo,\
-                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoContributions,\
-                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoRepository,\
+                # JDO implementation of the BackgroundCommandService (depends on: CommandContext service), \
+                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdo,\
+                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoContributions,\
+                org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoRepository,\
                 \
-                # JDO implementation of the PublishingService, \
+                # JDO implementation of the PublishingService (depends on: CommandContext service), \
                 org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdo,\
                 org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdoContributions,\
                 org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdoRepository,\

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/simple_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
----------------------------------------------------------------------
diff --git a/example/application/simple_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties b/example/application/simple_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
index e8b4dcf..2357d5e 100644
--- a/example/application/simple_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
+++ b/example/application/simple_wicket_restful_jdo/webapp/src/main/webapp/WEB-INF/isis.properties
@@ -188,15 +188,15 @@ isis.services = \
                 # org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdoContributions,\
                 # org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdoRepository,\
                 \
-                # Core implementation of BackgroundService (depends on: MementoService & BackgroundActionService), \
+                # Core implementation of BackgroundService (depends on: MementoService & BackgroundCommandService & CommandContext service), \
                 # org.apache.isis.core.runtime.services.background.BackgroundServiceDefault,\
                 \
-                # JDO implementation of the BackgroundTaskService (depends on: ReifiableActionContext service), \
-                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdo,\
-                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoContributions,\
-                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoRepository,\
+                # JDO implementation of the BackgroundCommandService (depends on: CommandContext service), \
+                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdo,\
+                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoContributions,\
+                # org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoRepository,\
                 \
-                # JDO implementation of the PublishingService, \
+                # JDO implementation of the PublishingService (depends on: CommandContext service), \
                 # org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdo,\
                 # org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdoContributions,\
                 # org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJdoRepository,\


[3/3] git commit: ISIS-667, ISIS-684, ISIS-685: async commands, tidy-up

Posted by da...@apache.org.
ISIS-667,ISIS-684,ISIS-685: async commands, tidy-up

ISIS-684:
- rename BackgroundActionService to BackgroundCommandService

ISIS-667:
- memberIdentifier, targetClass, targetAction, targetStr consistent across PublishedEventJdo, AuditEntryJdo, CommandJdo

ISIS-685:
- @Command annotation extended, with persistence() and executeIn() attributes
- corresponding updates to CommandFacet
- Command#executor and Command#executedIn keep track of whether being run by user or background
- ActionInvocationFacetViaMethod new logic, short-circuits execution if executor = user but executedIn = background,
  and return the command instead (if persistable)
- CommandService API extended to allow callers to request persistence of Command early
  (as used by ActionInvocationFacetViaMethod)


Project: http://git-wip-us.apache.org/repos/asf/isis/repo
Commit: http://git-wip-us.apache.org/repos/asf/isis/commit/4ce9e812
Tree: http://git-wip-us.apache.org/repos/asf/isis/tree/4ce9e812
Diff: http://git-wip-us.apache.org/repos/asf/isis/diff/4ce9e812

Branch: refs/heads/master
Commit: 4ce9e812ff6be219cdb1d4ca6df362491ea2f339
Parents: 30ee896
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Wed Feb 5 08:45:38 2014 +0000
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Wed Feb 5 08:45:38 2014 +0000

----------------------------------------------------------------------
 component/objectstore/jdo/jdo-applib/pom.xml    |  16 ++
 .../jdo/applib/service/JdoColumnLength.java     |  18 +-
 .../jdo/applib/service/audit/AuditEntryJdo.java |  74 ++++++-
 .../jdo/applib/service/audit/AuditEntryJdo.png  | Bin 0 -> 477 bytes
 .../service/audit/AuditingServiceJdo.java       |  13 +-
 .../background/BackgroundActionServiceJdo.java  |  76 --------
 ...BackgroundActionServiceJdoContributions.java |  64 -------
 .../BackgroundActionServiceJdoRepository.java   |  63 ------
 .../background/BackgroundCommandServiceJdo.java |  80 ++++++++
 ...ackgroundCommandServiceJdoContributions.java |  65 +++++++
 .../BackgroundCommandServiceJdoRepository.java  |  63 ++++++
 .../jdo/applib/service/command/CommandJdo.java  | 173 ++++++++++++-----
 .../jdo/applib/service/command/CommandJdo.png   | Bin 0 -> 582 bytes
 .../service/command/CommandServiceJdo.java      |  37 ++--
 .../service/publish/PublishedEventJdo.java      | 192 ++++++++++++++++---
 .../service/publish/PublishedEventJdo.png       | Bin 0 -> 653 bytes
 .../service/publish/PublishingServiceJdo.java   |   7 +
 .../ui/components/actions/ActionPanel.java      |   5 +-
 .../apache/isis/applib/annotation/Command.java  |  59 +++++-
 .../isis/applib/events/InteractionEvent.java    |   2 +-
 .../applib/services/audit/AuditingService3.java |  12 +-
 .../background/ActionInvocationMemento.java     |   4 +-
 .../background/BackgroundActionService.java     |  37 ----
 .../background/BackgroundCommandService.java    |  37 ++++
 .../isis/applib/services/command/Command.java   | 173 +++++++++++++----
 .../applib/services/command/CommandDefault.java | 101 +++++++---
 .../services/command/spi/CommandService.java    |  15 ++
 .../applib/services/publish/EventMetadata.java  |  55 +++++-
 .../facets/actions/command/CommandFacet.java    |   5 +
 .../actions/invoke/ActionInvocationFacet.java   |  35 +++-
 .../actions/command/CommandFacetAbstract.java   |  20 +-
 .../CommandAnnotationFacetFactory.java          |   4 +-
 .../annotation/CommandFacetAnnotation.java      |  10 +-
 .../invoke/ActionInvocationFacetViaMethod.java  | 121 +++++++-----
 .../background/BackgroundActionExecution.java   | 153 ---------------
 .../background/BackgroundCommandExecution.java  | 155 +++++++++++++++
 .../background/BackgroundServiceDefault.java    |  12 +-
 .../system/transaction/IsisTransaction.java     |  41 ++--
 ...sActionsTest_returnNewTransientInstance.java |  10 +-
 .../dom/src/main/java/dom/todo/ToDoItem.java    |  24 ++-
 .../src/main/java/dom/todo/ToDoItem.layout.json |   5 +-
 .../src/main/java/webapp/admin/Admin.java       |  65 ++++---
 .../BackgroundActionExecutionQuartzJob.java     |  46 -----
 .../BackgroundCommandExecutionQuartzJob.java    |  48 +++++
 .../webapp/scheduler/quartz-config.xml          |   8 +-
 .../src/main/webapp/WEB-INF/isis.properties     |  12 +-
 .../src/main/webapp/WEB-INF/isis.properties     |  12 +-
 47 files changed, 1478 insertions(+), 749 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/pom.xml
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/pom.xml b/component/objectstore/jdo/jdo-applib/pom.xml
index 9f88bd7..f9fc154 100644
--- a/component/objectstore/jdo/jdo-applib/pom.xml
+++ b/component/objectstore/jdo/jdo-applib/pom.xml
@@ -38,6 +38,22 @@
     <url>http://isis.apache.org/${relativeUrl}</url>
 
 	<build>
+        <resources>
+            <resource>
+                <filtering>false</filtering>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <filtering>false</filtering>
+                <directory>src/main/java</directory>
+                <includes>
+                    <include>**</include>
+                </includes>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </resource>
+        </resources>
 		<plugins>
             <plugin>
                 <groupId>org.datanucleus</groupId>

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/JdoColumnLength.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/JdoColumnLength.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/JdoColumnLength.java
index 814316f..ca3a42a 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/JdoColumnLength.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/JdoColumnLength.java
@@ -1,9 +1,9 @@
 /*
- *
- *  Copyright 2012-2014 Eurocommercial Properties NV
- *
- *
- *  Licensed under the Apache License, Version 2.0 (the
+ *  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
  *
@@ -26,8 +26,10 @@ public final class JdoColumnLength {
     public final static int TRANSACTION_ID = 36;
     // ie OID str
     public final static int BOOKMARK = 255; 
-    public static final int ACTION_IDENTIFIER = 255;
+    public static final int MEMBER_IDENTIFIER = 255;
     public static final int USER_NAME = 50;
+    public final static int TARGET_CLASS = 50;
+    public final static int TARGET_ACTION = 50;
     
     public static final int DESCRIPTION = 254;
 
@@ -42,11 +44,9 @@ public final class JdoColumnLength {
     public static final class Command {
         private Command() {
         }
-        public final static int TARGET_CLASS = 50;
-        public final static int TARGET_ACTION = 50;
         public final static int ARGUMENTS = 1024;
         public final static int EXCEPTION = 16000;
-        public static final int NATURE = 20;
+        public static final int EXECUTE_IN = 10;
     }
 
     public static final class BackgroundTask {

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.java
index 7cf2c93..c692ed8 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.java
@@ -27,6 +27,7 @@ import javax.jdo.annotations.Index;
 import javax.jdo.annotations.Indices;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.ActionSemantics;
 import org.apache.isis.applib.annotation.ActionSemantics.Of;
 import org.apache.isis.applib.annotation.Disabled;
@@ -42,6 +43,7 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.HasTransactionId;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.util.ObjectContracts;
 import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.objectstore.jdo.applib.service.JdoColumnLength;
 import org.apache.isis.objectstore.jdo.applib.service.Util;
@@ -70,7 +72,10 @@ import org.apache.isis.objectstore.jdo.applib.service.Util;
 @Immutable
 @Named("Audit Entry")
 @ObjectType("IsisAuditEntry")
-@MemberGroupLayout(left={"Identifiers","Target","Detail"})
+@MemberGroupLayout(
+        columnSpans={6,0,6},
+        left={"Identifiers","Target"},
+        right={"Detail"})
 public class AuditEntryJdo implements HasTransactionId {
 
     
@@ -79,7 +84,8 @@ public class AuditEntryJdo implements HasTransactionId {
         buf.append(
         new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(getTimestamp()));
         buf.append(",", getUser());
-        buf.append(":", getPropertyId());
+        buf.append(":", getTargetStr());
+        buf.append(" ", getMemberIdentifier());
         return buf.toString();
     }
     
@@ -152,6 +158,25 @@ public class AuditEntryJdo implements HasTransactionId {
 
 
     // //////////////////////////////////////
+    // targetClass (property)
+    // //////////////////////////////////////
+
+    private String targetClass;
+
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.TARGET_CLASS)
+    @TypicalLength(30)
+    @MemberOrder(name="Target", sequence = "10")
+    @Named("Class")
+    public String getTargetClass() {
+        return targetClass;
+    }
+
+    public void setTargetClass(final String targetClass) {
+        this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.TARGET_CLASS);
+    }
+
+
+    // //////////////////////////////////////
     // target (property)
     // openTargetObject (action)
     // //////////////////////////////////////
@@ -172,7 +197,7 @@ public class AuditEntryJdo implements HasTransactionId {
 
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.BOOKMARK, name="target")
     @Named("Object")
-    @MemberOrder(name="Target", sequence="3")
+    @MemberOrder(name="Target", sequence="30")
     public String getTargetStr() {
         return targetStr;
     }
@@ -196,13 +221,40 @@ public class AuditEntryJdo implements HasTransactionId {
     
 
     // //////////////////////////////////////
+    // memberIdentifier (property)
+    // //////////////////////////////////////
+
+    private String memberIdentifier;
+
+    /**
+     * This is the fully-qualified class and property Id, as per
+     * {@link Identifier#toClassAndNameIdentityString()}.
+     */
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.MEMBER_IDENTIFIER)
+    @TypicalLength(60)
+    @Hidden(where=Where.ALL_TABLES)
+    @MemberOrder(name="Detail",sequence = "1")
+    public String getMemberIdentifier() {
+        return memberIdentifier;
+    }
+
+    public void setMemberIdentifier(final String memberIdentifier) {
+        this.memberIdentifier = Util.abbreviated(memberIdentifier, JdoColumnLength.MEMBER_IDENTIFIER);
+    }
+
+
+
+    // //////////////////////////////////////
     // propertyId (property)
     // //////////////////////////////////////
     
     private String propertyId;
-    
+
+    /**
+     * This is the property name (without the class).
+     */
     @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.AuditEntry.PROPERTY_ID)
-    @MemberOrder(name="Target",sequence = "5")
+    @MemberOrder(name="Target",sequence = "20")
     public String getPropertyId() {
         return propertyId;
     }
@@ -245,6 +297,18 @@ public class AuditEntryJdo implements HasTransactionId {
         this.postValue = Util.abbreviated(postValue, JdoColumnLength.AuditEntry.PROPERTY_VALUE);
     }
     
+    
+    
+    // //////////////////////////////////////
+    // toString
+    // //////////////////////////////////////
+
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "timestamp,user,targetStr,memberIdentifier");
+    }
+
+    
     // //////////////////////////////////////
     // Injected services
     // //////////////////////////////////////

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.png
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.png b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.png
new file mode 100644
index 0000000..4e4352c
Binary files /dev/null and b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditEntryJdo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditingServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditingServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditingServiceJdo.java
index a1b93ea..13e12f7 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditingServiceJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/audit/AuditingServiceJdo.java
@@ -29,17 +29,26 @@ public class AuditingServiceJdo extends AbstractFactoryAndRepository implements
 
     @Programmatic
     public void audit(
-            final UUID transactionId, final Bookmark target, final String propertyId, 
+            final UUID transactionId, String targetClass, final Bookmark target, 
+            String memberIdentifier, final String propertyId, 
             final String preValue, final String postValue, 
             final String user, final java.sql.Timestamp timestamp) {
-        AuditEntryJdo auditEntry = newTransientInstance(AuditEntryJdo.class);
+        
+        final AuditEntryJdo auditEntry = newTransientInstance(AuditEntryJdo.class);
+        
         auditEntry.setTimestamp(timestamp);
         auditEntry.setUser(user);
         auditEntry.setTransactionId(transactionId);
+
+        auditEntry.setTargetClass(targetClass);
         auditEntry.setTarget(target);
+        
+        auditEntry.setMemberIdentifier(memberIdentifier);
         auditEntry.setPropertyId(propertyId);
+        
         auditEntry.setPreValue(preValue);
         auditEntry.setPostValue(postValue);
+        
         persistIfNotAlready(auditEntry);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdo.java
deleted file mode 100644
index b5936fd..0000000
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdo.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.objectstore.jdo.applib.service.background;
-
-import java.util.UUID;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.AbstractService;
-import org.apache.isis.applib.annotation.Named;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.services.background.ActionInvocationMemento;
-import org.apache.isis.applib.services.background.BackgroundActionService;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.Command.Nature;
-import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
-
-@Named("Background Actions")
-public class BackgroundActionServiceJdo extends AbstractService implements BackgroundActionService {
-
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(BackgroundActionServiceJdo.class);
-    
-    @Programmatic
-    @Override
-    public void schedule(
-            final ActionInvocationMemento aim, 
-            final Command parentAction, 
-            final String targetClassName, 
-            final String targetActionName, 
-            final String targetArgs) {
-        
-        final UUID transactionId = UUID.randomUUID();
-        final String user = parentAction.getUser();
-
-        final CommandJdo backgroundAction = newTransientInstance(CommandJdo.class);
-
-        backgroundAction.setParent(parentAction);
-        
-        backgroundAction.setTransactionId(transactionId);
-
-        backgroundAction.setUser(user);
-        backgroundAction.setTimestamp(Clock.getTimeAsJavaSqlTimestamp());
-
-        backgroundAction.setNature(Nature.BACKGROUND);
-
-        backgroundAction.setTargetClass(targetClassName);
-        backgroundAction.setTargetAction(targetActionName);
-        backgroundAction.setTargetStr(aim.getTarget().toString());
-        backgroundAction.setActionIdentifier(aim.getActionId());
-
-        backgroundAction.setArguments(targetArgs);
-        backgroundAction.setMemento(aim.asMementoString());
-        
-        parentAction.setPersistHint(true);
-        
-        persist(backgroundAction);
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoContributions.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoContributions.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoContributions.java
deleted file mode 100644
index 4598b52..0000000
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoContributions.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.objectstore.jdo.applib.service.background;
-
-import java.util.Collections;
-import java.util.List;
-
-import org.apache.isis.applib.AbstractFactoryAndRepository;
-import org.apache.isis.applib.annotation.ActionSemantics;
-import org.apache.isis.applib.annotation.ActionSemantics.Of;
-import org.apache.isis.applib.annotation.NotContributed;
-import org.apache.isis.applib.annotation.NotContributed.As;
-import org.apache.isis.applib.annotation.NotInServiceMenu;
-import org.apache.isis.applib.annotation.Render;
-import org.apache.isis.applib.annotation.Render.Type;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
-
-
-public class BackgroundActionServiceJdoContributions extends AbstractFactoryAndRepository {
-
-    @ActionSemantics(Of.SAFE)
-    @NotInServiceMenu
-    @NotContributed(As.ACTION)
-    @Render(Type.EAGERLY)
-    public List<CommandJdo> backgroundActions(final CommandJdo parent) {
-        return backgroundActionRepository.findByParent(parent);
-    }
-
-    @ActionSemantics(Of.SAFE)
-    @NotInServiceMenu
-    @NotContributed(As.ACTION)
-    @Render(Type.EAGERLY)
-    public List<CommandJdo> siblingActions(final CommandJdo siblingAction) {
-        final Command parent = siblingAction.getParent();
-        if(parent == null || !(parent instanceof CommandJdo)) {
-            return Collections.emptyList();
-        }
-        final CommandJdo parentJdo = (CommandJdo) parent;
-        final List<CommandJdo> siblingActions = backgroundActionRepository.findByParent(parentJdo);
-        siblingActions.remove(siblingAction);
-        return siblingActions;
-    }
-    
-    // //////////////////////////////////////
-
-    @javax.inject.Inject
-    private BackgroundActionServiceJdoRepository backgroundActionRepository;
-    
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoRepository.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoRepository.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoRepository.java
deleted file mode 100644
index bb93323..0000000
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundActionServiceJdoRepository.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.objectstore.jdo.applib.service.background;
-
-import java.util.List;
-import java.util.UUID;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import org.apache.isis.applib.AbstractFactoryAndRepository;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.query.QueryDefault;
-import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
-
-public class BackgroundActionServiceJdoRepository extends AbstractFactoryAndRepository {
-
-    @SuppressWarnings("unused")
-    private static final Logger LOG = LoggerFactory.getLogger(BackgroundActionServiceJdoRepository.class);
-
-    @Programmatic
-    public List<CommandJdo> listAll() {
-        return allInstances(CommandJdo.class);
-    }
-
-    @Programmatic
-    public List<CommandJdo> findByTransactionId(final UUID transactionId) {
-        return allMatches(
-                new QueryDefault<CommandJdo>(CommandJdo.class, 
-                        "findBackgroundActionByTransactionId", 
-                        "transactionId", transactionId));
-    }
-
-    @Programmatic
-    public List<CommandJdo> findByParent(CommandJdo parent) {
-        return allMatches(
-                new QueryDefault<CommandJdo>(CommandJdo.class, 
-                        "findBackgroundActionsByParent", 
-                        "parent", parent));
-    }
-
-    @Programmatic
-    public List<CommandJdo> findBackgroundActionsNotYetStarted() {
-        return allMatches(
-                new QueryDefault<CommandJdo>(CommandJdo.class, 
-                        "findBackgroundActionsNotYetStarted"));
-    }
-    
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdo.java
new file mode 100644
index 0000000..2a29faa
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdo.java
@@ -0,0 +1,80 @@
+/**
+ *  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.objectstore.jdo.applib.service.background;
+
+import java.util.UUID;
+
+import javax.validation.executable.ExecutableType;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.applib.services.background.ActionInvocationMemento;
+import org.apache.isis.applib.services.background.BackgroundCommandService;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
+import org.apache.isis.applib.services.wrapper.WrapperFactory.ExecutionMode;
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+@Named("Background Commands")
+public class BackgroundCommandServiceJdo extends AbstractService implements BackgroundCommandService {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(BackgroundCommandServiceJdo.class);
+    
+    @Programmatic
+    @Override
+    public void schedule(
+            final ActionInvocationMemento aim, 
+            final Command parentCommand, 
+            final String targetClassName, 
+            final String targetActionName, 
+            final String targetArgs) {
+        
+        final UUID transactionId = UUID.randomUUID();
+        final String user = parentCommand.getUser();
+
+        final CommandJdo backgroundCommand = newTransientInstance(CommandJdo.class);
+
+        backgroundCommand.setParent(parentCommand);
+        
+        backgroundCommand.setTransactionId(transactionId);
+
+        backgroundCommand.setUser(user);
+        backgroundCommand.setTimestamp(Clock.getTimeAsJavaSqlTimestamp());
+
+        backgroundCommand.setExecuteIn(ExecuteIn.BACKGROUND);
+
+        backgroundCommand.setTargetClass(targetClassName);
+        backgroundCommand.setTargetAction(targetActionName);
+        backgroundCommand.setTargetStr(aim.getTarget().toString());
+        backgroundCommand.setMemberIdentifier(aim.getActionId());
+
+        backgroundCommand.setArguments(targetArgs);
+        backgroundCommand.setMemento(aim.asMementoString());
+        
+        parentCommand.setPersistHint(true);
+        
+        persist(backgroundCommand);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoContributions.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoContributions.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoContributions.java
new file mode 100644
index 0000000..eb57e84
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoContributions.java
@@ -0,0 +1,65 @@
+/**
+ *  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.objectstore.jdo.applib.service.background;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.ActionSemantics;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.NotContributed;
+import org.apache.isis.applib.annotation.NotContributed.As;
+import org.apache.isis.applib.annotation.NotInServiceMenu;
+import org.apache.isis.applib.annotation.Render;
+import org.apache.isis.applib.annotation.Render.Type;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+
+public class BackgroundCommandServiceJdoContributions extends AbstractFactoryAndRepository {
+
+    @ActionSemantics(Of.SAFE)
+    @NotInServiceMenu
+    @NotContributed(As.ACTION)
+    @Render(Type.EAGERLY)
+    public List<CommandJdo> childCommands(final CommandJdo parent) {
+        return backgroundCommandRepository.findByParent(parent);
+    }
+
+    @ActionSemantics(Of.SAFE)
+    @NotInServiceMenu
+    @NotContributed(As.ACTION)
+    @Render(Type.EAGERLY)
+    public List<CommandJdo> siblingCommands(final CommandJdo siblingCommand) {
+        final Command parent = siblingCommand.getParent();
+        if(parent == null || !(parent instanceof CommandJdo)) {
+            return Collections.emptyList();
+        }
+        final CommandJdo parentJdo = (CommandJdo) parent;
+        final List<CommandJdo> siblingCommands = backgroundCommandRepository.findByParent(parentJdo);
+        siblingCommands.remove(siblingCommand);
+        return siblingCommands;
+    }
+
+
+    // //////////////////////////////////////
+
+    @javax.inject.Inject
+    private BackgroundCommandServiceJdoRepository backgroundCommandRepository;
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoRepository.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoRepository.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoRepository.java
new file mode 100644
index 0000000..ee43a6f
--- /dev/null
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/background/BackgroundCommandServiceJdoRepository.java
@@ -0,0 +1,63 @@
+/**
+ *  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.objectstore.jdo.applib.service.background;
+
+import java.util.List;
+import java.util.UUID;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+public class BackgroundCommandServiceJdoRepository extends AbstractFactoryAndRepository {
+
+    @SuppressWarnings("unused")
+    private static final Logger LOG = LoggerFactory.getLogger(BackgroundCommandServiceJdoRepository.class);
+
+    @Programmatic
+    public List<CommandJdo> listAll() {
+        return allInstances(CommandJdo.class);
+    }
+
+    @Programmatic
+    public List<CommandJdo> findByTransactionId(final UUID transactionId) {
+        return allMatches(
+                new QueryDefault<CommandJdo>(CommandJdo.class, 
+                        "findBackgroundCommandByTransactionId", 
+                        "transactionId", transactionId));
+    }
+
+    @Programmatic
+    public List<CommandJdo> findByParent(CommandJdo parent) {
+        return allMatches(
+                new QueryDefault<CommandJdo>(CommandJdo.class, 
+                        "findBackgroundCommandsByParent", 
+                        "parent", parent));
+    }
+
+    @Programmatic
+    public List<CommandJdo> findBackgroundCommandsNotYetStarted() {
+        return allMatches(
+                new QueryDefault<CommandJdo>(CommandJdo.class, 
+                        "findBackgroundCommandsNotYetStarted"));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
index fd1274d..fbcfe06 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.java
@@ -33,6 +33,9 @@ import org.slf4j.LoggerFactory;
 import org.apache.isis.applib.DomainObjectContainer;
 import org.apache.isis.applib.annotation.ActionSemantics;
 import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.applib.annotation.Hidden;
 import org.apache.isis.applib.annotation.Immutable;
 import org.apache.isis.applib.annotation.MemberGroupLayout;
@@ -47,8 +50,9 @@ import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.spi.CommandService;
+import org.apache.isis.applib.services.publish.EventType;
 import org.apache.isis.applib.util.ObjectContracts;
+import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.objectstore.jdo.applib.service.JdoColumnLength;
 import org.apache.isis.objectstore.jdo.applib.service.Util;
 
@@ -61,25 +65,24 @@ import org.apache.isis.objectstore.jdo.applib.service.Util;
             name="findByTransactionId", language="JDOQL",  
             value="SELECT "
                     + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
-                    + "WHERE transactionId == :transactionId "
-                    + "&& nature == 'USER_INITIATED'"),
+                    + "WHERE transactionId == :transactionId "),
     @javax.jdo.annotations.Query(
-            name="findBackgroundActionByTransactionId", language="JDOQL",  
+            name="findBackgroundCommandByTransactionId", language="JDOQL",  
             value="SELECT "
                     + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
                     + "WHERE transactionId == :transactionId "
-                    + "&& nature == 'BACKGROUND'"),
+                    + "&& executeIn == 'BACKGROUND'"),
     @javax.jdo.annotations.Query(
-            name="findBackgroundActionsByParent", language="JDOQL",  
+            name="findBackgroundCommandsByParent", language="JDOQL",  
             value="SELECT "
                     + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
                     + "WHERE parent == :parent "
-                    + "&& nature == 'BACKGROUND'"),
+                    + "&& executeIn == 'BACKGROUND'"),
     @javax.jdo.annotations.Query(
-            name="findBackgroundActionsNotYetStarted", language="JDOQL",  
+            name="findBackgroundCommandsNotYetStarted", language="JDOQL",  
             value="SELECT "
                     + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
-                    + "WHERE nature == 'BACKGROUND' "
+                    + "WHERE executeIn == 'BACKGROUND' "
                     + "&& startedAt == null "
                     + "ORDER BY timestamp ASC "
                     ),
@@ -94,7 +97,7 @@ import org.apache.isis.objectstore.jdo.applib.service.Util;
             value="SELECT "
                     + "FROM org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo "
                     + "WHERE completedAt != null "
-                    + "&& nature == 'USER_INITIATED' "
+                    + "&& executeIn == 'FOREGROUND' "
                     + "ORDER BY timestamp DESC")
 })
 @ObjectType("IsisCommand")
@@ -111,13 +114,25 @@ public class CommandJdo implements Command {
 
 
     // //////////////////////////////////////
+    // Identification
+    // //////////////////////////////////////
+
+    public String title() {
+        final TitleBuffer buf = new TitleBuffer();
+        buf.append(getTargetStr());
+        buf.append(" ").append(getMemberIdentifier());
+        return buf.toString();
+    }
+
+
+
+    // //////////////////////////////////////
     // user (property)
     // //////////////////////////////////////
 
     private String user;
 
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.USER_NAME)
-    @Title(sequence="2", prepend=", ")
     @MemberOrder(name="Identifiers", sequence = "10")
     public String getUser() {
         return user;
@@ -153,35 +168,48 @@ public class CommandJdo implements Command {
     }
 
     
+    // //////////////////////////////////////
+    // executor (property)
+    // //////////////////////////////////////
+    
+    private Executor executor;
     
+    @Programmatic
+    @javax.jdo.annotations.NotPersistent
+    @Override
+    public Executor getExecutor() {
+        return executor;
+    }
+
+    @Override
+    public void setExecutor(Executor nature) {
+        this.executor = nature;
+    }
+
     // //////////////////////////////////////
-    // nature (property)
+    // executeIn (property)
     // //////////////////////////////////////
 
-    private Nature nature;
+    private ExecuteIn executeIn;
 
     /**
      * Whether the action was invoked explicitly by the user, or scheduled as a background
      * task, or as for some other reason, eg a side-effect of rendering an object due to 
      * get-after-post).
      */
-    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.NATURE)
-    @TypicalLength(30)
-    @MemberOrder(name="Identifiers", sequence = "30")
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.EXECUTE_IN)
+    @MemberOrder(name="Identifiers", sequence = "32")
     @Override
-    public Nature getNature() {
-        return nature;
+    public ExecuteIn getExecuteIn() {
+        return executeIn;
     }
     
     /**
      * <b>NOT API</b>: intended to be called only by the framework.
-     * 
-     * <p>
-     * Implementation notes: populated by the viewer as hint to {@link CommandService} implementation.
      */
     @Override
-    public void setNature(Nature nature) {
-        this.nature = nature;
+    public void setExecuteIn(ExecuteIn nature) {
+        this.executeIn = nature;
     }
 
 
@@ -243,7 +271,7 @@ public class CommandJdo implements Command {
 
     private String targetClass;
 
-    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.TARGET_CLASS)
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_CLASS)
     @TypicalLength(30)
     @MemberOrder(name="Target", sequence = "10")
     @Named("Class")
@@ -252,7 +280,7 @@ public class CommandJdo implements Command {
     }
 
     public void setTargetClass(final String targetClass) {
-        this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.Command.TARGET_CLASS);
+        this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.TARGET_CLASS);
     }
 
 
@@ -262,7 +290,7 @@ public class CommandJdo implements Command {
     
     private String targetAction;
     
-    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.TARGET_ACTION)
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_ACTION)
     @TypicalLength(30)
     @MemberOrder(name="Target", sequence = "20")
     @Named("Action")
@@ -271,7 +299,7 @@ public class CommandJdo implements Command {
     }
     
     public void setTargetAction(final String targetAction) {
-        this.targetAction = Util.abbreviated(targetAction, JdoColumnLength.Command.TARGET_ACTION);
+        this.targetAction = Util.abbreviated(targetAction, JdoColumnLength.TARGET_ACTION);
     }
     
 
@@ -309,6 +337,7 @@ public class CommandJdo implements Command {
 
     // //////////////////////////////////////
 
+    @Bulk
     @ActionSemantics(Of.SAFE)
     @MemberOrder(name="TargetStr", sequence="1")
     @Named("Open")
@@ -327,7 +356,7 @@ public class CommandJdo implements Command {
     private String arguments;
     
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.Command.ARGUMENTS)
-    @MultiLine(numberOfLines=6)
+    @MultiLine(numberOfLines=7)
     @Hidden(where=Where.ALL_TABLES)
     @MemberOrder(name="Target",sequence = "40")
     public String getArguments() {
@@ -341,22 +370,21 @@ public class CommandJdo implements Command {
     
 
     // //////////////////////////////////////
-    // actionIdentifier (property)
+    // memberIdentifier (property)
     // //////////////////////////////////////
 
-    private String actionIdentifier;
+    private String memberIdentifier;
     
-    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.ACTION_IDENTIFIER)
-    @Title(sequence="1")
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.MEMBER_IDENTIFIER)
     @TypicalLength(60)
     @Hidden(where=Where.ALL_TABLES)
     @MemberOrder(name="Detail",sequence = "1")
-    public String getActionIdentifier() {
-        return actionIdentifier;
+    public String getMemberIdentifier() {
+        return memberIdentifier;
     }
 
-    public void setActionIdentifier(final String actionIdentifier) {
-        this.actionIdentifier = Util.abbreviated(actionIdentifier, JdoColumnLength.ACTION_IDENTIFIER);
+    public void setMemberIdentifier(final String memberIdentifier) {
+        this.memberIdentifier = Util.abbreviated(memberIdentifier, JdoColumnLength.MEMBER_IDENTIFIER);
     }
 
 
@@ -368,7 +396,7 @@ public class CommandJdo implements Command {
     private String memento;
     
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.BackgroundTask.MEMENTO)
-    @MultiLine(numberOfLines=10)
+    @MultiLine(numberOfLines=9)
     @Hidden(where=Where.ALL_TABLES)
     @MemberOrder(name="Detail",sequence = "30")
     public String getMemento() {
@@ -460,10 +488,33 @@ public class CommandJdo implements Command {
     
     
     // //////////////////////////////////////
+    // state (derived property)
+    // //////////////////////////////////////
+
+    @javax.jdo.annotations.NotPersistent
+    @MemberOrder(name="Results",sequence = "10")
+    @Hidden(where=Where.OBJECT_FORMS)
+    @Named("Result")
+    public String getResultSummary() {
+        if(getCompletedAt() == null) {
+            return "";
+        }
+        if(getException() != null) {
+            return "EXCEPTION";
+        } 
+        if(getResultStr() != null) {
+            return "OK";
+        } else {
+            return "OK (VOID)";
+        }
+    }
+
+    
+    // //////////////////////////////////////
     // result (property)
     // openResultObject (action)
     // //////////////////////////////////////
-
+    
     @Programmatic
     @Override
     public Bookmark getResult() {
@@ -578,6 +629,26 @@ public class CommandJdo implements Command {
         return next.get();
     }
 
+    
+    // //////////////////////////////////////
+    // persistence (programmatic)
+    // //////////////////////////////////////
+
+    private Persistence persistence;
+    
+    @javax.jdo.annotations.NotPersistent
+    @Programmatic
+    @Override
+    public Persistence getPersistence() {
+        return persistence;
+    }
+
+    @Override
+    public void setPersistence(Persistence persistence) {
+        this.persistence = persistence;
+    }
+
+
     // //////////////////////////////////////
     // setPersistHint (SPI impl)
     // //////////////////////////////////////
@@ -596,26 +667,42 @@ public class CommandJdo implements Command {
         this.persistHint = persistHint;
     }
 
+    
+    // //////////////////////////////////////
+    
+    @Programmatic
+    boolean shouldPersist() {
+        if(Persistence.PERSISTED == getPersistence()) {
+            return true;
+        }
+        if(Persistence.IF_HINTED == getPersistence()) {
+            return isPersistHint();
+        }
+        return false;
+    }
+
+
+
     // //////////////////////////////////////
     // toString
     // //////////////////////////////////////
 
-
     @Override
     public String toString() {
-        return ObjectContracts.toString(this, "startedAt,user,actionIdentifier,target,completedAt,duration,transactionId");
+        return ObjectContracts.toString(this, "targetStr,memberIdentifier,user,startedAt,completedAt,duration,transactionId");
     }
 
     
+    
+    // //////////////////////////////////////
+    // dependencies
     // //////////////////////////////////////
     
+
     @javax.inject.Inject
     private BookmarkService bookmarkService;
     
     @javax.inject.Inject
     private DomainObjectContainer container;
 
-    
-
-
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.png
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.png b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.png
new file mode 100644
index 0000000..7545614
Binary files /dev/null and b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandJdo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
index 42ff6ff..53f98eb 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/command/CommandServiceJdo.java
@@ -22,9 +22,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import org.apache.isis.applib.AbstractService;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
 import org.apache.isis.applib.services.command.spi.CommandService;
 
 public class CommandServiceJdo extends AbstractService implements CommandService {
@@ -34,14 +37,15 @@ public class CommandServiceJdo extends AbstractService implements CommandService
 
     /**
      * Creates an {@link CommandJdo}, initializing its 
-     * {@link Command#setNature(Command.Nature) nature} to be
-     * {@link Command.Nature#OTHER rendering}.
+     * {@link Command#setExecuteIn(Command.ExecuteIn) nature} to be
+     * {@link Command.ExecuteIn#OTHER rendering}.
      */
     @Programmatic
     @Override
     public Command create() {
         CommandJdo command = newTransientInstance(CommandJdo.class);
-        command.setNature(Command.Nature.OTHER);
+        command.setExecutor(Executor.OTHER);
+        command.setPersistence(Persistence.IF_HINTED);
         return command;
     }
 
@@ -64,7 +68,7 @@ public class CommandServiceJdo extends AbstractService implements CommandService
     @Programmatic
     @Override
     public void complete(final Command command) {
-        CommandJdo commandJdo = asUserInitiatedCommandJdo(command);
+        final CommandJdo commandJdo = asUserInitiatedCommandJdo(command);
         if(commandJdo == null) {
             return;
         }
@@ -73,25 +77,32 @@ public class CommandServiceJdo extends AbstractService implements CommandService
         persistIfNotAlready(commandJdo);
     }
 
+    @Override
+    public boolean persistIfPossible(Command command) {
+        if(!(command instanceof CommandJdo)) {
+            // ought not to be the case, since this service created the object in the #create() method
+            return false;
+        }
+        final CommandJdo commandJdo = (CommandJdo)command;
+        persistIfNotAlready(commandJdo);
+        return true;
+    }
+    
+    
     /**
-     * Not API, factored out from {@link CommandServiceJdoRepository}.
+     * Not API, also used by {@link CommandServiceJdoRepository}.
      */
     CommandJdo asUserInitiatedCommandJdo(final Command command) {
         if(!(command instanceof CommandJdo)) {
             // ought not to be the case, since this service created the object in the #create() method
             return null;
         }
-        if(command.getNature() != Command.Nature.USER_INITIATED) {
+        if(command.getExecuteIn() != ExecuteIn.FOREGROUND) {
             return null;
         } 
         final CommandJdo commandJdo = (CommandJdo) command;
-        if(!commandJdo.isPersistHint()) {
-            return null;
-        } 
-        return commandJdo;
+        return commandJdo.shouldPersist()? commandJdo: null;
     }
-    
-    
-    
+
     
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
index 3f086a3..07b0987 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.java
@@ -24,6 +24,7 @@ import java.util.UUID;
 import javax.jdo.annotations.IdentityType;
 
 import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.ActionSemantics;
 import org.apache.isis.applib.annotation.ActionSemantics.Of;
 import org.apache.isis.applib.annotation.Bulk;
@@ -36,11 +37,14 @@ import org.apache.isis.applib.annotation.Named;
 import org.apache.isis.applib.annotation.NotPersisted;
 import org.apache.isis.applib.annotation.ObjectType;
 import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.annotation.Title;
+import org.apache.isis.applib.annotation.TypicalLength;
 import org.apache.isis.applib.annotation.Where;
 import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.publish.EventType;
+import org.apache.isis.applib.util.ObjectContracts;
+import org.apache.isis.applib.util.TitleBuffer;
 import org.apache.isis.objectstore.jdo.applib.service.JdoColumnLength;
 import org.apache.isis.objectstore.jdo.applib.service.Util;
 
@@ -61,7 +65,9 @@ import org.apache.isis.objectstore.jdo.applib.service.Util;
                     + "WHERE transactionId == :transactionId")
 })
 @MemberGroupLayout(
-        left={"Identifiers","Target","Detail"})
+        columnSpans={6,0,6},
+        left={"Identifiers","Target"},
+        right={"Detail","State"})
 @Immutable
 @ObjectType("IsisPublishedEvent")
 public class PublishedEventJdo implements HasTransactionId {
@@ -71,6 +77,21 @@ public class PublishedEventJdo implements HasTransactionId {
     }
     
 
+    // //////////////////////////////////////
+    // Identification
+    // //////////////////////////////////////
+
+    public String title() {
+        final TitleBuffer buf = new TitleBuffer();
+        buf.append(getEventType().name()).append(" ").append(getTargetStr());
+        if(getEventType()==EventType.ACTION_INVOCATION) {
+            buf.append(" ").append(getMemberIdentifier());
+        }
+        buf.append(",").append(getState());
+        return buf.toString();
+    }
+
+
     
     // //////////////////////////////////////
     // user (property)
@@ -168,10 +189,17 @@ public class PublishedEventJdo implements HasTransactionId {
 
     private String title;
 
+    /**
+     * Consists of the full oidStr (with version info etc), concatenated 
+     * (if an {@link EventType#ACTION_INVOCATION}) with the name/parms of the action.
+     * 
+     * <p>
+     * @deprecated - the oid of the target is also available (without the version info) through {@link #getTarget()}, and
+     *               the action identifier is available through {@link #getMemberIdentifier()}.
+     */
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.TITLE)
-    @Title
-    @MemberOrder(name="Target", sequence = "10")
-    @Named("Object")
+    @Hidden
+    @Deprecated
     public String getTitle() {
         return title;
     }
@@ -180,24 +208,7 @@ public class PublishedEventJdo implements HasTransactionId {
         this.title = title;
     }
     
-    // //////////////////////////////////////
-
     
-    @ActionSemantics(Of.SAFE)
-    @MemberOrder(name="Title", sequence="1")
-    @Named("Open")
-    public Object openTitleObject() {
-        String title2 = getTitle();
-        int indexOf = title2.indexOf("^");
-        if(indexOf != -1) {
-            title2 = title2.substring(0, indexOf);
-        }
-        return Util.lookupBookmark(Util.bookmarkFor(title2), bookmarkService, container);
-    }
-    public boolean hideOpenTitleObject() {
-        return getTitle() == null;
-    }
-
     // //////////////////////////////////////
     // eventType (property)
     // //////////////////////////////////////
@@ -205,7 +216,7 @@ public class PublishedEventJdo implements HasTransactionId {
     private EventType eventType;
 
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.EVENT_TYPE)
-    @MemberOrder(name="Detail",sequence = "20")
+    @MemberOrder(name="Identifiers",sequence = "50")
     public EventType getEventType() {
         return eventType;
     }
@@ -216,13 +227,131 @@ public class PublishedEventJdo implements HasTransactionId {
     
 
     // //////////////////////////////////////
+    // targetClass (property)
+    // //////////////////////////////////////
+
+    private String targetClass;
+
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.TARGET_CLASS)
+    @TypicalLength(30)
+    @MemberOrder(name="Target", sequence = "10")
+    @Named("Class")
+    public String getTargetClass() {
+        return targetClass;
+    }
+
+    public void setTargetClass(final String targetClass) {
+        this.targetClass = Util.abbreviated(targetClass, JdoColumnLength.TARGET_CLASS);
+    }
+
+
+    // //////////////////////////////////////
+    // targetAction (property)
+    // //////////////////////////////////////
+    
+    private String targetAction;
+    
+    /**
+     * Only populated for {@link EventType#ACTION_INVOCATION}
+     */
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.TARGET_ACTION)
+    @TypicalLength(30)
+    @MemberOrder(name="Target", sequence = "20")
+    @Named("Action")
+    public String getTargetAction() {
+        return targetAction;
+    }
+    
+    public void setTargetAction(final String targetAction) {
+        this.targetAction = Util.abbreviated(targetAction, JdoColumnLength.TARGET_ACTION);
+    }
+    
+
+    // //////////////////////////////////////
+    // target (property)
+    // openTargetObject (action)
+    // //////////////////////////////////////
+
+    @Programmatic
+    public Bookmark getTarget() {
+        return Util.bookmarkFor(getTargetStr());
+    }
+    
+    @Programmatic
+    public void setTarget(Bookmark target) {
+        setTargetStr(Util.asString(target));
+    }
+
+    // //////////////////////////////////////
+    
+    private String targetStr;
+    @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.BOOKMARK, name="target")
+//    @Hidden(where=Where.ALL_TABLES)
+    @MemberOrder(name="Target", sequence="30")
+    @Named("Object")
+    public String getTargetStr() {
+        return targetStr;
+    }
+
+    public void setTargetStr(final String targetStr) {
+        this.targetStr = targetStr;
+    }
+
+    // //////////////////////////////////////
+
+    @Bulk
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(name="TargetStr", sequence="1")
+    @Named("Open")
+    public Object openTargetObject() {
+        return Util.lookupBookmark(getTarget(), bookmarkService, container);
+    }
+    public boolean hideOpenTargetObject() {
+        return getTarget() == null;
+    }
+
+
+    // //////////////////////////////////////
+    // memberIdentifier (property)
+    // //////////////////////////////////////
+
+    private String memberIdentifier;
+    
+    /**
+     * Holds a string representation of the invoked action, equivalent to
+     * {@link Identifier#toClassAndNameIdentityString()}.
+     * 
+     * <p>
+     * Only populated for {@link EventType#ACTION_INVOCATION}, 
+     * returns <tt>null</tt> otherwise.
+     * 
+     * <p>
+     * This property is called 'memberIdentifier' rather than 'actionIdentifier' for
+     * consistency with other services (such as auditing and publishing) that may act on
+     * properties rather than simply just actions.
+     */
+    @javax.jdo.annotations.Column(allowsNull="true", length=JdoColumnLength.MEMBER_IDENTIFIER)
+    @TypicalLength(60)
+    @Hidden(where=Where.ALL_TABLES)
+    @MemberOrder(name="Detail",sequence = "20")
+    public String getMemberIdentifier() {
+        return memberIdentifier;
+    }
+
+    public void setMemberIdentifier(final String actionIdentifier) {
+        this.memberIdentifier = Util.abbreviated(actionIdentifier, JdoColumnLength.MEMBER_IDENTIFIER);
+    }
+
+
+
+    // //////////////////////////////////////
     // state (property)
     // //////////////////////////////////////
 
     private State state;
 
     @javax.jdo.annotations.Column(allowsNull="false", length=JdoColumnLength.PublishedEvent.STATE)
-    @MemberOrder(name="Detail", sequence = "30")
+    @MemberOrder(name="State", sequence = "30")
     public State getState() {
         return state;
     }
@@ -243,7 +372,7 @@ public class PublishedEventJdo implements HasTransactionId {
 
     @javax.jdo.annotations.NotPersistent
     @NotPersisted
-    @MultiLine(numberOfLines=20)
+    @MultiLine(numberOfLines=14)
     @Hidden(where=Where.ALL_TABLES)
     @MemberOrder(name="Detail", sequence = "40")
     public String getSerializedForm() {
@@ -301,6 +430,19 @@ public class PublishedEventJdo implements HasTransactionId {
     }
     
 
+    
+    // //////////////////////////////////////
+    // toString
+    // //////////////////////////////////////
+
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "targetStr,timestamp,user,eventType,memberIdentifier,state");
+    }
+
+
+    // //////////////////////////////////////
+    // dependencies
     // //////////////////////////////////////
 
     @javax.inject.Inject

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.png
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.png b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.png
new file mode 100644
index 0000000..42076a5
Binary files /dev/null and b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishedEventJdo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
----------------------------------------------------------------------
diff --git a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
index 2037080..64f2d79 100644
--- a/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
+++ b/component/objectstore/jdo/jdo-applib/src/main/java/org/apache/isis/objectstore/jdo/applib/service/publish/PublishingServiceJdo.java
@@ -25,6 +25,7 @@ import javax.annotation.PostConstruct;
 
 import org.apache.isis.applib.AbstractService;
 import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.applib.services.publish.EventMetadata;
 import org.apache.isis.applib.services.publish.EventPayload;
@@ -68,6 +69,12 @@ public class PublishingServiceJdo extends AbstractService implements PublishingS
         publishedEvent.setTimestamp(metadata.getJavaSqlTimestamp());
         publishedEvent.setUser(metadata.getUser());
         publishedEvent.setTitle(metadata.getTitle());
+        
+        publishedEvent.setTargetClass(metadata.getTargetClass());
+        publishedEvent.setTarget(metadata.getTarget());
+        publishedEvent.setTargetAction(metadata.getTargetAction());
+        publishedEvent.setMemberIdentifier(metadata.getActionIdentifier());
+        
         persist(publishedEvent);
     }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
----------------------------------------------------------------------
diff --git a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
index 4c9fffb..e8ddbcf 100644
--- a/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
+++ b/component/viewer/wicket/ui/src/main/java/org/apache/isis/viewer/wicket/ui/components/actions/ActionPanel.java
@@ -29,9 +29,11 @@ import org.apache.wicket.markup.html.form.Form;
 import org.apache.wicket.model.Model;
 
 import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
 import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizer;
 import org.apache.isis.applib.services.exceprecog.ExceptionRecognizerComposite;
@@ -171,7 +173,6 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
             final ObjectAdapter targetAdapter, 
             final AjaxRequestTarget target, 
             final Form<?> feedbackForm) {
-
         
         final ActionModel actionModel = getActionModel();
         
@@ -187,7 +188,7 @@ public class ActionPanel extends PanelAbstract<ActionModel> implements ActionExe
         final Command command;
         if (commandContext != null) {
             command = commandContext.getCommand();
-            command.setNature(Command.Nature.USER_INITIATED);
+            command.setExecutor(Executor.USER);
         } else {
             command = null;
         }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java b/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
index c72f34b..266d140 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/annotation/Command.java
@@ -25,15 +25,68 @@ import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
-import org.apache.isis.applib.services.command.spi.CommandService;
+import org.apache.isis.applib.services.background.BackgroundCommandService;
 
 /**
- * Indicates that an action invocation should be persisted as a {@link Command},
- * (if persistable commands are supported by the configured {@link CommandService}).
+ * Indicates how the {@link org.apache.isis.applib.services.command.Command Command} object provided by the
+ * (request-scoped) {@link org.apache.isis.applib.services.command.CommandContext command context} service should be
+ * used.
+ * 
  */
 @Inherited
 @Target({ ElementType.METHOD })
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Command {
 
+    public static enum Persistence {
+        /**
+         * The {@link org.apache.isis.applib.services.command.Command Command} object should be persisted.
+         */
+        PERSISTED,
+        /**
+         * The {@link org.apache.isis.applib.services.command.Command Command} object should only be persisted if
+         * another service, such as the {@link BackgroundCommandService}, hints that it should.
+         */
+        IF_HINTED,
+        /**
+         * {@link org.apache.isis.applib.services.command.Command Command} object should not be persisted (even if
+         * another service, such as the {@link BackgroundCommandService}, hints that it should).
+         */
+        NOT_PERSISTED
+    }
+    
+    /**
+     * How the {@link org.apache.isis.applib.services.command.Command Command} object provided by the
+     * {@link org.apache.isis.applib.services.command.CommandContext CommandContext} domain service should be persisted.
+     */
+    Persistence persistence() default Persistence.PERSISTED;
+
+    
+    // //////////////////////////////////////
+
+    
+    public static enum ExecuteIn {
+        /**
+         * Execute synchronously in the &quot;foreground&quot;, wait for the results.
+         */
+        FOREGROUND,
+        /**
+         * Execute &quot;asynchronously&quot; through the {@link BackgroundCommandService}, returning (if possible) the
+         * persisted {@link org.apache.isis.applib.services.command.Command command} object as a placeholder to the
+         * result.
+         */
+        BACKGROUND
+    }
+
+
+    /**
+     * How the command/action should be executed.
+     * 
+     * <p>
+     * If the corresponding {@link org.apache.isis.applib.services.command.Command Command} object is persisted, 
+     * then its {@link org.apache.isis.applib.services.command.Command#getExecuteIn() invocationType} property 
+     * will be set to this value.
+     */
+    ExecuteIn executeIn() default ExecuteIn.FOREGROUND;
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/events/InteractionEvent.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/events/InteractionEvent.java b/core/applib/src/main/java/org/apache/isis/applib/events/InteractionEvent.java
index dba1bb8..7b2b4c5 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/events/InteractionEvent.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/events/InteractionEvent.java
@@ -123,7 +123,7 @@ public abstract class InteractionEvent extends EventObject {
      * otherwise disallowed.
      * 
      * <p>
-     * Intended to be {@link #setReason(String) set} as a result of consulting
+     * Intended to be {@link #setExecuteIn(String) set} as a result of consulting
      * one of the facets.
      * 
      * @return

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/audit/AuditingService3.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/audit/AuditingService3.java b/core/applib/src/main/java/org/apache/isis/applib/services/audit/AuditingService3.java
index 9426573..2378815 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/audit/AuditingService3.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/audit/AuditingService3.java
@@ -31,15 +31,21 @@ public interface AuditingService3 {
     
     @Programmatic
     public void audit(
-            final UUID transactionId, final Bookmark target, final String propertyId, 
+            final UUID transactionId, String targetClassName, final Bookmark target, 
+            String memberIdentifier, final String propertyName, 
             final String preValue, final String postValue, 
             final String user, final java.sql.Timestamp timestamp);
     
+    
     public static class Stderr implements AuditingService3 {
 
         @Override
-        public void audit(UUID transactionId, Bookmark target, String propertyId, String preValue, String postValue, String user, Timestamp timestamp) {
-            String auditMessage = target.toString() + " by " + user + ", " + propertyId +": " + preValue + " -> " + postValue;
+        public void audit(
+                final UUID transactionId, final String targetClassName, final Bookmark target, 
+                final String memberId, final String propertyName, 
+                final String preValue, final String postValue, 
+                final String user, final Timestamp timestamp) {
+            String auditMessage = target.toString() + " by " + user + ", " + propertyName +": " + preValue + " -> " + postValue;
             System.err.println(auditMessage);
         }
     }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/background/ActionInvocationMemento.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/background/ActionInvocationMemento.java b/core/applib/src/main/java/org/apache/isis/applib/services/background/ActionInvocationMemento.java
index 333362f..8b9e983 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/background/ActionInvocationMemento.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/background/ActionInvocationMemento.java
@@ -31,8 +31,8 @@ import org.apache.isis.applib.services.memento.MementoService.Memento;
  * 
  * <p>
  * Provided as a mechanism by which implementations of {@link BackgroundService} can 
- * hand-off work to the {@link BackgroundActionService} through 
- * {@link BackgroundActionService#execute(ActionInvocationMemento)}.   This is used by the
+ * hand-off work to the {@link BackgroundCommandService} through 
+ * {@link BackgroundCommandService#execute(ActionInvocationMemento)}.   This is used by the
  * default implementation of <tt>BackgroundServiceDefault</tt> in Isis' core-runtime.
  * 
  * <p>

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundActionService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundActionService.java b/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundActionService.java
deleted file mode 100644
index eda85d7..0000000
--- a/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundActionService.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.applib.services.background;
-
-import org.apache.isis.applib.services.command.Command;
-
-
-/**
- * Execute a {@link ActionInvocationMemento memento-ized} action as a
- * decoupled task.
- * 
- * <p>
- * Separate from {@link BackgroundService} primarily so that the default
- * implementation, <tt>BackgroundServiceDefault</tt> (in core-runtime) can
- * delegate to different implementations of this service.
- */
-public interface BackgroundActionService {
-
-    void schedule(
-            final ActionInvocationMemento aim, 
-            final Command command, 
-            final String targetClassName, final String targetActionName, final String targetArgs);
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundCommandService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundCommandService.java b/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundCommandService.java
new file mode 100644
index 0000000..02d434f
--- /dev/null
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/background/BackgroundCommandService.java
@@ -0,0 +1,37 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.applib.services.background;
+
+import org.apache.isis.applib.services.command.Command;
+
+
+/**
+ * Execute a {@link ActionInvocationMemento memento-ized} action as a
+ * decoupled task.
+ * 
+ * <p>
+ * Separate from {@link BackgroundService} primarily so that the default
+ * implementation, <tt>BackgroundServiceDefault</tt> (in core-runtime) can
+ * delegate to different implementations of this service.
+ */
+public interface BackgroundCommandService {
+
+    void schedule(
+            final ActionInvocationMemento aim, 
+            final Command command, 
+            final String targetClassName, final String targetActionName, final String targetArgs);
+}


[2/3] ISIS-667,ISIS-684,ISIS-685: async commands, tidy-up

Posted by da...@apache.org.
http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java b/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
index dab341d..fbdebba 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/command/Command.java
@@ -19,13 +19,15 @@ package org.apache.isis.applib.services.command;
 import java.sql.Timestamp;
 
 import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.applib.annotation.Disabled;
 import org.apache.isis.applib.annotation.HomePage;
 import org.apache.isis.applib.annotation.Optional;
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.services.HasTransactionId;
-import org.apache.isis.applib.services.background.BackgroundActionService;
+import org.apache.isis.applib.services.background.BackgroundCommandService;
 import org.apache.isis.applib.services.background.BackgroundService;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
@@ -35,6 +37,8 @@ public interface Command extends HasTransactionId {
 
     
     // //////////////////////////////////////
+    // user (property)
+    // //////////////////////////////////////
 
     /**
      * The user that initiated the action.
@@ -50,6 +54,8 @@ public interface Command extends HasTransactionId {
     public abstract void setUser(String user);
 
     // //////////////////////////////////////
+    // timestamp (property)
+    // //////////////////////////////////////
 
     /**
      * The date/time at which this action was created.
@@ -66,6 +72,8 @@ public interface Command extends HasTransactionId {
     
     
     // //////////////////////////////////////
+    // target (property)
+    // //////////////////////////////////////
 
     
     /**
@@ -84,6 +92,9 @@ public interface Command extends HasTransactionId {
      */
     public abstract void setTarget(Bookmark target);
     
+    
+    // //////////////////////////////////////
+    // memberIdentifier (property)
     // //////////////////////////////////////
 
     /**
@@ -91,10 +102,12 @@ public interface Command extends HasTransactionId {
      * {@link Identifier#toClassAndNameIdentityString()}.
      * 
      * <p>
-     * Returns <tt>null</tt> otherwise.
+     * This property is called 'memberIdentifier' rather than 'actionIdentifier' for
+     * consistency with other services (such as auditing and publishing) that may act on
+     * properties rather than simply just actions.
      */
     @Disabled
-    public abstract String getActionIdentifier();
+    public abstract String getMemberIdentifier();
 
     /**
      * <b>NOT API</b>: intended to be called only by the framework.
@@ -102,9 +115,11 @@ public interface Command extends HasTransactionId {
      * <p>
      * Implementation notes: set when the action is invoked (in the <tt>ActionInvocationFacet</tt>).
      */
-    public abstract void setActionIdentifier(String actionIdentifier);
+    public abstract void setMemberIdentifier(String actionIdentifier);
     
     // //////////////////////////////////////
+    // targetClass (property)
+    // //////////////////////////////////////
 
     /**
      * A human-friendly description of the class of the target object.
@@ -121,6 +136,8 @@ public interface Command extends HasTransactionId {
     public abstract void setTargetClass(String targetClass);
 
     // //////////////////////////////////////
+    // targetAction (property)
+    // //////////////////////////////////////
     
     /**
      * The human-friendly name of the action invoked on the target object.
@@ -137,6 +154,8 @@ public interface Command extends HasTransactionId {
     public abstract void setTargetAction(String targetAction);
     
     // //////////////////////////////////////
+    // arguments (property)
+    // //////////////////////////////////////
     
     /**
      * A human-friendly description of the arguments with which the action was invoked.
@@ -154,6 +173,8 @@ public interface Command extends HasTransactionId {
 
     
     // //////////////////////////////////////
+    // memento (property)
+    // //////////////////////////////////////
 
     /**
      * A formal (XML or similar) specification of the action to invoke/being invoked.
@@ -169,56 +190,89 @@ public interface Command extends HasTransactionId {
      */
     public void setMemento(final String memento);
 
+
+    // //////////////////////////////////////
+    // executeIn (property)
     // //////////////////////////////////////
     
-    public static enum Nature {
+    /**
+     * The mechanism by which this command is to be executed, either synchronously &quot;in the 
+     * {@link ExecuteIn#FOREGROUND foreground}&quot; or is to be executed asynchronously &quot;in the 
+     * {@link ExecuteIn#BACKGROUND background}&quot; through the {@link BackgroundCommandService}.
+     */
+    @Disabled
+    public ExecuteIn getExecuteIn();
+    
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setExecuteIn(final ExecuteIn executeIn);
+
+    
+
+    
+    // //////////////////////////////////////
+    // executor (property)
+    // //////////////////////////////////////
+    
+    
+    public static enum Executor {
         /**
-         * Action has occurred as the result of an explicit action invocation
-         * on the part of the user.
+         * Command being executed by the end-user.
          */
-        USER_INITIATED,
+        USER,
         /**
-         * Action is run by virtue of being previously scheduled as a background through
-         * the {@link BackgroundService} and {@link BackgroundTaskService}.
+         * Command being executed by a background execution service.
          */
         BACKGROUND,
         /**
-         * Indicates that the action has been run for some other reason.
+         * Command being executed for some other reason, eg as result of redirect-after-post, or the homePage action.
          */
         OTHER
     }
 
     /**
-     * The nature of this action, for example whether it was
-     * {@link #USER_INITIATED user initiated} on the part of the user, or merely as
-     * a {@link #OTHER other} (typically indirect) side-effect, eg the re-rendering of an entity in a viewer (such as the
-     * Wicket viewer) that uses the <a href="http://en.wikipedia.org/wiki/Post/Redirect/Get">post/redirect/get</a>
-     * to avoid duplicate submissions, or the action nominated as the {@link HomePage} action.
+     * The (current) executor of this command.
+     * 
+     * <p>
+     * Note that (even for implementations of {@link BackgroundCommandService} that persist {@link Command}s), this
+     * property is never (likely to be) persisted, because it is always updated to indicate how the command is
+     * currently being executed.
      * 
      * <p>
-     * The Isis implementations uses this field as to a hint as to whether to populate the interaction's
-     * {@link Command#setActionIdentifier(String) action identifier} and related properties.  The expectation 
-     * is that implementations of {@link CommandService} will only persist interactions that were explicitly started
-     * by the user.
+     * If the {@link #getExecutor() executor} matches the required {@link #getExecuteIn() execution policy}, then the
+     * command actually is executed.  The combinations are:
+     * <ul>
+     * <li>executor = USER, executeIn = FOREGROUND, then execute</li>
+     * <li>executor = USER, executeIn = BACKGROUND, then persist and return persisted command as a placeholder for the result</li>
+     * <li>executor = BACKGROUND, executeIn = FOREGROUND, then ignore</li>
+     * <li>executor = BACKGROUND, executeIn = BACKGROUND, then execute, update the command with result</li>
+     * </ul>
+     * 
      */
     @Disabled
-    public Nature getNature();
+    public Executor getExecutor();
+
     
     /**
      * <b>NOT API</b>: intended to be called only by the framework.
      */
-    public void setNature(final Nature nature);
-
+    public void setExecutor(final Executor executor);
     
+    
+
+
+    // //////////////////////////////////////
+    // startedAt (property)
     // //////////////////////////////////////
 
     /**
-     * The date/time at which this action started.
+     * The date/time at  which this action started.
      * 
      * <p>
-     * For {@link Nature#USER_INITIATED user-initiated} actions, this will always be
+     * For {@link ExecuteIn#FOREGROUND user-initiated} actions, this will always be
      * populated and have the same value as the {@link #getTimestamp() timestamp}; for
-     * {@link Nature#BACKGROUND background} actions, this will be populated only when the
+     * {@link ExecuteIn#BACKGROUND background} actions, this will be populated only when the
      * action is executed by a background execution process.
      */
     @Disabled
@@ -234,6 +288,8 @@ public interface Command extends HasTransactionId {
     
     
     // //////////////////////////////////////
+    // completedAt (property)
+    // //////////////////////////////////////
 
     
     /**
@@ -252,10 +308,12 @@ public interface Command extends HasTransactionId {
 
 
     // //////////////////////////////////////
+    // parent (property)
+    // //////////////////////////////////////
 
 
     /**
-     * For actions created through the {@link BackgroundService} and {@link BackgroundActionService},
+     * For actions created through the {@link BackgroundService} and {@link BackgroundCommandService},
      * captures the parent action.
      */
     @Optional
@@ -269,6 +327,8 @@ public interface Command extends HasTransactionId {
 
     
     // //////////////////////////////////////
+    // exception (property)
+    // //////////////////////////////////////
 
     @Disabled
     @Optional
@@ -280,6 +340,8 @@ public interface Command extends HasTransactionId {
     public void setException(String stackTrace);
     
     // //////////////////////////////////////
+    // result (property)
+    // //////////////////////////////////////
 
     
     /**
@@ -304,27 +366,66 @@ public interface Command extends HasTransactionId {
 
     
     // //////////////////////////////////////
-
+    // persistence (programmatic)
+    // //////////////////////////////////////
     
     /**
-     * Hint that this {@link Command} should be persisted.
+     * Whether this command should ultimately be persisted (if the configured {@link BackgroundCommandService} supports
+     * it) or not.
      * 
      * <p>
-     * This is most commonly done if the action being invoked has been explicitly annotated to be reified, eg
-     * using the {@link Command} annotation.  But it might also happen as a hint from another domain service.
-     * For example, a {@link BackgroundActionService} implementations that creates persisted background tasks ought to be
-     * associated (via the {@link Command#getTransactionId() transactionId}) to a persisted
-     * {@link Command}.  The app can then provide a mechanism for the end-user to query for their
-     * running background actions from this original {@link Command}.
+     * If the action being executed has been annotated with the {@link org.apache.isis.applib.annotation.Command} 
+     * annotation, then (unless its {@link org.apache.isis.applib.annotation.Command#persistence() persistence} 
+     * attribute has been set to a different value than its default of {@link Persistence#PERSISTED}), the 
+     * {@link Command} object will be persisted.
+     * 
+     * <p>
+     * However, it is possible to prevent the {@link Command} object from ever being persisted by setting the
+     * {@link org.apache.isis.applib.annotation.Command#persistence() persistence} attribute to 
+     * {@link Persistence#NOT_PERSISTED}, or it can be set to {@link Persistence#IF_HINTED}, meaning it is dependent
+     * on whether {@link #setPersistHint(boolean) a hint has been set} by some other means.  
+     *
+     * <p>
+     * For example, a {@link BackgroundCommandService} implementation that creates persisted background commands ought 
+     * associate them (via its {@link Command#getParent() parent}) to an original persisted
+     * {@link Command}.  The hinting mechanism allows the service to suggest that the parent command be persisted so
+     * that the app can then provide a mechanism to find all child background commands for that original parent command.
+     */
+    @Disabled
+    public Persistence getPersistence();
+    
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    public void setPersistence(final Persistence persistence);
+    
+
+    // //////////////////////////////////////
+    // persistHint (programmatic)
+    // //////////////////////////////////////
+
+    
+    /**
+     * Whether that this {@link Command} should be persisted, if possible.
+     */
+    @Programmatic
+    public boolean isPersistHint();
+    
+    /**
+     * Hint that this {@link Command} should be persisted, if possible.
      * 
      * <p>
      * <b>NOT API</b>: intended to be called only by the framework.  
+     * 
+     * @see #getPersistence()
      */
     @Programmatic
     public void setPersistHint(boolean persistHint);
     
     // //////////////////////////////////////
-    
+    // next (programmatic)
+    // //////////////////////////////////////
+
     /**
      * Generates numbers in a named sequence
      * 

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/command/CommandDefault.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/command/CommandDefault.java b/core/applib/src/main/java/org/apache/isis/applib/services/command/CommandDefault.java
index 58cb3ac..43f3cc3 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/command/CommandDefault.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/command/CommandDefault.java
@@ -23,7 +23,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import com.google.common.collect.Maps;
 
-import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.command.spi.CommandService;
 import org.apache.isis.applib.util.ObjectContracts;
@@ -31,7 +32,7 @@ import org.apache.isis.applib.util.ObjectContracts;
 public class CommandDefault implements Command {
 
     public CommandDefault() {
-        setNature(Command.Nature.OTHER);
+        setExecutor(Executor.OTHER);
     }
     
     // //////////////////////////////////////
@@ -39,11 +40,11 @@ public class CommandDefault implements Command {
     // //////////////////////////////////////
 
     private String actionIdentifier;
-    public String getActionIdentifier() {
+    public String getMemberIdentifier() {
         return actionIdentifier;
     }
     @Override
-    public void setActionIdentifier(String actionIdentifier) {
+    public void setMemberIdentifier(String actionIdentifier) {
         this.actionIdentifier = actionIdentifier;
     }
 
@@ -181,27 +182,42 @@ public class CommandDefault implements Command {
         this.user = user;
     }
 
+    // //////////////////////////////////////
+    // executor (property)
+    // //////////////////////////////////////
+
+    private Executor executor;
+    
+    @Override
+    public Executor getExecutor() {
+        return executor;
+    }
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     */
+    @Override
+    public void setExecutor(Executor nature) {
+        this.executor = nature;
+    }
 
     // //////////////////////////////////////
-    // nature (property)
+    // executionType (property)
     // //////////////////////////////////////
 
-    private Nature nature;
+    private ExecuteIn executionType;
 
     @Override
-    public Nature getNature() {
-        return nature;
+    public ExecuteIn getExecuteIn() {
+        return executionType;
     }
 
     /**
      * <b>NOT API</b>: intended to be called only by the framework.
-     * 
-     * <p>
-     * Implementation notes: populated by the viewer as hint to {@link CommandService} implementation.
      */
     @Override
-    public void setNature(Nature nature) {
-        this.nature = nature;
+    public void setExecuteIn(ExecuteIn executionType) {
+        this.executionType = executionType;
     }
 
     
@@ -254,13 +270,7 @@ public class CommandDefault implements Command {
     }
     
     // //////////////////////////////////////
-
-    @Override
-    public String toString() {
-        return ObjectContracts.toString(this, "startedAt,user,actionIdentifier,target,guid");
-    }
-    
-    
+    // transactionId (property)
     // //////////////////////////////////////
     
     private UUID transactionId;
@@ -274,8 +284,42 @@ public class CommandDefault implements Command {
         this.transactionId = transactionId;
     }
     
+
     
     // //////////////////////////////////////
+    // persistence
+    // //////////////////////////////////////
+
+    private Persistence persistence;
+    
+    @Override
+    public Persistence getPersistence() {
+        return persistence;
+    }
+    
+    @Override
+    public void setPersistence(Persistence persistence) {
+        this.persistence = persistence; 
+    }
+
+    // //////////////////////////////////////
+    // persistHint
+    // //////////////////////////////////////
+    
+    private boolean persistHint;
+    
+    public boolean isPersistHint() {
+        return persistHint;
+    }
+    
+    public void setPersistHint(boolean persistHint) {
+        this.persistHint = persistHint;
+    }
+
+
+    // //////////////////////////////////////
+    // next
+    // //////////////////////////////////////
 
     private final Map<String, AtomicInteger> sequenceByName = Maps.newHashMap();
 
@@ -292,17 +336,16 @@ public class CommandDefault implements Command {
     }
 
     
+
     // //////////////////////////////////////
-    
-    private boolean persistHint;
-    
-    public boolean isPersistHint() {
-        return persistHint;
-    }
-    
-    public void setPersistHint(boolean persistHint) {
-        this.persistHint = persistHint;
+    // toString
+    // //////////////////////////////////////
+
+    @Override
+    public String toString() {
+        return ObjectContracts.toString(this, "startedAt,user,actionIdentifier,target,guid");
     }
     
     
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java b/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
index 28f6345..f671b49 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/command/spi/CommandService.java
@@ -49,7 +49,22 @@ public interface CommandService {
     @Programmatic
     void startTransaction(final Command command, final UUID transactionId);
     
+    /**
+     * &quot;Complete&quot; the command, typically meaning to indicate that the command is completed, and to 
+     * persist it if its {@link Command#getPersistence()} and {@link Command#isPersistHint() persistence hint} 
+     * indicate that it should be.
+     * 
+     * <p>
+     * However, not every implementation necessarily {@link #persistIfPossible(Command) supports persistence}.
+     */
     @Programmatic
     void complete(final Command command);
+
+    /**
+     * Hint for this implementation to eagerly persist the {@link Command}s if possible; influences the behaviour 
+     * of actions annotated to execute in the {@link org.apache.isis.applib.annotation.Command.ExecuteIn#BACKGROUND}.
+     */
+    @Programmatic
+    boolean persistIfPossible(Command command);
     
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/applib/src/main/java/org/apache/isis/applib/services/publish/EventMetadata.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/publish/EventMetadata.java b/core/applib/src/main/java/org/apache/isis/applib/services/publish/EventMetadata.java
index 1272574..0e8e673 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/publish/EventMetadata.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/publish/EventMetadata.java
@@ -22,6 +22,9 @@ package org.apache.isis.applib.services.publish;
 import java.sql.Timestamp;
 import java.util.UUID;
 
+import org.apache.isis.applib.Identifier;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+
 /**
  * Standard metadata about an event to be published.
  * 
@@ -38,9 +41,13 @@ public class EventMetadata {
     private final java.sql.Timestamp javaSqlTimestamp;
     private final String title;
     private final EventType eventType;
+    private final String targetClass;
+    private final String targetAction;
+    private final Bookmark target;
+    private final String actionIdentifier;
     
     /**
-     * @deprecated - use {@link #EventMetadata(UUID, int, EventType, String, Timestamp, String)}
+     * @deprecated - no longer called by the framework.
      */
     @Deprecated
     public EventMetadata(
@@ -50,7 +57,7 @@ public class EventMetadata {
             final String user, 
             final long timestamp, 
             final String title) {
-        this(transactionId, sequence, eventType, user, new java.sql.Timestamp(timestamp), title);
+        this(transactionId, sequence, eventType, user, new java.sql.Timestamp(timestamp), title, null, null, null, null);
     }
     
     public EventMetadata(
@@ -59,13 +66,21 @@ public class EventMetadata {
             final EventType eventType, 
             final String user, 
             final java.sql.Timestamp javaSqlTimestamp, 
-            final String title) {
+            final String title, 
+            final String targetClass, 
+            final String targetAction, 
+            final Bookmark target, 
+            final String actionIdentifier) {
         this.transactionId = transactionId;
         this.sequence = sequence;
         this.user = user;
         this.javaSqlTimestamp = javaSqlTimestamp;
         this.title = title;
         this.eventType = eventType;
+        this.targetClass = targetClass;
+        this.targetAction = targetAction;
+        this.target = target;
+        this.actionIdentifier = actionIdentifier;
     }
     
     /**
@@ -120,7 +135,8 @@ public class EventMetadata {
     }
     
     /**
-     * A user-friendly title for this event.
+     * A title for this event, consisting of the oidStr and (for {@link EventType#ACTION_INVOCATION}) also an
+     * identifier of the action.
      */
     public String getTitle() {
         return title;
@@ -129,6 +145,37 @@ public class EventMetadata {
     public EventType getEventType() {
         return eventType;
     }
+
+    /**
+     * User-friendly class name.
+     */
+    public String getTargetClass() {
+        return targetClass;
+    }
+    
+    public Bookmark getTarget() {
+        return target;
+    }
+
+    /**
+     * User-friendly action name (populated only for {@link EventType#ACTION_INVOCATION}s).
+     */
+    public String getTargetAction() {
+        return targetAction;
+    }
+    
+    /**
+     * Formal action identifier, corresponding to {@link Identifier#toClassAndNameIdentityString()}).
+     * 
+     * <p>
+     * Populated only  for for {@link EventType#ACTION_INVOCATION}s.
+     */
+    public String getActionIdentifier() {
+        return actionIdentifier;
+    }
+
+    // //////////////////////////////////////
+
     
     @Override
     public String toString() {

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
index 6b49280..e7b52e2 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/command/CommandFacet.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.metamodel.facets.actions.command;
 
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 
@@ -32,4 +34,7 @@ import org.apache.isis.core.metamodel.facetapi.Facet;
  */
 public interface CommandFacet extends Facet {
 
+    public Persistence persistence();
+    
+    public ExecuteIn executeIn();
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/invoke/ActionInvocationFacet.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/invoke/ActionInvocationFacet.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/invoke/ActionInvocationFacet.java
index b4e9dd6..b188611 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/invoke/ActionInvocationFacet.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/invoke/ActionInvocationFacet.java
@@ -21,11 +21,9 @@ package org.apache.isis.core.metamodel.facets.actions.invoke;
 
 import java.util.Arrays;
 import java.util.List;
-import java.util.UUID;
 
-import org.apache.isis.applib.services.HasTransactionId;
+import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.applib.services.command.spi.CommandService;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
@@ -52,6 +50,9 @@ public interface ActionInvocationFacet extends Facet {
     public ObjectSpecification getOnType();
 
     public static class CurrentInvocation {
+
+        private final Command command;
+        
         private final ObjectAdapter target;
         private final IdentifiedHolder action;
         private final List<ObjectAdapter> parameters;
@@ -59,32 +60,52 @@ public interface ActionInvocationFacet extends Facet {
 
         public CurrentInvocation(
                 final ObjectAdapter target, final IdentifiedHolder action, final ObjectAdapter[] parameters, 
-                final ObjectAdapter result) {
-            this(target, action, Arrays.asList(parameters), result);
+                final ObjectAdapter result, 
+                final Command command) {
+            this(target, action, Arrays.asList(parameters), result, command);
         }
 
         public CurrentInvocation(
                 final ObjectAdapter target, final IdentifiedHolder action, final List<ObjectAdapter> parameters, 
-                final ObjectAdapter result) {
+                final ObjectAdapter result, 
+                final Command command) {
             this.target = target;
             this.action = action;
             this.parameters = parameters;
             this.result = result;
+            this.command = command;
         }
-        
+
+        /**
+         * deprecated since part of {@link #getCommand()}
+         */
+        @Deprecated
         public ObjectAdapter getTarget() {
             return target;
         }
+        /**
+         * deprecated since part of {@link #getCommand()}
+         */
+        @Deprecated
         public IdentifiedHolder getAction() {
             return action;
         }
+
         public List<ObjectAdapter> getParameters() {
             return parameters;
         }
         
+        /**
+         * deprecated since part of {@link #getCommand()}
+         */
+        @Deprecated
         public ObjectAdapter getResult() {
             return result;
         }
+        
+        public Command getCommand() {
+            return command;
+        }
     }
     
     /**

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/CommandFacetAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/CommandFacetAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/CommandFacetAbstract.java
index f3c6666..2d72e1d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/CommandFacetAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/CommandFacetAbstract.java
@@ -19,6 +19,8 @@
 
 package org.apache.isis.core.progmodel.facets.actions.command;
 
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.core.metamodel.facetapi.Facet;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.MarkerFacetAbstract;
@@ -30,8 +32,24 @@ public abstract class CommandFacetAbstract extends MarkerFacetAbstract implement
         return CommandFacet.class;
     }
 
-    public CommandFacetAbstract(final FacetHolder holder) {
+    private final Persistence persistence;
+    private final ExecuteIn executeIn;
+
+    public CommandFacetAbstract(
+            final Persistence persistence, final ExecuteIn executeIn, final FacetHolder holder) {
         super(type(), holder);
+        this.persistence = persistence;
+        this.executeIn = executeIn;
+    }
+
+    @Override
+    public Persistence persistence() {
+        return this.persistence;
+    }
+
+    @Override
+    public ExecuteIn executeIn() {
+        return executeIn;
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandAnnotationFacetFactory.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandAnnotationFacetFactory.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandAnnotationFacetFactory.java
index ca4b4be..f626421 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandAnnotationFacetFactory.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandAnnotationFacetFactory.java
@@ -45,7 +45,9 @@ public class CommandAnnotationFacetFactory extends FacetFactoryAbstract {
     }
 
     private CommandFacet create(final Command annotation, final FacetHolder holder) {
-        return annotation == null ? null : new CommandFacetAnnotation(holder);
+        return annotation == null 
+                ? null 
+                : new CommandFacetAnnotation(annotation.persistence(), annotation.executeIn(), holder);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandFacetAnnotation.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandFacetAnnotation.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandFacetAnnotation.java
index f2c47ad..812e62d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandFacetAnnotation.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/command/annotation/CommandFacetAnnotation.java
@@ -19,13 +19,19 @@
 
 package org.apache.isis.core.progmodel.facets.actions.command.annotation;
 
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.progmodel.facets.actions.command.CommandFacetAbstract;
 
 public class CommandFacetAnnotation extends CommandFacetAbstract {
 
-    public CommandFacetAnnotation(final FacetHolder holder) {
-        super(holder);
+    public CommandFacetAnnotation(
+            final Persistence persistence, 
+            final ExecuteIn executeIn,
+            final FacetHolder holder) {
+        super(persistence, executeIn, holder);
     }
 
+
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/invoke/ActionInvocationFacetViaMethod.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/invoke/ActionInvocationFacetViaMethod.java b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/invoke/ActionInvocationFacetViaMethod.java
index d1f729e..cf583b6 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/invoke/ActionInvocationFacetViaMethod.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/progmodel/facets/actions/invoke/ActionInvocationFacetViaMethod.java
@@ -19,14 +19,11 @@
 
 package org.apache.isis.core.progmodel.facets.actions.invoke;
 
-import java.awt.Desktop.Action;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.Collections;
 import java.util.List;
 
-import com.google.common.collect.Lists;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -34,19 +31,20 @@ import org.apache.isis.applib.NonRecoverableException;
 import org.apache.isis.applib.RecoverableException;
 import org.apache.isis.applib.annotation.Bulk;
 import org.apache.isis.applib.annotation.Bulk.InteractionContext.InvokedAs;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
+import org.apache.isis.applib.annotation.Command.Persistence;
+import org.apache.isis.applib.clock.Clock;
 import org.apache.isis.applib.services.background.ActionInvocationMemento;
 import org.apache.isis.applib.services.background.BackgroundService;
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.Command.Executor;
 import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.applib.services.memento.MementoService;
+import org.apache.isis.applib.services.command.spi.CommandService;
 import org.apache.isis.core.commons.exceptions.IsisException;
 import org.apache.isis.core.commons.lang.ThrowableExtensions;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
-import org.apache.isis.core.metamodel.adapter.oid.Oid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
 import org.apache.isis.core.metamodel.facetapi.FacetHolder;
 import org.apache.isis.core.metamodel.facets.ImperativeFacet;
 import org.apache.isis.core.metamodel.facets.actions.command.CommandFacet;
@@ -68,7 +66,6 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
     private final static Logger LOG = LoggerFactory.getLogger(ActionInvocationFacetViaMethod.class);
 
     private final Method method;
-    private final int paramCount;
     private final ObjectSpecification onType;
     private final ObjectSpecification returnType;
 
@@ -86,7 +83,6 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
             final ServicesInjector servicesInjector) {
         super(holder);
         this.method = method;
-        this.paramCount = method.getParameterTypes().length;
         this.onType = onType;
         this.returnType = returnType;
         this.runtimeContext = runtimeContext;
@@ -119,15 +115,15 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
     }
 
     @Override
-    public ObjectAdapter invoke(ObjectAction owningAction, ObjectAdapter targetAdapter, ObjectAdapter[] arguments) {
-        if (arguments.length != paramCount) {
-            LOG.error(method + " requires " + paramCount + " parameters, not " + arguments.length);
-        }
+    public ObjectAdapter invoke(
+            final ObjectAction owningAction, 
+            final ObjectAdapter targetAdapter, 
+            final ObjectAdapter[] arguments) {
 
         final Bulk.InteractionContext bulkInteractionContext = getServicesInjector().lookupService(Bulk.InteractionContext.class);
         final CommandContext commandContext = getServicesInjector().lookupService(CommandContext.class);
         final Command command = commandContext != null ? commandContext.getCommand() : null;
-        
+
         try {
             final Object[] executionParameters = new Object[arguments.length];
             for (int i = 0; i < arguments.length; i++) {
@@ -145,11 +141,9 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
                 bulkInteractionContext.setDomainObjects(Collections.singletonList(object));
             }
 
+            if(command != null && command.getExecutor() == Executor.USER && owningAction != null) {
 
-            if(command != null && command.getNature() == Command.Nature.USER_INITIATED && owningAction != null) {
-
-                command.setStartedAt(command.getTimestamp());
-                command.setActionIdentifier(CommandUtil.actionIdentifierFor(owningAction));
+                command.setMemberIdentifier(CommandUtil.actionIdentifierFor(owningAction));
                 command.setTargetClass(CommandUtil.targetClassNameFor(targetAdapter));
                 command.setTargetAction(CommandUtil.targetActionNameFor(owningAction));
                 command.setArguments(CommandUtil.argDescriptionFor(owningAction, arguments));
@@ -157,7 +151,7 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
                 final Bookmark targetBookmark = CommandUtil.bookmarkFor(targetAdapter);
                 command.setTarget(targetBookmark);
                 
-                
+                // the background service is used here merely as a means to capture an invocation memento
                 final BackgroundService backgroundService = getServicesInjector().lookupService(BackgroundService.class);
                 if(backgroundService != null) {
                     final Object targetObject = unwrap(targetAdapter);
@@ -167,44 +161,79 @@ public class ActionInvocationFacetViaMethod extends ActionInvocationFacetAbstrac
                     if(aim != null) {
                         command.setMemento(aim.asMementoString());
                     } else {
-                        throw new IsisException("Unable to build memento for action " + owningAction.getIdentifier().toClassAndNameIdentityString());
+                        throw new IsisException(
+                            "Unable to build memento for action " + 
+                            owningAction.getIdentifier().toClassAndNameIdentityString());
                     }
                 }
 
-                final boolean hasCommandFacet = getFacetHolder().containsDoOpFacet(CommandFacet.class);
-                command.setPersistHint(hasCommandFacet);
+                // copy over the command execution 'context' (if available)
+                final CommandFacet commandFacet = getFacetHolder().getFacet(CommandFacet.class);
+                if(commandFacet != null) {
+                    command.setExecuteIn(commandFacet.executeIn());
+                    command.setPersistence(commandFacet.persistence());
+                } else {
+                    // if no facet, assume do want to execute right now, but only persist (eventually) if hinted.
+                    command.setExecuteIn(ExecuteIn.FOREGROUND);
+                    command.setPersistence(Persistence.IF_HINTED);
+                }
             }
             
-            final Object result = method.invoke(object, executionParameters);
+            
+            if( command != null && 
+                command.getExecutor() == Executor.USER && 
+                command.getExecuteIn() == ExecuteIn.BACKGROUND) {
+                
+                // persist command so can be this command can be in the 'background'
+                final CommandService commandService = getServicesInjector().lookupService(CommandService.class);
+                if(commandService.persistIfPossible(command)) {
+                    // force persistence, then return the command itself.
+                    final ObjectAdapter resultAdapter = getAdapterManager().adapterFor(command);
+                    return resultAdapter;
+                } else {
+                    throw new IsisException(
+                            "Unable to schedule action '"
+                            + owningAction.getIdentifier().toClassAndNameIdentityString() + "' to run in background: "
+                            + "CommandService does not support persistent commands " );
+                }
+            } else {
+                
+                // otherwise, go ahead and execute action in the 'foreground'
 
-            if (LOG.isDebugEnabled()) {
-                LOG.debug(" action result " + result);
-            }
-            if (result == null) {
-                return null;
-            }
+                if(command != null) {
+                    command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
+                }
+                
+                final Object result = method.invoke(object, executionParameters);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug(" action result " + result);
+                }
+                if (result == null) {
+                    return null;
+                }
 
-            final ObjectAdapter resultAdapter = getAdapterManager().adapterFor(result);
+                final ObjectAdapter resultAdapter = getAdapterManager().adapterFor(result);
 
-            // copy over TypeOfFacet if required
-            final TypeOfFacet typeOfFacet = getFacetHolder().getFacet(TypeOfFacet.class);
-            resultAdapter.setElementSpecificationProvider(ElementSpecificationProviderFromTypeOfFacet.createFrom(typeOfFacet));
+                // copy over TypeOfFacet if required
+                final TypeOfFacet typeOfFacet = getFacetHolder().getFacet(TypeOfFacet.class);
+                resultAdapter.setElementSpecificationProvider(ElementSpecificationProviderFromTypeOfFacet.createFrom(typeOfFacet));
 
-            
-            if(command != null) {
-                if(!resultAdapter.getSpecification().containsDoOpFacet(ViewModelFacet.class)) {
-                    final Bookmark bookmark = CommandUtil.bookmarkFor(resultAdapter);
-                    command.setResult(bookmark);
+                if(command != null) {
+                    if(!resultAdapter.getSpecification().containsDoOpFacet(ViewModelFacet.class)) {
+                        final Bookmark bookmark = CommandUtil.bookmarkFor(resultAdapter);
+                        command.setResult(bookmark);
+                    }
                 }
+                
+                final PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
+                ActionInvocationFacet.currentInvocation.set(
+                        publishedActionFacet != null
+                            ? new CurrentInvocation(targetAdapter, getIdentified(), arguments, resultAdapter, command)
+                            :null);
+                
+                return resultAdapter;
             }
-            
-            PublishedActionFacet publishedActionFacet = getIdentified().getFacet(PublishedActionFacet.class);
-            ActionInvocationFacet.currentInvocation.set(
-                    publishedActionFacet != null
-                        ? new CurrentInvocation(targetAdapter, getIdentified(), arguments, resultAdapter)
-                        :null);
-            
-            return resultAdapter;
 
         } catch (final IllegalArgumentException e) {
             throw e;

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundActionExecution.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundActionExecution.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundActionExecution.java
deleted file mode 100644
index b9cc7b7..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundActionExecution.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package org.apache.isis.core.runtime.services.background;
-
-import java.util.List;
-
-import com.google.common.base.Throwables;
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.clock.Clock;
-import org.apache.isis.applib.services.background.ActionInvocationMemento;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService;
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.applib.services.command.CommandContext;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.adapter.oid.RootOid;
-import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
-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.progmodel.facets.actions.invoke.CommandUtil;
-import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
-import org.apache.isis.core.runtime.sessiontemplate.AbstractIsisSessionTemplate;
-
-/**
- * Intended to be used as a base class for executing queued up {@link Command background action}s.
- * 
- * <p>
- * This implementation uses the {@link #findBackgroundActionsToExecute() hook method} so that it is
- * independent of the location where the actions have actually been persisted to.
- */
-public abstract class BackgroundActionExecution extends AbstractIsisSessionTemplate {
-
-    private final MementoServiceDefault mementoService;
-
-    public BackgroundActionExecution() {
-        // same as configured by BackgroundServiceDefault
-        mementoService = new MementoServiceDefault().withNoEncoding();
-    }
-    
-    // //////////////////////////////////////
-
-    
-    protected void doExecute(Object context) {
-        final List<? extends Command> findBackgroundActionsToExecute = findBackgroundActionsToExecute(); 
-        for (final Command backgroundAction : findBackgroundActionsToExecute) {
-            execute(backgroundAction);
-        }
-    }
-
-    /**
-     * Mandatory hook method
-     */
-    protected abstract List<? extends Command> findBackgroundActionsToExecute();
-
-    // //////////////////////////////////////
-
-    
-    private void execute(final Command backgroundAction) {
-        try {
-            commandContext.setCommand(backgroundAction);
-
-            backgroundAction.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
-            
-            final String memento = backgroundAction.getMemento();
-            final ActionInvocationMemento aim = new ActionInvocationMemento(mementoService, memento);
-            
-            final String actionId = aim.getActionId();
-   
-            final Bookmark targetBookmark = aim.getTarget();
-            final Object targetObject = bookmarkService.lookup(targetBookmark);
-            
-            final ObjectAdapter targetAdapter = adapterFor(targetObject);
-            final ObjectSpecification specification = targetAdapter.getSpecification();
-   
-            final ObjectAction objectAction = findAction(specification, actionId);
-            if(objectAction == null) {
-                throw new Exception("Unknown action '" + actionId + "'");
-            }
-            
-            final ObjectAdapter[] argAdapters = argAdaptersFor(aim);
-            final ObjectAdapter resultAdapter = objectAction.execute(targetAdapter, argAdapters);
-            if(resultAdapter != null) {
-                Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
-                backgroundAction.setResult(resultBookmark);
-            }
-
-        } catch (Exception e) {
-            backgroundAction.setException(Throwables.getStackTraceAsString(e));
-        } finally {
-            backgroundAction.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp());
-        }
-    }
-
-    private ObjectAction findAction(final ObjectSpecification specification, final String actionId) {
-        final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED);
-        for (final ObjectAction objectAction : objectActions) {
-            if(objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) {
-                return objectAction;
-            }
-        }
-        return null;
-    }
-
-    private ObjectAdapter[] argAdaptersFor(final ActionInvocationMemento aim) throws ClassNotFoundException {
-        final int numArgs = aim.getNumArgs();
-        final List<ObjectAdapter> argumentAdapters = Lists.newArrayList();
-        for(int i=0; i<numArgs; i++) {
-            final ObjectAdapter argAdapter = argAdapterFor(aim, i);
-            argumentAdapters.add(argAdapter);
-        }
-        return argumentAdapters.toArray(new ObjectAdapter[]{});
-    }
-
-    private ObjectAdapter argAdapterFor(final ActionInvocationMemento aim, int num) throws ClassNotFoundException {
-        final Class<?> argType = aim.getArgType(num);
-        final Object arg = aim.getArg(num, argType);
-        if(arg == null) {
-            return null;
-        }
-        if(Bookmark.class != argType) {
-            return adapterFor(arg);
-        } else {
-            final Bookmark argBookmark = (Bookmark)arg;
-            final RootOid rootOid = RootOidDefault.create(argBookmark);
-            return adapterFor(rootOid);
-        }
-    }
-
-    
-    // //////////////////////////////////////
-
-    @javax.inject.Inject
-    private BookmarkService bookmarkService;
-
-    @javax.inject.Inject
-    private CommandContext commandContext;
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
new file mode 100644
index 0000000..756aa86
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundCommandExecution.java
@@ -0,0 +1,155 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.core.runtime.services.background;
+
+import java.util.List;
+
+import com.google.common.base.Throwables;
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.applib.services.background.ActionInvocationMemento;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.CommandContext;
+import org.apache.isis.applib.services.command.Command.Executor;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.adapter.oid.RootOidDefault;
+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.progmodel.facets.actions.invoke.CommandUtil;
+import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
+import org.apache.isis.core.runtime.sessiontemplate.AbstractIsisSessionTemplate;
+
+/**
+ * Intended to be used as a base class for executing queued up {@link Command background action}s.
+ * 
+ * <p>
+ * This implementation uses the {@link #findBackgroundCommandsToExecute() hook method} so that it is
+ * independent of the location where the actions have actually been persisted to.
+ */
+public abstract class BackgroundCommandExecution extends AbstractIsisSessionTemplate {
+
+    private final MementoServiceDefault mementoService;
+
+    public BackgroundCommandExecution() {
+        // same as configured by BackgroundServiceDefault
+        mementoService = new MementoServiceDefault().withNoEncoding();
+    }
+    
+    // //////////////////////////////////////
+
+    
+    protected void doExecute(Object context) {
+        final List<? extends Command> commands = findBackgroundCommandsToExecute(); 
+        for (final Command command : commands) {
+            execute(command);
+        }
+    }
+
+    /**
+     * Mandatory hook method
+     */
+    protected abstract List<? extends Command> findBackgroundCommandsToExecute();
+
+    // //////////////////////////////////////
+
+    
+    private void execute(final Command command) {
+        try {
+            commandContext.setCommand(command);
+
+            command.setStartedAt(Clock.getTimeAsJavaSqlTimestamp());
+            command.setExecutor(Executor.BACKGROUND);
+            
+            final String memento = command.getMemento();
+            final ActionInvocationMemento aim = new ActionInvocationMemento(mementoService, memento);
+            
+            final String actionId = aim.getActionId();
+   
+            final Bookmark targetBookmark = aim.getTarget();
+            final Object targetObject = bookmarkService.lookup(targetBookmark);
+            
+            final ObjectAdapter targetAdapter = adapterFor(targetObject);
+            final ObjectSpecification specification = targetAdapter.getSpecification();
+   
+            final ObjectAction objectAction = findAction(specification, actionId);
+            if(objectAction == null) {
+                throw new Exception("Unknown action '" + actionId + "'");
+            }
+            
+            final ObjectAdapter[] argAdapters = argAdaptersFor(aim);
+            final ObjectAdapter resultAdapter = objectAction.execute(targetAdapter, argAdapters);
+            if(resultAdapter != null) {
+                Bookmark resultBookmark = CommandUtil.bookmarkFor(resultAdapter);
+                command.setResult(resultBookmark);
+            }
+
+        } catch (Exception e) {
+            command.setException(Throwables.getStackTraceAsString(e));
+        } finally {
+            command.setCompletedAt(Clock.getTimeAsJavaSqlTimestamp());
+        }
+    }
+
+    private ObjectAction findAction(final ObjectSpecification specification, final String actionId) {
+        final List<ObjectAction> objectActions = specification.getObjectActions(Contributed.INCLUDED);
+        for (final ObjectAction objectAction : objectActions) {
+            if(objectAction.getIdentifier().toClassAndNameIdentityString().equals(actionId)) {
+                return objectAction;
+            }
+        }
+        return null;
+    }
+
+    private ObjectAdapter[] argAdaptersFor(final ActionInvocationMemento aim) throws ClassNotFoundException {
+        final int numArgs = aim.getNumArgs();
+        final List<ObjectAdapter> argumentAdapters = Lists.newArrayList();
+        for(int i=0; i<numArgs; i++) {
+            final ObjectAdapter argAdapter = argAdapterFor(aim, i);
+            argumentAdapters.add(argAdapter);
+        }
+        return argumentAdapters.toArray(new ObjectAdapter[]{});
+    }
+
+    private ObjectAdapter argAdapterFor(final ActionInvocationMemento aim, int num) throws ClassNotFoundException {
+        final Class<?> argType = aim.getArgType(num);
+        final Object arg = aim.getArg(num, argType);
+        if(arg == null) {
+            return null;
+        }
+        if(Bookmark.class != argType) {
+            return adapterFor(arg);
+        } else {
+            final Bookmark argBookmark = (Bookmark)arg;
+            final RootOid rootOid = RootOidDefault.create(argBookmark);
+            return adapterFor(rootOid);
+        }
+    }
+
+    
+    // //////////////////////////////////////
+
+    @javax.inject.Inject
+    private BookmarkService bookmarkService;
+
+    @javax.inject.Inject
+    private CommandContext commandContext;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
index 7010778..943f009 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/background/BackgroundServiceDefault.java
@@ -35,7 +35,7 @@ import com.google.common.collect.Lists;
 
 import org.apache.isis.applib.annotation.Programmatic;
 import org.apache.isis.applib.services.background.ActionInvocationMemento;
-import org.apache.isis.applib.services.background.BackgroundActionService;
+import org.apache.isis.applib.services.background.BackgroundCommandService;
 import org.apache.isis.applib.services.background.BackgroundService;
 import org.apache.isis.applib.services.bookmark.Bookmark;
 import org.apache.isis.applib.services.bookmark.BookmarkService;
@@ -79,7 +79,7 @@ public class BackgroundServiceDefault implements BackgroundService {
     
     private void ensureDependenciesInjected() {
         Ensure.ensureThatState(this.bookmarkService, is(not(nullValue())), "BookmarkService domain service must be configured");
-        Ensure.ensureThatState(this.backgroundActionService, is(not(nullValue())), "BackgroundActionService domain service must be configured");
+        Ensure.ensureThatState(this.backgroundCommandService, is(not(nullValue())), "BackgroundCommandService domain service must be configured");
         Ensure.ensureThatState(this.commandContext, is(not(nullValue())), "CommandContext domain service must be configured");
     }
 
@@ -187,7 +187,7 @@ public class BackgroundServiceDefault implements BackgroundService {
                                 argTypes,
                                 argObjs);
                
-                backgroundActionService.schedule(aim, command, targetClassName, targetActionName, targetArgs);
+                backgroundCommandService.schedule(aim, command, targetClassName, targetActionName, targetArgs);
                 
                 return null;
             }
@@ -250,12 +250,12 @@ public class BackgroundServiceDefault implements BackgroundService {
         this.bookmarkService = bookmarkService;
     }
     
-    private BackgroundActionService backgroundActionService;
+    private BackgroundCommandService backgroundCommandService;
     /**
      * Mandatory service.
      */
-    public void injectBackgroundActionService(final BackgroundActionService backgroundActionService) {
-        this.backgroundActionService = backgroundActionService;
+    public void injectBackgroundCommandService(final BackgroundCommandService backgroundCommandService) {
+        this.backgroundCommandService = backgroundCommandService;
     }
 
     private CommandContext commandContext;

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
index 763c603..a389d7b 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/system/transaction/IsisTransaction.java
@@ -42,6 +42,7 @@ import com.google.common.collect.Sets;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.isis.applib.Identifier;
 import org.apache.isis.applib.annotation.PublishedAction;
 import org.apache.isis.applib.annotation.PublishedObject;
 import org.apache.isis.applib.annotation.PublishedObject.ChangeKind;
@@ -64,6 +65,7 @@ import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.metamodel.adapter.oid.Oid;
 import org.apache.isis.core.metamodel.adapter.oid.OidMarshaller;
 import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facetapi.IdentifiedHolder;
 import org.apache.isis.core.metamodel.facets.actions.invoke.ActionInvocationFacet;
 import org.apache.isis.core.metamodel.facets.actions.invoke.ActionInvocationFacet.CurrentInvocation;
 import org.apache.isis.core.metamodel.facets.actions.publish.PublishedActionFacet;
@@ -73,6 +75,7 @@ import org.apache.isis.core.metamodel.facets.object.publish.PublishedObjectFacet
 import org.apache.isis.core.metamodel.runtimecontext.RuntimeContext.TransactionState;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.progmodel.facets.actions.invoke.CommandUtil;
 import org.apache.isis.core.runtime.persistence.ObjectPersistenceException;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.CreateObjectCommand;
 import org.apache.isis.core.runtime.persistence.objectstore.transaction.DestroyObjectCommand;
@@ -469,7 +472,8 @@ public class IsisTransaction implements TransactionScopedComponent {
             if(currentInvocation == null) {
                 return;
             } 
-            final PublishedActionFacet publishedActionFacet = currentInvocation.getAction().getFacet(PublishedActionFacet.class);
+            IdentifiedHolder action = currentInvocation.getAction();
+            final PublishedActionFacet publishedActionFacet = action.getFacet(PublishedActionFacet.class);
             if(publishedActionFacet == null) {
                 return;
             } 
@@ -477,9 +481,16 @@ public class IsisTransaction implements TransactionScopedComponent {
             
             final RootOid adapterOid = (RootOid) currentInvocation.getTarget().getOid();
             final String oidStr = getOidMarshaller().marshal(adapterOid);
-            final String title = oidStr + ": " + currentInvocation.getAction().getIdentifier().toNameParmsIdentityString();
+            final Identifier actionIdentifier = action.getIdentifier();
+            final String title = oidStr + ": " + actionIdentifier.toNameParmsIdentityString();
             
-            final EventMetadata metadata = newEventMetadata(EventType.ACTION_INVOCATION, currentUser, timestamp, title);
+            final Command command = currentInvocation.getCommand();
+            final String targetClass = command.getTargetClass();
+            final String targetAction = command.getTargetAction();
+            final Bookmark target = command.getTarget();
+            final String memberIdentifier = command.getMemberIdentifier();
+            
+            final EventMetadata metadata = newEventMetadata(EventType.ACTION_INVOCATION, currentUser, timestamp, title, targetClass, targetAction, target, memberIdentifier);
             publishingService.publishAction(payloadFactory, metadata, currentInvocation, objectStringifier());
         } finally {
             // ensures that cannot publish this action more than once
@@ -506,12 +517,16 @@ public class IsisTransaction implements TransactionScopedComponent {
             }
             final PublishedObject.PayloadFactory payloadFactory = publishedObjectFacet.value();
         
-            final RootOid adapterOid = (RootOid) enlistedAdapter.getOid();
-            final String oidStr = getOidMarshaller().marshal(adapterOid);
+            final RootOid enlistedAdapterOid = (RootOid) enlistedAdapter.getOid();
+            final String oidStr = getOidMarshaller().marshal(enlistedAdapterOid);
             final String title = oidStr;
         
             final EventType eventTypeFor = eventTypeFor(changeKind);
-            final EventMetadata metadata = newEventMetadata(eventTypeFor, currentUser, timestamp, title);
+            
+            final String enlistedAdapterClass = CommandUtil.targetClassNameFor(enlistedAdapter);
+            final Bookmark enlistedTarget = enlistedAdapterOid.asBookmark();
+            
+            final EventMetadata metadata = newEventMetadata(eventTypeFor, currentUser, timestamp, title, enlistedAdapterClass, null, enlistedTarget, null);
         
             publishingService.publishObject(payloadFactory, metadata, enlistedAdapter, changeKind, objectStringifier());
         }
@@ -559,11 +574,11 @@ public class IsisTransaction implements TransactionScopedComponent {
         return objectStringifier;
     }
 
-    private EventMetadata newEventMetadata(
-            final EventType eventType, final String currentUser, final java.sql.Timestamp timestampEpoch, final String title) {
+    private EventMetadata newEventMetadata(final EventType eventType, final String currentUser, final java.sql.Timestamp timestampEpoch, final String title, String targetClass, String targetAction, Bookmark target, String memberIdentifier) {
         int nextEventSequence = nextEventSequence();
         return new EventMetadata(
-                getTransactionId(), nextEventSequence, eventType, currentUser, timestampEpoch, title);
+                getTransactionId(), nextEventSequence, eventType, currentUser, timestampEpoch, title, 
+                targetClass, targetAction, target, memberIdentifier);
     }
 
     private int nextEventSequence() {
@@ -586,11 +601,15 @@ public class IsisTransaction implements TransactionScopedComponent {
         final PreAndPostValues papv = auditEntry.getValue();
         final String preValue = asString(papv.getPre());
         final String postValue = asString(papv.getPost());
-        final String propertyId = aap.getProperty().getId();
+        
+        final ObjectAssociation property = aap.getProperty();
+        final String memberId = property.getIdentifier().toClassAndNameIdentityString();
+        final String propertyId = property.getId();
 
+        final String targetClass = CommandUtil.targetClassNameFor(adapter);
         final Bookmark target = new Bookmark(objectType, identifier);
 
-        auditingService3.audit(getTransactionId(), target, propertyId, preValue, postValue, user, timestamp);
+        auditingService3.audit(getTransactionId(), targetClass, target, memberId, propertyId, preValue, postValue, user, timestamp);
     }
 
     private static String asString(Object object) {

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/core/unittestsupport/src/test/java/org/apache/isis/core/unittestsupport/jmocking/IsisActionsTest_returnNewTransientInstance.java
----------------------------------------------------------------------
diff --git a/core/unittestsupport/src/test/java/org/apache/isis/core/unittestsupport/jmocking/IsisActionsTest_returnNewTransientInstance.java b/core/unittestsupport/src/test/java/org/apache/isis/core/unittestsupport/jmocking/IsisActionsTest_returnNewTransientInstance.java
index 4bbdc8b..02773da 100644
--- a/core/unittestsupport/src/test/java/org/apache/isis/core/unittestsupport/jmocking/IsisActionsTest_returnNewTransientInstance.java
+++ b/core/unittestsupport/src/test/java/org/apache/isis/core/unittestsupport/jmocking/IsisActionsTest_returnNewTransientInstance.java
@@ -1,9 +1,9 @@
 /*
- *
- *  Copyright 2012-2013 Eurocommercial Properties NV
- *
- *
- *  Licensed under the Apache License, Version 2.0 (the
+ *  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://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
index 2d7c26a..5a4ca57 100644
--- a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
+++ b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.java
@@ -51,6 +51,7 @@ import org.apache.isis.applib.annotation.Bookmarkable;
 import org.apache.isis.applib.annotation.Bulk;
 import org.apache.isis.applib.annotation.Bulk.AppliesTo;
 import org.apache.isis.applib.annotation.Bulk.InteractionContext.InvokedAs;
+import org.apache.isis.applib.annotation.Command.ExecuteIn;
 import org.apache.isis.applib.annotation.Disabled;
 import org.apache.isis.applib.annotation.Hidden;
 import org.apache.isis.applib.annotation.MinLength;
@@ -613,20 +614,32 @@ public class ToDoItem implements Comparable<ToDoItem> /*, Locatable*/ { // GMAP3
     
 
     // //////////////////////////////////////
-    // totalCost
+    // scheduleExplicitly
+    // scheduleImplicitly
     // //////////////////////////////////////
     
     @ActionSemantics(Of.IDEMPOTENT)
     @Prototype
-    public ToDoItem completeInBackground() {
-        backgroundService.execute(this).slowCompleted(2000);
+    public ToDoItem scheduleExplicitly() {
+        backgroundService.execute(this).completeSlowly(2000);
         container.informUser("Task '" + getDescription() + "' scheduled for completion");
         return this;
     }
     
+    // //////////////////////////////////////
+
+    @ActionSemantics(Of.IDEMPOTENT)
+    @Command(executeIn=ExecuteIn.BACKGROUND)
+    @Prototype
+    public ToDoItem scheduleImplicitly() {
+        completeSlowly(3000);
+        return this;
+    }
+    
+    // //////////////////////////////////////
     
     @Hidden
-    public void slowCompleted(int millis) {
+    public void completeSlowly(int millis) {
         try {
             Thread.sleep(millis);
         } catch (InterruptedException e) {
@@ -634,7 +647,8 @@ public class ToDoItem implements Comparable<ToDoItem> /*, Locatable*/ { // GMAP3
         setComplete(true);
         container.informUser("Completed " + this.getDescription() + "!");
     }
-
+    
+    
     
     // //////////////////////////////////////
     // OpenSourceCodeOnGithub (action)

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
index da28f6a..81cdea3 100644
--- a/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
+++ b/example/application/quickstart_wicket_restful_jdo/dom/src/main/java/dom/todo/ToDoItem.layout.json
@@ -54,8 +54,9 @@
                                 },
                                 cssClass: { value: "x-highlight" }
                             },
-                            completeInBackground: {
-                                named: { value: "Schedule" }
+                            scheduleExplicitly: {
+                            },
+                            scheduleImplicitly: {
                             },
                             notYetCompleted: {
                                 named: { value: "Not done" }

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/admin/Admin.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/admin/Admin.java b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/admin/Admin.java
index 9139939..cbe8aee 100644
--- a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/admin/Admin.java
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/admin/Admin.java
@@ -28,7 +28,7 @@ import org.apache.isis.applib.annotation.Named;
 import org.apache.isis.applib.annotation.Prototype;
 import org.apache.isis.objectstore.jdo.applib.service.audit.AuditEntryJdo;
 import org.apache.isis.objectstore.jdo.applib.service.audit.AuditingServiceJdoRepository;
-import org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoRepository;
+import org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoRepository;
 import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
 import org.apache.isis.objectstore.jdo.applib.service.command.CommandServiceJdoRepository;
 import org.apache.isis.objectstore.jdo.applib.service.publish.PublishedEventJdo;
@@ -36,47 +36,50 @@ import org.apache.isis.objectstore.jdo.applib.service.publish.PublishingServiceJ
 
 public class Admin extends AbstractService {
 
-
     @MemberOrder(sequence="10.1")
     @ActionSemantics(Of.SAFE)
     @Prototype
-    public CommandJdo lookup(final @Named("Transaction Id") UUID transactionId) {
-        return interactionRepository.findByTransactionId(transactionId);
+    public CommandJdo lookupCommand(
+            final @Named("Transaction Id") UUID transactionId) {
+        return commandServiceRepository.findByTransactionId(transactionId);
     }
-    public boolean hideLookup() {
-        return interactionRepository == null;
+    public boolean hideLookupCommand() {
+        return commandServiceRepository == null;
     }
     
+    // //////////////////////////////////////
+    
     @ActionSemantics(Of.SAFE)
     @Bookmarkable
     @MemberOrder(sequence="10.2")
-    public List<CommandJdo> currentlyRunning() {
-        return interactionRepository.findCurrent();
+    public List<CommandJdo> commandsCurrentlyRunning() {
+        return commandServiceRepository.findCurrent();
     }
-    public boolean hideCurrentlyRunning() {
-        return interactionRepository == null;
+    public boolean hideCommandsCurrentlyRunning() {
+        return commandServiceRepository == null;
     }
     
+    // //////////////////////////////////////
+    
     @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence="10.3")
-    public List<CommandJdo> previouslyRan() {
-        return interactionRepository.findCompleted();
+    public List<CommandJdo> commandsPreviouslyRan() {
+        return commandServiceRepository.findCompleted();
     }
-    public boolean hidePreviouslyRan() {
-        return interactionRepository == null;
+    public boolean hideCommandsPreviouslyRan() {
+        return commandServiceRepository == null;
     }
 
-    
     // //////////////////////////////////////
 
     @ActionSemantics(Of.SAFE)
     @Prototype
     @MemberOrder(sequence="20")
-    public List<CommandJdo> allTasks() {
-        return backgroundTaskRepository.listAll();
+    public List<CommandJdo> allCommands() {
+        return backgroundCommandServiceRepository.listAll();
     }
-    public boolean hideAllTasks() {
-        return backgroundTaskRepository == null;
+    public boolean hideAllCommands() {
+        return backgroundCommandServiceRepository == null;
     }
 
     // //////////////////////////////////////
@@ -85,10 +88,10 @@ public class Admin extends AbstractService {
     @Prototype
     @MemberOrder(sequence="30")
     public List<AuditEntryJdo> allAuditEntries() {
-        return auditEntryRepository.listAll();
+        return auditingServiceRepository.listAll();
     }
     public boolean hideAllAuditEntries() {
-        return auditEntryRepository == null;
+        return auditingServiceRepository == null;
     }
     
     // //////////////////////////////////////
@@ -96,44 +99,44 @@ public class Admin extends AbstractService {
     @ActionSemantics(Of.SAFE)
     @MemberOrder(sequence="40.1")
     public List<PublishedEventJdo> allQueuedEvents() {
-        return publishedEventRepository.findQueued();
+        return publishingServiceRepository.findQueued();
     }
     public boolean hideAllQueuedEvents() {
-        return publishedEventRepository == null;
+        return publishingServiceRepository == null;
     }
 
     @ActionSemantics(Of.SAFE)
     @Prototype
     @MemberOrder(sequence="40.2")
     public List<PublishedEventJdo> allProcessedEvents() {
-        return publishedEventRepository.findProcessed();
+        return publishingServiceRepository.findProcessed();
     }
     public boolean hideAllProcessedEvents() {
-        return publishedEventRepository == null;
+        return publishingServiceRepository == null;
     }
 
     @ActionSemantics(Of.IDEMPOTENT)
     @MemberOrder(sequence="40.3")
     public void purgeProcessedEvents() {
-        publishedEventRepository.purgeProcessed();
+        publishingServiceRepository.purgeProcessed();
     }
     public boolean hidePurgeProcessedEvents() {
-        return publishedEventRepository == null;
+        return publishingServiceRepository == null;
     }
 
     // //////////////////////////////////////
 
     @javax.inject.Inject
-    private CommandServiceJdoRepository interactionRepository;
+    private CommandServiceJdoRepository commandServiceRepository;
     
     @javax.inject.Inject
-    private BackgroundActionServiceJdoRepository backgroundTaskRepository;
+    private BackgroundCommandServiceJdoRepository backgroundCommandServiceRepository;
     
     @javax.inject.Inject
-    private AuditingServiceJdoRepository auditEntryRepository;
+    private AuditingServiceJdoRepository auditingServiceRepository;
     
     @javax.inject.Inject
-    private PublishingServiceJdoRepository publishedEventRepository;
+    private PublishingServiceJdoRepository publishingServiceRepository;
     
 }
 

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundActionExecutionQuartzJob.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundActionExecutionQuartzJob.java b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundActionExecutionQuartzJob.java
deleted file mode 100644
index d41da34..0000000
--- a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundActionExecutionQuartzJob.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- *  Licensed to the Apache Software Foundation (ASF) under one or more
- *  contributor license agreements.  See the NOTICE file distributed with
- *  this work for additional information regarding copyright ownership.
- *  The ASF licenses this file to You under the Apache License, Version 2.0
- *  (the "License"); you may not use this file except in compliance with
- *  the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License.
- */
-package webapp.scheduler;
-
-import java.util.List;
-
-import org.apache.isis.applib.services.command.Command;
-import org.apache.isis.core.runtime.services.background.BackgroundActionExecution;
-import org.apache.isis.objectstore.jdo.applib.service.background.BackgroundActionServiceJdoRepository;
-
-public class BackgroundActionExecutionQuartzJob extends AbstractIsisQuartzJob {
-
-    public BackgroundActionExecutionQuartzJob() {
-        super(new BackgroundActionExecutionFromBackgroundActionServicesJdo());   
-    }
-
-    // //////////////////////////////////////
-
-    public final static class BackgroundActionExecutionFromBackgroundActionServicesJdo extends BackgroundActionExecution {
-
-        @Override
-        protected List<? extends Command> findBackgroundActionsToExecute() {
-            return backgroundActionRepository.findBackgroundActionsNotYetStarted(); 
-        }
-        
-        // //////////////////////////////////////
-
-        @javax.inject.Inject
-        private BackgroundActionServiceJdoRepository backgroundActionRepository;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/4ce9e812/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundCommandExecutionQuartzJob.java
----------------------------------------------------------------------
diff --git a/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundCommandExecutionQuartzJob.java b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundCommandExecutionQuartzJob.java
new file mode 100644
index 0000000..1b99782
--- /dev/null
+++ b/example/application/quickstart_wicket_restful_jdo/webapp/src/main/java/webapp/scheduler/BackgroundCommandExecutionQuartzJob.java
@@ -0,0 +1,48 @@
+/**
+ *  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 webapp.scheduler;
+
+import java.util.List;
+
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.core.runtime.services.background.BackgroundCommandExecution;
+import org.apache.isis.objectstore.jdo.applib.service.background.BackgroundCommandServiceJdoRepository;
+import org.apache.isis.objectstore.jdo.applib.service.command.CommandJdo;
+
+public class BackgroundCommandExecutionQuartzJob extends AbstractIsisQuartzJob {
+
+    public BackgroundCommandExecutionQuartzJob() {
+        super(new BackgroundCommandExecutionFromBackgroundCommandServiceJdo());   
+    }
+
+    // //////////////////////////////////////
+
+    public final static class BackgroundCommandExecutionFromBackgroundCommandServiceJdo extends BackgroundCommandExecution {
+
+        @Override
+        protected List<? extends Command> findBackgroundCommandsToExecute() {
+            final List<CommandJdo> commands = backgroundCommandRepository.findBackgroundCommandsNotYetStarted();
+            return commands; 
+        }
+        
+        // //////////////////////////////////////
+
+        @javax.inject.Inject
+        private BackgroundCommandServiceJdoRepository backgroundCommandRepository;
+    }
+
+}