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/07/18 07:26:54 UTC

[05/52] ISIS-839: renaming examples and archetypes

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemChangedPayloadFactory.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemChangedPayloadFactory.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemChangedPayloadFactory.java
new file mode 100644
index 0000000..7c03f19
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemChangedPayloadFactory.java
@@ -0,0 +1,50 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 dom.todo;
+
+import org.apache.isis.applib.annotation.PublishedObject.ChangeKind;
+import org.apache.isis.applib.annotation.PublishedObject.PayloadFactory;
+import org.apache.isis.applib.services.publish.EventPayload;
+import org.apache.isis.applib.services.publish.EventPayloadForObjectChanged;
+
+public class ToDoItemChangedPayloadFactory implements PayloadFactory{
+
+    public static class ToDoItemPayload extends EventPayloadForObjectChanged<ToDoItem> {
+
+        public ToDoItemPayload(ToDoItem changed) {
+            super(changed);
+        }
+        
+        /**
+         * Expose the item's {@link ToDoItem${symbol_pound}getDescription() description} more explicitly
+         * in the payload.
+         */
+        public String getDescription() {
+            return getChanged().getDescription();
+        }
+    }
+    @Override
+    public EventPayload payloadFor(Object changedObject, ChangeKind changeKind) {
+        return new ToDoItemPayload((ToDoItem) changedObject);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemContributions.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemContributions.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemContributions.java
new file mode 100644
index 0000000..eb7c606
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemContributions.java
@@ -0,0 +1,245 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 dom.todo;
+
+import dom.todo.ToDoItem.Category;
+import dom.todo.ToDoItem.Subcategory;
+
+import java.util.List;
+import java.util.concurrent.Callable;
+import com.google.common.base.Function;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Ordering;
+import org.joda.time.LocalDate;
+import org.apache.isis.applib.AbstractFactoryAndRepository;
+import org.apache.isis.applib.annotation.*;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.annotation.NotContributed.As;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
+
+public class ToDoItemContributions extends AbstractFactoryAndRepository {
+
+    //region > priority (contributed property)
+    // //////////////////////////////////////
+    
+    @DescribedAs("The relative priority of this item compared to others not yet complete (using 'due by' date)")
+    @NotInServiceMenu
+    @ActionSemantics(Of.SAFE)
+    @NotContributed(As.ACTION) // ie contributed as association
+    @Hidden(where=Where.ALL_TABLES)
+    @Disabled(reason="Relative priority, derived from due date")
+    public Integer relativePriority(final ToDoItem toDoItem) {
+        return queryResultsCache.execute(new Callable<Integer>(){
+            @Override
+            public Integer call() throws Exception {
+                if(toDoItem.isComplete()) {
+                    return null;
+                }
+
+                // sort items, then locate this one
+                int i=1;
+                for (ToDoItem each : sortedNotYetComplete()) {
+                    if(each == toDoItem) {
+                        return i;
+                    }
+                    i++;
+                }
+                return null;
+            }}, ToDoItemContributions.class, "relativePriority", toDoItem);
+    }
+
+
+    private List<ToDoItem> sortedNotYetComplete() {
+        return ORDERING_DUE_BY
+        .compound(ORDERING_DESCRIPTION)
+        .sortedCopy(toDoItems.notYetComplete());
+    }
+
+    private static Ordering<ToDoItem> ORDERING_DUE_BY = 
+        Ordering.natural().nullsLast().onResultOf(new Function<ToDoItem, LocalDate>(){
+            @Override
+            public LocalDate apply(ToDoItem input) {
+                return input.getDueBy();
+            }
+        });
+    
+    private static Ordering<ToDoItem> ORDERING_DESCRIPTION = 
+        Ordering.natural().nullsLast().onResultOf(new Function<ToDoItem, String>(){
+            @Override
+            public String apply(ToDoItem input) {
+                return input.getDescription();
+            }
+        });
+
+
+    //endregion
+
+    //region >  next, previous (contributed actions)
+    // //////////////////////////////////////
+
+    @DescribedAs("The next item not yet completed")
+    @NotInServiceMenu
+    @ActionSemantics(Of.SAFE)
+    @NotContributed(As.ASSOCIATION) // ie contributed as action
+    public ToDoItem next(final ToDoItem item) {
+        final Integer priority = relativePriority(item);
+        if(priority == null) {
+            return item;
+        }
+        int priorityOfNext = priority != null ? priority + 1 : 0;
+        return itemWithPriorityElse(priorityOfNext, item);
+    }
+    public String disableNext(final ToDoItem toDoItem) {
+        if (toDoItem.isComplete()) {
+            return "Completed";
+        } 
+        if(next(toDoItem) == null) {
+            return "No next item";
+        }
+        return null;
+    }
+
+    // //////////////////////////////////////
+    
+    @DescribedAs("The previous item not yet completed")
+    @NotInServiceMenu
+    @ActionSemantics(Of.SAFE)
+    @NotContributed(As.ASSOCIATION) // ie contributed as action
+    public ToDoItem previous(final ToDoItem item) {
+        final Integer priority = relativePriority(item);
+        if(priority == null) {
+            return item;
+        }
+        int priorityOfPrevious = priority != null? priority - 1 : 0;
+        return itemWithPriorityElse(priorityOfPrevious, item);
+    }
+    public String disablePrevious(final ToDoItem toDoItem) {
+        if (toDoItem.isComplete()) {
+            return "Completed";
+        }
+        if(previous(toDoItem) == null) {
+            return "No previous item";
+        }
+        return null;
+    }
+
+    // //////////////////////////////////////
+
+    /**
+     * @param priority : 1-based priority
+     */
+    private ToDoItem itemWithPriorityElse(int priority, final ToDoItem itemElse) {
+        if(priority < 1) {
+            return null;
+        }
+        final List<ToDoItem> items = sortedNotYetComplete();
+        if(priority > items.size()) {
+            return null;
+        }
+        return priority>=0 && items.size()>=priority? items.get(priority-1): itemElse;
+    }
+    //endregion
+
+    //region > similarTo (contributed collection)
+    // //////////////////////////////////////
+    
+    @NotInServiceMenu
+    @ActionSemantics(Of.SAFE)
+    @NotContributed(As.ACTION)
+    public List<ToDoItem> similarTo(final ToDoItem toDoItem) {
+        final List<ToDoItem> similarToDoItems = allMatches(
+                new QueryDefault<ToDoItem>(ToDoItem.class, 
+                        "findByOwnedByAndCategory", 
+                        "ownedBy", currentUserName(), 
+                        "category", toDoItem.getCategory()));
+        return Lists.newArrayList(Iterables.filter(similarToDoItems, excluding(toDoItem)));
+    }
+
+
+    private static Predicate<ToDoItem> excluding(final ToDoItem toDoItem) {
+        return new Predicate<ToDoItem>() {
+            @Override
+            public boolean apply(ToDoItem input) {
+                return input != toDoItem;
+            }
+        };
+    }
+    //endregion
+
+    //region > updateCategory (contributed action)
+    // //////////////////////////////////////
+
+    @DescribedAs("Update category and subcategory")
+    @NotInServiceMenu
+    @ActionSemantics(Of.IDEMPOTENT)
+    public ToDoItem updateCategory(
+            final ToDoItem item, 
+            final @Named("Category") Category category,
+            final @Optional @Named("Subcategory") Subcategory subcategory) {
+        item.setCategory(category);
+        item.setSubcategory(subcategory);
+        return item;
+    }
+
+    public Category default1UpdateCategory(
+            final ToDoItem item) {
+        return item != null? item.getCategory(): null;
+    }
+    public Subcategory default2UpdateCategory(
+            final ToDoItem item) {
+        return item != null? item.getSubcategory(): null;
+    }
+
+    public List<Subcategory> choices2UpdateCategory(
+            final ToDoItem item, final Category category) {
+        return Subcategory.listFor(category);
+    }
+    
+    public String validateUpdateCategory(
+            final ToDoItem item, final Category category, final Subcategory subcategory) {
+        return Subcategory.validate(category, subcategory);
+    }
+    //endregion
+
+    //region > helpers
+    // //////////////////////////////////////
+    
+    protected String currentUserName() {
+        return getContainer().getUser().getName();
+    }
+
+    //endregion
+
+    //region > injected services
+    // //////////////////////////////////////
+
+    @javax.inject.Inject
+    private ToDoItems toDoItems;
+
+    @javax.inject.Inject
+    private QueryResultsCache queryResultsCache;
+    //endregion
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemSubscriptions.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemSubscriptions.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemSubscriptions.java
new file mode 100644
index 0000000..1ee6d98
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItemSubscriptions.java
@@ -0,0 +1,184 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 dom.todo;
+
+import java.util.EventObject;
+import java.util.List;
+import com.google.common.collect.Lists;
+import com.google.common.eventbus.Subscribe;
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.NonRecoverableException;
+import org.apache.isis.applib.RecoverableException;
+import org.apache.isis.applib.annotation.*;
+import org.apache.isis.applib.services.eventbus.CollectionAddedToEvent;
+import org.apache.isis.applib.services.eventbus.CollectionRemovedFromEvent;
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.applib.services.eventbus.PropertyChangedEvent;
+
+public class ToDoItemSubscriptions {
+
+    //region > LOG
+    private final static org.slf4j.Logger LOG = org.slf4j.LoggerFactory.getLogger(ToDoItemSubscriptions.class);
+    //endregion
+
+
+    //region > on(Event)...
+    // //////////////////////////////////////
+    public static enum Behaviour {
+        AcceptEvents,
+        RejectEventsWithRecoverableException,
+        RejectEventsWithNonRecoverableException,
+        ThrowOtherException
+    }
+    private Behaviour behaviour = Behaviour.AcceptEvents;
+
+    /**
+     * To demo/test what occurs if a subscriber that might veto an event.
+     */
+    @Prototype
+    @MemberOrder(name = "Prototyping", sequence = "80")
+    @Named("Set subscriber behaviour")
+    @ActionSemantics(ActionSemantics.Of.IDEMPOTENT)
+    public String subscriberBehaviour(@Named("Behaviour") Behaviour behaviour) {
+        this.behaviour = behaviour;
+        return "Subscriber behaviour set to: " + behaviour;
+    }
+    public Behaviour default0SubscriberBehaviour() {
+        return this.behaviour;
+    }
+    @Programmatic
+    public Behaviour getSubscriberBehaviour() {
+        return behaviour;
+    }
+    private void rejectIfRequired() {
+        if(behaviour == Behaviour.RejectEventsWithRecoverableException) {
+            throw new RecoverableException("Rejecting event (recoverable exception thrown)");
+        }
+        if(behaviour == Behaviour.RejectEventsWithNonRecoverableException) {
+            throw new NonRecoverableException("Rejecting event (recoverable exception thrown)");
+        }
+        if(behaviour == Behaviour.ThrowOtherException) {
+            throw new RuntimeException("Throwing some other exception");
+        }
+    }
+    //endregion
+
+    //region > on(Event)...
+    // //////////////////////////////////////
+
+    @Programmatic
+    @Subscribe
+    public void on(ToDoItem.AbstractActionInvokedEvent ev) {
+        rejectIfRequired();
+        recordEvent(ev);
+        LOG.info(ev.getEventDescription() + ": " + container.titleOf(ev.getSource()));
+    }
+
+
+    @Programmatic
+    @Subscribe
+    public void on(PropertyChangedEvent<?,?> ev) {
+        rejectIfRequired();
+        recordEvent(ev);
+        if(ev.getIdentifier().getMemberName().contains("description")) {
+            String newValue = (String) ev.getNewValue();
+            if(newValue.matches(".*demo veto.*")) {
+                throw new RecoverableException("oh no you don't! " + ev.getNewValue());
+            }
+        }
+        LOG.info(container.titleOf(ev.getSource()) + ", changed " + ev.getIdentifier().getMemberName() + " : " + ev.getOldValue() + " -> " + ev.getNewValue());
+    }
+    
+    @Programmatic
+    @Subscribe
+    public void on(CollectionAddedToEvent<?,?> ev) {
+        rejectIfRequired();
+        recordEvent(ev);
+        LOG.info(container.titleOf(ev.getSource()) + ", added to " + ev.getIdentifier().getMemberName() + " : " + ev.getValue());
+    }
+    
+    @Programmatic
+    @Subscribe
+    public void on(CollectionRemovedFromEvent<?,?> ev) {
+        rejectIfRequired();
+        recordEvent(ev);
+        LOG.info(container.titleOf(ev.getSource()) + ", removed from " + ev.getIdentifier().getMemberName() + " : " + ev.getValue());
+    }
+
+    //endregion
+
+    //region > receivedEvents
+    // //////////////////////////////////////
+    
+    private final List<java.util.EventObject> receivedEvents = Lists.newLinkedList();
+
+    /**
+     * Used in integration tests.
+     */
+    @Programmatic
+    public List<java.util.EventObject> receivedEvents() {
+        return receivedEvents;
+    }
+    /**
+     * Used in integration tests.
+     */
+    @Programmatic
+    public <T extends java.util.EventObject> T mostRecentlyReceivedEvent(Class<T> expectedType) {
+        if (receivedEvents.isEmpty()) {
+            return null;
+        } 
+        final EventObject ev = receivedEvents.get(0);
+        if(!expectedType.isAssignableFrom(ev.getClass())) {
+            return null;
+        } 
+        return expectedType.cast(ev);
+    }
+    private void recordEvent(final java.util.EventObject ev) {
+        receivedEvents.add(0, ev);
+    }
+    /**
+     * Used in integration tests.
+     */
+    @Programmatic
+    public void reset() {
+        receivedEvents.clear();
+        subscriberBehaviour(ToDoItemSubscriptions.Behaviour.AcceptEvents);
+    }
+
+    //endregion
+
+
+    //region > injected services
+    // //////////////////////////////////////
+    
+    @javax.inject.Inject
+    private DomainObjectContainer container;
+
+    @SuppressWarnings("unused")
+    private EventBusService eventBusService;
+    public final void injectEventBusService(EventBusService eventBusService) {
+        eventBusService.register(this);
+    }
+    //endregion
+
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItems.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItems.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItems.java
new file mode 100644
index 0000000..7c58d7c
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/java/dom/todo/ToDoItems.java
@@ -0,0 +1,239 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 dom.todo;
+
+import dom.todo.ToDoItem.Category;
+import dom.todo.ToDoItem.Subcategory;
+
+import java.math.BigDecimal;
+import java.util.List;
+import com.google.common.base.Predicates;
+import org.joda.time.LocalDate;
+import org.apache.isis.applib.DomainObjectContainer;
+import org.apache.isis.applib.annotation.*;
+import org.apache.isis.applib.annotation.ActionSemantics.Of;
+import org.apache.isis.applib.query.QueryDefault;
+import org.apache.isis.applib.services.clock.ClockService;
+
+@Named("ToDos")
+public class ToDoItems {
+
+    //region > identification in the UI
+    // //////////////////////////////////////
+
+    public String getId() {
+        return "toDoItems";
+    }
+
+    public String iconName() {
+        return "ToDoItem";
+    }
+    //endregion
+
+    //region > notYetComplete (action)
+    // //////////////////////////////////////
+
+    @Bookmarkable
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "1")
+    public List<ToDoItem> notYetComplete() {
+        final List<ToDoItem> items = notYetCompleteNoUi();
+        if(items.isEmpty()) {
+            container.informUser("All to-do items have been completed :-)");
+        }
+        return items;
+    }
+
+    @Programmatic
+    public List<ToDoItem> notYetCompleteNoUi() {
+        return container.allMatches(
+                new QueryDefault<ToDoItem>(ToDoItem.class, 
+                        "findByOwnedByAndCompleteIsFalse", 
+                        "ownedBy", currentUserName()));
+    }
+    //endregion
+
+    //region > complete (action)
+    // //////////////////////////////////////
+    
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "3")
+    public List<ToDoItem> complete() {
+        final List<ToDoItem> items = completeNoUi();
+        if(items.isEmpty()) {
+            container.informUser("No to-do items have yet been completed :-(");
+        }
+        return items;
+    }
+
+    @Programmatic
+    public List<ToDoItem> completeNoUi() {
+        return container.allMatches(
+            new QueryDefault<ToDoItem>(ToDoItem.class, 
+                    "findByOwnedByAndCompleteIsTrue", 
+                    "ownedBy", currentUserName()));
+    }
+    //endregion
+
+    //region > categorized (action)
+    // //////////////////////////////////////
+
+	@SuppressWarnings("unchecked")
+	@Bookmarkable
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "30")
+    public List<ToDoItem> categorized(
+    		@Named("Category") final Category category,
+    		@Named("Subcategory") final Subcategory subcategory,
+    		@Named("Completed?") final boolean completed) {
+    	// an example "naive" implementation (filtered in Java code, not DBMS)
+        return container.allMatches(ToDoItem.class, 
+                Predicates.and(
+                    ToDoItem.Predicates.thoseOwnedBy(currentUserName()), 
+                    ToDoItem.Predicates.thoseCompleted(completed),
+                    ToDoItem.Predicates.thoseCategorised(category, subcategory)));
+    }
+    public Category default0Categorized() {
+        return Category.Professional;
+    }
+    public Subcategory default1Categorized() {
+        return default0Categorized().subcategories().get(0);
+    }
+    public boolean default2Categorized() {
+    	return false;
+    }
+    public List<Subcategory> choices1Categorized(
+            final Category category) {
+        return Subcategory.listFor(category);
+    }
+    public String validateCategorized(
+            final Category category, 
+            final Subcategory subcategory, 
+            final boolean completed) {
+        return Subcategory.validate(category, subcategory);
+    }
+    //endregion
+
+    //region > newToDo (action)
+    // //////////////////////////////////////
+
+    @MemberOrder(sequence = "40")
+    public ToDoItem newToDo(
+            final @RegEx(validation = "${symbol_escape}${symbol_escape}w[@&:${symbol_escape}${symbol_escape}-${symbol_escape}${symbol_escape},${symbol_escape}${symbol_escape}.${symbol_escape}${symbol_escape}+ ${symbol_escape}${symbol_escape}w]*") @Named("Description") String description, 
+            final @Named("Category") Category category,
+            final @Optional @Named("Subcategory") Subcategory subcategory,
+            final @Optional @Named("Due by") LocalDate dueBy,
+            final @Optional @Named("Cost") BigDecimal cost) {
+        return newToDo(description, category, subcategory, currentUserName(), dueBy, cost);
+    }
+    public Category default1NewToDo() {
+        return Category.Professional;
+    }
+    public Subcategory default2NewToDo() {
+        return Category.Professional.subcategories().get(0);
+    }
+    public LocalDate default3NewToDo() {
+        return clockService.now().plusDays(14);
+    }
+    public List<Subcategory> choices2NewToDo(
+            final String description, final Category category) {
+        return Subcategory.listFor(category);
+    }
+    public String validateNewToDo(
+            final String description, 
+            final Category category, final Subcategory subcategory, 
+            final LocalDate dueBy, final BigDecimal cost) {
+        return Subcategory.validate(category, subcategory);
+    }
+    //endregion
+
+    //region > allToDos (action)
+    // //////////////////////////////////////
+
+    @ActionSemantics(Of.SAFE)
+    @MemberOrder(sequence = "50")
+    public List<ToDoItem> allToDos() {
+        final List<ToDoItem> items = container.allMatches(
+                new QueryDefault<ToDoItem>(ToDoItem.class, 
+                        "findByOwnedBy", 
+                        "ownedBy", currentUserName()));
+        if(items.isEmpty()) {
+            container.warnUser("No to-do items found.");
+        }
+        return items;
+    }
+    //endregion
+
+    //region > autoComplete (programmatic)
+    // //////////////////////////////////////
+
+    @Programmatic // not part of metamodel
+    public List<ToDoItem> autoComplete(final String description) {
+        return container.allMatches(
+                new QueryDefault<ToDoItem>(ToDoItem.class, 
+                        "findByOwnedByAndDescriptionContains", 
+                        "ownedBy", currentUserName(), 
+                        "description", description));
+    }
+    //endregion
+
+    //region > helpers
+    // //////////////////////////////////////
+
+    @Programmatic // for use by fixtures
+    public ToDoItem newToDo(
+            final String description, 
+            final Category category, 
+            final Subcategory subcategory,
+            final String userName, 
+            final LocalDate dueBy, final BigDecimal cost) {
+        final ToDoItem toDoItem = container.newTransientInstance(ToDoItem.class);
+        toDoItem.setDescription(description);
+        toDoItem.setCategory(category);
+        toDoItem.setSubcategory(subcategory);
+        toDoItem.setOwnedBy(userName);
+        toDoItem.setDueBy(dueBy);
+        toDoItem.setCost(cost);
+
+        container.persist(toDoItem);
+        container.flush();
+
+        return toDoItem;
+    }
+    
+    private String currentUserName() {
+        return container.getUser().getName();
+    }
+
+    //endregion
+
+    //region > injected services
+    // //////////////////////////////////////
+    
+    @javax.inject.Inject
+    private DomainObjectContainer container;
+
+    @javax.inject.Inject
+    private ClockService clockService;
+    //endregion
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/Dashboard.png
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/Dashboard.png b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/Dashboard.png
new file mode 100644
index 0000000..c22ab2b
Binary files /dev/null and b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/Dashboard.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-done.png
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-done.png b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-done.png
new file mode 100644
index 0000000..b0fc6e8
Binary files /dev/null and b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-done.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-todo.png
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-todo.png b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-todo.png
new file mode 100644
index 0000000..99a9fed
Binary files /dev/null and b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem-todo.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem.png
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem.png b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem.png
new file mode 100644
index 0000000..99a9fed
Binary files /dev/null and b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/main/resources/images/ToDoItem.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_completed.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_completed.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_completed.java
new file mode 100644
index 0000000..718460f
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_completed.java
@@ -0,0 +1,71 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *  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 dom.todo;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+
+public class ToDoTest_completed {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private EventBusService eventBusService;
+
+    private ToDoItem toDoItem;
+
+    @Before
+    public void setUp() throws Exception {
+        toDoItem = new ToDoItem();
+        toDoItem.bulkInteractionContext = Bulk.InteractionContext.regularAction(toDoItem);
+        toDoItem.eventBusService = eventBusService;
+
+        context.ignoring(eventBusService);
+
+        toDoItem.setComplete(false);
+    }
+    
+    @Test
+    public void happyCase() throws Exception {
+        // given
+        assertThat(toDoItem.disableCompleted(), is(nullValue()));
+        
+        // when
+        toDoItem.completed();
+        
+        // then
+        assertThat(toDoItem.isComplete(), is(true));
+        assertThat(toDoItem.disableCompleted(), is(not(nullValue())));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_notYetCompleted.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_notYetCompleted.java b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_notYetCompleted.java
new file mode 100644
index 0000000..bc02446
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/dom/src/test/java/dom/todo/ToDoTest_notYetCompleted.java
@@ -0,0 +1,71 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *  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 dom.todo;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.services.eventbus.EventBusService;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2;
+import org.apache.isis.core.unittestsupport.jmocking.JUnitRuleMockery2.Mode;
+
+public class ToDoTest_notYetCompleted {
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    @Mock
+    private EventBusService eventBusService;
+    
+    private ToDoItem toDoItem;
+
+    @Before
+    public void setUp() throws Exception {
+        toDoItem = new ToDoItem();
+
+        toDoItem.bulkInteractionContext = Bulk.InteractionContext.regularAction(toDoItem);
+        toDoItem.eventBusService = eventBusService;
+
+        context.ignoring(eventBusService);
+        toDoItem.setComplete(true);
+    }
+    
+    @Test
+    public void happyCase() throws Exception {
+        // given
+        assertThat(toDoItem.disableNotYetCompleted(), is(nullValue()));
+        
+        // when
+        toDoItem.notYetCompleted();
+        
+        // then
+        assertThat(toDoItem.isComplete(), is(false));
+        assertThat(toDoItem.disableNotYetCompleted(), is(not(nullValue())));
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/.gitignore
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/.gitignore b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/.gitignore
new file mode 100644
index 0000000..a48e45b
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/.gitignore
@@ -0,0 +1 @@
+/target-ide

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/pom.xml
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/pom.xml b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/pom.xml
new file mode 100644
index 0000000..1872775
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+    <parent>
+    	<groupId>${groupId}</groupId>
+        <artifactId>${rootArtifactId}</artifactId>
+        <version>${version}</version>
+    </parent>
+
+	<artifactId>${artifactId}</artifactId>
+	<name>Quickstart Wicket/Restful/JDO Fixtures</name>
+
+	<dependencies>
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>${rootArtifactId}-dom</artifactId>
+		</dependency>
+	</dependencies>
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
new file mode 100644
index 0000000..38676d4
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/ToDoItemsFixturesService.java
@@ -0,0 +1,59 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo;
+
+import fixture.todo.scenarios.RecreateToDoItemsAndCompleteSeveralForCurrent;
+
+import java.util.List;
+import org.apache.isis.applib.annotation.MemberOrder;
+import org.apache.isis.applib.annotation.Named;
+import org.apache.isis.applib.annotation.Prototype;
+import org.apache.isis.applib.fixturescripts.FixtureResult;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.applib.fixturescripts.FixtureScripts;
+
+/**
+ * Enables fixtures to be installed from the application.
+ */
+@Named("Prototyping") // has the effect of defining a "Prototyping" menu item
+public class ToDoItemsFixturesService extends FixtureScripts {
+
+    public ToDoItemsFixturesService() {
+        super("fixture.todo");
+    }
+
+    /**
+     * Raising visibility to <tt>public</tt> so that choices are available for first param
+     * of {@link ${symbol_pound}runFixtureScript(FixtureScript, String)}.
+     */
+    @Override
+    public List<FixtureScript> choices0RunFixtureScript() {
+        return super.choices0RunFixtureScript();
+    }
+
+    @Prototype
+    @MemberOrder(sequence="20")
+    public Object recreateToDoItemsForCurrentAndReturnFirst() {
+        final List<FixtureResult> run = findFixtureScriptFor(RecreateToDoItemsAndCompleteSeveralForCurrent.class).run(null);
+        return run.get(0).getObject();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/integtests/ToDoItemsIntegTestFixture.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/integtests/ToDoItemsIntegTestFixture.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/integtests/ToDoItemsIntegTestFixture.java
new file mode 100644
index 0000000..d844083
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/integtests/ToDoItemsIntegTestFixture.java
@@ -0,0 +1,43 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.integtests;
+
+import fixture.todo.simple.ToDoItemsRecreateAndCompleteSeveral;
+
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+
+/**
+ * Refactored to reuse the newer {@link FixtureScript} API.
+ */
+public class ToDoItemsIntegTestFixture extends FixtureScript {
+
+    public ToDoItemsIntegTestFixture() {
+        super(null, "integ-test");
+    }
+
+    @Override
+    protected void execute(ExecutionContext executionContext) {
+        execute(new ToDoItemsRecreateAndCompleteSeveral(null), executionContext);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsFor.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsFor.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsFor.java
new file mode 100644
index 0000000..6d627a5
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsFor.java
@@ -0,0 +1,39 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsDelete;
+
+import com.google.common.base.Strings;
+
+public class DeleteToDoItemsFor extends ToDoItemsDelete {
+
+    public DeleteToDoItemsFor() {
+        super(null);
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+    
+    @Override
+    public String validateRun(final String parameters) {
+        return Strings.isNullOrEmpty(parameters) ? "Specify the owner of the ToDoItems to be deleted" : null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsForSven.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsForSven.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsForSven.java
new file mode 100644
index 0000000..9bf14e4
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/DeleteToDoItemsForSven.java
@@ -0,0 +1,33 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsDelete;
+
+public final class DeleteToDoItemsForSven extends ToDoItemsDelete {
+
+    public DeleteToDoItemsForSven() {
+        super("sven");
+        withDiscoverability(Discoverability.DISCOVERABLE);
+
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsAndCompleteSeveralForCurrent.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsAndCompleteSeveralForCurrent.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsAndCompleteSeveralForCurrent.java
new file mode 100644
index 0000000..f6c1b22
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsAndCompleteSeveralForCurrent.java
@@ -0,0 +1,33 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsRecreateAndCompleteSeveral;
+
+public class RecreateToDoItemsAndCompleteSeveralForCurrent extends ToDoItemsRecreateAndCompleteSeveral {
+
+    public RecreateToDoItemsAndCompleteSeveralForCurrent() {
+        super(null);
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsFor.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsFor.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsFor.java
new file mode 100644
index 0000000..bc0d0ca
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsFor.java
@@ -0,0 +1,39 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsRecreate;
+
+import com.google.common.base.Strings;
+
+public final class RecreateToDoItemsFor extends ToDoItemsRecreate {
+
+    public RecreateToDoItemsFor() {
+        super(null);
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+    
+    @Override
+    public String validateRun(String parameters) {
+        return Strings.isNullOrEmpty(parameters) ? "Specify the owner of the ToDoItems to be recreated" : null;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForDick.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForDick.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForDick.java
new file mode 100644
index 0000000..f95e100
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForDick.java
@@ -0,0 +1,32 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsRecreate;
+
+public final class RecreateToDoItemsForDick extends ToDoItemsRecreate {
+
+    public RecreateToDoItemsForDick() {
+        super("dick");
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForJoe.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForJoe.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForJoe.java
new file mode 100644
index 0000000..b6b5a28
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForJoe.java
@@ -0,0 +1,32 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsRecreate;
+
+public final class RecreateToDoItemsForJoe extends ToDoItemsRecreate {
+
+    public RecreateToDoItemsForJoe() {
+        super("joe");
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForSven.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForSven.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForSven.java
new file mode 100644
index 0000000..ec57d94
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/scenarios/RecreateToDoItemsForSven.java
@@ -0,0 +1,32 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.scenarios;
+
+import fixture.todo.simple.ToDoItemsRecreate;
+
+public final class RecreateToDoItemsForSven extends ToDoItemsRecreate {
+
+    public RecreateToDoItemsForSven() {
+        super("sven");
+        withDiscoverability(Discoverability.DISCOVERABLE);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsDelete.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsDelete.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsDelete.java
new file mode 100644
index 0000000..f9c81d0
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsDelete.java
@@ -0,0 +1,56 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.simple;
+
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.objectstore.jdo.applib.service.support.IsisJdoSupport;
+
+public class ToDoItemsDelete extends FixtureScript {
+
+    //region > constructor
+    private final String user;
+
+    /**
+     * @param user - if null then executes for the current user or will use any {@link ${symbol_pound}run(String) parameters} provided when run.
+     */
+    public ToDoItemsDelete(final String user) {
+        super(null, Util.localNameFor("delete", user));
+        this.user = user;
+    }
+    //endregion
+
+    //region > execute
+    @Override
+    protected void execute(ExecutionContext executionContext) {
+        final String ownedBy = Util.coalesce(user, executionContext.getParameters(), getContainer().getUser().getName());
+
+        isisJdoSupport.executeUpdate("delete from ${symbol_escape}"ToDoItem${symbol_escape}" where ${symbol_escape}"ownedBy${symbol_escape}" = '" + ownedBy + "'");
+    }
+
+    //endregion
+
+    //region > injected services
+    @javax.inject.Inject
+    private IsisJdoSupport isisJdoSupport;
+    //endregion
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreate.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreate.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreate.java
new file mode 100644
index 0000000..8f8077e
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreate.java
@@ -0,0 +1,98 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.simple;
+
+import dom.todo.ToDoItem;
+import dom.todo.ToDoItem.Category;
+import dom.todo.ToDoItem.Subcategory;
+import dom.todo.ToDoItems;
+
+import java.math.BigDecimal;
+import org.joda.time.LocalDate;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+import org.apache.isis.applib.services.clock.ClockService;
+
+public class ToDoItemsRecreate extends FixtureScript {
+
+    //region > constructor
+    private final String user;
+
+    /**
+     * @param user - if null then executes for the current user or will use any {@link ${symbol_pound}run(String) parameters} provided when run.
+     */
+    public ToDoItemsRecreate(final String user) {
+        super(null, Util.localNameFor("create", user));
+        this.user = user;
+    }
+    //endregion
+
+    //region > execute
+    @Override
+    protected void execute(ExecutionContext executionContext) {
+        final String ownedBy = Util.coalesce(user, executionContext.getParameters(), getContainer().getUser().getName());
+
+        // prereqs
+        execute(new ToDoItemsDelete(null), executionContext);
+
+        // this fixture
+        createToDoItem("Buy milk", Category.Domestic, Subcategory.Shopping, ownedBy, nowPlusDays(0), new BigDecimal("0.75"), executionContext);
+        createToDoItem("Buy bread", Category.Domestic, Subcategory.Shopping, ownedBy, nowPlusDays(0), new BigDecimal("1.75"), executionContext);
+        createToDoItem("Buy stamps", Category.Domestic, Subcategory.Shopping, ownedBy, nowPlusDays(0), new BigDecimal("10.00"), executionContext);
+        createToDoItem("Pick up laundry", Category.Domestic, Subcategory.Chores, ownedBy, nowPlusDays(6), new BigDecimal("7.50"), executionContext);
+        createToDoItem("Mow lawn", Category.Domestic, Subcategory.Garden, ownedBy, nowPlusDays(6), null, executionContext);
+        createToDoItem("Vacuum house", Category.Domestic, Subcategory.Housework, ownedBy, nowPlusDays(3), null, executionContext);
+        createToDoItem("Sharpen knives", Category.Domestic, Subcategory.Chores, ownedBy, nowPlusDays(14), null, executionContext);
+
+        createToDoItem("Write to penpal", Category.Other, Subcategory.Other, ownedBy, null, null, executionContext);
+
+        createToDoItem("Write blog post", Category.Professional, Subcategory.Marketing, ownedBy, nowPlusDays(7), null, executionContext);
+        createToDoItem("Organize brown bag", Category.Professional, Subcategory.Consulting, ownedBy, nowPlusDays(14), null, executionContext);
+        createToDoItem("Submit conference session", Category.Professional, Subcategory.Education, ownedBy, nowPlusDays(21), null, executionContext);
+        createToDoItem("Stage Isis release", Category.Professional, Subcategory.OpenSource, ownedBy, null, null, executionContext);
+    }
+
+    private ToDoItem createToDoItem(
+            final String description,
+            final Category category, Subcategory subcategory,
+            final String user,
+            final LocalDate dueBy,
+            final BigDecimal cost,
+            final ExecutionContext executionContext) {
+        ToDoItem newToDo = toDoItems.newToDo(description, category, subcategory, user, dueBy, cost);
+        return executionContext.add(this, newToDo);
+    }
+
+    private LocalDate nowPlusDays(int days) {
+        return clockService.now().plusDays(days);
+    }
+    //endregion
+
+    //region > injected services
+    @javax.inject.Inject
+    private ToDoItems toDoItems;
+
+    @javax.inject.Inject
+    private ClockService clockService;
+    //endregion
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreateAndCompleteSeveral.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreateAndCompleteSeveral.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreateAndCompleteSeveral.java
new file mode 100644
index 0000000..b04bfd5
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/ToDoItemsRecreateAndCompleteSeveral.java
@@ -0,0 +1,75 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.simple;
+
+import dom.todo.ToDoItem;
+
+import java.util.Collection;
+import com.google.common.base.Objects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Collections2;
+import org.apache.isis.applib.fixturescripts.FixtureScript;
+
+public class ToDoItemsRecreateAndCompleteSeveral extends FixtureScript {
+
+    //region > constructor
+    private final String user;
+    /**
+     * @param user - if null then executes for the current user or will use any {@link ${symbol_pound}run(String) parameters} provided when run.
+     */
+    public ToDoItemsRecreateAndCompleteSeveral(final String user) {
+        super(null, Util.localNameFor("complete", user));
+        this.user = user;
+    }
+    //endregion
+
+    //region > doRun
+    @Override
+    protected void execute(ExecutionContext executionContext) {
+        final String ownedBy = Util.coalesce(user, executionContext.getParameters(), getContainer().getUser().getName());
+
+        // prereqs
+        execute(new ToDoItemsRecreate(null), executionContext);
+
+        // this fixture
+        complete(ownedBy, "Buy stamps", executionContext);
+        complete(ownedBy, "Write blog post", executionContext);
+    }
+
+    private void complete(final String user, final String description, final ExecutionContext executionContext) {
+        final ToDoItem toDoItem = findToDoItem(description, user);
+        toDoItem.setComplete(true);
+        executionContext.add(this, toDoItem);
+    }
+
+    private ToDoItem findToDoItem(final String description, final String user) {
+        final Collection<ToDoItem> filtered = Collections2.filter(getContainer().allInstances(ToDoItem.class), new Predicate<ToDoItem>() {
+            @Override
+            public boolean apply(ToDoItem input) {
+                return Objects.equal(description, input.getDescription()) &&
+                       Objects.equal(user, input.getOwnedBy());
+            }
+        });
+        return filtered.isEmpty()? null: filtered.iterator().next();
+    }
+    //endregion
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/Util.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/Util.java b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/Util.java
new file mode 100644
index 0000000..133a35b
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/fixture/src/main/java/fixture/todo/simple/Util.java
@@ -0,0 +1,39 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/*
+ *  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 fixture.todo.simple;
+
+public final class Util {
+    
+    private Util(){}
+
+    static String localNameFor(final String prefix, String user) {
+        return prefix + "-" + coalesce(user, "current");
+    }
+
+    static String coalesce(final String... strings) {
+        for (String str : strings) {
+            if(str != null) { return str; }
+        }
+        return null;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/logging.properties
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/logging.properties b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/logging.properties
new file mode 100644
index 0000000..f49afbf
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/logging.properties
@@ -0,0 +1,104 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+${symbol_pound}  Licensed to the Apache Software Foundation (ASF) under one
+${symbol_pound}  or more contributor license agreements.  See the NOTICE file
+${symbol_pound}  distributed with this work for additional information
+${symbol_pound}  regarding copyright ownership.  The ASF licenses this file
+${symbol_pound}  to you under the Apache License, Version 2.0 (the
+${symbol_pound}  "License"); you may not use this file except in compliance
+${symbol_pound}  with the License.  You may obtain a copy of the License at
+${symbol_pound}  
+${symbol_pound}         http://www.apache.org/licenses/LICENSE-2.0
+${symbol_pound}         
+${symbol_pound}  Unless required by applicable law or agreed to in writing,
+${symbol_pound}  software distributed under the License is distributed on an
+${symbol_pound}  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+${symbol_pound}  KIND, either express or implied.  See the License for the
+${symbol_pound}  specific language governing permissions and limitations
+${symbol_pound}  under the License.
+
+
+${symbol_pound}
+${symbol_pound} Isis uses log4j is used to provide system logging
+${symbol_pound}
+log4j.rootCategory=INFO, Console
+
+${symbol_pound} The console appender
+log4j.appender.Console=org.apache.log4j.ConsoleAppender
+log4j.appender.Console.target=System.out
+log4j.appender.Console.layout=org.apache.log4j.PatternLayout
+log4j.appender.Console.layout.ConversionPattern=%d{ABSOLUTE}  [%-20c{1} %-10t %-5p]  %m%n
+
+log4j.appender.File=org.apache.log4j.RollingFileAppender
+log4j.appender.File.file=isis.log
+log4j.appender.File.append=false
+log4j.appender.File.layout=org.apache.log4j.PatternLayout
+log4j.appender.File.layout.ConversionPattern=%d [%-20c{1} %-10t %-5p]  %m%n
+
+! turn on the internal log4j debugging flag so we can see what it is doing
+${symbol_pound}log4j.debug=true
+
+${symbol_pound} DataNucleus
+${symbol_pound} the first two log the DML and DDL (if set to DEBUG)
+log4j.logger.DataNucleus.Datastore.Native=WARN, Console
+log4j.logger.DataNucleus.Datastore.Schema=DEBUG, Console
+${symbol_pound} the remainder can probably be left to WARN
+log4j.logger.DataNucleus.Persistence=WARN, Console
+log4j.logger.DataNucleus.Transaction=WARN, Console
+log4j.logger.DataNucleus.Connection=WARN, Console
+log4j.logger.DataNucleus.Query=WARN, Console
+log4j.logger.DataNucleus.Cache=WARN, Console
+log4j.logger.DataNucleus.MetaData=WARN, Console
+log4j.logger.DataNucleus.Datastore=WARN, Console
+log4j.logger.DataNucleus.Datastore.Persist=WARN, Console
+log4j.logger.DataNucleus.Datastore.Retrieve=WARN, Console
+log4j.logger.DataNucleus.General=WARN, Console
+log4j.logger.DataNucleus.Lifecycle=WARN, Console
+log4j.logger.DataNucleus.ValueGeneration=WARN, Console
+log4j.logger.DataNucleus.Enhancer=WARN, Console
+log4j.logger.DataNucleus.SchemaTool=ERROR, Console
+log4j.logger.DataNucleus.JDO=WARN, Console
+log4j.logger.DataNucleus.JPA=ERROR, Console
+log4j.logger.DataNucleus.JCA=WARN, Console
+log4j.logger.DataNucleus.IDE=ERROR, Console
+
+log4j.additivity.DataNucleus.Datastore.Native=false
+log4j.additivity.DataNucleus.Datastore.Schema=false
+log4j.additivity.DataNucleus.Datastore.Persistence=false
+log4j.additivity.DataNucleus.Datastore.Transaction=false
+log4j.additivity.DataNucleus.Datastore.Connection=false
+log4j.additivity.DataNucleus.Datastore.Query=false
+log4j.additivity.DataNucleus.Datastore.Cache=false
+log4j.additivity.DataNucleus.Datastore.MetaData=false
+log4j.additivity.DataNucleus.Datastore.Datastore=false
+log4j.additivity.DataNucleus.Datastore.Datastore.Persist=false
+log4j.additivity.DataNucleus.Datastore.Datastore.Retrieve=false
+log4j.additivity.DataNucleus.Datastore.General=false
+log4j.additivity.DataNucleus.Datastore.Lifecycle=false
+log4j.additivity.DataNucleus.Datastore.ValueGeneration=false
+log4j.additivity.DataNucleus.Datastore.Enhancer=false
+log4j.additivity.DataNucleus.Datastore.SchemaTool=false
+log4j.additivity.DataNucleus.Datastore.JDO=false
+log4j.additivity.DataNucleus.Datastore.JPA=false
+log4j.additivity.DataNucleus.Datastore.JCA=false
+log4j.additivity.DataNucleus.Datastore.IDE=false
+
+
+
+
+${symbol_pound} if using log4jdbc-remix as JDBC driver
+${symbol_pound}log4j.logger.jdbc.sqlonly=DEBUG, sql, Console
+${symbol_pound}log4j.additivity.jdbc.sqlonly=false
+${symbol_pound}log4j.logger.jdbc.resultsettable=DEBUG, jdbc, Console
+${symbol_pound}log4j.additivity.jdbc.resultsettable=false
+
+${symbol_pound}log4j.logger.jdbc.audit=WARN,jdbc, Console
+${symbol_pound}log4j.additivity.jdbc.audit=false
+${symbol_pound}log4j.logger.jdbc.resultset=WARN,jdbc
+${symbol_pound}log4j.additivity.jdbc.resultset=false
+${symbol_pound}log4j.logger.jdbc.sqltiming=WARN,sqltiming
+${symbol_pound}log4j.additivity.jdbc.sqltiming=false
+${symbol_pound}log4j.logger.jdbc.connection=FATAL,connection
+${symbol_pound}log4j.additivity.jdbc.connection=false
+

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/pom.xml
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/pom.xml b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/pom.xml
new file mode 100644
index 0000000..93dbfee
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+--><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+
+    <parent>
+    	<groupId>${groupId}</groupId>
+        <artifactId>${rootArtifactId}</artifactId>
+        <version>${version}</version>
+    </parent>
+
+	<artifactId>${artifactId}</artifactId>
+	<name>Quickstart Wicket/Restful/JDO Integration Tests</name>
+
+    <build>
+        <testResources>
+            <testResource>
+                <directory>src/test/resources</directory>
+            </testResource>
+            <testResource>
+                <directory>src/test/java</directory>
+                <includes>
+                    <include>**</include>
+                </includes>
+                <excludes>
+                    <exclude>**/*.java</exclude>
+                </excludes>
+            </testResource>
+        </testResources>  
+    </build>
+  	<dependencies>
+	
+		<!-- other modules in this project -->
+		<dependency>
+			<groupId>${project.groupId}</groupId>
+			<artifactId>${rootArtifactId}-fixture</artifactId>
+		</dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-unittestsupport</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-integtestsupport</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-specsupport</artifactId>
+        </dependency>
+        
+        <dependency>
+            <groupId>org.hamcrest</groupId>
+            <artifactId>hamcrest-library</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.isis.core</groupId>
+            <artifactId>isis-core-wrapper</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.isis.objectstore</groupId>
+            <artifactId>isis-objectstore-jdo-datanucleus</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.hsqldb</groupId>
+            <artifactId>hsqldb</artifactId>
+        </dependency>
+
+        <!-- 
+        uncomment to enable enhanced cucumber-jvm reporting
+        http://www.masterthought.net/section/cucumber-reporting
+        <dependency>  
+            <groupId>com.googlecode.totallylazy</groupId>  
+            <artifactId>totallylazy</artifactId>  
+            <version>991</version>  
+        </dependency>
+
+        <dependency>
+            <groupId>net.masterthought</groupId>
+            <artifactId>cucumber-reporting</artifactId>
+            <version>0.0.21</version>
+        </dependency>
+        <dependency>
+            <groupId>net.masterthought</groupId>
+            <artifactId>maven-cucumber-reporting</artifactId>
+            <version>0.0.4</version>
+        </dependency>  
+        -->
+	</dependencies>
+
+    <!-- 
+    uncomment for enhanced cucumber-jvm reporting
+    http://www.masterthought.net/section/cucumber-reporting
+    <repositories>  
+        <repository>  
+            <id>repo.bodar.com</id>  
+            <url>http://repo.bodar.com</url>  
+        </repository>  
+    </repositories>  
+     -->
+  
+
+</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/8cbe55c5/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/src/test/java/integration/ToDoSystemInitializer.java
----------------------------------------------------------------------
diff --git a/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/src/test/java/integration/ToDoSystemInitializer.java b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/src/test/java/integration/ToDoSystemInitializer.java
new file mode 100644
index 0000000..f0f0cdf
--- /dev/null
+++ b/example/archetype/todo-app/src/main/resources/archetype-resources/integtests/src/test/java/integration/ToDoSystemInitializer.java
@@ -0,0 +1,91 @@
+#set( $symbol_pound = '#' )
+#set( $symbol_dollar = '$' )
+#set( $symbol_escape = '\' )
+/**
+ *  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 integration;
+
+import app.ToDoItemAnalysis;
+import dom.todo.ToDoItemContributions;
+import dom.todo.ToDoItemSubscriptions;
+import dom.todo.ToDoItems;
+import fixture.todo.ToDoItemsFixturesService;
+
+import org.apache.isis.applib.annotation.Bulk;
+import org.apache.isis.applib.services.classdiscovery.ClassDiscoveryServiceUsingReflections;
+import org.apache.isis.applib.services.clock.ClockService;
+import org.apache.isis.applib.services.queryresultscache.QueryResultsCache;
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.integtestsupport.IsisSystemForTest;
+import org.apache.isis.core.metamodel.services.bookmarks.BookmarkServiceDefault;
+import org.apache.isis.core.runtime.services.memento.MementoServiceDefault;
+import org.apache.isis.core.wrapper.WrapperFactoryDefault;
+import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPersistenceMechanismInstaller;
+import org.apache.isis.objectstore.jdo.datanucleus.IsisConfigurationForJdoIntegTests;
+import org.apache.isis.objectstore.jdo.datanucleus.service.eventbus.EventBusServiceJdo;
+import org.apache.isis.objectstore.jdo.datanucleus.service.support.IsisJdoSupportImpl;
+
+/**
+ * Holds an instance of an {@link IsisSystemForTest} as a {@link ThreadLocal} on the current thread,
+ * initialized with ToDo app's domain services. 
+ */
+public class ToDoSystemInitializer {
+    
+    private ToDoSystemInitializer(){}
+
+    public static IsisSystemForTest initIsft() {
+        IsisSystemForTest isft = IsisSystemForTest.getElseNull();
+        if(isft == null) {
+            isft = new ToDoSystemBuilder().build().setUpSystem();
+            IsisSystemForTest.set(isft);
+        }
+        return isft;
+    }
+
+    private static class ToDoSystemBuilder extends IsisSystemForTest.Builder {
+
+        public ToDoSystemBuilder() {
+            //withFixtures( ... reference data fixtures ...); // if we had any...
+            withLoggingAt(org.apache.log4j.Level.INFO);
+            with(testConfiguration());
+            with(new DataNucleusPersistenceMechanismInstaller());
+            
+            withServices(
+                    new ToDoItems(),
+                    new ToDoItemAnalysis(),
+                    new ToDoItemContributions(),
+                    new ToDoItemsFixturesService(),
+                    new ClassDiscoveryServiceUsingReflections(),
+                    new ToDoItemSubscriptions(),
+                    new WrapperFactoryDefault(),
+                    new IsisJdoSupportImpl(),
+                    new Bulk.InteractionContext(),
+                    new EventBusServiceJdo(),
+                    new QueryResultsCache(),
+                    new MementoServiceDefault(),
+                    new BookmarkServiceDefault(),
+                    new ClockService()
+                    );
+        }
+
+        private static IsisConfiguration testConfiguration() {
+            final IsisConfigurationForJdoIntegTests testConfiguration = new IsisConfigurationForJdoIntegTests();
+            testConfiguration.addRegisterEntitiesPackagePrefix("dom");
+            return testConfiguration;
+        }
+    }
+}