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 2012/12/06 11:10:34 UTC

[17/51] [partial] ISIS-188: moving modules into core

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/eclipse-templates.xml
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/eclipse-templates.xml b/framework/core/applib/src/docbkx/to-incorporate/eclipse-templates.xml
new file mode 100644
index 0000000..7492af1
--- /dev/null
+++ b/framework/core/applib/src/docbkx/to-incorporate/eclipse-templates.xml
@@ -0,0 +1,467 @@
+<?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.
+-->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.1//EN"
+"http://www.oasis-open.org/docbook/xml/simple/1.1/sdocbook.dtd">
+<article>
+  <articleinfo>
+    <title></title>
+
+    <author>
+      <firstname></firstname>
+
+      <surname></surname>
+
+      <affiliation>
+        <orgname></orgname>
+      </affiliation>
+    </author>
+
+    <pubdate></pubdate>
+  </articleinfo>
+
+  <section>
+    <title>Using the templates in Eclipse</title>
+
+    <para>The latest release of [[NAME]] (version 4) provides a set of
+    templates for quickly adding snippets to your domain classes,  from properties and collections to title and dependencies.</para>
+
+    <para>To set up Eclipse so these are available you need to import the template files that are included in the distribution. In both the Ant and
+    Maven based distributions they can be found the following
+    directory:</para>
+
+    <literallayout>resources
+|-- ide
+|   `-- eclipse
+|       |-- launch
+|       `-- templates
+|           |-- jmock2-templates.xml
+|           |-- junit4-templates.xml
+|           `-- isis-templates.xml
+</literallayout>
+
+    <para>Open up Eclipse's preferences dialog
+    (<option>Windows</option>/<option>Preferences</option>) and navigate to
+    <option>Java</option> - <option>Editor</option> -
+    <option>Template</option>. Click the <option>Import</option> button,
+    browse to the <filename>templates</filename> directory, select the
+    <filename>isis-templates.xml</filename> file and press OK. A
+    series of templates will be added prefixed with <emphasis>no</emphasis>
+    such as <emphasis>noa</emphasis>, <emphasis>nol</emphasis>,
+    <emphasis>nop</emphasis> etc. Press OK to commit the changes and you are
+    ready to use them.</para>
+
+    <para>For example, to insert a property type <emphasis>nop</emphasis> in the editor
+    window within the class declations and press
+    <userinput>ctrl-space</userinput> to bring up the available
+    templates.</para>
+
+    <mediaobject>
+      <imageobject>
+        <imagedata fileref="images/template-list.png" />
+      </imageobject>
+    </mediaobject>
+
+    <para>Each template has a brief description and the template result is
+    shown in the box next to the list. Selecting the template inserts the code
+    into your file at the cursor replacing the template name that you
+    typed.</para>
+
+    <mediaobject>
+      <imageobject>
+        <imagedata fileref="images/template-insert.png" />
+      </imageobject>
+    </mediaobject>
+
+    <para>It also highlights the parts that you can change. So in this example
+    when we type <emphasis>Purchase</emphasis>, tab,
+    <emphasis>Date</emphasis>, tab, and <emphasis>date</emphasis> we end up
+    with a complete property declaration for a Date value that will display
+    with the label <emphasis>Date</emphasis>.</para>
+
+    <mediaobject>
+      <imageobject>
+        <imagedata fileref="images/template-complete.png" />
+      </imageobject>
+    </mediaobject>
+
+    <para>The other files each provide a couple of templates for building
+    Junit version 4 tests and using JMock.</para>
+
+    <para>The available [[NAME]] templates are:-</para>
+
+    <variablelist>
+      <varlistentry>
+        <term>noa</term>
+
+        <listitem>
+          <para>Action</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noacho</term>
+
+        <listitem>
+          <para>Action argument N choices</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noadef</term>
+
+        <listitem>
+          <para>Action argument defaults</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noadis</term>
+
+        <listitem>
+          <para>Action disabling</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noahid</term>
+
+        <listitem>
+          <para>Action hiding</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noaval</term>
+
+        <listitem>
+          <para>Action validation</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noc-1m</term>
+
+        <listitem>
+          <para>Collection (1:m bidir parent)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noc-mmc</term>
+
+        <listitem>
+          <para>Collection (m:m bidir child)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noc-mmp</term>
+
+        <listitem>
+          <para>Collection (m:m bidir parent)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nocdis</term>
+
+        <listitem>
+          <para>Collection disabling</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nochid</term>
+
+        <listitem>
+          <para>Collection hiding</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nocl</term>
+
+        <listitem>
+          <para>Collection (list)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nocmod</term>
+
+        <listitem>
+          <para>Collection modify</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nocs</term>
+
+        <listitem>
+          <para>Collection (set)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nocval</term>
+
+        <listitem>
+          <para>Collection validation</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nod</term>
+
+        <listitem>
+          <para>Dependencies region</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nods</term>
+
+        <listitem>
+          <para>Dependencies - injected service</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nofp</term>
+
+        <listitem>
+          <para>Factory - new instance (persistent)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noft</term>
+
+        <listitem>
+          <para>Factory - new instance (transient)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noid</term>
+
+        <listitem>
+          <para>Identification region</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noidicon</term>
+
+        <listitem>
+          <para>Identification - icon</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noidtitle</term>
+
+        <listitem>
+          <para>Identification - title</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nol</term>
+
+        <listitem>
+          <para>Lifecycle region</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nolc</term>
+
+        <listitem>
+          <para>Lifecycle - create</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noll</term>
+
+        <listitem>
+          <para>Lifecycle - load</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nolp</term>
+
+        <listitem>
+          <para>Lifecycle - persist</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nolr</term>
+
+        <listitem>
+          <para>Lifecycle - remove</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nolu</term>
+
+        <listitem>
+          <para>Lifecycle - update</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nop</term>
+
+        <listitem>
+          <para>Property</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nop-11c</term>
+
+        <listitem>
+          <para>Property (1:1 bidir child)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nop-11p</term>
+
+        <listitem>
+          <para>Property (1:1 bidir parent)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nop-m1</term>
+
+        <listitem>
+          <para>Property (m:1 bidir child)</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nopcho</term>
+
+        <listitem>
+          <para>Property choices</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nopdef</term>
+
+        <listitem>
+          <para>Property defaults</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nopdis</term>
+
+        <listitem>
+          <para>Property disabling</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nophid</term>
+
+        <listitem>
+          <para>Property hiding</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nopmod</term>
+
+        <listitem>
+          <para>Property modify</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nopval</term>
+
+        <listitem>
+          <para>Property validation</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nosa</term>
+
+        <listitem>
+          <para>Search for all</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nosafil</term>
+
+        <listitem>
+          <para>Search for all matching</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nosffil</term>
+
+        <listitem>
+          <para>Search for first matching</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>nosufil</term>
+
+        <listitem>
+          <para>Search for unique matching</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term>noval</term>
+
+        <listitem>
+          <para>Object-level validation</para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <variablelist>
+      <varlistentry>
+        <term></term>
+
+        <listitem>
+          <para></para>
+        </listitem>
+      </varlistentry>
+    </variablelist>
+
+    <para></para>
+  </section>
+</article>

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/images/create-patch-dialog.png
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/images/create-patch-dialog.png b/framework/core/applib/src/docbkx/to-incorporate/images/create-patch-dialog.png
new file mode 100644
index 0000000..5588e1d
Binary files /dev/null and b/framework/core/applib/src/docbkx/to-incorporate/images/create-patch-dialog.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/images/template-complete.png
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/images/template-complete.png b/framework/core/applib/src/docbkx/to-incorporate/images/template-complete.png
new file mode 100644
index 0000000..db0713a
Binary files /dev/null and b/framework/core/applib/src/docbkx/to-incorporate/images/template-complete.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/images/template-insert.png
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/images/template-insert.png b/framework/core/applib/src/docbkx/to-incorporate/images/template-insert.png
new file mode 100644
index 0000000..4c781ea
Binary files /dev/null and b/framework/core/applib/src/docbkx/to-incorporate/images/template-insert.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/images/template-list.png
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/images/template-list.png b/framework/core/applib/src/docbkx/to-incorporate/images/template-list.png
new file mode 100644
index 0000000..cd02cfb
Binary files /dev/null and b/framework/core/applib/src/docbkx/to-incorporate/images/template-list.png differ

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/docbkx/to-incorporate/snippet-fixture-service.xml
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/docbkx/to-incorporate/snippet-fixture-service.xml b/framework/core/applib/src/docbkx/to-incorporate/snippet-fixture-service.xml
new file mode 100644
index 0000000..f151cc2
--- /dev/null
+++ b/framework/core/applib/src/docbkx/to-incorporate/snippet-fixture-service.xml
@@ -0,0 +1,82 @@
+<?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.
+-->
+<!DOCTYPE article PUBLIC "-//OASIS//DTD Simplified DocBook XML V1.1//EN"
+"http://www.oasis-open.org/docbook/xml/simple/1.1/sdocbook.dtd">
+<article>
+  <articleinfo>
+    <title></title>
+
+    <author>
+      <firstname></firstname>
+
+      <surname></surname>
+
+      <affiliation>
+        <orgname></orgname>
+      </affiliation>
+    </author>
+
+    <pubdate></pubdate>
+  </articleinfo>
+
+  <section>
+    <title>Dynamic fixture service</title>
+
+    <para>When developing applications it is nice to ready prepared objects so
+    you don't have to continually create them every time you run in
+    exploration mode. As you read already these can be created using fixtures,
+    but that requires coding specific classes. Whilst turing on persistence
+    means that you get back what you had last time, but that probably includes
+    objects that you didn't want to keep. A better solution is to use the new
+    fixture service that allows you to save specific objects on the desktop
+    and have them, and only them, recreated when you next start up.</para>
+
+    <para></para>
+
+    <section>
+      <title>Configuration</title>
+
+      <para>Add the following property to
+      <filename>isis.properties</filename> to enable this feature.
+      Better still create and add it to a file called
+      <filename>exploration.properties</filename> so it is only used in
+      exploration mode.</para>
+
+      <literallayout>isis.exploration-objects=true</literallayout>
+
+      <para>There is a second property that allows you specify where your data
+      file is stored.</para>
+
+      <literallayout>isis.exploration-objects.file=tmp/data</literallayout>
+
+      <section>
+        <title></title>
+
+        <para></para>
+      </section>
+    </section>
+
+    <section>
+      <title></title>
+
+      <para>Data for an object is </para>
+    </section>
+  </section>
+</article>

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
new file mode 100644
index 0000000..ec0978a
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractContainedObject.java
@@ -0,0 +1,327 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Aggregated;
+import org.apache.isis.applib.annotation.Hidden;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.security.UserMemento;
+
+/**
+ * Convenience super class for all classes that wish to interact with the
+ * container.
+ * 
+ * @see org.apache.isis.applib.DomainObjectContainer
+ */
+public abstract class AbstractContainedObject {
+
+    // {{ factory methods
+    @Hidden
+    protected <T> T newTransientInstance(final Class<T> ofType) {
+        return getContainer().newTransientInstance(ofType);
+    }
+
+    /**
+     * Create an instance that will be persisted as part of this domain object
+     * (ie this domain object is its parent in the aggregate).
+     * 
+     * <p>
+     * The type provided should be annotated with {@link Aggregated}.
+     * 
+     *  @see #newAggregatedInstance(Object, Class)
+     */
+    @Hidden
+    protected <T> T newAggregatedInstance(final Class<T> ofType) {
+        return newAggregatedInstance(this, ofType);
+    }
+
+    /**
+     * Create an instance that will be persisted as part of specified paremt domain object
+     * (ie that domain object will be its parent in the aggregate).
+     * 
+     * <p>
+     * The type provided should be annotated with {@link Aggregated}.
+     * 
+     *  @see #newAggregatedInstance(Class)
+     */
+    @Hidden
+    protected <T> T newAggregatedInstance(final Object parent, final Class<T> ofType) {
+        return getContainer().newAggregatedInstance(parent, ofType);
+    }
+    // }}
+
+    // {{ allInstances, allMatches
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#allInstances(Class)
+     */
+    protected <T> List<T> allInstances(final Class<T> ofType) {
+        return getContainer().allInstances(ofType);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#allMatches(Class, Filter)
+     */
+    protected <T> List<T> allMatches(final Class<T> ofType, final Filter<? super T> filter) {
+        return getContainer().allMatches(ofType, filter);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#allMatches(Class, Object)
+     */
+    protected <T> List<T> allMatches(final Class<T> ofType, final T pattern) {
+        return getContainer().allMatches(ofType, pattern);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#allMatches(Class, String)
+     */
+    protected <T> List<T> allMatches(final Class<T> ofType, final String title) {
+        return getContainer().allMatches(ofType, title);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#allMatches(Query)
+     */
+    protected <T> List<T> allMatches(final Query<T> query) {
+        return getContainer().allMatches(query);
+    }
+
+    // }}
+
+    // {{ firstMatch
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#firstMatch(Class, Filter)
+     */
+    protected <T> T firstMatch(final Class<T> ofType, final Filter<T> filter) {
+        return getContainer().firstMatch(ofType, filter);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#firstMatch(Class, Object)
+     */
+    protected <T> T firstMatch(final Class<T> ofType, final T pattern) {
+        return getContainer().firstMatch(ofType, pattern);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#firstMatch(Class, String)
+     */
+    protected <T> T firstMatch(final Class<T> ofType, final String title) {
+        return getContainer().firstMatch(ofType, title);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#firstMatch(Query)
+     */
+    protected <T> T firstMatch(final Query<T> query) {
+        return getContainer().firstMatch(query);
+    }
+
+    // }}
+
+    // {{ uniqueMatch
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#uniqueMatch(Class, Filter)
+     */
+    protected <T> T uniqueMatch(final Class<T> ofType, final Filter<T> filter) {
+        return getContainer().uniqueMatch(ofType, filter);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#uniqueMatch(Class, String)
+     */
+    protected <T> T uniqueMatch(final Class<T> ofType, final String title) {
+        return getContainer().uniqueMatch(ofType, title);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#uniqueMatch(Class, Object)
+     */
+    protected <T> T uniqueMatch(final Class<T> ofType, final T pattern) {
+        return getContainer().uniqueMatch(ofType, pattern);
+    }
+
+    /**
+     * Convenience method that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#uniqueMatch(Query)
+     */
+    protected <T> T uniqueMatch(final Query<T> query) {
+        return getContainer().uniqueMatch(query);
+    }
+
+    // }}
+
+    // {{ isValid, validate
+    /**
+     * Convenience methods that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#isValid(Object)
+     */
+    protected boolean isValid(final Object domainObject) {
+        return getContainer().isValid(domainObject);
+    }
+
+    /**
+     * Convenience methods that delegates to {@link DomainObjectContainer}.
+     * 
+     * @see DomainObjectContainer#validate(Object)
+     */
+    protected String validate(final Object domainObject) {
+        return getContainer().validate(domainObject);
+    }
+
+    // }}
+
+    // {{ isPersistent, persist, remove
+    /**
+     * Whether the provided object is persistent.
+     */
+    @Hidden
+    protected boolean isPersistent(final Object domainObject) {
+        return getContainer().isPersistent(domainObject);
+    }
+
+    /**
+     * Save provided object to the persistent object store.
+     * 
+     * <p>
+     * If the object {@link #isPersistent(Object) is persistent} already, then
+     * will throw an exception.
+     * 
+     * @see #persistIfNotAlready(Object)
+     */
+    @Hidden
+    protected <T> T persist(final T transientDomainObject) {
+        getContainer().persist(transientDomainObject);
+        return transientDomainObject;
+    }
+
+    /**
+     * Saves the object, but only if not already {@link #isPersistent()
+     * persistent}.
+     * 
+     * @see #isPersistent()
+     * @see #persist(Object)
+     */
+    @Hidden
+    protected <T> T persistIfNotAlready(final T domainObject) {
+        getContainer().persistIfNotAlready(domainObject);
+        return domainObject;
+    }
+
+    /**
+     * Delete the provided object from the persistent object store.
+     */
+    protected <T> T remove(final T persistentDomainObject) {
+        getContainer().remove(persistentDomainObject);
+        return persistentDomainObject;
+    }
+
+    // }}
+
+    // {{ Error/Warning Methods
+    /**
+     * Display the specified message to the user, in a non-intrusive fashion.
+     */
+    protected void informUser(final String message) {
+        getContainer().informUser(message);
+    }
+
+    /**
+     * Display the specified message as a warning to the user, in a more visible
+     * fashion, but without requiring explicit acknowledgement.
+     */
+    protected void warnUser(final String message) {
+        getContainer().warnUser(message);
+    }
+
+    /**
+     * Display the specified message as an error to the user, ensuring that it
+     * is acknowledged.
+     */
+    protected void raiseError(final String message) {
+        getContainer().raiseError(message);
+    }
+
+    // }}
+
+    // {{ Security Methods
+    protected UserMemento getUser() {
+        return getContainer().getUser();
+    }
+
+    // }}
+
+    // {{ Injected: Container
+    /**
+     * @uml.property name="container"
+     * @uml.associationEnd
+     */
+    private DomainObjectContainer container;
+
+    /**
+     * This field is not persisted, nor displayed to the user.
+     * 
+     * @uml.property name="container"
+     */
+    @Hidden
+    protected DomainObjectContainer getContainer() {
+        return this.container;
+    }
+
+    /**
+     * Injected by the application container itself.
+     * 
+     * @uml.property name="container"
+     */
+    public final void setContainer(final DomainObjectContainer container) {
+        this.container = container;
+    }
+    // }}
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractDomainObject.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractDomainObject.java b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractDomainObject.java
new file mode 100644
index 0000000..0d25e4c
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractDomainObject.java
@@ -0,0 +1,120 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+import org.apache.isis.applib.annotation.Hidden;
+
+/**
+ * Convenience super class for all domain objects that wish to interact with the
+ * container.
+ * 
+ * <p>
+ * Subclassing is NOT mandatory; the methods in this superclass can be pushed
+ * down into domain objects and another superclass used if required.
+ * 
+ * @see org.apache.isis.applib.DomainObjectContainer
+ */
+public abstract class AbstractDomainObject extends AbstractContainedObject {
+
+    // {{ resolve, objectChanged
+    /**
+     * Resolve this object, populating references to other objects.
+     */
+    @Hidden
+    protected void resolve() {
+        getContainer().resolve(this);
+    }
+
+    /**
+     * Resolve this object if the referenced object is still unknown.
+     */
+    @Hidden
+    protected void resolve(final Object referencedObject) {
+        getContainer().resolve(this, referencedObject);
+    }
+
+    /**
+     * Notifies the container that this object has changed, so that it can be
+     * persisted.
+     */
+    @Hidden
+    protected void objectChanged() {
+        getContainer().objectChanged(this);
+    }
+
+    // }}
+
+    // {{ isPersistent, makePersistent (overloads)
+    /**
+     * Whether this object is persistent.
+     * 
+     * @deprecated - instead use {@link #isPersistent(Object)}.
+     */
+    @Deprecated
+    @Hidden
+    protected boolean isPersistent() {
+        return isPersistent(this);
+    }
+
+    /**
+     * Save this object to the persistent object store.
+     * 
+     * <p>
+     * If the object {@link #isPersistent(Object) is persistent} already, then
+     * will throw an exception.
+     * 
+     * @see #persistIfNotAlready(Object)
+     * 
+     * @deprecated - instead use {@link #persist(Object)}.
+     */
+    @Deprecated
+    @Hidden
+    protected void makePersistent() {
+        persist(this);
+    }
+
+    /**
+     * Saves the object, but only if not already {@link #isPersistent(Object)
+     * persistent}.
+     * 
+     * @see #isPersistent(Object)
+     * @see #persist(Object)
+     * 
+     * @deprecated - instead use {@link #persistIfNotAlready(Object)}.
+     */
+    @Deprecated
+    @Hidden
+    protected void makePersistentIfNotAlready() {
+        persistIfNotAlready(this);
+    }
+
+    /**
+     * Delete this object from the persistent object store.
+     * 
+     * @deprecated - instead use {@link #remove(Object)}.
+     */
+    @Deprecated
+    @Hidden
+    protected void disposeInstance() {
+        remove(this);
+    }
+    // }}
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractFactoryAndRepository.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractFactoryAndRepository.java b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractFactoryAndRepository.java
new file mode 100644
index 0000000..bbe3162
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractFactoryAndRepository.java
@@ -0,0 +1,50 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+public abstract class AbstractFactoryAndRepository extends AbstractService {
+
+    // {{ newPersistenceInstance, newInstance
+    /**
+     * Returns a new instance of the specified class that will have been
+     * persisted.
+     * 
+     * <p>
+     * This method isn't quite deprecated, but generally consider using
+     * {@link #newTransientInstance(Class)} instead.
+     */
+    protected <T> T newPersistentInstance(final Class<T> ofClass) {
+        return getContainer().newPersistentInstance(ofClass);
+    }
+
+    /**
+     * Returns a new instance of the specified class that has the sane persisted
+     * state as the specified object.
+     * 
+     * <p>
+     * This method isn't quite deprecated, but generally consider using
+     * {@link #newTransientInstance(Class)} instead.
+     */
+    protected <T> T newInstance(final Class<T> ofClass, final Object object) {
+        return getContainer().newInstance(ofClass, object);
+    }
+    // }}
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractService.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractService.java b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractService.java
new file mode 100644
index 0000000..fa65b82
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/AbstractService.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.applib;
+
+import org.apache.isis.applib.annotation.Hidden;
+
+public abstract class AbstractService extends AbstractContainedObject {
+
+    @Hidden
+    public String getId() {
+        return getClassName();
+    }
+
+    protected String getClassName() {
+        return getClass().getName();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/ApplicationException.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/ApplicationException.java b/framework/core/applib/src/main/java/org/apache/isis/applib/ApplicationException.java
new file mode 100644
index 0000000..2945c71
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/ApplicationException.java
@@ -0,0 +1,48 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+/**
+ * Indicates that a problem has occurred within the application, as opposed to
+ * within a supporting framework or system.
+ */
+public class ApplicationException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private Throwable cause;
+
+    public ApplicationException(final String msg) {
+        super(msg);
+    }
+
+    public ApplicationException(final Throwable cause) {
+        this(cause.getMessage());
+        this.cause = cause;
+    }
+
+    public ApplicationException(final String msg, final Throwable cause) {
+        this(msg);
+        this.cause = cause;
+    }
+
+    @Override
+    public Throwable getCause() {
+        return cause;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/Defaults.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/Defaults.java b/framework/core/applib/src/main/java/org/apache/isis/applib/Defaults.java
new file mode 100755
index 0000000..eebad2a
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/Defaults.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.applib;
+
+import java.util.Calendar;
+
+import org.joda.time.DateTimeZone;
+
+public class Defaults {
+    static {
+        setTimeZone(DateTimeZone.UTC);
+    }
+
+    static DateTimeZone timeZone = DateTimeZone.UTC;
+
+    public static DateTimeZone getTimeZone() {
+        return timeZone;
+    }
+
+    public static void setTimeZone(final DateTimeZone timezone) {
+        timeZone = timezone;
+        calendar = Calendar.getInstance(timezone.toTimeZone());
+    }
+
+    private static Calendar calendar;
+
+    public static Calendar getCalendar() {
+        return calendar;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java b/framework/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
new file mode 100644
index 0000000..f7b379f
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/DomainObjectContainer.java
@@ -0,0 +1,431 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Aggregated;
+import org.apache.isis.applib.filter.Filter;
+import org.apache.isis.applib.query.Query;
+import org.apache.isis.applib.security.UserMemento;
+
+/**
+ * Represents a container that the domain objects work within. It provides
+ * access to the persistence mechanism and user interface.
+ */
+public interface DomainObjectContainer {
+
+    // ////////////////////////////////////////////////////////////////
+    // titleOf
+    // ////////////////////////////////////////////////////////////////
+
+    String titleOf(Object domainObject);
+
+    // ////////////////////////////////////////////////////////////////
+    // resolve, objectChanged
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Ensure that the specified object is completely loaded into memory.
+     * 
+     * <p>
+     * This forces the lazy loading mechanism to load the object if it is not
+     * already loaded.
+     */
+    void resolve(Object domainObject);
+
+    /**
+     * Ensure that the specified object is completely loaded into memory, though
+     * only if the supplied field reference is <tt>null</tt>.
+     * 
+     * <p>
+     * This forces the lazy loading mechanism to load the object if it is not
+     * already loaded.
+     */
+    void resolve(Object domainObject, Object field);
+
+    /**
+     * Flags that the specified object's state has changed and its changes need
+     * to be saved.
+     */
+    void objectChanged(Object domainObject);
+
+    // ////////////////////////////////////////////////////////////////
+    // flush, commit
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Flush all changes to the object store.
+     * 
+     * <p>
+     * Typically only for use by tests.
+     * 
+     * @return <tt>true</tt>
+     */
+    boolean flush();
+
+    /**
+     * Commit all changes to the object store.
+     * 
+     * <p>
+     * Typically only for use by tests.
+     */
+    void commit();
+
+    // ////////////////////////////////////////////////////////////////
+    // new{Transient/Persistent}Instance
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Create a new instance of the specified class, but do not persist it.
+     * 
+     * <p>
+     * If the type is annotated with {@link Aggregated}, then as per
+     * {@link #newAggregatedInstance(Object, Class)}.  Otherwise will be an
+     * aggregate root.
+     * 
+     * @see #newPersistentInstance(Class)
+     * @see #newAggregatedInstance(Object, Class)
+     */
+    <T> T newTransientInstance(Class<T> ofType);
+
+    /**
+     * Create a new instance that will be persisted as part of the specified
+     * parent (ie will be a part of a larger aggregate).
+     */
+    <T> T newAggregatedInstance(Object parent, Class<T> ofType);
+
+    /**
+     * Returns a new instance of the specified class that will have been
+     * persisted.
+     */
+    <T> T newPersistentInstance(final Class<T> ofType);
+
+    /**
+     * Returns a new instance of the specified class that has the sane persisted
+     * state as the specified object.
+     */
+    <T> T newInstance(final Class<T> ofType, final Object object);
+
+    // ////////////////////////////////////////////////////////////////
+    // isValid, validate
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Whether the object is in a valid state, that is that none of the
+     * validation of properties, collections and object-level is vetoing.
+     * 
+     * @see #validate(Object)
+     */
+    boolean isValid(Object domainObject);
+
+    /**
+     * The reason, if any why the object is in a invalid state
+     * 
+     * <p>
+     * Checks the validation of all of the properties, collections and
+     * object-level.
+     * 
+     * @see #isValid(Object)
+     */
+    String validate(Object domainObject);
+
+    // ////////////////////////////////////////////////////////////////
+    // isPersistent, persist, remove
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Determines if the specified object is persistent (that it is stored
+     * permanently outside of the virtual machine).
+     */
+    boolean isPersistent(Object domainObject);
+
+    /**
+     * Make the specified transient object persistent.
+     * 
+     * <p>
+     * Throws an exception if object is already persistent.
+     * 
+     * @see #isPersistent(Object)
+     * @see #persistIfNotAlready(Object)
+     */
+    void persist(Object transientDomainObject);
+
+    /**
+     * Make the specified object persistent if not already.
+     * 
+     * <p>
+     * Does nothing otherwise.
+     * 
+     * @see #isPersistent(Object)
+     * @see #persist(Object)
+     */
+    void persistIfNotAlready(Object domainObject);
+
+    /**
+     * Removes (deletes) the persisted object.
+     * 
+     * @param persistentDomainObject
+     */
+    void remove(Object persistentDomainObject);
+
+    /**
+     * Removes (deletes) the domain object but only if is persistent.
+     * 
+     * @param domainObject
+     */
+    void removeIfNotAlready(Object domainObject);
+
+    // ////////////////////////////////////////////////////////////////
+    // info, warn, error
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Make the specified message available to the user. Note this will probably
+     * be displayed in transitory fashion, so is only suitable for useful but
+     * optional information.
+     * 
+     * @see #warnUser(String)
+     * @see #raiseError(String)
+     */
+    void informUser(String message);
+
+    /**
+     * Warn the user about a situation with the specified message. The container
+     * should guarantee to display this warning to the user, and will typically
+     * require acknowledgement.
+     * 
+     * @see #raiseError(String)
+     * @see #informUser(String)
+     */
+    void warnUser(String message);
+
+    /**
+     * Notify the user of an application error with the specified message. Note
+     * this will probably be displayed in an alarming fashion, so is only
+     * suitable for errors. The user will typically be required to perform
+     * additional steps after the error (eg to inform the helpdesk).
+     * 
+     * @see #warnUser(String)
+     * @see #informUser(String)
+     */
+    void raiseError(String message);
+
+    // ////////////////////////////////////////////////////////////////
+    // properties
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Get the configuration property with the specified name.
+     */
+    String getProperty(String name);
+
+    /**
+     * Get the configuration property with the specified name and if it doesn't
+     * exist then return the specified default value.
+     */
+    String getProperty(String name, String defaultValue);
+
+    /**
+     * Get the names of all the available properties.
+     */
+    List<String> getPropertyNames();
+
+    // ////////////////////////////////////////////////////////////////
+    // security
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Get the details about the current user.
+     * 
+     * @uml.property name="user"
+     * @uml.associationEnd
+     */
+    UserMemento getUser();
+
+    // ////////////////////////////////////////////////////////////////
+    // allInstances, allMatches, firstMatch, uniqueMatch
+    // ////////////////////////////////////////////////////////////////
+
+    /**
+     * Returns all the instances of the specified type (including subtypes).
+     * 
+     * <p>
+     * If there are no instances the list will be empty. This method creates a
+     * new {@link List} object each time it is called so the caller is free to
+     * use or modify the returned {@link List}, but the changes will not be
+     * reflected back to the repository.
+     * 
+     * <p>
+     * This method should only be called where the number of instances is known
+     * to be relatively low.
+     */
+    public <T> List<T> allInstances(Class<T> ofType);
+
+    /**
+     * Returns all the instances of the specified type (including subtypes) that
+     * the filter object accepts.
+     * 
+     * <p>
+     * If there are no instances the list will be empty. This method creates a
+     * new {@link List} object each time it is called so the caller is free to
+     * use or modify the returned {@link List}, but the changes will not be
+     * reflected back to the repository.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #allMatches(Query)} for production code.
+     */
+    public <T> List<T> allMatches(final Class<T> ofType, final Filter<? super T> filter);
+
+    /**
+     * Returns all the instances of the specified type (including subtypes) that
+     * have the given title.
+     * 
+     * <p>
+     * If there are no instances the list will be empty. This method creates a
+     * new {@link List} object each time it is called so the caller is free to
+     * use or modify the returned {@link List}, but the changes will not be
+     * reflected back to the repository.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #allMatches(Query)} for production code.
+     */
+    public <T> List<T> allMatches(Class<T> ofType, String title);
+
+    /**
+     * Returns all the instances of the specified type (including subtypes) that
+     * match the given object: where any property that is set will be tested and
+     * properties that are not set will be ignored.
+     * 
+     * <p>
+     * If there are no instances the list will be empty. This method creates a
+     * new {@link List} object each time it is called so the caller is free to
+     * use or modify the returned {@link List}, but the changes will not be
+     * reflected back to the repository.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #allMatches(Query)} for production code.
+     */
+    <T> List<T> allMatches(Class<T> ofType, T pattern);
+
+    /**
+     * Returns all the instances that match the given {@link Query}.
+     * 
+     * <p>
+     * If there are no instances the list will be empty. This method creates a
+     * new {@link List} object each time it is called so the caller is free to
+     * use or modify the returned {@link List}, but the changes will not be
+     * reflected back to the repository.
+     */
+    <T> List<T> allMatches(Query<T> query);
+
+    /**
+     * Returns the first instance of the specified type (including subtypes)
+     * that matches the supplied {@link Filter}, or <tt>null</tt> if none.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #firstMatch(Query)} for production code.
+     */
+    public <T> T firstMatch(final Class<T> ofType, final Filter<T> filter);
+
+    /**
+     * Returns the first instance of the specified type (including subtypes)
+     * that matches the supplied title, or <tt>null</tt> if none.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #firstMatch(Query)} for production code.
+     */
+    <T> T firstMatch(Class<T> ofType, String title);
+
+    /**
+     * Returns the first instance of the specified type (including subtypes)
+     * that matches the supplied object as a pattern, or <tt>null</tt> if none.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #firstMatch(Query)} for production code.
+     */
+    <T> T firstMatch(Class<T> ofType, T pattern);
+
+    /**
+     * Returns the first instance that matches the supplied query, or
+     * <tt>null</tt> if none.
+     */
+    <T> T firstMatch(Query<T> query);
+
+    /**
+     * Find the only instance of the specified type (including subtypes) that
+     * has the specified title.
+     * 
+     * <p>
+     * If no instance is found then <tt>null</tt> will be return, while if there
+     * is more that one instances a run-time exception will be thrown.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #uniqueMatch(Query)} for production code.
+     */
+    public <T> T uniqueMatch(final Class<T> ofType, final Filter<T> filter);
+
+    /**
+     * Find the only instance of the specified type (including subtypes) that
+     * has the specified title.
+     * 
+     * <p>
+     * If no instance is found then <tt>null</tt> will be returned, while if
+     * there is more that one instances a run-time exception will be thrown.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #uniqueMatch(Query)} for production code.
+     */
+    <T> T uniqueMatch(Class<T> ofType, String title);
+
+    /**
+     * Find the only instance of the patterned object type (including subtypes)
+     * that matches the set fields in the pattern object: where any property
+     * that is set will be tested and properties that are not set will be
+     * ignored.
+     * 
+     * <p>
+     * If no instance is found then null will be return, while if there is more
+     * that one instances a run-time exception will be thrown.
+     * 
+     * <p>
+     * This method is useful during exploration/prototyping, but you may want to
+     * use {@link #uniqueMatch(Query)} for production code.
+     */
+    <T> T uniqueMatch(Class<T> ofType, T pattern);
+
+    /**
+     * Find the only instance that matches the provided query.
+     * 
+     * <p>
+     * If no instance is found then null will be return, while if there is more
+     * that one instances a run-time exception will be thrown.
+     */
+    <T> T uniqueMatch(Query<T> query);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/Identifier.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/Identifier.java b/framework/core/applib/src/main/java/org/apache/isis/applib/Identifier.java
new file mode 100644
index 0000000..258de6f
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/Identifier.java
@@ -0,0 +1,441 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Lists;
+
+public class Identifier implements Comparable<Identifier> {
+
+    private static final List<String> EMPTY_LIST_OF_STRINGS = Collections.<String> emptyList();
+
+    /**
+     * What type of feature this identifies.
+     */
+    public static enum Type {
+        CLASS, PROPERTY_OR_COLLECTION, ACTION
+    }
+
+    public static enum Depth {
+        CLASS {
+            @Override
+            public String toIdentityString(final Identifier identifier) {
+                return identifier.toClassIdentityString();
+            }
+        },
+        CLASS_MEMBERNAME {
+            @Override
+            public String toIdentityString(final Identifier identifier) {
+                return identifier.toClassAndNameIdentityString();
+            }
+        },
+        CLASS_MEMBERNAME_PARAMETERS {
+            @Override
+            public String toIdentityString(final Identifier identifier) {
+                return identifier.toFullIdentityString();
+            }
+        },
+        MEMBERNAME_ONLY {
+            @Override
+            public String toIdentityString(final Identifier identifier) {
+                return identifier.toNameIdentityString();
+            }
+        },
+        PARAMETERS_ONLY {
+            @Override
+            public String toIdentityString(final Identifier identifier) {
+                return identifier.toParmsIdentityString();
+            }
+        };
+        public abstract String toIdentityString(Identifier identifier);
+    }
+
+    public static Depth CLASS = Depth.CLASS;
+    public static Depth CLASS_MEMBERNAME = Depth.CLASS_MEMBERNAME;
+    public static Depth CLASS_MEMBERNAME_PARAMETERS = Depth.CLASS_MEMBERNAME_PARAMETERS;
+    public static Depth MEMBERNAME_ONLY = Depth.MEMBERNAME_ONLY;
+    public static Depth PARAMETERS_ONLY = Depth.PARAMETERS_ONLY;
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // Factory methods
+    // ///////////////////////////////////////////////////////////////////////////
+
+    public static Identifier classIdentifier(final Class<?> cls) {
+        return classIdentifier(cls.getName());
+    }
+
+    public static Identifier classIdentifier(final String className) {
+        return new Identifier(className, "", EMPTY_LIST_OF_STRINGS, Type.CLASS);
+    }
+
+    public static Identifier propertyOrCollectionIdentifier(final Class<?> declaringClass, final String propertyOrCollectionName) {
+        return propertyOrCollectionIdentifier(declaringClass.getCanonicalName(), propertyOrCollectionName);
+    }
+
+    public static Identifier propertyOrCollectionIdentifier(final String declaringClassName, final String propertyOrCollectionName) {
+        return new Identifier(declaringClassName, propertyOrCollectionName, EMPTY_LIST_OF_STRINGS, Type.PROPERTY_OR_COLLECTION);
+    }
+
+    public static Identifier actionIdentifier(final Class<?> declaringClass, final String actionName, final Class<?>... parameterClasses) {
+        return actionIdentifier(declaringClass.getCanonicalName(), actionName, classNamesOf(parameterClasses));
+    }
+
+    public static Identifier actionIdentifier(final String declaringClassName, final String actionName, final Class<?>... parameterClasses) {
+        return actionIdentifier(declaringClassName, actionName, classNamesOf(parameterClasses));
+    }
+
+    public static Identifier actionIdentifier(final String declaringClassName, final String actionName, final List<String> parameterClassNames) {
+        return new Identifier(declaringClassName, actionName, parameterClassNames, Type.ACTION);
+    }
+
+    /**
+     * Helper, used within contructor chaining
+     */
+    private static List<String> classNamesOf(final Class<?>[] parameterClasses) {
+        if (parameterClasses == null) {
+            return EMPTY_LIST_OF_STRINGS;
+        }
+        final List<String> parameterClassNames = Lists.newArrayList();
+        for (final Class<?> parameterClass : parameterClasses) {
+            parameterClassNames.add(parameterClass.getName());
+        }
+        return parameterClassNames;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // Instance variables
+    // ///////////////////////////////////////////////////////////////////////////
+
+    private final String className;
+    private final String memberName;
+    private final List<String> parameterNames;
+    private final Type type;
+    private String identityString;
+
+    /**
+     * Caching of {@link #toString()}, for performance.
+     */
+    private String asString = null;
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // Constructor
+    // ///////////////////////////////////////////////////////////////////////////
+
+    private Identifier(final String className, final String memberName, final List<String> parameterNames, final Type type) {
+        this.className = className;
+        this.memberName = memberName;
+        this.parameterNames = Collections.unmodifiableList(parameterNames);
+        this.type = type;
+    }
+
+    public String getClassName() {
+        return className;
+    }
+
+    public String getClassNaturalName() {
+        final String className = getClassName();
+        final String isolatedName = className.substring(className.lastIndexOf('.') + 1);
+        return NameUtils.naturalName(isolatedName);
+    }
+
+    public String getMemberName() {
+        return memberName;
+    }
+
+    public String getMemberNaturalName() {
+        return NameUtils.naturalName(memberName);
+    }
+
+    public List<String> getMemberParameterNames() {
+        return parameterNames;
+    }
+
+    public List<String> getMemberParameterNaturalNames() {
+        return NameUtils.naturalNames(parameterNames);
+    }
+
+    public Type getType() {
+        return type;
+    }
+
+    /**
+     * Convenience method.
+     * 
+     * @return
+     */
+    public boolean isPropertyOrCollection() {
+        return type == Type.PROPERTY_OR_COLLECTION;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // toXxxString
+    // ///////////////////////////////////////////////////////////////////////////
+
+    public String toIdentityString(final Depth depth) {
+        return depth.toIdentityString(this);
+    }
+
+    public String toClassIdentityString() {
+        return toClassIdentityString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toClassIdentityString(final StringBuilder buf) {
+        return buf.append(className);
+    }
+
+    public String toNameIdentityString() {
+        return toNameIdentityString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toNameIdentityString(final StringBuilder buf) {
+        return buf.append(memberName);
+    }
+
+    public String toClassAndNameIdentityString() {
+        return toClassAndNameIdentityString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toClassAndNameIdentityString(final StringBuilder buf) {
+        final StringBuilder builder = toClassIdentityString(buf).append("#").append(memberName);
+        if (type == Type.ACTION) {
+            builder.append("()");
+        }
+        return builder;
+    }
+
+    public String toParmsIdentityString() {
+        return toParmsIdentityString(new StringBuilder()).toString();
+    }
+
+    public StringBuilder toParmsIdentityString(final StringBuilder buf) {
+        if (type == Type.ACTION) {
+            appendParameterNamesTo(buf);
+        }
+        return buf;
+    }
+
+    private void appendParameterNamesTo(final StringBuilder buf) {
+        buf.append('(');
+        Joiner.on(',').appendTo(buf, parameterNames);
+        buf.append(')');
+    }
+
+    public String toNameParmsIdentityString() {
+        return getMemberName() + toParmsIdentityString();
+    }
+
+    public StringBuilder toNameParmsIdentityString(final StringBuilder buf) {
+        buf.append(getMemberName());
+        toParmsIdentityString(buf);
+        return buf;
+    }
+
+    public String toFullIdentityString() {
+        if (identityString == null) {
+            if (memberName.length() == 0) {
+                identityString = toClassIdentityString();
+            } else {
+                final StringBuilder buf = new StringBuilder();
+                toClassIdentityString(buf).append("#").append(memberName);
+                toParmsIdentityString(buf);
+                identityString = buf.toString();
+            }
+        }
+        return identityString;
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // compareTo
+    // ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public int compareTo(final Identifier o2) {
+        return toString().compareTo(o2.toString());
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // equals, hashCode
+    // ///////////////////////////////////////////////////////////////////////////
+
+    /**
+     * REVIEW: why not just compare the {@link #toString()} representations?
+     */
+    @Override
+    public boolean equals(final Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof Identifier)) {
+            return false;
+        }
+        final Identifier other = (Identifier) obj;
+        return equals(other);
+    }
+
+    public boolean equals(final Identifier other) {
+        return equals(other.className, className) && equals(other.memberName, other.memberName) && equals(other.parameterNames, parameterNames);
+    }
+
+    private boolean equals(final String a, final String b) {
+        if (a == b) {
+            return true;
+        }
+
+        return a != null && a.equals(b);
+    }
+
+    private boolean equals(final List<String> a, final List<String> b) {
+        if (a == null && b == null) {
+            return true;
+        } else if (a == null && b != null) {
+            return false;
+        } else if (a != null && b == null) {
+            return false;
+        } else if (a != null && b != null) {
+            return a.equals(b);
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    // ///////////////////////////////////////////////////////////////////////////
+    // toString
+    // ///////////////////////////////////////////////////////////////////////////
+
+    @Override
+    public String toString() {
+        if (asString == null) {
+            final StringBuilder buf = new StringBuilder();
+            buf.append(className);
+            buf.append('#');
+            buf.append(memberName);
+            appendParameterNamesTo(buf);
+            asString = buf.toString();
+        }
+        return asString;
+    }
+
+    /**
+     * Factory method.
+     * 
+     * @see #toIdentityString(int)
+     */
+    public static Identifier fromIdentityString(final String asString) {
+        if (asString == null) {
+            throw new IllegalArgumentException("expected: non-null identity string");
+        }
+
+        final int indexOfHash = asString.indexOf("#");
+        final int indexOfOpenBracket = asString.indexOf("(");
+        final int indexOfCloseBracket = asString.indexOf(")");
+        final String className = asString.substring(0, indexOfHash == -1 ? asString.length() : indexOfHash);
+        if (indexOfHash == -1 || indexOfHash == (asString.length() - 1)) {
+            return classIdentifier(className);
+        }
+        String name = null;
+        if (indexOfOpenBracket == -1) {
+            name = asString.substring(indexOfHash + 1);
+            return propertyOrCollectionIdentifier(className, name);
+        }
+        final List<String> parmList = new ArrayList<String>();
+        name = asString.substring(indexOfHash + 1, indexOfOpenBracket);
+        final String allParms = asString.substring(indexOfOpenBracket + 1, indexOfCloseBracket).trim();
+        if (allParms.length() > 0) {
+            // use StringTokenizer for .NET compatibility
+            final StringTokenizer tokens = new StringTokenizer(allParms, ",", false);
+            while (tokens.hasMoreTokens()) {
+                final String nextParam = tokens.nextToken();
+                parmList.add(nextParam);
+            }
+        }
+        return actionIdentifier(className, name, parmList);
+    }
+
+}
+
+/**
+ * Not public API, provides a number of utilities to represent formal
+ * {@link Identifier} names more naturally.
+ */
+class NameUtils {
+    private static final char SPACE = ' ';
+
+    /**
+     * Returns a word spaced version of the specified name, so there are spaces
+     * between the words, where each word starts with a capital letter. E.g.,
+     * "NextAvailableDate" is returned as "Next Available Date".
+     */
+    public static String naturalName(final String name) {
+
+        final int length = name.length();
+
+        if (length <= 1) {
+            return name.toUpperCase();// ensure first character is upper case
+        }
+
+        final StringBuffer naturalName = new StringBuffer(length);
+
+        char previousCharacter;
+        char character = Character.toUpperCase(name.charAt(0));// ensure first
+                                                               // character is
+                                                               // upper case
+        naturalName.append(character);
+        char nextCharacter = name.charAt(1);
+
+        for (int pos = 2; pos < length; pos++) {
+            previousCharacter = character;
+            character = nextCharacter;
+            nextCharacter = name.charAt(pos);
+
+            if (previousCharacter != SPACE) {
+                if (Character.isUpperCase(character) && !Character.isUpperCase(previousCharacter)) {
+                    naturalName.append(SPACE);
+                }
+                if (Character.isUpperCase(character) && Character.isLowerCase(nextCharacter) && Character.isUpperCase(previousCharacter)) {
+                    naturalName.append(SPACE);
+                }
+                if (Character.isDigit(character) && !Character.isDigit(previousCharacter)) {
+                    naturalName.append(SPACE);
+                }
+            }
+            naturalName.append(character);
+        }
+        naturalName.append(nextCharacter);
+        return naturalName.toString();
+    }
+
+    public static List<String> naturalNames(final List<String> names) {
+        final List<String> naturalNames = Lists.newArrayList();
+        for (final String name : names) {
+            naturalNames.add(NameUtils.naturalName(name));
+        }
+        return Collections.unmodifiableList(naturalNames);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/PersistFailedException.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/PersistFailedException.java b/framework/core/applib/src/main/java/org/apache/isis/applib/PersistFailedException.java
new file mode 100644
index 0000000..c308ca8
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/PersistFailedException.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+/**
+ * Indicates that the persistence of an object failed.
+ */
+public class PersistFailedException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private Throwable cause;
+
+    public PersistFailedException() {
+        super();
+    }
+
+    public PersistFailedException(final String msg) {
+        super(msg);
+    }
+
+    public PersistFailedException(final Throwable cause) {
+        this(cause.getMessage());
+        this.cause = cause;
+    }
+
+    public PersistFailedException(final String msg, final Throwable cause) {
+        this(msg);
+        this.cause = cause;
+    }
+
+    @Override
+    public Throwable getCause() {
+        return cause;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/RepositoryException.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/RepositoryException.java b/framework/core/applib/src/main/java/org/apache/isis/applib/RepositoryException.java
new file mode 100644
index 0000000..786fcc2
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/RepositoryException.java
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib;
+
+/**
+ * Indicates that a repository method has failed.
+ */
+public class RepositoryException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private Throwable cause;
+
+    public RepositoryException() {
+        super();
+    }
+
+    public RepositoryException(final String msg) {
+        super(msg);
+    }
+
+    public RepositoryException(final Throwable cause) {
+        this(cause.getMessage());
+        this.cause = cause;
+    }
+
+    public RepositoryException(final String msg, final Throwable cause) {
+        this(msg);
+        this.cause = cause;
+    }
+
+    @Override
+    public Throwable getCause() {
+        return cause;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/AbstractValueSemanticsProvider.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/AbstractValueSemanticsProvider.java b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/AbstractValueSemanticsProvider.java
new file mode 100644
index 0000000..bd1ba51
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/AbstractValueSemanticsProvider.java
@@ -0,0 +1,74 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib.adapters;
+
+public abstract class AbstractValueSemanticsProvider<T> implements ValueSemanticsProvider<T> {
+
+    private boolean immutable;
+    private boolean equalByContent;
+
+    /**
+     * Defaults {@link #isImmutable()} to <tt>true</tt> and
+     * {@link #isEqualByContent()} to <tt>true</tt> also.
+     */
+    public AbstractValueSemanticsProvider() {
+        this(true, true);
+    }
+
+    public AbstractValueSemanticsProvider(final boolean immutable, final boolean equalByContent) {
+        this.immutable = immutable;
+        this.equalByContent = equalByContent;
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public EncoderDecoder<T> getEncoderDecoder() {
+        return (EncoderDecoder<T>) (this instanceof EncoderDecoder ? this : null);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public Parser<T> getParser() {
+        return (Parser<T>) (this instanceof Parser ? this : null);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public DefaultsProvider<T> getDefaultsProvider() {
+        return (DefaultsProvider<T>) (this instanceof DefaultsProvider ? this : null);
+    }
+
+    /**
+     * Defaults to <tt>true</tt> if no-arg constructor is used.
+     */
+    @Override
+    public boolean isEqualByContent() {
+        return equalByContent;
+    }
+
+    /**
+     * Defaults to <tt>true</tt> if no-arg constructor is used.
+     */
+    @Override
+    public boolean isImmutable() {
+        return immutable;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/DefaultsProvider.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/DefaultsProvider.java b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/DefaultsProvider.java
new file mode 100644
index 0000000..d73ab08
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/DefaultsProvider.java
@@ -0,0 +1,55 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib.adapters;
+
+/**
+ * Provides a mechanism for providing a default value for an object.
+ * 
+ * <p>
+ * This interface is used in two complementary ways:
+ * <ul>
+ * <li>As one option, it allows objects to take control of their own default
+ * values, by implementing directly. However, the instance is used as a factory
+ * for itself. The framework will instantiate an instance, invoke the
+ * appropriate method method, and use the returned object. The instantiated
+ * instance itself will be discarded.</li>
+ * <li>Alternatively, an implementor of this interface can be nominated in the
+ * {@link org.apache.isis.applib.annotations.Defaulted} annotation, allowing a
+ * class that needs to have a default to indicate where its default comes from.</li>
+ * 
+ * <p>
+ * Whatever the class that implements this interface, it must also expose either
+ * a <tt>public</tt> no-arg constructor, or (for implementations that also are
+ * <tt>Facet</tt>s) a <tt>public</tt> constructor that accepts a single
+ * <tt>FacetHolder</tt>. This constructor allows the framework to instantiate
+ * the object reflectively.
+ * 
+ * @see Parser
+ * @see EncoderDecoder
+ * @see ValueSemanticsProvider
+ */
+public interface DefaultsProvider<T> {
+
+    /**
+     * The default, if any (as a pojo).
+     */
+    T getDefaultValue();
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncoderDecoder.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncoderDecoder.java b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncoderDecoder.java
new file mode 100644
index 0000000..2c70d24
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncoderDecoder.java
@@ -0,0 +1,71 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib.adapters;
+
+/**
+ * Provides a mechanism for encoding/decoding objects.
+ * 
+ * <p>
+ * This interface is used in two complementary ways:
+ * <ul>
+ * <li>As one option, it allows objects to take control of their own
+ * encoding/decoding, by implementing directly. However, the instance is used as
+ * a factory for itself. The framework will instantiate an instance, invoke the
+ * appropriate method method, and use the returned object. The instantiated
+ * instance itself will be discarded.</li>
+ * <li>Alternatively, an implementor of this interface can be nominated in the
+ * {@link org.apache.isis.applib.annotation.Encodable} annotation, allowing a
+ * class that needs to be encodeable to indicate how it can be encoded/decoded.</li>
+ * 
+ * <p>
+ * Whatever the class that implements this interface, it must also expose either
+ * a <tt>public</tt> no-arg constructor, or (for implementations that also are
+ * <tt>Facet</tt>s) a <tt>public</tt> constructor that accepts a single
+ * <tt>FacetHolder</tt>. This constructor allows the framework to instantiate
+ * the object reflectively.
+ * 
+ * @see Parser
+ * @see DefaultsProvider
+ * @see ValueSemanticsProvider
+ */
+public interface EncoderDecoder<T> {
+
+    /**
+     * Returns the provided object as an encoded string.
+     * 
+     * <p>
+     * Even if the class is self-encodeable, note that this method is always
+     * called on a new instance of the object created via the no-arg
+     * constructor. That is, the object shouldn't encode itself, it should
+     * encode the object provided to it.
+     */
+    String toEncodedString(T toEncode);
+
+    /**
+     * Converts an encoded string to an instance of the object.
+     * 
+     * <p>
+     * Note that here the implementing class is acting as a factory for itself.
+     * 
+     * @see #toEncodedString(% toEncode)
+     */
+    T fromEncodedString(String encodedString);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/dbb64345/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncodingException.java
----------------------------------------------------------------------
diff --git a/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncodingException.java b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncodingException.java
new file mode 100644
index 0000000..625d059
--- /dev/null
+++ b/framework/core/applib/src/main/java/org/apache/isis/applib/adapters/EncodingException.java
@@ -0,0 +1,44 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.applib.adapters;
+
+/**
+ * Indicates that encoding or decoding has failed.
+ */
+public class EncodingException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+
+    public EncodingException() {
+        super();
+    }
+
+    public EncodingException(final String msg) {
+        super(msg);
+    }
+
+    public EncodingException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+
+    public EncodingException(final Throwable cause) {
+        super(cause);
+    }
+
+}