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 2013/07/12 09:08:24 UTC

[08/19] ISIS-463: mothballing BDD viewer

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractFixturePeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractFixturePeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractFixturePeer.java
new file mode 100644
index 0000000..573dbd6
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractFixturePeer.java
@@ -0,0 +1,88 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.mgr.AdapterManager;
+import org.apache.isis.core.metamodel.spec.SpecificationLoaderSpi;
+import org.apache.isis.core.runtime.system.context.IsisContext;
+import org.apache.isis.core.runtime.system.persistence.ObjectStore;
+import org.apache.isis.core.runtime.system.persistence.PersistenceSession;
+import org.apache.isis.core.runtime.system.transaction.IsisTransactionManager;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+
+public abstract class AbstractFixturePeer {
+
+    private final AliasRegistry aliasRegistry;
+    private final List<CellBinding> cellBindings;
+
+    public AbstractFixturePeer(final AliasRegistry aliasRegistry, final CellBinding... cellBindings) {
+        this(aliasRegistry, Arrays.asList(cellBindings));
+    }
+
+    public AbstractFixturePeer(final AliasRegistry storyRegistries, final List<CellBinding> cellBindings) {
+        this.aliasRegistry = storyRegistries;
+        this.cellBindings = cellBindings;
+    }
+
+    public AliasRegistry getAliasRegistry() {
+        return aliasRegistry;
+    }
+
+    public List<CellBinding> getCellBindings() {
+        return cellBindings;
+    }
+
+    public List<Object> getServices() {
+        return IsisContext.getServices();
+    }
+
+    public SpecificationLoaderSpi getSpecificationLoader() {
+        return IsisContext.getSpecificationLoader();
+    }
+
+    public AuthenticationSession getAuthenticationSession() {
+        return IsisContext.getAuthenticationSession();
+    }
+
+    public PersistenceSession getPersistenceSession() {
+        return IsisContext.getPersistenceSession();
+    }
+
+    protected AdapterManager getAdapterManager() {
+        return getPersistenceSession().getAdapterManager();
+    }
+
+    protected ObjectStore getObjectStore() {
+        return getPersistenceSession().getObjectStore();
+    }
+
+    protected IsisTransactionManager getTransactionManager() {
+        return IsisContext.getTransactionManager();
+    }
+
+    public boolean isValidAlias(final String alias) {
+        return getAliasRegistry().getAliased(alias) != null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractListFixturePeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractListFixturePeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractListFixturePeer.java
new file mode 100644
index 0000000..3201927
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractListFixturePeer.java
@@ -0,0 +1,87 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.google.common.collect.Iterables;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionFacet;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioValueException;
+
+public class AbstractListFixturePeer extends AbstractFixturePeer {
+
+    private final String listAlias;
+
+    /**
+     * @see #collectionAdapters()
+     */
+    private List<ObjectAdapter> objects;
+
+    public AbstractListFixturePeer(final AliasRegistry aliasesRegistry, final String listAlias, final CellBinding... cellBindings) {
+        super(aliasesRegistry, cellBindings);
+
+        this.listAlias = listAlias;
+    }
+
+    protected boolean isValidListAlias() {
+        return getListAdapter() != null && isList();
+    }
+
+    protected ObjectAdapter getListAdapter() {
+        return getAliasRegistry().getAliased(listAlias);
+    }
+
+    public void assertIsList() throws ScenarioValueException {
+        if (!(getListAdapter() != null)) {
+            throw new ScenarioValueException("no such alias");
+        }
+        if (!isList()) {
+            throw new ScenarioValueException("not a list");
+        }
+    }
+
+    public boolean isList() {
+        return getCollectionFacet() != null;
+    }
+
+    /**
+     * Lazily populated, and populated only once.
+     */
+    protected List<ObjectAdapter> collectionAdapters() {
+        if (objects == null) {
+            objects = new ArrayList<ObjectAdapter>();
+            Iterables.addAll(objects, collectionContents());
+        }
+        return objects;
+    }
+
+    private Iterable<ObjectAdapter> collectionContents() {
+        return getCollectionFacet().iterable(getListAdapter());
+    }
+
+    private CollectionFacet getCollectionFacet() {
+        return getListAdapter() != null ? getListAdapter().getSpecification().getFacet(CollectionFacet.class) : null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractSetUpFixturePeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractSetUpFixturePeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractSetUpFixturePeer.java
new file mode 100644
index 0000000..e329f1d
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AbstractSetUpFixturePeer.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+
+public class AbstractSetUpFixturePeer extends AbstractFixturePeer {
+
+    public AbstractSetUpFixturePeer(final AliasRegistry aliasRegistry, final CellBinding... cellBindings) {
+        super(aliasRegistry, cellBindings);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AliasItemsInListPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AliasItemsInListPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AliasItemsInListPeer.java
new file mode 100644
index 0000000..a0b8e21
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/AliasItemsInListPeer.java
@@ -0,0 +1,105 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioBoundValueException;
+import org.apache.isis.viewer.bdd.common.ScenarioCell;
+
+public class AliasItemsInListPeer extends AbstractListFixturePeer {
+
+    private final CellBinding titleBinding;
+    private final CellBinding typeBinding;
+    private final CellBinding aliasBinding;
+
+    public AliasItemsInListPeer(final AliasRegistry aliasesRegistry, final String listAlias, final CellBinding titleBinding, final CellBinding typeBinding, final CellBinding aliasBinding) {
+        super(aliasesRegistry, listAlias, titleBinding, typeBinding, aliasBinding);
+
+        this.titleBinding = titleBinding;
+        this.typeBinding = typeBinding;
+        this.aliasBinding = aliasBinding;
+    }
+
+    public CellBinding getTitleBinding() {
+        return titleBinding;
+    }
+
+    public CellBinding getTypeBinding() {
+        return typeBinding;
+    }
+
+    public CellBinding getAliasBinding() {
+        return aliasBinding;
+    }
+
+    public ScenarioCell findAndAlias() throws ScenarioBoundValueException {
+        final ObjectAdapter foundAdapter = findAdapter();
+        if (foundAdapter == null) {
+            throw ScenarioBoundValueException.current(titleBinding, "not found");
+        }
+
+        final ScenarioCell currentCell = aliasBinding.getCurrentCell();
+        final String currentCellText = currentCell.getText();
+        getAliasRegistry().aliasAs(currentCellText, foundAdapter);
+        return currentCell;
+    }
+
+    private ObjectAdapter findAdapter() {
+        for (final ObjectAdapter adapter : collectionAdapters()) {
+
+            if (!titleMatches(adapter)) {
+                continue; // keep looking
+            }
+            if (!typeMatches(adapter)) {
+                continue; // keep looking
+            }
+
+            return adapter;
+        }
+        return null;
+    }
+
+    private boolean titleMatches(final ObjectAdapter adapter) {
+        final String adapterTitle = adapter.titleString();
+        final String requiredTitle = titleBinding.getCurrentCell().getText();
+        return StringUtils.nullSafeEquals(adapterTitle, requiredTitle);
+    }
+
+    private boolean typeMatches(final ObjectAdapter adapter) {
+        if (typeBinding == null || !typeBinding.isFound()) {
+            return true;
+        }
+
+        final ObjectSpecification spec = adapter.getSpecification();
+        final String requiredTypeName = typeBinding.getCurrentCell().getText();
+        final String specFullName = spec.getFullIdentifier();
+        if (specFullName.equals(requiredTypeName)) {
+            return true;
+        }
+
+        final String simpleSpecName = StringUtils.simpleName(specFullName);
+        final String simpleRequiredType = StringUtils.simpleName(requiredTypeName);
+        return simpleSpecName.equalsIgnoreCase(simpleRequiredType);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckCollectionContentsPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckCollectionContentsPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckCollectionContentsPeer.java
new file mode 100644
index 0000000..7155dd5
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckCollectionContentsPeer.java
@@ -0,0 +1,119 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+
+public class CheckCollectionContentsPeer extends AbstractListFixturePeer {
+
+    public CheckCollectionContentsPeer(final AliasRegistry aliasesRegistry, final String listAlias) {
+        super(aliasesRegistry, listAlias);
+    }
+
+    /**
+     * Returns <tt>true</tt> if collection contains specified alias.
+     * 
+     * <p>
+     * If either the list alias is invalid, or the provided alias is
+     * {@link #isValidAlias(String) invalid}, will return <tt>false</tt>.
+     */
+    public boolean contains(final String alias) {
+        if (!isValidListAlias()) {
+            return false;
+        }
+
+        final ObjectAdapter adapter = getAliasRegistry().getAliased(alias);
+        if (adapter == null) {
+            return false;
+        }
+        return collectionAdapters().contains(adapter);
+    }
+
+    /**
+     * Returns <tt>true</tt> if collection does not contain specified alias.
+     * 
+     * <p>
+     * If either the list alias is invalid, or the provided alias is
+     * {@link #isValidAlias(String) invalid}, will return <tt>false</tt>.
+     */
+    public boolean doesNotContain(final String alias) {
+        if (!isValidListAlias()) {
+            return false;
+        }
+        final ObjectAdapter adapter = getAliasRegistry().getAliased(alias);
+        if (adapter == null) {
+            return false;
+        }
+        return !collectionAdapters().contains(adapter);
+    }
+
+    /**
+     * Returns <tt>true</tt> if is empty.
+     * 
+     * @return <tt>false</tt> if the alias is invalid or does not represent a
+     *         list
+     */
+    public boolean isEmpty() {
+        if (!isValidListAlias()) {
+            return false;
+        }
+        return collectionAdapters().size() == 0;
+    }
+
+    /**
+     * Returns <tt>true</tt> if is not empty.
+     * 
+     * @return <tt>false</tt> if the alias is invalid or does not represent a
+     *         list
+     */
+    public boolean isNotEmpty() {
+        if (!isValidListAlias()) {
+            return false;
+        }
+
+        return collectionAdapters().size() != 0;
+    }
+
+    /**
+     * Returns <tt>true</tt> if collection has specified size.
+     * 
+     * @return <tt>false</tt> if the alias is invalid or does not represent a
+     *         list
+     */
+    public boolean assertSize(final int size) {
+        if (!isValidListAlias()) {
+            return false;
+        }
+        return getSize() == size;
+    }
+
+    /**
+     * Returns the size of the collection.
+     * 
+     * @return <tt>-1</tt> if the alias is invalid or does not represent a list.
+     */
+    public int getSize() {
+        if (!isValidListAlias()) {
+            return -1;
+        }
+        return collectionAdapters().size();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListConstants.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListConstants.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListConstants.java
new file mode 100644
index 0000000..69c7cf6
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListConstants.java
@@ -0,0 +1,30 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+public final class CheckListConstants {
+
+    private CheckListConstants() {
+    }
+
+    public static final String TITLE_HEAD = "title";
+    public static final String[] TITLE_HEAD_SET = { TITLE_HEAD };
+    public static final String TITLE_NAME = TITLE_HEAD;
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListPeer.java
new file mode 100644
index 0000000..5244d3d
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/CheckListPeer.java
@@ -0,0 +1,148 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+
+public class CheckListPeer extends AbstractListFixturePeer {
+
+    public static enum CheckMode {
+        EXACT {
+            @Override
+            public boolean isExact() {
+                return true;
+            }
+        },
+        NOT_EXACT {
+            @Override
+            public boolean isExact() {
+                return false;
+            }
+        };
+        public abstract boolean isExact();
+    }
+
+    private final CheckMode checkMode;
+
+    private final CellBinding titleBinding;
+    /**
+     * Can be set to null, indicating that no type checking is performed.
+     */
+    private final CellBinding typeBinding;
+
+    /**
+     * Objects found while processing table.
+     */
+    private final List<ObjectAdapter> foundAdapters = new ArrayList<ObjectAdapter>();
+
+    public CheckListPeer(final AliasRegistry aliasesRegistry, final String listAlias, final CheckMode checkMode, final CellBinding titleBinding) {
+        this(aliasesRegistry, listAlias, checkMode, titleBinding, null);
+    }
+
+    public CheckListPeer(final AliasRegistry aliasesRegistry, final String listAlias, final CheckMode checkMode, final CellBinding titleBinding, final CellBinding typeBinding) {
+        super(aliasesRegistry, listAlias, titleBinding, typeBinding);
+        this.checkMode = checkMode;
+        this.titleBinding = titleBinding;
+        this.typeBinding = typeBinding;
+    }
+
+    public boolean isCheckModeExact() {
+        return getCheckMode().isExact();
+    }
+
+    public CellBinding getTitleBinding() {
+        return titleBinding;
+    }
+
+    /**
+     * May be <tt>null</tt> (indicating that no type checking to be performed.
+     */
+    public CellBinding getTypeBinding() {
+        return typeBinding;
+    }
+
+    private CheckMode getCheckMode() {
+        return checkMode;
+    }
+
+    public List<ObjectAdapter> getFoundAdapters() {
+        return foundAdapters;
+    }
+
+    public List<ObjectAdapter> getNotFoundAdapters() {
+        final List<ObjectAdapter> allAdapters = new ArrayList<ObjectAdapter>(collectionAdapters());
+        allAdapters.removeAll(foundAdapters);
+        return allAdapters;
+    }
+
+    public boolean findAndAddObject() {
+        final ObjectAdapter foundAdapter = findAdapter();
+        if (foundAdapter == null) {
+            return false;
+        }
+        foundAdapters.add(foundAdapter);
+        return true;
+    }
+
+    private ObjectAdapter findAdapter() {
+        for (final ObjectAdapter adapter : collectionAdapters()) {
+
+            if (!titleMatches(adapter)) {
+                continue; // keep looking
+            }
+            if (!typeMatches(adapter)) {
+                continue; // keep looking
+            }
+
+            return adapter;
+        }
+        return null;
+    }
+
+    private boolean titleMatches(final ObjectAdapter adapter) {
+        final String adapterTitle = adapter.titleString();
+        final String requiredTitle = titleBinding.getCurrentCell().getText();
+        return StringUtils.nullSafeEquals(adapterTitle, requiredTitle);
+    }
+
+    private boolean typeMatches(final ObjectAdapter adapter) {
+        if (typeBinding == null || !typeBinding.isFound()) {
+            return true;
+        }
+
+        final ObjectSpecification spec = adapter.getSpecification();
+        final String requiredTypeName = typeBinding.getCurrentCell().getText();
+        final String specFullName = spec.getFullIdentifier();
+        if (specFullName.equals(requiredTypeName)) {
+            return true;
+        }
+
+        final String simpleSpecName = StringUtils.simpleName(specFullName);
+        final String simpleRequiredType = StringUtils.simpleName(requiredTypeName);
+        return simpleSpecName.equalsIgnoreCase(simpleRequiredType);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugClockPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugClockPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugClockPeer.java
new file mode 100644
index 0000000..e6a82e6
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugClockPeer.java
@@ -0,0 +1,49 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import org.apache.isis.applib.clock.Clock;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioCell;
+
+public class DebugClockPeer extends AbstractFixturePeer {
+
+    private final CellBinding cellBinding;
+    private final static SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MMM-yyyy HH:mm");
+
+    public DebugClockPeer(final AliasRegistry aliasesRegistry, final CellBinding cellBinding) {
+        super(aliasesRegistry, cellBinding);
+        this.cellBinding = cellBinding;
+    }
+
+    public ScenarioCell getCurrentCell() {
+        return cellBinding.getCurrentCell();
+    }
+
+    public String getFormattedClockTime() {
+        final Calendar cal = Clock.getTimeAsCalendar();
+        final String formattedDate = DATE_FORMAT.format(cal.getTime());
+        return formattedDate;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugObjectStorePeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugObjectStorePeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugObjectStorePeer.java
new file mode 100644
index 0000000..86e0c01
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugObjectStorePeer.java
@@ -0,0 +1,39 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import org.apache.isis.core.commons.debug.DebugString;
+import org.apache.isis.core.runtime.system.persistence.ObjectStore;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+
+public class DebugObjectStorePeer extends AbstractFixturePeer {
+
+    public DebugObjectStorePeer(final AliasRegistry aliasesRegistry, final CellBinding... cellBindings) {
+        super(aliasesRegistry, cellBindings);
+    }
+
+    public String debugObjectStore() {
+        final ObjectStore objectStore = getObjectStore();
+        final DebugString debug = new DebugString();
+        objectStore.debugData(debug);
+        return debug.toString().replaceAll("\n", "<br>");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugServicesPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugServicesPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugServicesPeer.java
new file mode 100644
index 0000000..767a13d
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/DebugServicesPeer.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.viewer.bdd.common.fixtures;
+
+import java.util.List;
+
+import org.apache.isis.core.commons.debug.DebugString;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+
+public class DebugServicesPeer extends AbstractFixturePeer {
+
+    public DebugServicesPeer(final AliasRegistry aliasesRegistry, final CellBinding... cellBindings) {
+        super(aliasesRegistry, cellBindings);
+    }
+
+    public String debugServices() {
+        final DebugString debug = new DebugString();
+
+        final List<Object> services = getServices();
+
+        for (final Object service : services) {
+            debug.append(service.getClass().getName());
+            debug.append("\n");
+        }
+        return debug.toString().replaceAll("\n", "<br>");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/SetUpObjectsPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/SetUpObjectsPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/SetUpObjectsPeer.java
new file mode 100644
index 0000000..321127e
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/SetUpObjectsPeer.java
@@ -0,0 +1,305 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertySetterFacet;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioBoundValueException;
+
+public class SetUpObjectsPeer extends AbstractFixturePeer {
+
+    public static enum Mode {
+        PERSIST, DO_NOT_PERSIST;
+
+        public boolean isPersist() {
+            return this == PERSIST;
+        }
+    }
+
+    public static enum PropertyResult {
+        ALIAS, NO_SUCH_PROPERTY, NOT_A_PROPERTY, OK;
+        public boolean isOk() {
+            return this == OK;
+        }
+    }
+
+    public static enum SetUpObjectResult {
+        OK, NO_ASSOCIATION, CLEARED, CANNOT_CLEAR("(cannot clear)"), CANNOT_SET("(cannot set"), CANNOT_PARSE("(cannot parse)"), UNKNOWN_REFERENCE("(unknown reference)");
+        private String errorMessage;
+
+        private SetUpObjectResult() {
+            this(null);
+        }
+
+        private SetUpObjectResult(final String errorMessage) {
+            this.errorMessage = errorMessage;
+        }
+
+        public boolean isHandled() {
+            return !isError();
+        }
+
+        public boolean isError() {
+            return errorMessage != null;
+        }
+
+        public String getErrorMessage() {
+            return errorMessage;
+        }
+    }
+
+    public interface AssociationVisitor {
+        void visit(OneToOneAssociation association, int colNum);
+    }
+
+    private final ObjectSpecification spec;
+
+    private final List<OneToOneAssociation> properties = new ArrayList<OneToOneAssociation>();
+    private final CellBinding aliasBinding;
+    private final SetUpObjectsPeer.Mode mode;
+
+    private final List<String> cellTextList = new ArrayList<String>();
+    private String alias;
+
+    // ///////////////////////////////////////////////////////////////////////
+    // constructor
+    // ///////////////////////////////////////////////////////////////////////
+
+    public SetUpObjectsPeer(final AliasRegistry aliasRegistry, final String className, final SetUpObjectsPeer.Mode mode, final CellBinding aliasBinding) {
+        super(aliasRegistry, aliasBinding);
+
+        this.spec = loadSpecIfValid(className);
+
+        this.mode = mode;
+        this.aliasBinding = aliasBinding;
+    }
+
+    private ObjectSpecification loadSpecIfValid(final String className) {
+        try {
+            return getSpecificationLoader().loadSpecification(className);
+        } catch (final IsisException ex) {
+            return null;
+        }
+    }
+
+    public boolean isSpecOk() {
+        return spec != null;
+    }
+
+    public List<OneToOneAssociation> getProperties() {
+        return properties;
+    }
+
+    public CellBinding getAliasBinding() {
+        return aliasBinding;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////
+    // header
+    // ///////////////////////////////////////////////////////////////////////
+
+    public PropertyResult definePropertyOrAlias(final String heading, final int colNum) {
+
+        OneToOneAssociation otoa = null;
+
+        try {
+            final int aliasColumn = getAliasBinding().getColumn();
+            if (colNum == aliasColumn) {
+                return PropertyResult.ALIAS;
+            }
+
+            ObjectAssociation association = null;
+            try {
+                final String memberName = StringUtils.memberIdFor(heading);
+                association = spec.getAssociation(memberName);
+            } catch (final Exception ex) {
+                return PropertyResult.NO_SUCH_PROPERTY;
+            }
+
+            if (!association.isOneToOneAssociation()) {
+                return PropertyResult.NOT_A_PROPERTY;
+            }
+
+            otoa = (OneToOneAssociation) association;
+
+            return PropertyResult.OK;
+        } finally {
+            // add an association if OK, add null otherwise
+            getProperties().add(otoa);
+        }
+    }
+
+    // ///////////////////////////////////////////////////////////////////////
+    // each row
+    // ///////////////////////////////////////////////////////////////////////
+
+    /**
+     * Used by Concordion only.
+     * 
+     * <p>
+     * FitNesse, on the other hand, uses a more fine-grained approach, calling
+     * the underlying methods.
+     */
+    public void createObject() throws ScenarioBoundValueException {
+        final ObjectAdapter adapter = createInstance();
+
+        for (int colNum = 0; colNum < getProperties().size(); colNum++) {
+            final SetUpObjectResult result = setUpProperty(adapter, colNum);
+
+            if (!result.isHandled()) {
+                final CellBinding cellBinding = getCellBindings().get(colNum);
+                throw ScenarioBoundValueException.current(cellBinding, result.getErrorMessage());
+            }
+        }
+
+        persistIfNecessary(adapter);
+        alias(adapter);
+        resetForNextObject();
+    }
+
+    public void resetForNextObject() {
+        cellTextList.clear();
+        this.alias = null;
+    }
+
+    public ObjectAdapter createInstance() {
+        if (spec == null) {
+            return null;
+        }
+        return getPersistenceSession().createTransientInstance(spec);
+    }
+
+    public SetUpObjectResult setUpProperty(final ObjectAdapter adapter, final int colNum) {
+
+        final OneToOneAssociation association = getProperties().get(colNum);
+        if (association == null) {
+            return SetUpObjectResult.NO_ASSOCIATION;
+        }
+
+        final String cellText = cellTextList.get(colNum);
+
+        // handle empty cell as null
+        if (cellText == null || cellText.length() == 0) {
+
+            // use clear facet if available
+            final PropertyClearFacet clearFacet = association.getFacet(PropertyClearFacet.class);
+
+            if (clearFacet != null) {
+                clearFacet.clearProperty(adapter);
+                return SetUpObjectResult.CLEARED;
+            }
+
+            // use setter facet otherwise
+            final PropertySetterFacet setterFacet = association.getFacet(PropertySetterFacet.class);
+
+            if (setterFacet != null) {
+                setterFacet.setProperty(adapter, null);
+                return SetUpObjectResult.CLEARED;
+            }
+
+            return SetUpObjectResult.CANNOT_CLEAR;
+        }
+
+        // non-empty, will need a setter
+        final PropertySetterFacet setterFacet = association.getFacet(PropertySetterFacet.class);
+        if (setterFacet == null) {
+            return SetUpObjectResult.CANNOT_SET;
+        }
+
+        final ObjectSpecification fieldSpecification = association.getSpecification();
+        final ParseableFacet parseableFacet = fieldSpecification.getFacet(ParseableFacet.class);
+
+        ObjectAdapter referencedAdapter = null;
+        if (parseableFacet != null) {
+            // handle as parseable value
+            try {
+                referencedAdapter = parseableFacet.parseTextEntry(adapter, cellText, null);
+            } catch (final IllegalArgumentException ex) {
+                return SetUpObjectResult.CANNOT_PARSE;
+            }
+
+        } else {
+            // handle as reference to known object
+            referencedAdapter = getAliasRegistry().getAliased(cellText);
+            if (referencedAdapter == null) {
+                return SetUpObjectResult.UNKNOWN_REFERENCE;
+            }
+        }
+
+        setterFacet.setProperty(adapter, referencedAdapter);
+        return SetUpObjectResult.OK;
+    }
+
+    public void persistIfNecessary(final ObjectAdapter adapter) {
+        if (mode.isPersist()) {
+            // xactn mgmt now done by PersistenceSession#makePersistent()
+            // getTransactionManager().startTransaction();
+            getPersistenceSession().makePersistent(adapter);
+            // getTransactionManager().endTransaction();
+        }
+    }
+
+    public void alias(final ObjectAdapter adapter) {
+        final String alias = aliasFor(adapter);
+        getAliasRegistry().aliasAs(alias, adapter);
+    }
+
+    public String aliasFor(final ObjectAdapter adapter) {
+        if (alias != null) {
+            return alias;
+        } else {
+            final String specShortName = StringUtils.lowerLeading(spec.getShortIdentifier());
+            return getAliasRegistry().aliasPrefixedAs(specShortName, adapter);
+        }
+    }
+
+    public void forEachAssociation(final AssociationVisitor visitor) {
+        for (int colNum = 0; colNum < getProperties().size(); colNum++) {
+            final OneToOneAssociation association = getProperties().get(colNum);
+            if (association != null) {
+                visitor.visit(association, colNum);
+            }
+        }
+    }
+
+    public boolean addPropertyValueOrAlias(final String propertyValue) {
+        cellTextList.add(propertyValue);
+
+        // capture alias if just added
+        final int aliasColumn1based = getAliasBinding().getColumn() + 1;
+        if (cellTextList.size() == aliasColumn1based) {
+            alias = propertyValue;
+        }
+
+        return true;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/UsingIsisViewerPeer.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/UsingIsisViewerPeer.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/UsingIsisViewerPeer.java
new file mode 100644
index 0000000..7524005
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/UsingIsisViewerPeer.java
@@ -0,0 +1,386 @@
+/*
+ *  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.viewer.bdd.common.fixtures;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.isis.core.commons.exceptions.NotYetImplementedException;
+import org.apache.isis.core.commons.lang.StringUtils;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.facets.object.parseable.ParseableFacet;
+import org.apache.isis.core.metamodel.facets.object.parseable.TextEntryParseException;
+import org.apache.isis.core.metamodel.spec.ActionType;
+import org.apache.isis.core.metamodel.spec.ObjectActionSet;
+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.ObjectActionContainer.Contributed;
+import org.apache.isis.core.metamodel.spec.feature.ObjectActionParameter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.runtime.system.DeploymentType;
+import org.apache.isis.viewer.bdd.common.AliasRegistry;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioBoundValueException;
+import org.apache.isis.viewer.bdd.common.ScenarioCell;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.AddToCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckAction;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckAddToCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckClearProperty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckObject;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckProperty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckRemoveFromCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.CheckSetProperty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.ClearProperty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetActionParameterChoices;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetActionParameterDefault;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetProperty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetPropertyChoices;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.GetPropertyDefault;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.InvokeAction;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.Perform;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.PerformContext;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.RemoveFromCollection;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.SaveObject;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.SetProperty;
+import org.apache.isis.viewer.bdd.common.parsers.DateParser;
+
+public class UsingIsisViewerPeer extends AbstractFixturePeer {
+
+    private static List<Perform> performCommands(final Perform.Mode mode) {
+        final ArrayList<Perform> commands = new ArrayList<Perform>();
+
+        commands.add(new CheckProperty(mode));
+        commands.add(new CheckSetProperty(mode));
+        commands.add(new CheckClearProperty(mode));
+        commands.add(new GetProperty(mode));
+        commands.add(new SetProperty(mode));
+        commands.add(new ClearProperty(mode));
+        commands.add(new GetPropertyDefault(mode));
+        commands.add(new GetPropertyChoices(mode));
+
+        commands.add(new CheckCollection(mode));
+        commands.add(new CheckAddToCollection(mode));
+        commands.add(new CheckRemoveFromCollection(mode));
+        commands.add(new AddToCollection(mode));
+        commands.add(new RemoveFromCollection(mode));
+        commands.add(new GetCollection(mode));
+
+        commands.add(new CheckAction(mode));
+        commands.add(new InvokeAction(mode));
+        commands.add(new GetActionParameterDefault(mode));
+        commands.add(new GetActionParameterChoices(mode));
+
+        commands.add(new CheckObject(mode));
+        commands.add(new SaveObject(mode));
+
+        return commands;
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // constructor
+    // //////////////////////////////////////////////////////////////////
+
+    private final CellBinding onObjectBinding;
+    private final CellBinding aliasResultAsBinding;
+    private final CellBinding performBinding;
+    private final CellBinding onMemberBinding;
+    private final CellBinding thatItBinding;
+    private final CellBinding arg0Binding;
+
+    private final DeploymentType deploymentType;
+    private final DateParser dateParser;
+
+    private final Map<String, Perform> commandByKey = new HashMap<String, Perform>();
+
+    public UsingIsisViewerPeer(final AliasRegistry aliasesRegistry, final DeploymentType deploymentType, final DateParser dateParser, final Perform.Mode mode, final CellBinding onObjectBinding, final CellBinding aliasResultAsBinding, final CellBinding performBinding,
+            final CellBinding onMemberBinding, final CellBinding thatItBinding, final CellBinding arg0Binding) {
+        super(aliasesRegistry, onObjectBinding, aliasResultAsBinding, performBinding, onMemberBinding, thatItBinding, arg0Binding);
+
+        this.onObjectBinding = onObjectBinding;
+        this.aliasResultAsBinding = aliasResultAsBinding;
+        this.performBinding = performBinding;
+        this.onMemberBinding = onMemberBinding;
+        this.thatItBinding = thatItBinding;
+        this.arg0Binding = arg0Binding;
+
+        this.deploymentType = deploymentType;
+        this.dateParser = dateParser;
+
+        final List<Perform> performCommands = performCommands(mode);
+        for (final Perform command : performCommands) {
+            commandByKey.put(command.getKey(), command);
+        }
+    }
+
+    public DeploymentType getDeploymentType() {
+        return deploymentType;
+    }
+
+    public DateParser getDateParser() {
+        return dateParser;
+    }
+
+    public CellBinding getOnObjectBinding() {
+        return onObjectBinding;
+    }
+
+    public CellBinding getAliasResultAsBinding() {
+        return aliasResultAsBinding;
+    }
+
+    public CellBinding getOnMemberBinding() {
+        return onMemberBinding;
+    }
+
+    public CellBinding getPerformBinding() {
+        return performBinding;
+    }
+
+    public CellBinding getThatItBinding() {
+        return thatItBinding;
+    }
+
+    public CellBinding getArg0Binding() {
+        return arg0Binding;
+    }
+
+    public boolean isArg0BindingLast() {
+        return !bindingAfterArg0();
+
+    }
+
+    private boolean bindingAfterArg0() {
+        if (!getArg0Binding().isFound()) {
+            return false;
+        }
+        for (final CellBinding binding : getCellBindings()) {
+            if (binding.getColumn() > getArg0Binding().getColumn()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // validate API
+    // //////////////////////////////////////////////////////////////////
+
+    public ObjectAdapter validateOnObject() throws ScenarioBoundValueException {
+
+        final ScenarioCell onObjectCell = onObjectBinding.getCurrentCell();
+        String onObject = onObjectCell.getText();
+        if (onObject == null) {
+            if (previousOnObject == null) {
+                throw ScenarioBoundValueException.current(onObjectBinding, "(required)");
+            }
+            onObject = previousOnObject;
+        } else {
+            previousOnObject = onObject;
+        }
+        final ObjectAdapter onAdapter = getAliasRegistry().getAliased(onObject);
+        if (onAdapter == null) {
+            throw ScenarioBoundValueException.current(onMemberBinding, "(unknown object)");
+        }
+        return onAdapter;
+    }
+
+    public String validateAliasAs() throws ScenarioBoundValueException {
+        if (getAliasResultAsBinding() == null) {
+            return null;
+        }
+        final ScenarioCell aliasCell = aliasResultAsBinding.getCurrentCell();
+        if (aliasCell == null) {
+            return null;
+        }
+
+        final String aliasAs = aliasCell.getText();
+        if (getAliasRegistry().getAliased(aliasAs) != null) {
+            throw ScenarioBoundValueException.current(aliasResultAsBinding, "(already used)");
+        }
+        return aliasAs;
+    }
+
+    public ObjectMember validateOnMember(final ObjectAdapter onAdapter) throws ScenarioBoundValueException {
+
+        final ScenarioCell onMemberCell = onMemberBinding.getCurrentCell();
+        final String onMember = onMemberCell.getText();
+
+        if (StringUtils.isNullOrEmpty(onMember)) {
+            throw ScenarioBoundValueException.current(onMemberBinding, "(required)");
+        }
+
+        if (onAdapter == null) {
+            return null;
+        }
+
+        // see if property, collection or action.
+        final String memberId = StringUtils.memberIdFor(onMember);
+        final ObjectSpecification spec = onAdapter.getSpecification();
+        final List<ObjectMember> objectMembers = new ArrayList<ObjectMember>();
+
+        objectMembers.addAll(spec.getAssociations());
+
+        // see if action (of any type)
+        objectMembers.addAll(spec.getObjectActions(Arrays.asList(ActionType.USER, ActionType.EXPLORATION, ActionType.DEBUG), Contributed.INCLUDED));
+        for (final ObjectMember member : objectMembers) {
+            if (matchesId(member, memberId)) {
+                return member;
+            }
+            // special handling for contributed actions.
+            if (member instanceof ObjectActionSet) {
+                final ObjectActionSet actionSet = (ObjectActionSet) member;
+                for (final ObjectAction contributedAction : actionSet.getActions()) {
+                    if (contributedAction.getId().equals(memberId)) {
+                        return contributedAction;
+                    }
+                }
+            }
+        }
+        throw ScenarioBoundValueException.current(onMemberBinding, "(unknown member)");
+    }
+
+    public Perform validatePerform() throws ScenarioBoundValueException {
+        final String perform = performBinding.getCurrentCell().getText();
+        if (perform == null) {
+            throw ScenarioBoundValueException.current(performBinding, "(required)");
+        }
+        final Perform performCommand = commandByKey.get(perform);
+        if (performCommand == null) {
+            throw ScenarioBoundValueException.current(performBinding, "(unknown interaction)");
+        }
+        return performCommand;
+    }
+
+    private boolean matchesId(final ObjectMember member, final String memberId) {
+        return member.getId().equals(memberId);
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    // "perform" API
+    // //////////////////////////////////////////////////////////////////
+
+    public void performCommand(final ObjectAdapter onAdapter, final String aliasAs, final ObjectMember objectMember, final Perform performCommand, final List<ScenarioCell> argumentStoryCells) throws ScenarioBoundValueException {
+        final PerformContext performContext = new PerformContext(this, onAdapter, objectMember, argumentStoryCells);
+        try {
+            performCommand.perform(performContext);
+        } catch (final RuntimeException ex) {
+            // handler should have colored in invalid cells.
+        }
+        aliasResultFromPerformCommand(performCommand, aliasAs);
+    }
+
+    private void aliasResultFromPerformCommand(final Perform performCommand, final String aliasAs) throws ScenarioBoundValueException {
+        if (StringUtils.isNullOrEmpty(aliasAs)) {
+            return;
+        }
+        final ObjectAdapter resultAdapter = performCommand.getResult();
+        if (resultAdapter == null) {
+            throw ScenarioBoundValueException.current(onMemberBinding, "(no result)");
+        }
+        getAliasRegistry().aliasAs(aliasAs, resultAdapter);
+    }
+
+    // //////////////////////////////////////////////////////////////////
+    //
+    // //////////////////////////////////////////////////////////////////
+
+    private String previousOnObject = null;
+
+    /**
+     * Not public API
+     */
+    public void provideDefault(final ScenarioCell storySource, final String resultStr) {
+        // TODO Auto-generated method stub
+        throw new NotYetImplementedException();
+    }
+
+    /**
+     * Not public API
+     */
+    public ObjectAdapter getAdapter(final ObjectAdapter contextAdapter, final ObjectSpecification noSpec, final CellBinding contextBinding, final ScenarioCell paramCell) throws ScenarioBoundValueException {
+
+        final String cellText = paramCell.getText();
+
+        // see if can handle as parseable value
+        final ParseableFacet parseableFacet = noSpec.getFacet(ParseableFacet.class);
+        if (parseableFacet != null) {
+            try {
+                return parseableFacet.parseTextEntry(contextAdapter, cellText, null);
+            } catch (final TextEntryParseException ex) {
+                throw ScenarioBoundValueException.arg(contextBinding, paramCell, "(cannot parse '" + cellText + "')");
+            } catch (final IllegalArgumentException ex) {
+                // REVIEW: isn't what is thrown, but perhaps
+                // TextEntryParseException should inherit from
+                // IllegalArgumentException?
+                throw ScenarioBoundValueException.arg(contextBinding, paramCell, "(cannot parse '" + cellText + "')");
+            }
+        }
+
+        // otherwise, handle as reference to known object
+        final ObjectAdapter adapter = getAliasRegistry().getAliased(cellText);
+        if (adapter == null) {
+            throw ScenarioBoundValueException.arg(contextBinding, paramCell, "(unknown reference'" + cellText + "')");
+        }
+
+        return adapter;
+    }
+
+    /**
+     * Not public API
+     * 
+     * <p>
+     * Ensures that there are at least enough arguments for the number of
+     * parameters required.
+     */
+    public ObjectAdapter[] getAdapters(final ObjectAdapter onAdapter, final ObjectAction objectAction, final CellBinding onMemberBinding, final List<ScenarioCell> argumentCells) throws ScenarioBoundValueException {
+        final List<ObjectActionParameter> parameters = objectAction.getParameters();
+
+        final int parameterCount = parameters.size();
+        if (argumentCells.size() < parameterCount) {
+            throw ScenarioBoundValueException.current(onMemberBinding, "(action requires " + parameterCount + " arguments)");
+        }
+        final ObjectAdapter[] adapters = new ObjectAdapter[parameterCount];
+
+        for (int i = 0; i < parameterCount; i++) {
+            final ScenarioCell paramCell = argumentCells.get(i);
+            final ObjectActionParameter parameter = parameters.get(i);
+            adapters[i] = getAdapter(null, parameter.getSpecification(), onMemberBinding, paramCell);
+        }
+        return adapters;
+    }
+
+    /**
+     * Not public API
+     */
+    public ObjectAdapter toAdaptedListOfPojos(final ObjectAdapter[] choiceAdapters) {
+        final List<Object> choiceList = new ArrayList<Object>();
+        if (choiceAdapters != null) {
+            for (final ObjectAdapter adapter : choiceAdapters) {
+                choiceList.add(adapter.getObject());
+            }
+        }
+        return getAdapterManager().adapterFor(choiceList);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/AddToCollection.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/AddToCollection.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/AddToCollection.java
new file mode 100644
index 0000000..1dff803
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/AddToCollection.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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.consent.InteractionInvocationMethod;
+import org.apache.isis.core.metamodel.facets.collections.modify.CollectionAddToFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToManyAssociation;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioBoundValueException;
+import org.apache.isis.viewer.bdd.common.ScenarioCell;
+
+public class AddToCollection extends PerformAbstractTypeParams {
+
+    private ObjectAdapter result;
+
+    public AddToCollection(final Perform.Mode mode) {
+        super("add to collection", Type.COLLECTION, NumParameters.ONE, mode);
+    }
+
+    @Override
+    public void doHandle(final PerformContext performContext) throws ScenarioBoundValueException {
+
+        final ObjectAdapter onAdapter = performContext.getOnAdapter();
+        final ObjectMember nakedObjectMember = performContext.getObjectMember();
+        final CellBinding onMemberBinding = performContext.getPeer().getOnMemberBinding();
+
+        final OneToManyAssociation otma = (OneToManyAssociation) nakedObjectMember;
+
+        final CollectionAddToFacet addToFacet = nakedObjectMember.getFacet(CollectionAddToFacet.class);
+        if (addToFacet == null) {
+            throw ScenarioBoundValueException.current(onMemberBinding, "(cannot add to collection)");
+        }
+
+        // safe since guaranteed by superclass
+        final CellBinding arg0Binding = performContext.getPeer().getArg0Binding();
+        final ScenarioCell arg0Cell = arg0Binding.getCurrentCell();
+        final String toAddAlias = arg0Cell.getText();
+
+        final ObjectAdapter toAddAdapter = performContext.getPeer().getAliasRegistry().getAliased(toAddAlias);
+        if (toAddAdapter == null) {
+            throw ScenarioBoundValueException.current(arg0Binding, "(unknown alias)");
+        }
+
+        // validate argument
+        otma.createValidateAddInteractionContext(getSession(), InteractionInvocationMethod.BY_USER, onAdapter, toAddAdapter);
+        final Consent validToAdd = otma.isValidToAdd(onAdapter, toAddAdapter);
+        if (validToAdd.isVetoed()) {
+            throw ScenarioBoundValueException.current(arg0Binding, validToAdd.getReason());
+        }
+
+        // add
+        addToFacet.add(onAdapter, toAddAdapter);
+    }
+
+    @Override
+    public ObjectAdapter getResult() {
+        return result;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAction.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAction.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAction.java
new file mode 100644
index 0000000..4359027
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAction.java
@@ -0,0 +1,35 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Disabled;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Hidden;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Usable;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Visible;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.action.ArgumentSetNotValid;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.action.ArgumentSetValid;
+
+public class CheckAction extends PerformCheckThatAbstract {
+
+    public CheckAction(final Perform.Mode mode) {
+        super("check action", OnMemberColumn.REQUIRED, mode, new Hidden(), new Visible(), new Disabled(), new Usable(), new ArgumentSetValid(), new ArgumentSetNotValid());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAddToCollection.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAddToCollection.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAddToCollection.java
new file mode 100644
index 0000000..2e35ebe
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckAddToCollection.java
@@ -0,0 +1,31 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsValidity;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.collections.ProposedAddTo;
+
+public class CheckAddToCollection extends PerformCheckThatAbstract {
+
+    public CheckAddToCollection(final Perform.Mode mode) {
+        super("check add to collection", OnMemberColumn.REQUIRED, mode, new ProposedAddTo(AssertsValidity.VALID), new ProposedAddTo(AssertsValidity.INVALID));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckClearProperty.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckClearProperty.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckClearProperty.java
new file mode 100644
index 0000000..865163b
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckClearProperty.java
@@ -0,0 +1,31 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsValidity;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.ProposedClear;
+
+public class CheckClearProperty extends PerformCheckThatAbstract {
+
+    public CheckClearProperty(final Perform.Mode mode) {
+        super("check clear property", OnMemberColumn.REQUIRED, mode, new ProposedClear(AssertsValidity.VALID), new ProposedClear(AssertsValidity.INVALID));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckCollection.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckCollection.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckCollection.java
new file mode 100644
index 0000000..08fa553
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckCollection.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsContainment;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsEmpty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Disabled;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Hidden;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Usable;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Visible;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.collections.Containment;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.collections.Emptiness;
+
+public class CheckCollection extends PerformCheckThatAbstract {
+
+    public CheckCollection(final Perform.Mode mode) {
+        super("check collection", OnMemberColumn.REQUIRED, mode, new Hidden(), new Visible(), new Disabled(), new Usable(), new Emptiness(AssertsEmpty.EMPTY), new Emptiness(AssertsEmpty.NOT_EMPTY), new Containment(AssertsContainment.CONTAINS), new Containment(AssertsContainment.DOES_NOT_CONTAIN));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckObject.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckObject.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckObject.java
new file mode 100644
index 0000000..93d677a
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckObject.java
@@ -0,0 +1,33 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.object.NotSaved;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.object.NotValid;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.object.Saved;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.object.Valid;
+
+public class CheckObject extends PerformCheckThatAbstract {
+
+    public CheckObject(final Perform.Mode mode) {
+        super("check object", OnMemberColumn.NOT_REQUIRED, mode, new Valid(), new NotValid(), new NotSaved(), new Saved());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckProperty.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckProperty.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckProperty.java
new file mode 100644
index 0000000..e69d8c6
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckProperty.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Disabled;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Hidden;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Usable;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.Visible;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.Contains;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.DoesNotContain;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.Empty;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.NotEmpty;
+
+public class CheckProperty extends PerformCheckThatAbstract {
+
+    public CheckProperty(final Perform.Mode mode) {
+        super("check property", OnMemberColumn.REQUIRED, mode, new Hidden(), new Visible(), new Disabled(), new Usable(), new Contains(), new DoesNotContain(), new Empty(), new NotEmpty());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckRemoveFromCollection.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckRemoveFromCollection.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckRemoveFromCollection.java
new file mode 100644
index 0000000..a39c7fb
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckRemoveFromCollection.java
@@ -0,0 +1,31 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsValidity;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.collections.ProposedRemoveFrom;
+
+public class CheckRemoveFromCollection extends PerformCheckThatAbstract {
+
+    public CheckRemoveFromCollection(final Perform.Mode mode) {
+        super("check remove from collection", OnMemberColumn.REQUIRED, mode, new ProposedRemoveFrom(AssertsValidity.VALID), new ProposedRemoveFrom(AssertsValidity.INVALID));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckSetProperty.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckSetProperty.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckSetProperty.java
new file mode 100644
index 0000000..ea4a853
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/CheckSetProperty.java
@@ -0,0 +1,31 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.AssertsValidity;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.PerformCheckThatAbstract;
+import org.apache.isis.viewer.bdd.common.fixtures.perform.checkthat.property.ProposedSet;
+
+public class CheckSetProperty extends PerformCheckThatAbstract {
+
+    public CheckSetProperty(final Perform.Mode mode) {
+        super("check set property", OnMemberColumn.REQUIRED, mode, new ProposedSet(AssertsValidity.VALID), new ProposedSet(AssertsValidity.INVALID));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/7276dc0b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/ClearProperty.java
----------------------------------------------------------------------
diff --git a/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/ClearProperty.java b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/ClearProperty.java
new file mode 100644
index 0000000..2568d42
--- /dev/null
+++ b/mothballed/bdd/common/src/main/java/org/apache/isis/viewer/bdd/common/fixtures/perform/ClearProperty.java
@@ -0,0 +1,67 @@
+/*
+ *  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.viewer.bdd.common.fixtures.perform;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.consent.Consent;
+import org.apache.isis.core.metamodel.facets.properties.modify.PropertyClearFacet;
+import org.apache.isis.core.metamodel.spec.feature.ObjectMember;
+import org.apache.isis.core.metamodel.spec.feature.OneToOneAssociation;
+import org.apache.isis.viewer.bdd.common.CellBinding;
+import org.apache.isis.viewer.bdd.common.ScenarioBoundValueException;
+
+public class ClearProperty extends PerformAbstractTypeParams {
+
+    private ObjectAdapter result;
+
+    public ClearProperty(final Perform.Mode mode) {
+        super("clear property", Type.PROPERTY, NumParameters.ZERO, mode);
+    }
+
+    @Override
+    public void doHandle(final PerformContext performContext) throws ScenarioBoundValueException {
+
+        final ObjectAdapter onAdapter = performContext.getOnAdapter();
+        final ObjectMember nakedObjectMember = performContext.getObjectMember();
+
+        final OneToOneAssociation otoa = (OneToOneAssociation) nakedObjectMember;
+
+        // set
+        final PropertyClearFacet clearFacet = otoa.getFacet(PropertyClearFacet.class);
+        final CellBinding thatItBinding = performContext.getPeer().getThatItBinding();
+        if (clearFacet == null) {
+            throw ScenarioBoundValueException.current(thatItBinding, "(cannot clear)");
+        }
+
+        // validate setting to null
+        final Consent validConsent = otoa.isAssociationValid(onAdapter, null);
+        if (validConsent.isVetoed()) {
+            throw ScenarioBoundValueException.current(thatItBinding, validConsent.getReason());
+        }
+
+        clearFacet.clearProperty(onAdapter);
+
+    }
+
+    @Override
+    public ObjectAdapter getResult() {
+        return result;
+    }
+
+}