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/05 00:41:11 UTC

[41/52] [partial] ISIS-188: consolidating isis-core

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/site/apt/index.apt
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/site/apt/index.apt b/framework/core/metamodel/src/site/apt/index.apt
index 82e597f..3afdc76 100644
--- a/framework/core/metamodel/src/site/apt/index.apt
+++ b/framework/core/metamodel/src/site/apt/index.apt
@@ -16,6 +16,29 @@
 ~~  under the License.
 
 
+Commons
+
+ The <core commons> module provides a set of common utilities and language 
+ extensions for use across the rest of the framework.
+ 
+ It also defines a number of small APIs that are used throughout:
+ 
+ * a set of interfaces for defining <<<Component>>>s and their scope
+ 
+ * a debug framework
+ 
+ * an <<<Ensure>>> API
+ 
+ * a set of {{{http://code.google.com/p/hamcrest}Hamcrest}} <<<Matcher>>>s
+ 
+ * a <<<ResourceStream>>> API  
+ 
+ * a <<<Filter>>> API
+ 
+ * a <<<Future>>> API
+
+ []
+
 
 MetaModel
 
@@ -43,6 +66,32 @@ MetaModel
  conventions; that is the responsibility of the 
  {{{../progmodel/index.html}core progmodel}}.
 
+
+ProgModel
+
+ The <core progmodel> provides a set of reusable elements (implementations of
+ the <<<FacetFactory>>> API) that can be reused to make up a programming model.
+ 
+ Most of those within <this> module are in fact used in the
+ default programming model, defined by the 
+ {{{../../progmodels/dflt/index.html}default progmodel}} module.  They are
+ defined within core, however, to allow custom programming models (perhaps
+ extending or trimming back the default programming model) to be defined.
+
+
+Runtime
+
+ The <core runtime> module defines a set of APIs common across
+ all runtime implementations.
+
+
+Webapp
+
+ The <core webapp> module provides a set of reusable servlets and filters 
+ that can be reused in any deployment irrespective of runtime implementation.
+
+
+
 Documentation
 
  See the {{{../index.html}core}} documentation 

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/config/another.properties
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/config/another.properties b/framework/core/metamodel/src/test/config/another.properties
new file mode 100644
index 0000000..d604173
--- /dev/null
+++ b/framework/core/metamodel/src/test/config/another.properties
@@ -0,0 +1,18 @@
+#  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.
+additional.example = added
+properties.example=two
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/config/isis.properties
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/config/isis.properties b/framework/core/metamodel/src/test/config/isis.properties
new file mode 100644
index 0000000..f6fb221
--- /dev/null
+++ b/framework/core/metamodel/src/test/config/isis.properties
@@ -0,0 +1,19 @@
+#  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.
+properties.example=one
+
+properties.trailingWhitespace=in-memory	 

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderFileSystemTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderFileSystemTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderFileSystemTest.java
new file mode 100644
index 0000000..78402d6
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderFileSystemTest.java
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.config;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class ConfigurationBuilderFileSystemTest extends TestCase {
+    IsisConfigurationBuilderFileSystem loader;
+
+    @Override
+    protected void setUp() throws Exception {
+        Logger.getRootLogger().setLevel(Level.OFF);
+        loader = new IsisConfigurationBuilderFileSystem("src/test/config");
+    }
+
+    public void testDefaultConfiguration() {
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals("one", configuration.getString("properties.example"));
+    }
+
+    public void testDefaultConfigurationTrailingWhitespace() {
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals("in-memory", configuration.getString("properties.trailingWhitespace"));
+    }
+
+    public void testAddConfiguration() {
+        loader.addConfigurationResource("another.properties", NotFoundPolicy.FAIL_FAST);
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals("added", configuration.getString("additional.example"));
+    }
+
+    public void testAddedConfigurationOveridesEarlierProperties() {
+        loader.addConfigurationResource("another.properties", NotFoundPolicy.FAIL_FAST);
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals("two", configuration.getString("properties.example"));
+    }
+
+    public void testAddedConfigurationFailsWhenFileNotFound() {
+        try {
+            loader.addConfigurationResource("unfound.properties", NotFoundPolicy.FAIL_FAST);
+            loader.getConfiguration();
+            fail();
+        } catch (final IsisException expected) {
+        }
+    }
+
+    public void testAddedConfigurationIgnoreUnfoundFile() {
+        loader.addConfigurationResource("unfound.properties", NotFoundPolicy.CONTINUE);
+        loader.getConfiguration();
+    }
+
+    public void testAddProperty() throws Exception {
+        loader.add("added.property", "added by code");
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals("added by code", configuration.getString("added.property"));
+    }
+
+    public void testIncludeSystemProperty() throws Exception {
+        loader.setIncludeSystemProperties(true);
+        final IsisConfiguration configuration = loader.getConfiguration();
+        assertEquals(System.getProperty("os.name"), configuration.getString("os.name"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderResourceStreamsConfigResourceAndPolicyTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderResourceStreamsConfigResourceAndPolicyTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderResourceStreamsConfigResourceAndPolicyTest.java
new file mode 100644
index 0000000..cadaaed
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderResourceStreamsConfigResourceAndPolicyTest.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.core.commons.config;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class ConfigurationBuilderResourceStreamsConfigResourceAndPolicyTest {
+
+    @Test
+    public void toStringWhenNull() throws Exception {
+        final IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy configurationResourceAndPolicy = new IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy(null, null);
+        assertThat(configurationResourceAndPolicy.toString(), is("null{null}"));
+    }
+
+    @Test
+    public void toStringWhenConfigResourceNotNull() throws Exception {
+        final IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy configurationResourceAndPolicy = new IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy("foo.properties", null);
+        assertThat(configurationResourceAndPolicy.toString(), is("foo.properties{null}"));
+    }
+
+    @Test
+    public void toStringWhenAllSpecified() throws Exception {
+        final IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy configurationResourceAndPolicy = new IsisConfigurationBuilderResourceStreams.ConfigurationResourceAndPolicy("foo.properties", NotFoundPolicy.CONTINUE);
+        assertThat(configurationResourceAndPolicy.toString(), is("foo.properties{CONTINUE}"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderTwoDirectoriesTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderTwoDirectoriesTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderTwoDirectoriesTest.java
new file mode 100644
index 0000000..81b2ebc
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/ConfigurationBuilderTwoDirectoriesTest.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.config;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+public class ConfigurationBuilderTwoDirectoriesTest extends TestCase {
+    IsisConfigurationBuilderFileSystem builder;
+
+    @Override
+    protected void setUp() throws Exception {
+        Logger.getRootLogger().setLevel(Level.OFF);
+        builder = new IsisConfigurationBuilderFileSystem("src/test/config", "src/test");
+    }
+
+    public void testAddConfigurationInDifferentDirectory() throws Exception {
+        builder.addConfigurationResource("three.properties", NotFoundPolicy.FAIL_FAST);
+        final IsisConfiguration configuration = builder.getConfiguration();
+        assertEquals("version 3", configuration.getString("different.property"));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefaultTest_createSubset.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefaultTest_createSubset.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefaultTest_createSubset.java
new file mode 100644
index 0000000..643a1ae
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefaultTest_createSubset.java
@@ -0,0 +1,100 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.commons.config;
+
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+import java.util.Iterator;
+
+import org.jmock.auto.Mock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.commons.config.IsisConfiguration;
+import org.apache.isis.core.commons.config.IsisConfigurationDefault;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+
+public class IsisConfigurationDefaultTest_createSubset {
+    
+    private IsisConfigurationDefault configuration;
+
+    @Before
+    public void setUp() throws Exception {
+        configuration = new IsisConfigurationDefault();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        configuration = null;
+    }
+
+    @Test
+    public void empty() {
+        final IsisConfiguration subset = configuration.createSubset("foo");
+        assertThat(subset.iterator().hasNext(), is(false));
+    }
+
+    @Test
+    public void nonEmptyButNoneInSubset() {
+        configuration.add("bar", "barValue");
+        final IsisConfiguration subset = configuration.createSubset("foo");
+        assertThat(subset.iterator().hasNext(), is(false));
+    }
+
+    @Test
+    public void nonEmptyButSingleKeyedInSubset() {
+        configuration.add("foo", "fooValue");
+        final IsisConfiguration subset = configuration.createSubset("foo");
+        final Iterator<String> iterator = subset.iterator();
+        assertThat(iterator.hasNext(), is(false));
+    }
+
+    @Test
+    public void nonEmptyAndMultiKeyedInSubset() {
+        configuration.add("foo.foz", "fozValue");
+        final IsisConfiguration subset = configuration.createSubset("foo");
+        final Iterator<String> iterator = subset.iterator();
+        assertThat(iterator.hasNext(), is(true));
+        assertThat(iterator.next(), is("foz"));
+        assertThat(iterator.hasNext(), is(false));
+        assertThat(subset.getString("foz"), is("fozValue"));
+    }
+
+    @Test
+    public void propertiesOutsideOfSubsetAreIgnored() {
+        configuration.add("foo.foz", "fozValue");
+        configuration.add("foo.faz", "fazValue");
+        configuration.add("bar.baz", "bazValue");
+        final IsisConfiguration subset = configuration.createSubset("foo");
+        assertThat(subset.getString("foz"), is("fozValue"));
+        assertThat(subset.getString("faz"), is("fazValue"));
+        
+        final Iterator<String> iterator = subset.iterator();
+        assertThat(iterator.hasNext(), is(true));
+        iterator.next();
+        assertThat(iterator.hasNext(), is(true));
+        iterator.next();
+        assertThat(iterator.hasNext(), is(false));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_PropertNamesTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_PropertNamesTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_PropertNamesTest.java
new file mode 100644
index 0000000..f8eb879
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_PropertNamesTest.java
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.config;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
+public class IsisConfigurationDefault_PropertNamesTest extends TestCase {
+
+    private IsisConfigurationDefault configuration;
+
+    public IsisConfigurationDefault_PropertNamesTest(final String name) {
+        super(name);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        BasicConfigurator.configure();
+        LogManager.getRootLogger().setLevel(Level.OFF);
+
+        configuration = new IsisConfigurationDefault();
+
+        final Properties p = new Properties();
+        p.put("isis.bool", "on");
+        p.put("isis.str", "string");
+        configuration.add(p);
+
+        final Properties p1 = new Properties();
+        p1.put("isis.int", "1");
+        p1.put("isis.str", "replacement");
+        configuration.add(p1);
+    }
+
+    public void testDuplicatedPropertyName() {
+        assertEquals("replacement", configuration.getString("isis.str"));
+    }
+
+    public void testUniqueEntries() {
+        assertEquals(1, configuration.getInteger("isis.int"));
+        assertEquals(true, configuration.getBoolean("isis.bool"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_WhitespaceTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_WhitespaceTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_WhitespaceTest.java
new file mode 100644
index 0000000..b3c05a8
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/config/IsisConfigurationDefault_WhitespaceTest.java
@@ -0,0 +1,75 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.config;
+
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+
+public class IsisConfigurationDefault_WhitespaceTest extends TestCase {
+
+    private IsisConfigurationDefault configuration;
+
+    public IsisConfigurationDefault_WhitespaceTest(final String name) {
+        super(name);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        BasicConfigurator.configure();
+        LogManager.getRootLogger().setLevel(Level.OFF);
+
+        configuration = new IsisConfigurationDefault();
+
+        final Properties p = new Properties();
+        p.put("properties.leadingSpaces", "  twoSpacesBeforeThis");
+        p.put("properties.leadingTab", "\toneTabBeforeThis");
+        p.put("properties.trailingSpaces", "twoSpacesAfterThis  ");
+        p.put("properties.trailingTab", "oneTabAfterThis\t");
+        p.put("properties.trailingTabAndSpaces", "oneTabAndTwoSpacesAfterThis\t  ");
+        configuration.add(p);
+
+    }
+
+    public void testLeadingSpaces() {
+        assertEquals("twoSpacesBeforeThis", configuration.getString("properties.leadingSpaces"));
+    }
+
+    public void testLeadingTab() {
+        assertEquals("oneTabBeforeThis", configuration.getString("properties.leadingTab"));
+    }
+
+    public void testTrailingSpaces() {
+        assertEquals("twoSpacesAfterThis", configuration.getString("properties.trailingSpaces"));
+    }
+
+    public void testTrailingTab() {
+        assertEquals("oneTabAfterThis", configuration.getString("properties.trailingTab"));
+    }
+
+    public void testTrailingTabSpaces() {
+        assertEquals("oneTabAndTwoSpacesAfterThis", configuration.getString("properties.trailingTabAndSpaces"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/debug/DebugStringTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/debug/DebugStringTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/debug/DebugStringTest.java
new file mode 100644
index 0000000..a71376f
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/debug/DebugStringTest.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.debug;
+
+import junit.framework.TestCase;
+
+public class DebugStringTest extends TestCase {
+    private DebugString str;
+
+    @Override
+    protected void setUp() throws Exception {
+        str = new DebugString();
+    }
+
+    public void testLFNotAddedToEmptyString() {
+        str.blankLine();
+        assertEquals("", str.toString());
+    }
+
+    public void testBlankLineAfterFirstLineWithLineFeed() {
+        str.appendln("fred");
+        str.blankLine();
+        assertEquals("fred\n\n", str.toString());
+    }
+
+    public void testBlankLineAfterFirstLine() {
+        str.append("fred");
+        str.blankLine();
+        assertEquals("fred\n\n", str.toString());
+    }
+
+    public void testOnlyOneBlankLine() {
+        str.append("fred");
+        str.blankLine();
+        str.blankLine();
+        str.blankLine();
+        assertEquals("fred\n\n", str.toString());
+    }
+
+    public void testOnlyOneBlankLine2() {
+        str.appendln("fred");
+        str.blankLine();
+        str.blankLine();
+        str.blankLine();
+        assertEquals("fred\n\n", str.toString());
+    }
+
+    public void testSection() {
+        str.startSection("Section A");
+        str.appendln("text 1");
+        str.appendln("text 2");
+        str.endSection();
+        str.startSection("Section B");
+        assertEquals("\n1. Section A\n" + "------------\n" + "   text 1\n" + "   text 2\n\n\n" + "2. Section B\n" + "------------\n", str.toString());
+    }
+
+    public void testTitle() {
+        str.appendTitle("New Section");
+        str.appendln("text");
+        assertEquals("\nNew Section\n" + "-----------\n" + "text\n", str.toString());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/ByteEncoderDecoderRoundtripTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/ByteEncoderDecoderRoundtripTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/ByteEncoderDecoderRoundtripTest.java
new file mode 100644
index 0000000..3b135ff
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/ByteEncoderDecoderRoundtripTest.java
@@ -0,0 +1,176 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.encoding;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ByteEncoderDecoderRoundtripTest {
+
+    private DataOutputStreamExtended outputImpl;
+    private DataInputStreamExtended inputImpl;
+
+    @Before
+    public void setUp() throws Exception {
+        final PipedInputStream pipedInputStream = new PipedInputStream();
+        final PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream);
+        outputImpl = new DataOutputStreamExtended(pipedOutputStream);
+        inputImpl = new DataInputStreamExtended(pipedInputStream);
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        // does nothing yet
+    }
+
+    @Test
+    public void encodeAndDecodeBoolean() throws IOException {
+        outputImpl.writeBoolean(true);
+        outputImpl.writeBoolean(false);
+
+        assertThat(inputImpl.readBoolean(), is(equalTo(true)));
+        assertThat(inputImpl.readBoolean(), is(equalTo(false)));
+    }
+
+    @Test
+    public void encodeAndDecodeByteArray() throws IOException {
+        final byte[] bytes = { 3, 76, -1, 21 };
+        outputImpl.writeBytes(bytes);
+        final byte[] decodedBytes = inputImpl.readBytes();
+
+        assertThatArraysEqual(bytes, decodedBytes);
+    }
+
+    @Test
+    public void encodeAndDecodeInt() throws IOException {
+        outputImpl.writeInt(245);
+        outputImpl.writeInt(-456);
+
+        assertThat(inputImpl.readInt(), is(equalTo(245)));
+        assertThat(inputImpl.readInt(), is(equalTo(-456)));
+    }
+
+    @Test
+    public void encodeAndDecodeLong() throws IOException {
+        outputImpl.writeLong(245L);
+        outputImpl.writeLong(-456L);
+
+        assertThat(inputImpl.readLong(), is(equalTo(245L)));
+        assertThat(inputImpl.readLong(), is(equalTo(-456L)));
+    }
+
+    @Test
+    public void encodeAndDecodeObject() throws IOException {
+        outputImpl.writeEncodable(new EncodableObject());
+
+        final Object object = inputImpl.readEncodable(Object.class);
+        assertThat(object, is(instanceOf(EncodableObject.class)));
+
+        final EncodableObject encodeableObject = (EncodableObject) object;
+        assertThat(encodeableObject.field, is(equalTo("test field")));
+    }
+
+    @Test
+    public void encodeAndDecodeNullObject() throws IOException {
+        outputImpl.writeEncodable(null);
+
+        final Object object = inputImpl.readEncodable(Object.class);
+        assertThat(object, is(nullValue()));
+    }
+
+    @Test
+    public void encodeAndDecodeObjectArray() throws IOException {
+        final EncodableObject[] array = new EncodableObject[] { new EncodableObject(), new EncodableObject(), new EncodableObject() };
+        outputImpl.writeEncodables(array);
+
+        final Encodable[] objects = inputImpl.readEncodables(Encodable.class);
+        assertThat(objects.length, is(3));
+        final EncodableObject encodeableObject = (EncodableObject) objects[2];
+        assertThat(encodeableObject.field, is(equalTo("test field")));
+    }
+
+    @Test
+    public void encodeAndDecodeNullObjectArray() throws IOException {
+        outputImpl.writeEncodables(null);
+
+        final Encodable[] objects = inputImpl.readEncodables(Encodable.class);
+        assertThat(objects, is(nullValue()));
+    }
+
+    @Test
+    public void encodeAndDecodeString() throws IOException {
+        outputImpl.writeUTF("test");
+        outputImpl.writeUTF("");
+        outputImpl.writeUTF("second");
+
+        assertThat(inputImpl.readUTF(), is(equalTo("test")));
+        assertThat(inputImpl.readUTF(), is(equalTo("")));
+        assertThat(inputImpl.readUTF(), is(equalTo("second")));
+    }
+
+    @Test
+    public void encodeAndDecodeStringArray() throws IOException {
+        final String[] list = { "one", "two", "three" };
+        outputImpl.writeUTFs(list);
+
+        final String[] returnedList = inputImpl.readUTFs();
+
+        assertThat(returnedList.length, is(equalTo(list.length)));
+        assertThat(returnedList[0], is(equalTo(list[0])));
+        assertThat(returnedList[1], is(equalTo(list[1])));
+        assertThat(returnedList[2], is(equalTo(list[2])));
+    }
+
+    private void assertThatArraysEqual(final byte[] bytes, final byte[] decodedBytes) {
+        assertThat(decodedBytes.length, is(equalTo(bytes.length)));
+        for (int i = 0; i < bytes.length; i++) {
+            assertThat(decodedBytes[i], is(equalTo(bytes[i])));
+        }
+    }
+
+}
+
+class EncodableObject implements Encodable {
+    String field;
+
+    public EncodableObject() {
+    }
+
+    public EncodableObject(final DataInputExtended input) throws IOException {
+        field = input.readUTF();
+    }
+
+    @Override
+    public void encode(final DataOutputExtended output) throws IOException {
+        output.writeUTF("test field");
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/EncodabilityContractTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/EncodabilityContractTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/EncodabilityContractTest.java
new file mode 100644
index 0000000..e289258
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/encoding/EncodabilityContractTest.java
@@ -0,0 +1,90 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.encoding;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+
+import org.jmock.Mockery;
+import org.jmock.integration.junit4.JUnit4Mockery;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+
+public abstract class EncodabilityContractTest {
+
+    protected final Mockery context = new JUnit4Mockery();
+    protected AuthenticationSession mockAuthSession;
+
+    protected Encodable encodable;
+
+    public EncodabilityContractTest() {
+        super();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        encodable = createEncodable();
+        mockAuthSession = context.mock(AuthenticationSession.class);
+    }
+
+    /**
+     * Hook for subclasses to provide object to be tested.
+     */
+    protected abstract Encodable createEncodable();
+
+    @Test
+    public void shouldImplementEncodeable() throws Exception {
+        assertThat(encodable, is(instanceOf(Encodable.class)));
+    }
+
+    @Test
+    public void shouldHaveOneArgConstructorThatAcceptsInput() {
+        final Object o = encodable;
+        try {
+            o.getClass().getConstructor(DataInputExtended.class);
+        } catch (final Exception e) {
+            fail("could not locate 1-arg constructor accepting a DataInputExtended instance");
+        }
+    }
+
+    @Test
+    public void shouldRoundTrip() throws IOException {
+        final PipedInputStream pipedInputStream = new PipedInputStream();
+        final PipedOutputStream pipedOutputStream = new PipedOutputStream(pipedInputStream);
+        final DataOutputStreamExtended outputImpl = new DataOutputStreamExtended(pipedOutputStream);
+        final DataInputStreamExtended inputImpl = new DataInputStreamExtended(pipedInputStream);
+
+        outputImpl.writeEncodable(encodable);
+        final Object decodedEncodable = inputImpl.readEncodable(Object.class);
+
+        assertRoundtripped(decodedEncodable, encodable);
+    }
+
+    protected abstract void assertRoundtripped(Object decodedEncodable, Object originalEncodable);
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesMatchTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesMatchTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesMatchTest.java
new file mode 100644
index 0000000..9edd180
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesMatchTest.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.core.commons.ensure;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.hamcrest.CoreMatchers.sameInstance;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class Ensure_GivenValueThatDoesMatchTest {
+
+    @Test
+    public void whenCallEnsureThatArgThenShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatArg(object, is(not(nullValue(String.class))));
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+    @Test
+    public void whenCallEnsureThatArgWithOverloadedShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatArg(object, is(not(nullValue(String.class))), "some message");
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+    @Test
+    public void whenCallEnsureThatStateThenShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatState(object, is(not(nullValue(String.class))));
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+    @Test
+    public void whenCallEnsureThatStateWithOverloadedShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatState(object, is(not(nullValue(String.class))), "some message");
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+    @Test
+    public void whenCallEnsureThatContextThenShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatContext(object, is(not(nullValue(String.class))));
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+    @Test
+    public void whenCallEnsureThatContextWithOverloadedShouldReturnOriginalObject() {
+        final String object = "foo";
+        final String returnedObject = Ensure.ensureThatContext(object, is(not(nullValue(String.class))), "some message");
+        assertThat(returnedObject, sameInstance(object));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesNotMatchTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesNotMatchTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesNotMatchTest.java
new file mode 100644
index 0000000..ad9c65a
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/ensure/Ensure_GivenValueThatDoesNotMatchTest.java
@@ -0,0 +1,91 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.ensure;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import org.junit.Test;
+
+public class Ensure_GivenValueThatDoesNotMatchTest {
+
+    @Test
+    public void whenCallEnsureThatArgShouldThrowIllegalArgumentException() {
+        try {
+            Ensure.ensureThatArg("foo", is(nullValue()));
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            assertThat(ex.getMessage(), is("illegal argument, expected: is null"));
+        }
+    }
+
+    @Test
+    public void whenCallEnsureThatArgOverloadedShouldThrowIllegalArgumentExceptionUsingSuppliedMessage() {
+        try {
+            Ensure.ensureThatArg("foo", is(nullValue()), "my message");
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            assertThat(ex.getMessage(), is("my message"));
+        }
+    }
+
+    @Test
+    public void whenCallEnsureThatStateShouldThrowIllegalStateException() {
+        try {
+            Ensure.ensureThatState("foo", is(nullValue()));
+            fail();
+        } catch (final IllegalStateException ex) {
+            assertThat(ex.getMessage(), is("illegal argument, expected: is null"));
+        }
+    }
+
+    @Test
+    public void whenCallEnsureThatStateOverloadedShouldThrowIllegalStateExceptionUsingSuppliedMessage() {
+        try {
+            Ensure.ensureThatState("foo", is(nullValue()), "my message");
+            fail();
+        } catch (final IllegalStateException ex) {
+            assertThat(ex.getMessage(), is("my message"));
+        }
+    }
+
+    @Test
+    public void whenCallEnsureThatContextShouldThrowIllegalThreadStateException() {
+        try {
+            Ensure.ensureThatContext("foo", is(nullValue()));
+            fail();
+        } catch (final IllegalThreadStateException ex) {
+            assertThat(ex.getMessage(), is("illegal argument, expected: is null"));
+        }
+    }
+
+    @Test
+    public void whenCallEnsureThatContextOverloadedShouldThrowIllegalThreadStateExceptionUsingSuppliedMessage() {
+        try {
+            Ensure.ensureThatContext("foo", is(nullValue()), "my message");
+            fail();
+        } catch (final IllegalThreadStateException ex) {
+            assertThat(ex.getMessage(), is("my message"));
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/IoUtils_CopyTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/IoUtils_CopyTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/IoUtils_CopyTest.java
new file mode 100644
index 0000000..b25f22e
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/IoUtils_CopyTest.java
@@ -0,0 +1,136 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.junit.Assert.assertThat;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class IoUtils_CopyTest {
+
+    private static final class ArrayMatcher extends TypeSafeMatcher<byte[]> {
+
+        private final byte[] expectedBytes;
+
+        public ArrayMatcher(final byte[] expectedBytes) {
+            this.expectedBytes = expectedBytes;
+        }
+
+        @Override
+        public boolean matchesSafely(final byte[] actualBytes) {
+            if (actualBytes.length != expectedBytes.length) {
+                return false;
+            }
+            for (int i = 0; i < actualBytes.length; i++) {
+                if (actualBytes[i] != expectedBytes[i]) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        @Override
+        public void describeTo(final Description arg0) {
+            arg0.appendText("does not match expected array");
+        }
+    }
+
+    private static int BUF_INTERNAL_SIZE = 1024;
+
+    @Before
+    public void setUp() throws Exception {
+    }
+
+    @After
+    public void tearDown() throws Exception {
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void handlesNullInputStream() throws Exception {
+        final ByteArrayInputStream bais = null;
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        IoUtils.copy(bais, baos);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void handlesNullOutputStream() throws Exception {
+        final byte[] bytes = createByteArray(10);
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final ByteArrayOutputStream baos = null;
+        IoUtils.copy(bais, baos);
+    }
+
+    @Test
+    public void copiesEmptyInputStream() throws Exception {
+        final byte[] bytes = createByteArray(0);
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        IoUtils.copy(bais, baos);
+        assertThat(baos.toByteArray(), arrayEqualTo(bytes));
+    }
+
+    @Test
+    public void copiesInputStreamSmallerThanInternalBuffer() throws Exception {
+        final byte[] bytes = createByteArray(BUF_INTERNAL_SIZE - 1);
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        IoUtils.copy(bais, baos);
+        assertThat(baos.toByteArray(), arrayEqualTo(bytes));
+    }
+
+    @Test
+    public void copiesInputStreamLargerThanInternalBuffer() throws Exception {
+        final byte[] bytes = createByteArray(BUF_INTERNAL_SIZE + 1);
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        IoUtils.copy(bais, baos);
+        assertThat(baos.toByteArray(), arrayEqualTo(bytes));
+    }
+
+    @Test
+    public void copiesInputStreamExactlySameSizeAsInternalBuffer() throws Exception {
+        final byte[] bytes = createByteArray(BUF_INTERNAL_SIZE);
+        final ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
+        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        IoUtils.copy(bais, baos);
+        assertThat(baos.toByteArray(), arrayEqualTo(bytes));
+    }
+
+    private Matcher<byte[]> arrayEqualTo(final byte[] bytes) {
+        return new ArrayMatcher(bytes);
+    }
+
+    private byte[] createByteArray(final int size) {
+        final byte[] bytes = new byte[size];
+        for (int i = 0; i < size; i++) {
+            bytes[i] = (byte) i;
+        }
+        return bytes;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/JavaClassUtilsTest_getBuiltIn.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/JavaClassUtilsTest_getBuiltIn.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/JavaClassUtilsTest_getBuiltIn.java
new file mode 100644
index 0000000..4155fdb
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/JavaClassUtilsTest_getBuiltIn.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class JavaClassUtilsTest_getBuiltIn {
+
+    @Test
+    public void voidBuiltIns() throws ClassNotFoundException {
+        assertEquals(JavaClassUtils.getBuiltIn("void"), void.class);
+        assertEquals(JavaClassUtils.getBuiltIn("boolean"), boolean.class);
+        assertEquals(JavaClassUtils.getBuiltIn("byte"), byte.class);
+        assertEquals(JavaClassUtils.getBuiltIn("short"), short.class);
+        assertEquals(JavaClassUtils.getBuiltIn("int"), int.class);
+        assertEquals(JavaClassUtils.getBuiltIn("long"), long.class);
+        assertEquals(JavaClassUtils.getBuiltIn("char"), char.class);
+        assertEquals(JavaClassUtils.getBuiltIn("float"), float.class);
+        assertEquals(JavaClassUtils.getBuiltIn("double"), double.class);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/LocaleUtilsTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/LocaleUtilsTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/LocaleUtilsTest.java
new file mode 100644
index 0000000..dc0b916
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/LocaleUtilsTest.java
@@ -0,0 +1,36 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class LocaleUtilsTest {
+
+    @Test
+    public void canFindEnGB() throws Exception {
+        assertThat(LocaleUtils.findLocale("en_GB"), is(not(nullValue())));
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/NameUtilTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/NameUtilTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/NameUtilTest.java
new file mode 100644
index 0000000..5904102
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/NameUtilTest.java
@@ -0,0 +1,82 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import junit.framework.TestCase;
+
+public class NameUtilTest extends TestCase {
+
+    public void testNaturalNameAddsSpacesToCamelCaseWords() {
+        assertEquals("Camel Case Word", NameUtils.naturalName("CamelCaseWord"));
+    }
+
+    public void testNaturalNameAddsSpacesBeforeNumbers() {
+        assertEquals("One 2 One", NameUtils.naturalName("One2One"));
+        assertEquals("Type 123", NameUtils.naturalName("Type123"));
+        assertEquals("4321 Go", NameUtils.naturalName("4321Go"));
+    }
+
+    public void testNaturalNameRecognisesAcronymns() {
+        assertEquals("TNT Power", NameUtils.naturalName("TNTPower"));
+        assertEquals("Spam RAM Can", NameUtils.naturalName("SpamRAMCan"));
+        assertEquals("DOB", NameUtils.naturalName("DOB"));
+    }
+
+    public void testNaturalNameWithShortNames() {
+        assertEquals("At", NameUtils.naturalName("At"));
+        assertEquals("I", NameUtils.naturalName("I"));
+    }
+
+    public void testNaturalNameNoChange() {
+        assertEquals("Camel Case Word", NameUtils.naturalName("CamelCaseWord"));
+        assertEquals("Almost Normal english sentence", NameUtils.naturalName("Almost Normal english sentence"));
+    }
+
+    public void testPluralNameAdd_S() {
+        assertEquals("Cans", NameUtils.pluralName("Can"));
+        assertEquals("Spaces", NameUtils.pluralName("Space"));
+        assertEquals("Noses", NameUtils.pluralName("Nose"));
+    }
+
+    public void testPluralNameReplace_Y_With_IES() {
+        assertEquals("Babies", NameUtils.pluralName("Baby"));
+        assertEquals("Cities", NameUtils.pluralName("City"));
+    }
+
+    public void testPluralNameReplaceAdd_ES() {
+        assertEquals("Foxes", NameUtils.pluralName("Fox"));
+        assertEquals("Bosses", NameUtils.pluralName("Boss"));
+    }
+
+    public void testSimpleNameAllToLowerCase() {
+        assertEquals("abcde", NameUtils.simpleName("ABCDE"));
+        assertEquals("camelcaseword", NameUtils.simpleName("CamelCaseWord"));
+    }
+
+    public void testSimpleNameNoChanges() {
+        assertEquals("nochanges", NameUtils.simpleName("nochanges"));
+    }
+
+    public void testSimpleNameRemoveSpaces() {
+        assertEquals("abcde", NameUtils.simpleName("a bc  de "));
+        assertEquals("twoparts", NameUtils.simpleName("two parts"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/PrintLocale.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/PrintLocale.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/PrintLocale.java
new file mode 100644
index 0000000..31c885f
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/PrintLocale.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.TimeZone;
+
+public class PrintLocale {
+    public static void main(final String[] args) {
+        if (args.length >= 2) {
+            final String localeSetting = args[0];
+            System.out.println("Setting Locale to " + localeSetting + "\n");
+            Locale.setDefault(new Locale(localeSetting));
+
+            final String timezoneSetting = args[1];
+            System.out.println("Setting TimeZone to " + timezoneSetting + "\n");
+            TimeZone.setDefault(TimeZone.getTimeZone(timezoneSetting));
+        }
+
+        final Locale locale = Locale.getDefault();
+        System.out.println("Locale");
+        System.out.println("Code: " + locale.toString());
+        try {
+            System.out.println("Country: " + locale.getISO3Country());
+        } catch (final MissingResourceException e) {
+            System.out.println("Country: " + e.getMessage());
+        }
+        try {
+            System.out.println("Language: " + locale.getISO3Language());
+        } catch (final MissingResourceException e) {
+            System.out.println("Language: " + e.getMessage());
+        }
+
+        System.out.println("\nTimezone");
+        final TimeZone timezone = TimeZone.getDefault();
+        System.out.println("Code: " + timezone.getID());
+        System.out.println("Name: " + timezone.getDisplayName());
+        System.out.println("Offset: " + timezone.getRawOffset() / (1000 * 60 * 60));
+        System.out.println("DST: " + timezone.getDSTSavings() / (1000 * 60 * 60));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtilsTest_enumTitle.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtilsTest_enumTitle.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtilsTest_enumTitle.java
new file mode 100644
index 0000000..4cec9e3
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtilsTest_enumTitle.java
@@ -0,0 +1,41 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtilsTest_enumTitle {
+
+    @Test
+    public void enumTitle() {
+        assertThat(StringUtils.enumTitle("FOO"), is("Foo"));
+        assertThat(StringUtils.enumTitle("FOO_BAR"), is("Foo Bar"));
+    }
+
+    @Test
+    public void enumDeTitle() {
+        assertThat(StringUtils.enumDeTitle("Foo"), is("FOO"));
+        assertThat(StringUtils.enumDeTitle("Foo Bar"), is("FOO_BAR"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalNameTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalNameTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalNameTest.java
new file mode 100644
index 0000000..0e3f7ee
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalNameTest.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtils_NaturalNameTest {
+
+    @Test
+    public void shouldCreateANaturalNameForABooleanPropertyAccessorName() {
+        assertThat(StringUtils.naturalName("isOutOfStock"), is("Out Of Stock"));
+    }
+
+    @Test
+    public void shouldCreateANaturalNameForABooleanPropertyAccessorNameSingleWord() {
+        assertThat(StringUtils.naturalName("isBlacklisted"), is("Blacklisted"));
+    }
+
+    @Test
+    public void shouldCreateANaturalNameForANonBooleanPropertyAccessorName() {
+        assertThat(StringUtils.naturalName("getFirstName"), is("First Name"));
+    }
+
+    @Test
+    public void shouldCreateANaturalNameForANonBooleanPropertyAccessorNameSingleWord() {
+        assertThat(StringUtils.naturalName("getAge"), is("Age"));
+    }
+
+    @Test
+    public void shouldCreateANaturalNameForAPropertyMutatorName() {
+        assertThat(StringUtils.naturalName("setFirstName"), is("First Name"));
+    }
+
+    @Test
+    public void shouldCreateANaturalNameForAPropertyMutatorNameSingleWord() {
+        assertThat(StringUtils.naturalName("setAge"), is("Age"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalizeTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalizeTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalizeTest.java
new file mode 100644
index 0000000..0c3dd89
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NaturalizeTest.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.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtils_NaturalizeTest {
+
+    @Test
+    public void shouldNaturalizeMultipleCamelCase() {
+        assertThat(StringUtils.naturalize("thisIsACamelCasePhrase"), is("This Is A Camel Case Phrase"));
+    }
+
+    @Test
+    public void shouldNaturalizeMultiplePascalCase() {
+        assertThat(StringUtils.naturalize("ThisIsAPascalCasePhrase"), is("This Is A Pascal Case Phrase"));
+    }
+
+    @Test
+    public void shouldNaturalizeSingleWordStartingWithLowerCase() {
+        assertThat(StringUtils.naturalize("foo"), is("Foo"));
+    }
+
+    @Test
+    public void shouldNaturalizeSingleWordStartingWithUpperCase() {
+        assertThat(StringUtils.naturalize("Foo"), is("Foo"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedTest.java
new file mode 100644
index 0000000..027258e
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedTest.java
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class StringUtils_NormalizedTest {
+
+    @Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] { { null, null, }, // null
+                { "", "", }, // empty string
+                { "yada Foobar", "yada Foobar", }, // alreadyNormalized
+                { "Yada\tFoobar", "Yada Foobar", }, // tab
+                { "Yada\t Foobar", "Yada Foobar", }, // tab and space
+                { "Yada  foobar", "Yada foobar", }, // two spaces
+                { "Yada\nfoobar", "Yada foobar", }, // new line
+                { "Yada\n Foobar", "Yada Foobar", }, // newline and space
+                { "Yada\r\n Foobar", "Yada Foobar", }, // windows newline
+                { "Yada\r Foobar", "Yada Foobar", }, // macos newline
+                { "Yada\r \tFoo \n\tbar  Baz", "Yada Foo bar Baz", }, // multiple
+        });
+    }
+
+    private final String input;
+    private final String expected;
+
+    public StringUtils_NormalizedTest(final String input, final String expected) {
+        this.input = input;
+        this.expected = expected;
+    }
+
+    @Test
+    public void normalizesOk() {
+        assertThat(StringUtils.normalized(input), is(expected));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedVarargsTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedVarargsTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedVarargsTest.java
new file mode 100644
index 0000000..4be6f0d
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_NormalizedVarargsTest.java
@@ -0,0 +1,54 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class StringUtils_NormalizedVarargsTest {
+
+    @Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] { { new String[] { "yada Foobar", "Yada\r \tFoo \n\tbar  Baz" }, new String[] { "yada Foobar", "Yada Foo bar Baz" }, }, });
+    }
+
+    private final String[] input;
+    private final String[] expected;
+
+    public StringUtils_NormalizedVarargsTest(final String[] input, final String[] expected) {
+        this.input = input;
+        this.expected = expected;
+    }
+
+    @Test
+    public void normalizesOk() {
+        assertThat(StringUtils.normalized(input), is(expected));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_RemoveLeadingWhiteSpace.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_RemoveLeadingWhiteSpace.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_RemoveLeadingWhiteSpace.java
new file mode 100644
index 0000000..7bc3816
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_RemoveLeadingWhiteSpace.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.core.commons.lang;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StringUtils_RemoveLeadingWhiteSpace {
+
+    @Test
+    public void whenHasLeadingWhiteSpace() {
+        final String removed = StringUtils.removeLeadingWhiteSpace(" 	 foo");
+        Assert.assertThat(removed, CoreMatchers.is("foo"));
+    }
+
+    @Test
+    public void whenNoLeadingWhiteSpace() {
+        final String removed = StringUtils.removeLeadingWhiteSpace("foo");
+        Assert.assertThat(removed, CoreMatchers.is("foo"));
+    }
+
+    @Test
+    public void empty() {
+        final String removed = StringUtils.removeLeadingWhiteSpace("");
+        Assert.assertThat(removed, CoreMatchers.is(""));
+    }
+
+    @Test
+    public void whenNull() {
+        final String removed = StringUtils.removeLeadingWhiteSpace(null);
+        Assert.assertThat(removed, CoreMatchers.is(CoreMatchers.nullValue()));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_SplitOnCommas.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_SplitOnCommas.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_SplitOnCommas.java
new file mode 100644
index 0000000..a09b30a
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_SplitOnCommas.java
@@ -0,0 +1,80 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.apache.isis.core.commons.lang;
+
+import java.util.List;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StringUtils_SplitOnCommas {
+
+    @Test
+    public void length() {
+        final List<String> list = StringUtils.splitOnCommas("foo,bar");
+        Assert.assertThat(list.size(), CoreMatchers.is(2));
+    }
+
+    @Test
+    public void elements() {
+        final List<String> list = StringUtils.splitOnCommas("foo,bar");
+        Assert.assertThat(list.get(0), CoreMatchers.is("foo"));
+        Assert.assertThat(list.get(1), CoreMatchers.is("bar"));
+    }
+
+    @Test
+    public void whenHasWhiteSpaceAfterComma() {
+        final List<String> list = StringUtils.splitOnCommas("foo, bar");
+        Assert.assertThat(list.get(0), CoreMatchers.is("foo"));
+        Assert.assertThat(list.get(1), CoreMatchers.is("bar"));
+    }
+
+    @Test
+    public void whenHasLeadingWhiteSpace() {
+        final List<String> list = StringUtils.splitOnCommas(" foo, bar");
+        Assert.assertThat(list.get(0), CoreMatchers.is("foo"));
+        Assert.assertThat(list.get(1), CoreMatchers.is("bar"));
+    }
+
+    @Test
+    public void whenNull() {
+        final List<String> list = StringUtils.splitOnCommas(null);
+        Assert.assertThat(list, CoreMatchers.is(CoreMatchers.nullValue()));
+    }
+
+    @Test
+    public void whenEmpty() {
+        final List<String> list = StringUtils.splitOnCommas("");
+        Assert.assertThat(list.size(), CoreMatchers.is(0));
+    }
+
+    @Test
+    public void whenOnlyWhiteSpace() {
+        final List<String> list = StringUtils.splitOnCommas(" ");
+        Assert.assertThat(list.size(), CoreMatchers.is(0));
+    }
+
+    @Test
+    public void whenOnlyWhiteSpaceTabs() {
+        final List<String> list = StringUtils.splitOnCommas("\t");
+        Assert.assertThat(list.size(), CoreMatchers.is(0));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripLeadingSlashTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripLeadingSlashTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripLeadingSlashTest.java
new file mode 100644
index 0000000..c8698ac
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripLeadingSlashTest.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.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtils_StripLeadingSlashTest {
+
+    @Test
+    public void shouldStripIfThereIsOne() {
+        assertThat(StringUtils.stripLeadingSlash("/foobar"), is("foobar"));
+    }
+
+    @Test
+    public void shouldLeaveUnchangedIfThereIsNone() {
+        assertThat(StringUtils.stripLeadingSlash("foobar"), is("foobar"));
+    }
+
+    @Test
+    public void shouldConvertSolitarySlashToEmptyString() {
+        assertThat(StringUtils.stripLeadingSlash("/"), is(""));
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void shouldFailOnNull() {
+        StringUtils.stripLeadingSlash(null);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripNewLinesTest.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripNewLinesTest.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripNewLinesTest.java
new file mode 100644
index 0000000..b020053
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_StripNewLinesTest.java
@@ -0,0 +1,59 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtils_StripNewLinesTest {
+
+    @Test
+    public void shouldDoNothingIfNone() {
+        assertThat(StringUtils.stripNewLines("abc"), is("abc"));
+    }
+
+    @Test
+    public void shouldStripIfJustBackslashN() {
+        assertThat(StringUtils.stripNewLines("abc\n"), is("abc"));
+    }
+
+    @Test
+    public void shouldStripIfBackslashRBackslashN() {
+        assertThat(StringUtils.stripNewLines("abc\r\n"), is("abc"));
+    }
+
+    @Test
+    public void shouldStripIfJustBackslashR() {
+        assertThat(StringUtils.stripNewLines("abc\r"), is("abc"));
+    }
+
+    @Test
+    public void shouldStripIfSeveral() {
+        assertThat(StringUtils.stripNewLines("abc\r\ndef\r\n"), is("abcdef"));
+    }
+
+    @Test
+    public void shouldStripIfBackslashRBackslashNBackslashR() {
+        assertThat(StringUtils.stripNewLines("abc\n\r\ndef"), is("abcdef"));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_camelLowerFirst.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_camelLowerFirst.java b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_camelLowerFirst.java
new file mode 100644
index 0000000..6b75903
--- /dev/null
+++ b/framework/core/metamodel/src/test/java/org/apache/isis/core/commons/lang/StringUtils_camelLowerFirst.java
@@ -0,0 +1,38 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.lang;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import org.junit.Test;
+
+public class StringUtils_camelLowerFirst {
+
+    @Test
+    public void asLowerCase() {
+        assertThat(StringUtils.camelLowerFirst("An Upper Case"), is("anUpperCase"));
+        assertThat(StringUtils.camelLowerFirst("a Lower Case"), is("aLowerCase"));
+        assertThat(StringUtils.camelLowerFirst("AnUpperCase"), is("anUpperCase"));
+        assertThat(StringUtils.camelLowerFirst("aLowerCase"), is("aLowerCase"));
+        assertThat(StringUtils.camelLowerFirst("a  Lower  Case"), is("aLowerCase"));
+    }
+
+}