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 2016/05/02 19:25:22 UTC

isis git commit: ISIS-1397: factored out InteractionDtoServiceInternal (cf CommandDtoServiceInternal); move responsibility to hold the Dto into the applib Interaction object.

Repository: isis
Updated Branches:
  refs/heads/ISIS-1291 e315af855 -> a282f199e


ISIS-1397: factored out InteractionDtoServiceInternal (cf CommandDtoServiceInternal); move responsibility to hold the Dto into the applib Interaction object.


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

Branch: refs/heads/ISIS-1291
Commit: a282f199e339ad4f022ea8885a60f7a6faefeb20
Parents: e315af8
Author: Dan Haywood <da...@haywood-associates.co.uk>
Authored: Mon May 2 18:25:12 2016 +0100
Committer: Dan Haywood <da...@haywood-associates.co.uk>
Committed: Mon May 2 18:25:12 2016 +0100

----------------------------------------------------------------------
 .../isis/applib/services/iactn/Interaction.java | 296 +++++++++++--------
 .../isis/schema/utils/InteractionDtoUtils.java  | 180 ++++++-----
 .../org/apache/isis/schema/utils/Roundtrip.java |   8 +-
 ...onInvocationFacetForDomainEventAbstract.java |  19 +-
 ...etterOrClearFacetForDomainEventAbstract.java |   4 +-
 .../services/command/CommandDtoService.java     |  79 -----
 .../command/CommandDtoServiceInternal.java      |  79 +++++
 .../ixn/InteractionDtoServiceInternal.java      |  45 +++
 .../specimpl/ObjectActionDefault.java           |   6 +-
 .../specimpl/ObjectMemberAbstract.java          |   6 +-
 .../specimpl/OneToOneAssociationDefault.java    |   6 +-
 .../background/BackgroundServiceDefault.java    |   8 +-
 .../command/CommandDtoServiceDefault.java       | 253 ----------------
 .../CommandDtoServiceInternalDefault.java       | 248 ++++++++++++++++
 .../InteractionDtoServiceInternalDefault.java   | 127 ++++++++
 .../PublishingServiceInternalDefault.java       |  85 +-----
 16 files changed, 834 insertions(+), 615 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java b/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
index ac4db35..7cdd78d 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/services/iactn/Interaction.java
@@ -37,6 +37,9 @@ import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.eventbus.AbstractDomainEvent;
 import org.apache.isis.applib.services.eventbus.EventBusService;
 import org.apache.isis.applib.services.wrapper.WrapperFactory;
+import org.apache.isis.schema.common.v1.PeriodDto;
+import org.apache.isis.schema.ixn.v1.InteractionExecutionDto;
+import org.apache.isis.schema.utils.jaxbadapters.JavaSqlTimestampXmlGregorianCalendarAdapter;
 
 /**
  * Represents an action invocation or property modification, resulting in some state change of the system.  It captures
@@ -98,7 +101,7 @@ public class Interaction implements HasTransactionId {
      * @param <T>
      */
     public interface MemberCallable<T extends MemberArgs> {
-        Object call(T args);
+        Object call(final Execution currentExecution, final T args);
     }
 
     public static abstract class MemberArgs {
@@ -214,7 +217,7 @@ public class Interaction implements HasTransactionId {
 
         try {
             try {
-                Object result = memberCallable.call(memberArgs);
+                Object result = memberCallable.call(currentExecution, memberArgs);
                 currentExecution.setReturned(result);
                 return (T)result;
             } catch (Exception e) {
@@ -234,6 +237,142 @@ public class Interaction implements HasTransactionId {
     }
 
     /**
+     * The current (most recently pushed) {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent}.
+     *
+     * <p>
+     *     Note that the {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent} itself is mutable,
+     *     as its {@link AbstractDomainEvent#getEventPhase()} phase} changes from
+     *     {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent.Phase#EXECUTING executing} to
+     *     {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent.Phase#EXECUTED executed}.  The
+     *     event returned from this method will always be in one or other of these phases.
+     * </p>
+     */
+    @Programmatic
+    public Execution getCurrentExecution() {
+        return currentExecution;
+    }
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     *
+     * <p>
+     * Push a new {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent}
+     * onto the stack of events held by the command.
+     * </p>
+     */
+    @Programmatic
+    Execution push(final Timestamp startedAt, final MemberArgs memberArgs) {
+
+        final Execution newExecution;
+        if(currentExecution == null) {
+            // new top-level execution
+            newExecution = new Execution(memberArgs, startedAt);
+            executionGraphs.add(newExecution);
+
+        } else {
+            // adds to graph of parent
+            newExecution = new Execution(memberArgs, startedAt, currentExecution);
+        }
+
+        // set
+        moveCurrentTo(newExecution);
+
+        return currentExecution;
+    }
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     *
+     * <p>
+     * Pops the top-most  {@link org.apache.isis.applib.services.eventbus.ActionDomainEvent}
+     * from the stack of events held by the command.
+     * </p>
+     * @param completedAt
+     */
+    @Programmatic
+    Execution pop(final Timestamp completedAt) {
+        if(currentExecution == null) {
+            throw new IllegalStateException("No current execution graph to pop");
+        }
+        final Execution popped = currentExecution;
+        popped.setCompletedAt(completedAt);
+
+        moveCurrentTo(currentExecution.getParent());
+        return popped;
+    }
+
+    private void moveCurrentTo(final Execution newExecution) {
+        priorExecution = currentExecution;
+        currentExecution = newExecution;
+    }
+
+    /**
+     * Returns a (list of) graph(es) indicating the domain events in the order that they were
+     * {@link #push(Timestamp, MemberArgs pushed}.
+     *
+     * <p>
+     *     Each {@link Execution} represents a call stack of domain events (action invocations or property edits),
+     *     that may in turn cause other domain events to be fired (by virtue of the {@link WrapperFactory}).
+     *     The reason that a list is returned is to support bulk command/actions (against multiple targets).  A non-bulk
+     *     action will return a list of just one element.
+     * </p>
+     */
+    @Programmatic
+    public List<Execution> getExecutions() {
+        return Collections.unmodifiableList(executionGraphs);
+    }
+
+    /**
+     * <b>NOT API</b>: intended to be called only by the framework.
+     *
+     * Clears the set of {@link AbstractDomainEvent}s that have been {@link #push(Timestamp, MemberArgs push)}ed.
+     */
+    @Programmatic
+    public void clear() {
+        executionGraphs.clear();
+    }
+    //endregion
+
+    //region > next (programmatic)
+
+    public enum SequenceName {
+
+        /**
+         * &quot;pe&quot; - published event.  For objects: multiple such could be dirtied and thus published as
+         * separate events.  For actions invocations/property edits : multiple sub-invocations could occur if sub-invocations are made through the {@link WrapperFactory}.
+         */
+        PUBLISHED_EVENT("pe");
+
+        private final String abbr;
+        SequenceName(final String abbr) {
+            this.abbr = abbr;
+        }
+        public String abbr() { return abbr; }
+    }
+
+
+    private final Map<String, AtomicInteger> sequenceByName = Maps.newHashMap();
+
+    /**
+     * Generates numbers in a named sequence
+     *
+     * @param sequenceAbbr - should be {@link SequenceName#abbr()}.
+     */
+    @Programmatic
+    public int next(String sequenceAbbr) {
+        AtomicInteger next = sequenceByName.get(sequenceAbbr);
+        if(next == null) {
+            next = new AtomicInteger(0);
+            sequenceByName.put(sequenceAbbr, next);
+        } else {
+            next.incrementAndGet();
+        }
+        return next.get();
+    }
+
+    //endregion
+
+    /**
      * Represents an action invocation/property edit as a node in a call-stack execution graph, with sub-interactions
      * being made by way of the {@link WrapperFactory}).
      */
@@ -333,6 +472,7 @@ public class Interaction implements HasTransactionId {
          */
         void setCompletedAt(Timestamp completedAt) {
             this.completedAt = completedAt;
+            syncMetrics();
         }
 
         //endregion
@@ -379,144 +519,46 @@ public class Interaction implements HasTransactionId {
             this.threw = threw;
         }
 
-        //endregion
-
-    }
-
-    /**
-     * The current (most recently pushed) {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent}.
-     *
-     * <p>
-     *     Note that the {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent} itself is mutable,
-     *     as its {@link AbstractDomainEvent#getEventPhase()} phase} changes from
-     *     {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent.Phase#EXECUTING executing} to
-     *     {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent.Phase#EXECUTED executed}.  The
-     *     event returned from this method will always be in one or other of these phases.
-     * </p>
-     */
-    @Programmatic
-    public Execution getCurrentExecution() {
-        return currentExecution;
-    }
-
-    /**
-     * <b>NOT API</b>: intended to be called only by the framework.
-     *
-     * <p>
-     * Push a new {@link org.apache.isis.applib.services.eventbus.AbstractDomainEvent}
-     * onto the stack of events held by the command.
-     * </p>
-     */
-    @Programmatic
-    Execution push(final Timestamp startedAt, final MemberArgs memberArgs) {
 
-        final Execution newExecution;
-        if(currentExecution == null) {
-            // new top-level execution
-            newExecution = new Execution(memberArgs, startedAt);
-            executionGraphs.add(newExecution);
+        //endregion
 
-        } else {
-            // adds to graph of parent
-            newExecution = new Execution(memberArgs, startedAt, currentExecution);
-        }
+        //region > dto (property)
 
-        // set
-        moveCurrentTo(newExecution);
-
-        return currentExecution;
-    }
+        private InteractionExecutionDto dto;
 
-    /**
-     * <b>NOT API</b>: intended to be called only by the framework.
-     *
-     * <p>
-     * Pops the top-most  {@link org.apache.isis.applib.services.eventbus.ActionDomainEvent}
-     * from the stack of events held by the command.
-     * </p>
-     * @param completedAt
-     */
-    @Programmatic
-    Execution pop(final Timestamp completedAt) {
-        if(currentExecution == null) {
-            throw new IllegalStateException("No current execution graph to pop");
+        public InteractionExecutionDto getDto() {
+            return dto;
         }
-        final Execution popped = currentExecution;
-        popped.setCompletedAt(completedAt);
-
-        moveCurrentTo(currentExecution.getParent());
-        return popped;
-    }
-
-    private void moveCurrentTo(final Execution newExecution) {
-        priorExecution = currentExecution;
-        currentExecution = newExecution;
-    }
-
-    /**
-     * Returns a (list of) graph(es) indicating the domain events in the order that they were
-     * {@link #push(Timestamp, MemberArgs pushed}.
-     *
-     * <p>
-     *     Each {@link Execution} represents a call stack of domain events (action invocations or property edits),
-     *     that may in turn cause other domain events to be fired (by virtue of the {@link WrapperFactory}).
-     *     The reason that a list is returned is to support bulk command/actions (against multiple targets).  A non-bulk
-     *     action will return a list of just one element.
-     * </p>
-     */
-    @Programmatic
-    public List<Execution> getExecutions() {
-        return Collections.unmodifiableList(executionGraphs);
-    }
-
-    /**
-     * <b>NOT API</b>: intended to be called only by the framework.
-     *
-     * Clears the set of {@link AbstractDomainEvent}s that have been {@link #push(Timestamp, MemberArgs push)}ed.
-     */
-    @Programmatic
-    public void clear() {
-        executionGraphs.clear();
-    }
-    //endregion
-
-    //region > next (programmatic)
-
-    public enum SequenceName {
 
         /**
-         * &quot;pe&quot; - published event.  For objects: multiple such could be dirtied and thus published as
-         * separate events.  For actions invocations/property edits : multiple sub-invocations could occur if sub-invocations are made through the {@link WrapperFactory}.
+         * Set by framework (implementation of {@link MemberCallable})
          */
-        PUBLISHED_EVENT("pe");
-
-        private final String abbr;
-        SequenceName(final String abbr) {
-            this.abbr = abbr;
+        public void setDto(final InteractionExecutionDto executionDto) {
+            this.dto = executionDto;
+            syncMetrics();
         }
-        public String abbr() { return abbr; }
-    }
 
+        //endregion
 
-    private final Map<String, AtomicInteger> sequenceByName = Maps.newHashMap();
+        //region > helpers (syncMetrics)
+        private void syncMetrics() {
+            if (this.dto == null) {
+                return;
+            }
+            final PeriodDto periodDto = periodDtoFor(this.dto);
+            periodDto.setStart(JavaSqlTimestampXmlGregorianCalendarAdapter.print(getStartedAt()));
+            periodDto.setComplete(JavaSqlTimestampXmlGregorianCalendarAdapter.print(getCompletedAt()));
+        }
 
-    /**
-     * Generates numbers in a named sequence
-     *
-     * @param sequenceAbbr - should be {@link SequenceName#abbr()}.
-     */
-    @Programmatic
-    public int next(String sequenceAbbr) {
-        AtomicInteger next = sequenceByName.get(sequenceAbbr);
-        if(next == null) {
-            next = new AtomicInteger(0);
-            sequenceByName.put(sequenceAbbr, next);
-        } else {
-            next.incrementAndGet();
+        private static PeriodDto periodDtoFor(final InteractionExecutionDto executionDto) {
+            PeriodDto timings = executionDto.getTimings();
+            if(timings == null) {
+                timings = new PeriodDto();
+            }
+            return timings;
         }
-        return next.get();
-    }
+        //endregion
 
-    //endregion
+    }
 
 }

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/applib/src/main/java/org/apache/isis/schema/utils/InteractionDtoUtils.java
----------------------------------------------------------------------
diff --git a/core/applib/src/main/java/org/apache/isis/schema/utils/InteractionDtoUtils.java b/core/applib/src/main/java/org/apache/isis/schema/utils/InteractionDtoUtils.java
index 1e7cb16..356c04c 100644
--- a/core/applib/src/main/java/org/apache/isis/schema/utils/InteractionDtoUtils.java
+++ b/core/applib/src/main/java/org/apache/isis/schema/utils/InteractionDtoUtils.java
@@ -31,7 +31,6 @@ import java.nio.charset.Charset;
 import java.sql.Timestamp;
 import java.util.Collections;
 import java.util.List;
-import java.util.UUID;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
@@ -116,58 +115,99 @@ public final class InteractionDtoUtils {
     }
     //endregion
 
-    //region > newDto
+    //region > newInteractionDto, newInteractionDtoWithActionExecution
 
-    enum Type {
-        ACTION_INVOCATION,
-        PROPERTY_MODIFICATION
+    public static InteractionDto newInteractionDto(final String transactionId) {
+        final InteractionDto interactionDto = new InteractionDto();
+
+        interactionDto.setMajorVersion("1");
+        interactionDto.setMinorVersion("0");
+
+        interactionDto.setTransactionId(transactionId);
+        return interactionDto;
     }
 
-    /**
-     *
-     * @param newValueDto - will be null if clearing the property
-     */
-    public static InteractionDto newPropertyDto(
-            final UUID transactionId,
+    public static InteractionDto newInteractionDtoWithActionInvocation(
+            final String transactionId,
+            final int sequence,
+            final Bookmark targetBookmark,
+            final String targetTitle,
+            final String actionIdentifier,
+            final List<ParamDto> parameterDtos,
+            final ReturnDto returnDto,
+            final String user) {
+
+        final InteractionDto interactionDto = newInteractionDto(transactionId);
+
+        final InteractionExecutionDto executionDto = newActionInvocation(
+                sequence, targetBookmark, targetTitle,
+                actionIdentifier, parameterDtos, returnDto,
+                user, transactionId);
+
+        addExecution(interactionDto, executionDto);
+
+        return interactionDto;
+    }
+
+    public static InteractionDto newInteractionDtoWithPropertyModification(
+            final String transactionId,
             final int sequence,
             final Bookmark targetBookmark,
             final String targetTitle,
             final String propertyIdentifier,
             final ParamDto newValueDto,
-            final String user,
-            final Timestamp startedAt, final Timestamp completedAt
+            final String user
     ) {
 
-        return newDto(Type.PROPERTY_MODIFICATION, transactionId, sequence, targetBookmark, targetTitle,
-                propertyIdentifier, null, null, newValueDto,
-                user, startedAt, completedAt);
+        final InteractionDto interactionDto = newInteractionDto(transactionId);
+
+        final InteractionExecutionDto executionDto = newPropertyModification(
+                sequence, targetBookmark, targetTitle,
+                propertyIdentifier, newValueDto,
+                user, transactionId);
+
+        addExecution(interactionDto, executionDto);
 
+        return interactionDto;
     }
 
-    public static InteractionDto newActionDto(
-            final UUID transactionId,
+    //endregion
+
+    //region > newActionInvocation, newPropertyModification
+
+    public static ActionInvocationDto newActionInvocation(
             final int sequence,
             final Bookmark targetBookmark,
             final String targetTitle,
             final String actionIdentifier,
             final List<ParamDto> parameterDtos,
-            final ReturnDto returnDto,
-            final String user,
-            final Timestamp startedAt, final Timestamp completedAt) {
+            final ReturnDto returnDto, final String user, final String transactionId) {
 
-        return newDto(Type.ACTION_INVOCATION, transactionId, sequence, targetBookmark, targetTitle, actionIdentifier,
+        return (ActionInvocationDto) newInteractionExecutionDto(
+                InteractionType.ACTION_INVOCATION, transactionId, sequence,
+                targetBookmark, targetTitle, actionIdentifier,
                 parameterDtos, returnDto, null,
-                user, startedAt, completedAt);
+                user);
     }
 
-    /**
-     * @param parameterDtos - populated only for actions
-     * @param returnDto     - populated only for actions (could be null)
-     * @param newValueDto   - populated only for property modificaitons
-     */
-    private static InteractionDto newDto(
-            final Type type,
-            final UUID transactionId,
+    public static PropertyModificationDto newPropertyModification(
+            final int sequence,
+            final Bookmark targetBookmark,
+            final String targetTitle,
+            final String propertyIdentifier,
+            final ParamDto newValueDto,
+            final String user,
+            final String transactionId) {
+        return (PropertyModificationDto) newInteractionExecutionDto(
+                InteractionType.PROPERTY_MODIFICATION, transactionId, sequence,
+                targetBookmark, targetTitle, propertyIdentifier,
+                null, null, newValueDto,
+                user);
+    }
+
+    private static InteractionExecutionDto newInteractionExecutionDto(
+            final InteractionType type,
+            final String transactionId,
             final int sequence,
             final Bookmark targetBookmark,
             final String targetTitle,
@@ -175,33 +215,27 @@ public final class InteractionDtoUtils {
             final List<ParamDto> parameterDtos,
             final ReturnDto returnDto,
             final ParamDto newValueDto,
-            final String user,
-            final Timestamp startedAt, final Timestamp completedAt) {
-        final InteractionDto interactionDto = new InteractionDto();
-
-        interactionDto.setMajorVersion("1");
-        interactionDto.setMinorVersion("0");
-
-        interactionDto.setTransactionId(transactionId.toString());
+            final String user) {
 
         final InteractionExecutionDto executionDto;
-        if(type == Type.ACTION_INVOCATION) {
+        if(type == InteractionType.ACTION_INVOCATION) {
+
+            final ActionInvocationDto invocation = new ActionInvocationDto();
 
-            final ActionInvocationDto invocation = actionInvocationFor(interactionDto);
             final ActionInvocationDto.Parameters parameters = invocation.getParameters();
             parameters.getParameter().addAll(parameterDtos);
             invocation.setReturned(returnDto);
 
             executionDto = invocation;
         } else {
-            final PropertyModificationDto modification = propertyModificationFor(interactionDto);
-            // modification.
+            final PropertyModificationDto modification = new PropertyModificationDto();
+            modification.setNewValue(newValueDto);
 
             executionDto = modification;
         }
 
         executionDto.setSequence(sequence);
-        executionDto.setId(interactionDto.getTransactionId() + "." + sequence);
+        executionDto.setId(transactionId + "." + sequence);
 
         final OidDto target = new OidDto();
         target.setObjectType(targetBookmark.getObjectType());
@@ -212,12 +246,33 @@ public final class InteractionDtoUtils {
         executionDto.setUser(user);
 
         executionDto.setMemberIdentifier(memberIdentifier);
+        return executionDto;
+    }
 
+    //endregion
+
+    //region > addExecution
+
+    public static void addExecution(final InteractionDto interactionDto, final InteractionExecutionDto executionDto) {
+        interactionDto.setExecution(executionDto);
+
+        interactionDto.setInteractionType(
+                executionDto instanceof ActionInvocationDto
+                        ? InteractionType.ACTION_INVOCATION
+                        : InteractionType.PROPERTY_MODIFICATION);
+    }
+
+
+    //endregion
+
+    //region > addTimings
+    public static void addTimings(
+            final InteractionExecutionDto executionDto,
+            final Timestamp startedAt,
+            final Timestamp completedAt) {
         final PeriodDto timings = timingsFor(executionDto);
         timings.setStart(JavaSqlTimestampXmlGregorianCalendarAdapter.print(startedAt));
         timings.setComplete(JavaSqlTimestampXmlGregorianCalendarAdapter.print(completedAt));
-
-        return interactionDto;
     }
 
     //endregion
@@ -284,29 +339,21 @@ public final class InteractionDtoUtils {
      * @param result - either a value type (possibly boxed primitive), or a reference type
      * @param bookmarkService - used if not a value type
      */
-    public static void addReturn(
-            final InteractionDto interactionDto,
+    // REVIEW: done in InteractionDtoServiceInternalDefault, I believe
+    private static void addReturn(
+            final ActionInvocationDto invocationDto,
             final Class<?> returnType,
-            final Object result,
-            final BookmarkService bookmarkService) {
-        boolean isValueType = InteractionDtoUtils.addReturnValue(interactionDto, returnType, result);
+            final Object result, final BookmarkService bookmarkService) {
+        final ReturnDto returnDto = returnValueFor(invocationDto);
+        boolean isValueType = setValue(returnDto, returnType, result);
         if(!isValueType) {
-            InteractionDtoUtils.addReturnReference(interactionDto, bookmarkService.bookmarkFor(result));
+            addReturnReference(bookmarkService.bookmarkFor(result), invocationDto);
         }
     }
 
-    public static boolean addReturnValue(
-            final InteractionDto interactionDto,
-            final Class<?> returnType,
-            final Object returnVal) {
-        final ReturnDto returnDto = returnValueDtoFor(interactionDto);
-        return setValue(returnDto, returnType, returnVal);
-    }
-
-    public static void addReturnReference(
-            final InteractionDto interactionDto,
-            final Bookmark bookmark) {
-        final ReturnDto returnedDto = returnValueDtoFor(interactionDto);
+    // REVIEW: done in InteractionDtoServiceInternalDefault, I believe
+    private static void addReturnReference(final Bookmark bookmark, final ActionInvocationDto invocationDto) {
+        final ReturnDto returnedDto = returnValueFor(invocationDto);
         OidDto oidDto = CommonDtoUtils.asOidDto(bookmark);
         ValueDto value = new ValueDto();
         value.setReference(oidDto);
@@ -314,8 +361,8 @@ public final class InteractionDtoUtils {
         returnedDto.setReturnType(ValueType.REFERENCE);
     }
 
-    private static ReturnDto returnValueDtoFor(final InteractionDto ixnDto) {
-        ActionInvocationDto invocationDto = actionInvocationFor(ixnDto);
+    // REVIEW: done in InteractionDtoServiceInternalDefault, I believe
+    private static ReturnDto returnValueFor(final ActionInvocationDto invocationDto) {
         ReturnDto returned = invocationDto.getReturned();
         if(returned == null) {
             returned = new ReturnDto();
@@ -476,6 +523,7 @@ public final class InteractionDtoUtils {
     public static void dump(final InteractionDto ixnDto, final PrintStream out) throws JAXBException {
         out.println(toXml(ixnDto));
     }
+
     //endregion
 
 

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
----------------------------------------------------------------------
diff --git a/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java b/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
index 22b0c68..1a81c2f 100644
--- a/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
+++ b/core/applib/src/test/java/org/apache/isis/schema/utils/Roundtrip.java
@@ -59,11 +59,11 @@ public class Roundtrip {
         returnDto.setReturnType(ValueType.BOOLEAN);
         returnDto.setNull(true);
 
-        final InteractionDto interactionDto = InteractionDtoUtils.newActionDto(
-                UUID.randomUUID(),
+        final InteractionDto interactionDto = InteractionDtoUtils.newInteractionDtoWithActionInvocation(
+                UUID.randomUUID().toString(),
                 1,
-                new Bookmark("CUS", "12345"), "John Customer", "com.mycompany.Customer#placeOrder", Arrays.<ParamDto>asList(), returnDto, "freddyUser",
-                startedAt, completedAt);
+                new Bookmark("CUS", "12345"), "John Customer", "com.mycompany.Customer#placeOrder", Arrays.<ParamDto>asList(), returnDto, "freddyUser"
+        );
 
         InteractionDtoUtils.addParamArg(interactionDto, "aString", String.class, "Fred", null);
         InteractionDtoUtils.addParamArg(interactionDto, "nullString", String.class, (String) null, null);

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
index c0d4346..77fbcc9 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/actions/action/invocation/ActionInvocationFacetForDomainEventAbstract.java
@@ -71,12 +71,14 @@ import org.apache.isis.core.metamodel.facets.actions.semantics.ActionSemanticsFa
 import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
 import org.apache.isis.core.metamodel.facets.object.viewmodel.ViewModelFacet;
 import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
+import org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal;
 import org.apache.isis.core.metamodel.services.publishing.PublishingServiceInternal;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.metamodel.specloader.ReflectiveActionException;
 import org.apache.isis.core.metamodel.transactions.TransactionState;
 import org.apache.isis.core.metamodel.transactions.TransactionStateProvider;
+import org.apache.isis.schema.ixn.v1.ActionInvocationDto;
 
 public abstract class ActionInvocationFacetForDomainEventAbstract
         extends ActionInvocationFacetAbstract
@@ -331,7 +333,9 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
             final Interaction.ActionArgs actionArgs = new Interaction.ActionArgs(actionId, target, arguments);
             final Interaction.MemberCallable callable = new Interaction.MemberCallable<Interaction.ActionArgs>() {
                 @Override
-                public Object call(final Interaction.ActionArgs actionArgs) {
+                public Object call(
+                        final Interaction.Execution currentExecution,
+                        final Interaction.ActionArgs actionArgs) {
 
                     try {
                         final Object resultPojo = invokeMethodElseFromCache(targetAdapter, argumentAdapters);
@@ -342,6 +346,14 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
 
                         ObjectAdapter resultAdapter = cloneIfViewModelCloneable(resultPojo, targetAdapter);
 
+                        // update the current execution
+                        final List<ObjectAdapter> parameterAdapters = Arrays.asList(argumentAdapters);
+                        final ActionInvocationDto invocationDto =
+                                getInteractionDtoServiceInternal().asActionInvocationDto(
+                                    owningAction, targetAdapter, parameterAdapters, resultAdapter);
+
+                        currentExecution.setDto(invocationDto);
+
                         return resultAdapter != null ? resultAdapter.getObject() : null;
 
                     } catch (InvocationTargetException | IllegalAccessException e) {
@@ -581,6 +593,11 @@ public abstract class ActionInvocationFacetForDomainEventAbstract
         return lookupService(PublishingServiceInternal.class);
     }
 
+    private InteractionDtoServiceInternal getInteractionDtoServiceInternal() {
+        return lookupService(InteractionDtoServiceInternal.class);
+    }
+
+
     private <T> T lookupService(final Class<T> serviceClass) {
         T service = lookupServiceIfAny(serviceClass);
         if(service == null) {

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
index f28d5a4..c2178fa 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/facets/properties/property/modify/PropertySetterOrClearFacetForDomainEventAbstract.java
@@ -238,7 +238,9 @@ public abstract class PropertySetterOrClearFacetForDomainEventAbstract
 
             final Interaction.PropertyArgs propertyArgs = new Interaction.PropertyArgs(propertyId, target, argValue);
             final Interaction.MemberCallable<?> callable = new Interaction.MemberCallable<Interaction.PropertyArgs>() {
-                        @Override public Object call(final Interaction.PropertyArgs propertyArgs11) {
+                        @Override public Object call(
+                                final Interaction.Execution currentExecution,
+                                final Interaction.PropertyArgs propertyArgs11) {
 
                             type.invoke(PropertySetterOrClearFacetForDomainEventAbstract.this, owningProperty, targetAdapter, valueAdapterOrNull, interactionInitiatedBy);
                             return null;

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoService.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoService.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoService.java
deleted file mode 100644
index f6f8fbb..0000000
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoService.java
+++ /dev/null
@@ -1,79 +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.metamodel.services.command;
-
-import java.lang.reflect.Method;
-import java.util.List;
-
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.background.ActionInvocationMemento;
-import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.schema.cmd.v1.ActionDto;
-import org.apache.isis.schema.cmd.v1.CommandDto;
-import org.apache.isis.schema.cmd.v1.PropertyDto;
-
-/**
- * Used to create mementos of a command, such that it can be persisted and then executed either immediately (ie invoke
- * in the foreground) or deferred (ie invoke in the background at some later time).
- */
-public interface CommandDtoService {
-
-    /**
-     * Note that this method (more precisely, {@link ActionInvocationMemento}) does <i>not</i> support mixins.
-     *
-     * @deprecated - use {@link #asCommandDto(List, ObjectAction, ObjectAdapter[])} instead.
-     */
-    @Deprecated
-    @Programmatic
-    ActionInvocationMemento asActionInvocationMemento(Method m, Object domainObject, Object[] args);
-
-    /**
-     * Returns a JAXB DTO (hence convertible to XML) that represents the intention to invoke an action on a
-     * target object (or possibly many targets, for bulk actions).  The action can be a mixin action or a
-     * contributed action.
-     */
-    @Programmatic
-    CommandDto asCommandDto(
-            final List<ObjectAdapter> targetAdapters,
-            final ObjectAction objectAction,
-            final ObjectAdapter[] argAdapters);
-
-    /**
-     * Returns a JAXB DTO (hence convertible to XML) that represents the intention to edit (set or clear) a property on
-     * a target (or possibly many targets, for symmetry with actions).  The property can be a mixin or contributed.
-     */
-    @Programmatic
-    CommandDto asCommandDto(
-            final List<ObjectAdapter> targetAdapters,
-            final OneToOneAssociation association,
-            final ObjectAdapter valueAdapterOrNull);
-
-    @Programmatic
-    void addActionArgs(
-            final ObjectAction objectAction,
-            final ActionDto actionDto,
-            final ObjectAdapter[] argAdapters);
-
-    @Programmatic
-    void addPropertyValue(
-            final OneToOneAssociation property,
-            final PropertyDto propertyDto,
-            final ObjectAdapter valueAdapter);
-
-    }

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoServiceInternal.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoServiceInternal.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoServiceInternal.java
new file mode 100644
index 0000000..25bb228
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/command/CommandDtoServiceInternal.java
@@ -0,0 +1,79 @@
+/**
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.isis.core.metamodel.services.command;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.background.ActionInvocationMemento;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.schema.cmd.v1.ActionDto;
+import org.apache.isis.schema.cmd.v1.CommandDto;
+import org.apache.isis.schema.cmd.v1.PropertyDto;
+
+/**
+ * Used to create mementos of a command, such that it can be persisted and then executed either immediately (ie invoke
+ * in the foreground) or deferred (ie invoke in the background at some later time).
+ */
+public interface CommandDtoServiceInternal {
+
+    /**
+     * Note that this method (more precisely, {@link ActionInvocationMemento}) does <i>not</i> support mixins.
+     *
+     * @deprecated - use {@link #asCommandDto(List, ObjectAction, ObjectAdapter[])} instead.
+     */
+    @Deprecated
+    @Programmatic
+    ActionInvocationMemento asActionInvocationMemento(Method m, Object domainObject, Object[] args);
+
+    /**
+     * Returns a JAXB DTO (hence convertible to XML) that represents the intention to invoke an action on a
+     * target object (or possibly many targets, for bulk actions).  The action can be a mixin action or a
+     * contributed action.
+     */
+    @Programmatic
+    CommandDto asCommandDto(
+            final List<ObjectAdapter> targetAdapters,
+            final ObjectAction objectAction,
+            final ObjectAdapter[] argAdapters);
+
+    /**
+     * Returns a JAXB DTO (hence convertible to XML) that represents the intention to edit (set or clear) a property on
+     * a target (or possibly many targets, for symmetry with actions).  The property can be a mixin or contributed.
+     */
+    @Programmatic
+    CommandDto asCommandDto(
+            final List<ObjectAdapter> targetAdapters,
+            final OneToOneAssociation association,
+            final ObjectAdapter valueAdapterOrNull);
+
+    @Programmatic
+    void addActionArgs(
+            final ObjectAction objectAction,
+            final ActionDto actionDto,
+            final ObjectAdapter[] argAdapters);
+
+    @Programmatic
+    void addPropertyValue(
+            final OneToOneAssociation property,
+            final PropertyDto propertyDto,
+            final ObjectAdapter valueAdapter);
+
+    }

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
new file mode 100644
index 0000000..716ba9b
--- /dev/null
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/services/ixn/InteractionDtoServiceInternal.java
@@ -0,0 +1,45 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.metamodel.services.ixn;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.schema.ixn.v1.ActionInvocationDto;
+import org.apache.isis.schema.ixn.v1.PropertyModificationDto;
+
+public interface InteractionDtoServiceInternal {
+
+    @Programmatic
+    ActionInvocationDto asActionInvocationDto(
+            ObjectAction objectAction,
+            ObjectAdapter targetAdapter,
+            List<ObjectAdapter> parameterAdapters,
+            ObjectAdapter resultAdapter);
+
+    @Programmatic PropertyModificationDto asPropertyModificationDto(
+            OneToOneAssociation property,
+            ObjectAdapter targetAdapter,
+            ObjectAdapter newValueAdapterIfAny);
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
index 7ff5bca..f10f570 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectActionDefault.java
@@ -66,7 +66,7 @@ import org.apache.isis.core.metamodel.interactions.InteractionUtils;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.ValidityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
 import org.apache.isis.core.metamodel.spec.ActionType;
 import org.apache.isis.core.metamodel.spec.DomainModelException;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
@@ -589,13 +589,13 @@ public class ObjectActionDefault extends ObjectMemberAbstract implements ObjectA
             final ObjectAdapter targetAdapter,
             final ObjectAdapter[] argumentAdapters) {
 
-        final CommandDtoService commandDtoService = getCommandDtoService();
+        final CommandDtoServiceInternal commandDtoServiceInternal = getCommandDtoService();
         final List<ObjectAdapter> commandTargetAdapters =
                 commandTargetAdaptersHolder.get() != null
                         ? commandTargetAdaptersHolder.get()
                         : Collections.singletonList(targetAdapter);
 
-        final CommandDto dto = commandDtoService.asCommandDto(
+        final CommandDto dto = commandDtoServiceInternal.asCommandDto(
                 commandTargetAdapters, this, argumentAdapters);
 
         setupCommandDtoAndExecutionContext(dto);

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
index 2de0fe7..5c489c4 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/ObjectMemberAbstract.java
@@ -56,7 +56,7 @@ import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
 import org.apache.isis.core.metamodel.runtimecontext.PersistenceSessionService;
 import org.apache.isis.core.metamodel.runtimecontext.ServicesInjector;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.SpecificationLoader;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
@@ -404,8 +404,8 @@ public abstract class ObjectMemberAbstract implements ObjectMember {
         return commandContext;
     }
 
-    protected CommandDtoService getCommandDtoService() {
-        return lookupService(CommandDtoService.class);
+    protected CommandDtoServiceInternal getCommandDtoService() {
+        return lookupService(CommandDtoServiceInternal.class);
     }
 
     //endregion

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
----------------------------------------------------------------------
diff --git a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
index 773adc9..70e6a1d 100644
--- a/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
+++ b/core/metamodel/src/main/java/org/apache/isis/core/metamodel/specloader/specimpl/OneToOneAssociationDefault.java
@@ -52,7 +52,7 @@ import org.apache.isis.core.metamodel.interactions.PropertyVisibilityContext;
 import org.apache.isis.core.metamodel.interactions.UsabilityContext;
 import org.apache.isis.core.metamodel.interactions.ValidityContext;
 import org.apache.isis.core.metamodel.interactions.VisibilityContext;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.MutableCurrentHolder;
 import org.apache.isis.core.metamodel.spec.feature.ObjectMemberDependencies;
@@ -351,8 +351,8 @@ public class OneToOneAssociationDefault extends ObjectAssociationAbstract implem
             final ObjectAdapter targetAdapter,
             final ObjectAdapter valueAdapterOrNull) {
 
-        final CommandDtoService commandDtoService = getCommandDtoService();
-        final CommandDto dto = commandDtoService.asCommandDto(
+        final CommandDtoServiceInternal commandDtoServiceInternal = getCommandDtoService();
+        final CommandDto dto = commandDtoServiceInternal.asCommandDto(
                 Collections.singletonList(targetAdapter), this, valueAdapterOrNull);
 
         setupCommandDtoAndExecutionContext(dto);

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/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 7007d71..6ed82fd 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
@@ -41,7 +41,7 @@ import org.apache.isis.core.commons.lang.ArrayExtensions;
 import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
 import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
 import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
 import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
 import org.apache.isis.core.metamodel.spec.feature.Contributed;
@@ -228,13 +228,13 @@ public class BackgroundServiceDefault implements BackgroundService2 {
 
                     final List<ObjectAdapter> targetList = Collections.singletonList(domainObjectAdapter);
                     final CommandDto dto =
-                            commandDtoService.asCommandDto(targetList, action, argAdapters);
+                            commandDtoServiceInternal.asCommandDto(targetList, action, argAdapters);
 
                     bcs2.schedule(dto, command, domainObjectClassName, targetActionName, targetArgs);
                 } else {
                     // fallback
                     final ActionInvocationMemento aim =
-                            commandDtoService.asActionInvocationMemento(proxyMethod, target, args);
+                            commandDtoServiceInternal.asActionInvocationMemento(proxyMethod, target, args);
 
                     backgroundCommandService.schedule(aim, command, domainObjectClassName, targetActionName, targetArgs);
                 }
@@ -282,7 +282,7 @@ public class BackgroundServiceDefault implements BackgroundService2 {
     private BackgroundCommandService backgroundCommandService;
 
     @javax.inject.Inject
-    private CommandDtoService commandDtoService;
+    private CommandDtoServiceInternal commandDtoServiceInternal;
 
     @javax.inject.Inject
     private CommandContext commandContext;

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceDefault.java
deleted file mode 100644
index 5cbc472..0000000
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceDefault.java
+++ /dev/null
@@ -1,253 +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.command;
-
-import java.lang.reflect.Method;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-import javax.annotation.PostConstruct;
-
-import com.google.common.collect.Lists;
-
-import org.apache.isis.applib.annotation.DomainService;
-import org.apache.isis.applib.annotation.NatureOfService;
-import org.apache.isis.applib.annotation.Programmatic;
-import org.apache.isis.applib.services.background.ActionInvocationMemento;
-import org.apache.isis.applib.services.background.BackgroundCommandService;
-import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService;
-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.RootOid;
-import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
-import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
-import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
-import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
-import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
-import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
-import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
-import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
-import org.apache.isis.core.runtime.system.context.IsisContext;
-import org.apache.isis.schema.cmd.v1.ActionDto;
-import org.apache.isis.schema.cmd.v1.CommandDto;
-import org.apache.isis.schema.cmd.v1.ParamDto;
-import org.apache.isis.schema.cmd.v1.PropertyDto;
-import org.apache.isis.schema.common.v1.InteractionType;
-import org.apache.isis.schema.utils.CommandDtoUtils;
-
-/**
- * Depends on an implementation of {@link BackgroundCommandService} to
- * be configured.
- */
-@DomainService(
-        nature = NatureOfService.DOMAIN
-)
-public class CommandDtoServiceDefault implements CommandDtoService {
-
-    private final MementoServiceDefault mementoService;
-
-    public CommandDtoServiceDefault() {
-        this(new MementoServiceDefault());
-    }
-
-    CommandDtoServiceDefault(MementoServiceDefault mementoService) {
-        this.mementoService = mementoService.withNoEncoding();
-    }
-    
-    // //////////////////////////////////////
-
-    
-    @Programmatic
-    @PostConstruct
-    public void init(Map<String,String> props) {
-    }
-
-    // //////////////////////////////////////
-
-
-    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
-        return getJavaSpecification(method.getDeclaringClass());
-    }
-
-    private ObjectSpecificationDefault getJavaSpecification(final Class<?> cls) {
-        final ObjectSpecification objectSpec = getSpecification(cls);
-        if (!(objectSpec instanceof ObjectSpecificationDefault)) {
-            throw new UnsupportedOperationException(
-                "Only Java is supported "
-                + "(specification is '" + objectSpec.getClass().getCanonicalName() + "')");
-        }
-        return (ObjectSpecificationDefault) objectSpec;
-    }
-
-    private ObjectSpecification getSpecification(final Class<?> type) {
-        return getSpecificationLoader().loadSpecification(type);
-    }
-
-
-    // //////////////////////////////////////
-
-    @Deprecated
-    @Programmatic
-    @Override
-    public ActionInvocationMemento asActionInvocationMemento(
-            final Method method,
-            final Object domainObject,
-            final Object[] args) {
-        
-        final ObjectSpecificationDefault targetObjSpec = getJavaSpecificationOfOwningClass(method);
-        final ObjectMember member = targetObjSpec.getMember(method);
-        if(member == null) {
-            return null;
-        }
-
-        if(!(member instanceof ObjectAction)) {
-            throw new UnsupportedOperationException(String.format(
-                    "Method %s does not correspond to an action.", method.getName()));
-        }
-
-        final ObjectAction action = (ObjectAction) member;
-        final String actionIdentifier = CommandUtil.memberIdentifierFor(action);
-        
-        final Bookmark domainObjectBookmark = bookmarkService.bookmarkFor(domainObject);
-
-        final List<Class<?>> argTypes = Lists.newArrayList();
-        final List<Object> argObjs = Lists.newArrayList();
-        CommandUtil.buildMementoArgLists(mementoService, bookmarkService, method, args, argTypes, argObjs);
-
-        final ActionInvocationMemento aim = 
-                new ActionInvocationMemento(mementoService, 
-                        actionIdentifier, 
-                        domainObjectBookmark,
-                        argTypes,
-                        argObjs);
-       
-        return aim;
-    }
-
-    @Override
-    public CommandDto asCommandDto(
-            final List<ObjectAdapter> targetAdapters,
-            final ObjectAction objectAction,
-            final ObjectAdapter[] argAdapters) {
-
-        final CommandDto dto = asCommandDto(targetAdapters);
-
-        dto.setInteractionType(InteractionType.ACTION_INVOCATION);
-        final ActionDto actionDto = new ActionDto();
-        dto.setMember(actionDto);
-
-        addActionArgs(objectAction, actionDto, argAdapters);
-
-        return dto;
-    }
-
-    @Override
-    public CommandDto asCommandDto(
-            final List<ObjectAdapter> targetAdapters,
-            final OneToOneAssociation property,
-            final ObjectAdapter valueAdapterOrNull) {
-
-        final CommandDto dto = asCommandDto(targetAdapters);
-
-        dto.setInteractionType(InteractionType.PROPERTY_MODIFICATION);
-        final PropertyDto propertyDto = new PropertyDto();
-        dto.setMember(propertyDto);
-
-        addPropertyValue(property, propertyDto, valueAdapterOrNull);
-
-        return dto;
-    }
-
-    private CommandDto asCommandDto(final List<ObjectAdapter> targetAdapters) {
-        final CommandDto dto = new CommandDto();
-        dto.setMajorVersion("1");
-        dto.setMinorVersion("0");
-
-        dto.setTransactionId(UUID.randomUUID().toString());
-
-        for (ObjectAdapter targetAdapter : targetAdapters) {
-            final RootOid rootOid = (RootOid) targetAdapter.getOid();
-            final Bookmark bookmark = rootOid.asBookmark();
-            dto.getTargets().add(bookmark.toOidDto());
-        }
-        return dto;
-    }
-
-
-    @Override
-    public void addActionArgs(
-            final ObjectAction objectAction,
-            final ActionDto actionDto,
-            final ObjectAdapter[] argAdapters) {
-        final String actionIdentifier = CommandUtil.memberIdentifierFor(objectAction);
-        actionDto.setMemberIdentifier(actionIdentifier);
-
-        List<ObjectActionParameter> actionParameters = objectAction.getParameters();
-        for (int paramNum = 0; paramNum < actionParameters.size(); paramNum++) {
-            final ObjectActionParameter actionParameter = actionParameters.get(paramNum);
-            final String parameterName = actionParameter.getName();
-            final Class<?> paramType = actionParameter.getSpecification().getCorrespondingClass();
-            final ObjectAdapter argAdapter = argAdapters[paramNum];
-            final Object arg = argAdapter != null? argAdapter.getObject(): null;
-            final List<ParamDto> parameters = actionDto.getParameters();
-
-            ParamDto paramDto = CommandDtoUtils.newParamDto(parameterName, paramType, arg, bookmarkService);
-            parameters.add(paramDto);
-        }
-    }
-
-    @Override
-    public void addPropertyValue(
-            final OneToOneAssociation property,
-            final PropertyDto propertyDto,
-            final ObjectAdapter valueAdapter) {
-
-        final String actionIdentifier = CommandUtil.memberIdentifierFor(property);
-        propertyDto.setMemberIdentifier(actionIdentifier);
-
-        final ObjectSpecification valueSpec = property.getSpecification();
-        final Class<?> valueType = valueSpec.getCorrespondingClass();
-
-        final ParamDto paramDto = CommandDtoUtils.newParamDto(
-                "newValue", valueType, ObjectAdapter.Util.unwrap(valueAdapter), bookmarkService);
-        propertyDto.setNewValue(paramDto);
-    }
-
-    // //////////////////////////////////////
-
-
-    @javax.inject.Inject
-    private BookmarkService bookmarkService;
-
-
-    // //////////////////////////////////////
-
-    protected SpecificationLoaderSpi getSpecificationLoader() {
-        return IsisContext.getSpecificationLoader();
-    }
-
-    protected AdapterManager getAdapterManager() {
-        return IsisContext.getPersistenceSession();
-    }
-
-
-
-}

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceInternalDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceInternalDefault.java
new file mode 100644
index 0000000..9511faf
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/command/CommandDtoServiceInternalDefault.java
@@ -0,0 +1,248 @@
+/**
+ *  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.command;
+
+import java.lang.reflect.Method;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.annotation.PostConstruct;
+
+import com.google.common.collect.Lists;
+
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+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.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.adapter.oid.RootOid;
+import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUtil;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.core.metamodel.specloader.specimpl.dflt.ObjectSpecificationDefault;
+import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.schema.cmd.v1.ActionDto;
+import org.apache.isis.schema.cmd.v1.CommandDto;
+import org.apache.isis.schema.cmd.v1.ParamDto;
+import org.apache.isis.schema.cmd.v1.PropertyDto;
+import org.apache.isis.schema.common.v1.InteractionType;
+import org.apache.isis.schema.utils.CommandDtoUtils;
+
+@DomainService(
+        nature = NatureOfService.DOMAIN
+)
+public class CommandDtoServiceInternalDefault implements CommandDtoServiceInternal {
+
+    private final MementoServiceDefault mementoService;
+
+    public CommandDtoServiceInternalDefault() {
+        this(new MementoServiceDefault());
+    }
+
+    CommandDtoServiceInternalDefault(MementoServiceDefault mementoService) {
+        this.mementoService = mementoService.withNoEncoding();
+    }
+    
+    // //////////////////////////////////////
+
+    
+    @Programmatic
+    @PostConstruct
+    public void init(Map<String,String> props) {
+    }
+
+    // //////////////////////////////////////
+
+
+    private ObjectSpecificationDefault getJavaSpecificationOfOwningClass(final Method method) {
+        return getJavaSpecification(method.getDeclaringClass());
+    }
+
+    private ObjectSpecificationDefault getJavaSpecification(final Class<?> cls) {
+        final ObjectSpecification objectSpec = getSpecification(cls);
+        if (!(objectSpec instanceof ObjectSpecificationDefault)) {
+            throw new UnsupportedOperationException(
+                "Only Java is supported "
+                + "(specification is '" + objectSpec.getClass().getCanonicalName() + "')");
+        }
+        return (ObjectSpecificationDefault) objectSpec;
+    }
+
+    private ObjectSpecification getSpecification(final Class<?> type) {
+        return getSpecificationLoader().loadSpecification(type);
+    }
+
+
+    // //////////////////////////////////////
+
+    @Deprecated
+    @Programmatic
+    @Override
+    public ActionInvocationMemento asActionInvocationMemento(
+            final Method method,
+            final Object domainObject,
+            final Object[] args) {
+        
+        final ObjectSpecificationDefault targetObjSpec = getJavaSpecificationOfOwningClass(method);
+        final ObjectMember member = targetObjSpec.getMember(method);
+        if(member == null) {
+            return null;
+        }
+
+        if(!(member instanceof ObjectAction)) {
+            throw new UnsupportedOperationException(String.format(
+                    "Method %s does not correspond to an action.", method.getName()));
+        }
+
+        final ObjectAction action = (ObjectAction) member;
+        final String actionIdentifier = CommandUtil.memberIdentifierFor(action);
+        
+        final Bookmark domainObjectBookmark = bookmarkService.bookmarkFor(domainObject);
+
+        final List<Class<?>> argTypes = Lists.newArrayList();
+        final List<Object> argObjs = Lists.newArrayList();
+        CommandUtil.buildMementoArgLists(mementoService, bookmarkService, method, args, argTypes, argObjs);
+
+        final ActionInvocationMemento aim = 
+                new ActionInvocationMemento(mementoService, 
+                        actionIdentifier, 
+                        domainObjectBookmark,
+                        argTypes,
+                        argObjs);
+       
+        return aim;
+    }
+
+    @Override
+    public CommandDto asCommandDto(
+            final List<ObjectAdapter> targetAdapters,
+            final ObjectAction objectAction,
+            final ObjectAdapter[] argAdapters) {
+
+        final CommandDto dto = asCommandDto(targetAdapters);
+
+        dto.setInteractionType(InteractionType.ACTION_INVOCATION);
+        final ActionDto actionDto = new ActionDto();
+        dto.setMember(actionDto);
+
+        addActionArgs(objectAction, actionDto, argAdapters);
+
+        return dto;
+    }
+
+    @Override
+    public CommandDto asCommandDto(
+            final List<ObjectAdapter> targetAdapters,
+            final OneToOneAssociation property,
+            final ObjectAdapter valueAdapterOrNull) {
+
+        final CommandDto dto = asCommandDto(targetAdapters);
+
+        dto.setInteractionType(InteractionType.PROPERTY_MODIFICATION);
+        final PropertyDto propertyDto = new PropertyDto();
+        dto.setMember(propertyDto);
+
+        addPropertyValue(property, propertyDto, valueAdapterOrNull);
+
+        return dto;
+    }
+
+    private CommandDto asCommandDto(final List<ObjectAdapter> targetAdapters) {
+        final CommandDto dto = new CommandDto();
+        dto.setMajorVersion("1");
+        dto.setMinorVersion("0");
+
+        dto.setTransactionId(UUID.randomUUID().toString());
+
+        for (ObjectAdapter targetAdapter : targetAdapters) {
+            final RootOid rootOid = (RootOid) targetAdapter.getOid();
+            final Bookmark bookmark = rootOid.asBookmark();
+            dto.getTargets().add(bookmark.toOidDto());
+        }
+        return dto;
+    }
+
+
+    @Override
+    public void addActionArgs(
+            final ObjectAction objectAction,
+            final ActionDto actionDto,
+            final ObjectAdapter[] argAdapters) {
+        final String actionIdentifier = CommandUtil.memberIdentifierFor(objectAction);
+        actionDto.setMemberIdentifier(actionIdentifier);
+
+        List<ObjectActionParameter> actionParameters = objectAction.getParameters();
+        for (int paramNum = 0; paramNum < actionParameters.size(); paramNum++) {
+            final ObjectActionParameter actionParameter = actionParameters.get(paramNum);
+            final String parameterName = actionParameter.getName();
+            final Class<?> paramType = actionParameter.getSpecification().getCorrespondingClass();
+            final ObjectAdapter argAdapter = argAdapters[paramNum];
+            final Object arg = argAdapter != null? argAdapter.getObject(): null;
+            final List<ParamDto> parameters = actionDto.getParameters();
+
+            ParamDto paramDto = CommandDtoUtils.newParamDto(parameterName, paramType, arg, bookmarkService);
+            parameters.add(paramDto);
+        }
+    }
+
+    @Override
+    public void addPropertyValue(
+            final OneToOneAssociation property,
+            final PropertyDto propertyDto,
+            final ObjectAdapter valueAdapter) {
+
+        final String actionIdentifier = CommandUtil.memberIdentifierFor(property);
+        propertyDto.setMemberIdentifier(actionIdentifier);
+
+        final ObjectSpecification valueSpec = property.getSpecification();
+        final Class<?> valueType = valueSpec.getCorrespondingClass();
+
+        final ParamDto paramDto = CommandDtoUtils.newParamDto(
+                "newValue", valueType, ObjectAdapter.Util.unwrap(valueAdapter), bookmarkService);
+        propertyDto.setNewValue(paramDto);
+    }
+
+    // //////////////////////////////////////
+
+
+    @javax.inject.Inject
+    private BookmarkService bookmarkService;
+
+
+    // //////////////////////////////////////
+
+    protected SpecificationLoaderSpi getSpecificationLoader() {
+        return IsisContext.getSpecificationLoader();
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return IsisContext.getPersistenceSession();
+    }
+
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ixn/InteractionDtoServiceInternalDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ixn/InteractionDtoServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ixn/InteractionDtoServiceInternalDefault.java
new file mode 100644
index 0000000..04fb7fe
--- /dev/null
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/ixn/InteractionDtoServiceInternalDefault.java
@@ -0,0 +1,127 @@
+/*
+ *  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.ixn;
+
+import java.util.List;
+import java.util.UUID;
+
+import javax.inject.Inject;
+
+import org.apache.isis.applib.annotation.DomainService;
+import org.apache.isis.applib.annotation.NatureOfService;
+import org.apache.isis.applib.annotation.Programmatic;
+import org.apache.isis.applib.services.bookmark.Bookmark;
+import org.apache.isis.applib.services.bookmark.BookmarkService;
+import org.apache.isis.applib.services.clock.ClockService;
+import org.apache.isis.applib.services.command.Command;
+import org.apache.isis.applib.services.command.CommandContext;
+import org.apache.isis.applib.services.iactn.Interaction;
+import org.apache.isis.applib.services.user.UserService;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.services.command.CommandDtoServiceInternal;
+import org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.schema.cmd.v1.ActionDto;
+import org.apache.isis.schema.ixn.v1.ActionInvocationDto;
+import org.apache.isis.schema.ixn.v1.PropertyModificationDto;
+import org.apache.isis.schema.ixn.v1.ReturnDto;
+import org.apache.isis.schema.utils.InteractionDtoUtils;
+
+@DomainService(nature = NatureOfService.DOMAIN)
+public class InteractionDtoServiceInternalDefault implements InteractionDtoServiceInternal {
+
+
+    @Override @Programmatic
+    public ActionInvocationDto asActionInvocationDto(
+            final ObjectAction objectAction,
+            final ObjectAdapter targetAdapter,
+            final List<ObjectAdapter> parameterAdapters,
+            final ObjectAdapter resultAdapter) {
+
+        final Command command = commandContext.getCommand();
+        final UUID transactionId = command.getTransactionId();
+
+        final Interaction.SequenceName sequenceName = Interaction.SequenceName.PUBLISHED_EVENT;
+        final int nextEventSequence = command.next(sequenceName.abbr());
+
+        final Object targetPojo = targetAdapter.getObject();
+        final Bookmark targetBookmark = bookmarkService.bookmarkFor(targetPojo);
+
+        final String actionClassNameId = objectAction.getIdentifier().toClassAndNameIdentityString();
+        final String actionId = actionClassNameId.substring(actionClassNameId.indexOf('#')+1);
+        final String targetTitle = targetBookmark.toString() + ": " + actionId;
+
+        final String currentUser = userService.getUser().getName();
+
+        final ActionDto actionDto = new ActionDto();
+        commandDtoServiceInternal.addActionArgs(
+                objectAction, actionDto, parameterAdapters.toArray(new ObjectAdapter[]{}));
+
+        final ObjectSpecification returnSpec = objectAction.getReturnType();
+
+        final Class<?> returnType = returnSpec.getCorrespondingClass();
+        final Object resultPojo = resultAdapter != null? resultAdapter.getObject(): null;
+
+        final ReturnDto returnDto = new ReturnDto();
+        InteractionDtoUtils.setValue(returnDto, returnType, resultPojo);
+
+        final String transactionIdStr = transactionId.toString();
+
+        // done above, I believe
+        // InteractionDtoUtils.addReturn(invocationDto, returnType, resultPojo, bookmarkService);
+        return InteractionDtoUtils.newActionInvocation(
+                nextEventSequence, targetBookmark, targetTitle,
+                actionDto.getMemberIdentifier(), actionDto.getParameters(), returnDto, currentUser,
+                transactionIdStr);
+    }
+
+    @Override @Programmatic
+    public PropertyModificationDto asPropertyModificationDto(
+            final OneToOneAssociation property,
+            final ObjectAdapter targetAdapter,
+            final ObjectAdapter newValueAdapterIfAny) {
+
+        //
+        //
+        //
+
+        throw new RuntimeException("not yet implemented");
+    }
+
+
+    @Inject
+    CommandDtoServiceInternal commandDtoServiceInternal;
+
+    @Inject
+    private BookmarkService bookmarkService;
+
+    @Inject
+    private CommandContext commandContext;
+
+    @Inject
+    private ClockService clockService;
+
+    @Inject
+    private UserService userService;
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/a282f199/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publishing/PublishingServiceInternalDefault.java
----------------------------------------------------------------------
diff --git a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publishing/PublishingServiceInternalDefault.java b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publishing/PublishingServiceInternalDefault.java
index 4e0a3fc..6340285 100644
--- a/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publishing/PublishingServiceInternalDefault.java
+++ b/core/runtime/src/main/java/org/apache/isis/core/runtime/services/publishing/PublishingServiceInternalDefault.java
@@ -39,12 +39,10 @@ import org.apache.isis.applib.annotation.PublishedAction;
 import org.apache.isis.applib.annotation.PublishedObject;
 import org.apache.isis.applib.annotation.PublishedObject.ChangeKind;
 import org.apache.isis.applib.services.bookmark.Bookmark;
-import org.apache.isis.applib.services.bookmark.BookmarkService;
 import org.apache.isis.applib.services.clock.ClockService;
 import org.apache.isis.applib.services.command.Command;
 import org.apache.isis.applib.services.command.CommandContext;
 import org.apache.isis.applib.services.iactn.Interaction;
-import org.apache.isis.applib.services.iactn.InteractionContext;
 import org.apache.isis.applib.services.publish.EventMetadata;
 import org.apache.isis.applib.services.publish.EventPayload;
 import org.apache.isis.applib.services.publish.EventType;
@@ -63,17 +61,15 @@ import org.apache.isis.core.metamodel.facets.actions.action.invocation.CommandUt
 import org.apache.isis.core.metamodel.facets.actions.publish.PublishedActionFacet;
 import org.apache.isis.core.metamodel.facets.object.encodeable.EncodableFacet;
 import org.apache.isis.core.metamodel.facets.object.publishedobject.PublishedObjectFacet;
-import org.apache.isis.core.metamodel.services.command.CommandDtoService;
+import org.apache.isis.core.metamodel.services.ixn.InteractionDtoServiceInternal;
 import org.apache.isis.core.metamodel.services.publishing.PublishingServiceInternal;
-import org.apache.isis.core.metamodel.spec.ObjectSpecification;
 import org.apache.isis.core.metamodel.spec.feature.ObjectAction;
 import org.apache.isis.core.runtime.services.enlist.EnlistedObjectsServiceInternal;
 import org.apache.isis.core.runtime.system.context.IsisContext;
 import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
 import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
-import org.apache.isis.schema.cmd.v1.ActionDto;
 import org.apache.isis.schema.ixn.v1.InteractionDto;
-import org.apache.isis.schema.ixn.v1.ReturnDto;
+import org.apache.isis.schema.ixn.v1.InteractionExecutionDto;
 import org.apache.isis.schema.utils.InteractionDtoUtils;
 
 /**
@@ -185,9 +181,7 @@ public class PublishingServiceInternalDefault implements PublishingServiceIntern
                 objectAction, identifiedHolder, targetAdapter, parameterAdapters, resultAdapter
         );
 
-        publishActionToPublisherServices(
-                objectAction, identifiedHolder, targetAdapter, parameterAdapters, resultAdapter,
-                execution);
+        publishActionToPublisherServices(execution);
 
     }
 
@@ -319,77 +313,28 @@ public class PublishingServiceInternalDefault implements PublishingServiceIntern
                 enlistedAdapterClass, null, enlistedTarget, null, null, null, null);
     }
 
-    private void publishActionToPublisherServices(
-            final ObjectAction objectAction,
-            final IdentifiedHolder identifiedHolder,
-            final ObjectAdapter targetAdapter,
-            final List<ObjectAdapter> parameterAdapters,
-            final ObjectAdapter resultAdapter,
-            final Interaction.Execution execution) {
+    private void publishActionToPublisherServices(final Interaction.Execution execution) {
 
         if(publisherServices == null || publisherServices.isEmpty()) {
             return;
         }
 
         //
-        // TODO: currently MemberInteractionMementoDtoUtils does _not_ serialize out the call graph of Interaction.Execution; that enhancement might follow at a later stage.
+        // TODO: this is where we could now stitch together a deep call graph from the execution.getDto()s
         //
 
-        final Command command = commandContext.getCommand();
-
-        final Interaction.SequenceName sequenceName = Interaction.SequenceName.PUBLISHED_EVENT;
-        final int nextEventSequence = command.next(sequenceName.abbr());
-        final UUID transactionId = command.getTransactionId();
-
-        final Object targetPojo = execution.getMemberArgs().getTarget();
-        final Bookmark targetBookmark = bookmarkService.bookmarkFor(targetPojo);
-
-        final String actionClassNameId = execution.getMemberArgs().getMemberId();
-        final String actionId = actionClassNameId.substring(actionClassNameId.indexOf('#')+1);
-        final String targetTitle = targetBookmark.toString() + ": " + actionId;
-
-        final String currentUser = userService.getUser().getName();
-        final Timestamp startedAt = execution.getStartedAt();
-        final Timestamp completedAt = execution.getCompletedAt();
-
-        final ActionDto actionDto = new ActionDto();
-        commandDtoService.addActionArgs(
-                objectAction, actionDto, parameterAdapters.toArray(new ObjectAdapter[]{}));
-
-        final ObjectSpecification returnSpec = objectAction.getReturnType();
+        final InteractionExecutionDto executionDto = execution.getDto();
 
-
-        final Class<?> returnType = returnSpec.getCorrespondingClass();
-        final ObjectAdapter argAdapter = resultAdapter;
-        final Object resultPojo = argAdapter != null? argAdapter.getObject(): null;
-
-        final ReturnDto returnDto = new ReturnDto();
-        InteractionDtoUtils.setValue(returnDto, returnType, resultPojo);
+        final String transactionId = commandContext.getCommand().getTransactionId().toString();
+        final InteractionDto interactionDto = InteractionDtoUtils.newInteractionDto(transactionId);
+        InteractionDtoUtils.addExecution(interactionDto, executionDto);
 
         for (PublisherService publisherService : publisherServices) {
-            final InteractionDto interactionDto =
-                InteractionDtoUtils.newActionDto(
-                        transactionId,
-                        nextEventSequence,
-                        targetBookmark,
-                        targetTitle,
-                        actionDto.getMemberIdentifier(),
-                        actionDto.getParameters(), returnDto,
-                        currentUser,
-                        startedAt, completedAt
-                );
-
-            InteractionDtoUtils.addReturn(interactionDto, returnType, resultPojo, bookmarkService);
-
             publisherService.publish(interactionDto);
         }
     }
 
 
-    private IsisTransactionManager.PersistenceSessionTransactionManagement getPersistenceSession() {
-        return IsisContext.getPersistenceSession();
-    }
-
 
     @Inject
     private List<PublisherService> publisherServices;
@@ -398,16 +343,10 @@ public class PublishingServiceInternalDefault implements PublishingServiceIntern
     private PublishingService publishingServiceIfAny;
 
     @Inject
-    CommandDtoService commandDtoService;
-
-    @Inject
-    private BookmarkService bookmarkService;
-
-    @Inject
     private EnlistedObjectsServiceInternal enlistedObjectsServiceInternal;
 
     @Inject
-    private InteractionContext interactionContext;
+    private InteractionDtoServiceInternal interactionDtoServiceInternal;
 
     @Inject
     private CommandContext commandContext;
@@ -419,4 +358,8 @@ public class PublishingServiceInternalDefault implements PublishingServiceIntern
     private UserService userService;
 
 
+    private IsisTransactionManager.PersistenceSessionTransactionManagement getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
 }