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:08 UTC

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

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Ensure.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Ensure.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Ensure.java
new file mode 100644
index 0000000..3cff2ae
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/Ensure.java
@@ -0,0 +1,157 @@
+/*
+ *  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 org.hamcrest.Matcher;
+import org.hamcrest.StringDescription;
+
+/**
+ * Uses the {@link Matcher Hamcrest API} as a means of verifying arguments and
+ * so on.
+ */
+public final class Ensure {
+
+    private Ensure() {
+    }
+
+    /**
+     * To ensure that the provided assertion is true
+     * 
+     * @throws IllegalArgumentException
+     */
+    public static void ensure(final String expectation, final boolean expression) {
+        if (!expression) {
+            throw new IllegalArgumentException("illegal argument, expected: " + expectation);
+        }
+    }
+
+    /**
+     * To ensure that the provided argument is correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher,State)
+     * @see #ensureThatState(Object, Matcher, String)
+     * @see #ensureThatContext(Object, Matcher)
+     * 
+     * @throws IllegalArgumentException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatArg(final T object, final Matcher<T> matcher) {
+        if (!matcher.matches(object)) {
+            throw new IllegalArgumentException("illegal argument, expected: " + descriptionOf(matcher));
+        }
+        return object;
+    }
+
+
+    /**
+     * To ensure that the provided argument is correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher)
+     * @see #ensureThatState(Object, Matcher, String)
+     * @see #ensureThatContext(Object, Matcher)
+     * 
+     * @throws IllegalArgumentException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatArg(final T arg, final Matcher<T> matcher, final String message) {
+        if (!matcher.matches(arg)) {
+            throw new IllegalArgumentException(message);
+        }
+        return arg;
+    }
+
+    /**
+     * To ensure that the current state of this object (instance fields) is
+     * correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher)
+     * @see #ensureThatContext(Object, Matcher)
+     * @see #ensureThatState(Object, Matcher, String)
+     * 
+     * @throws IllegalStateException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatState(final T field, final Matcher<T> matcher) {
+        if (!matcher.matches(field)) {
+            throw new IllegalStateException("illegal argument, expected: " + descriptionOf(matcher));
+        }
+        return field;
+    }
+
+    /**
+     * To ensure that the current state of this object (instance fields) is
+     * correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher)
+     * @see #ensureThatContext(Object, Matcher)
+     * @see #ensureThatState(Object, Matcher)
+     * 
+     * @throws IllegalStateException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatState(final T field, final Matcher<T> matcher, final String message) {
+        if (!matcher.matches(field)) {
+            throw new IllegalStateException(message);
+        }
+        return field;
+    }
+
+    /**
+     * To ensure that the current context (<tt>IsisContext</tt>) is correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher)
+     * @see #ensureThatState(Object, Matcher)
+     * @see #ensureThatContext(Object, Matcher, String)
+     * 
+     * @throws IllegalThreadStateException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatContext(final T contextProperty, final Matcher<T> matcher) {
+        if (!matcher.matches(contextProperty)) {
+            throw new IllegalThreadStateException("illegal argument, expected: " + descriptionOf(matcher));
+        }
+        return contextProperty;
+    }
+
+    /**
+     * To ensure that the current context (<tt>IsisContext</tt>) is correct.
+     * 
+     * @see #ensureThatArg(Object, Matcher)
+     * @see #ensureThatState(Object, Matcher)
+     * @see #ensureThatContext(Object, Matcher, String)
+     * 
+     * @throws IllegalThreadStateException
+     *             if matcher does not {@link Matcher#matches(Object) match}.
+     */
+    public static <T> T ensureThatContext(final T contextProperty, final Matcher<T> matcher, final String message) {
+        if (!matcher.matches(contextProperty)) {
+            throw new IllegalThreadStateException(message);
+        }
+        return contextProperty;
+    }
+
+    private static <T> String descriptionOf(final Matcher<T> matcher) {
+        final StringDescription stringDescription = new StringDescription();
+        matcher.describeTo(stringDescription);
+        final String description = stringDescription.toString();
+        return description;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/IsisAssertException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/IsisAssertException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/IsisAssertException.java
new file mode 100644
index 0000000..ba48022
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/IsisAssertException.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.core.commons.ensure;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class IsisAssertException extends IsisException {
+
+    private static final long serialVersionUID = 1L;
+
+    public IsisAssertException() {
+        super();
+    }
+
+    public IsisAssertException(final String s) {
+        super(s);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/package-info.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/package-info.java
new file mode 100644
index 0000000..5bd67fe
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/ensure/package-info.java
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+/**
+ * Provides an infrastructure for encoding {@link org.apache.isis.core.commons.encoding.Encodable}
+ * into an {@link org.apache.isis.core.commons.encoding.DataOutputExtended output stream}
+ * or from an {@link org.apache.isis.core.commons.encoding.DataInputExtended input stream}.
+ * 
+ * <p>
+ * This is primarily for remoting (marshalling objects across the wire) but
+ * is also used in various other places, including the creation of
+ * mementos (to capture state at a point in time). 
+ */
+package org.apache.isis.core.commons.ensure;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisApplicationException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisApplicationException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisApplicationException.java
new file mode 100644
index 0000000..3387e23
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisApplicationException.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.exceptions;
+
+/**
+ * Indicates an error raised by the application code.
+ * 
+ * <p>
+ * The viewer is expected to render the message within the application in a
+ * user-friendly fashion.
+ */
+public class IsisApplicationException extends IsisException {
+
+    private static final long serialVersionUID = 1L;
+
+    public IsisApplicationException() {
+        super();
+    }
+
+    public IsisApplicationException(final String msg) {
+        super(msg);
+    }
+
+    public IsisApplicationException(final Throwable cause) {
+        super(cause);
+    }
+
+    public IsisApplicationException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisException.java
new file mode 100644
index 0000000..b8fb515
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/IsisException.java
@@ -0,0 +1,109 @@
+/*
+ *  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.exceptions;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.text.MessageFormat;
+
+/**
+ * General exception raised by the framework, typically a system exception.
+ */
+public class IsisException extends RuntimeException {
+    private static final long serialVersionUID = 1L;
+    private static boolean THROWABLE_SUPPORTS_CAUSE;
+
+    static {
+        // Java 1.4, and after, holds a cause; Java 1.1, 1.2 and .Net do not, so
+        // we need to
+        // do the work ourselves.
+        final Class<?> c = Throwable.class;
+        try {
+            THROWABLE_SUPPORTS_CAUSE = c.getMethod("getCause", new Class[0]) != null;
+        } catch (final Exception ignore) {
+            // this should never occur in proper Java environment
+            THROWABLE_SUPPORTS_CAUSE = false;
+        }
+    }
+
+    private final Throwable cause;
+
+    public IsisException() {
+        super("");
+        cause = null;
+    }
+
+    public IsisException(final String message) {
+        super(message);
+        cause = null;
+    }
+
+    public IsisException(final String messageFormat, final Object... args) {
+        super(MessageFormat.format(messageFormat, args));
+        cause = null;
+    }
+
+    public IsisException(final String message, final Throwable cause) {
+        super(message);
+        this.cause = cause;
+    }
+
+    public IsisException(final Throwable cause) {
+        super(cause == null ? null : cause.toString());
+        this.cause = cause;
+    }
+
+    @Override
+    public Throwable getCause() {
+        return (cause == this ? null : cause);
+    }
+
+    @Override
+    public void printStackTrace(final PrintStream s) {
+        if (THROWABLE_SUPPORTS_CAUSE) {
+            super.printStackTrace(s);
+        } else {
+            synchronized (s) {
+                super.printStackTrace(s);
+                final Throwable c = getCause();
+                if (c != null) {
+                    s.print("Root cause: ");
+                    c.printStackTrace(s);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void printStackTrace(final PrintWriter s) {
+        if (THROWABLE_SUPPORTS_CAUSE) {
+            super.printStackTrace(s);
+        } else {
+            synchronized (s) {
+                super.printStackTrace(s);
+                final Throwable c = getCause();
+                if (c != null) {
+                    s.println("Root cause: ");
+                    c.printStackTrace(s);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/NotYetImplementedException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/NotYetImplementedException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/NotYetImplementedException.java
new file mode 100644
index 0000000..dc42844
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/NotYetImplementedException.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.exceptions;
+
+/**
+ * Flags a method as not having been implemented yet, but is be implemented.
+ */
+public class NotYetImplementedException extends IsisException {
+
+    private static final long serialVersionUID = 1L;
+
+    public NotYetImplementedException() {
+        super("This method is not implemented yet");
+    }
+
+    public NotYetImplementedException(final String arg0) {
+        super(arg0);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/UnexpectedCallException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/UnexpectedCallException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/UnexpectedCallException.java
new file mode 100644
index 0000000..b1e77e5
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/UnexpectedCallException.java
@@ -0,0 +1,37 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.core.commons.exceptions;
+
+/**
+ * Indicates that a call was made to a method (normally an overridden one) that
+ * was not expected, and hence not coded for.
+ */
+public class UnexpectedCallException extends IsisException {
+    private static final long serialVersionUID = 1L;
+
+    public UnexpectedCallException() {
+        super("This method call was not expected");
+    }
+
+    public UnexpectedCallException(final String arg0) {
+        super(arg0);
+    }
+
+}

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

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/package-info.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/package-info.java
new file mode 100644
index 0000000..803004e
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/exceptions/package-info.java
@@ -0,0 +1,25 @@
+/*
+ *  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.
+ */
+
+/**
+ * Defines {@link org.apache.isis.core.commons.exceptions.IsisException base class}
+ * for exceptions raised either by Isis itself or by the domain model
+ * running on top of Isis.  
+ */
+package org.apache.isis.core.commons.exceptions;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationClassException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationClassException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationClassException.java
new file mode 100644
index 0000000..159091b
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationClassException.java
@@ -0,0 +1,42 @@
+/*
+ *  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.factory;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class InstanceCreationClassException extends IsisException {
+    private static final long serialVersionUID = 1L;
+
+    public InstanceCreationClassException() {
+        super();
+    }
+
+    public InstanceCreationClassException(final String s) {
+        super(s);
+    }
+
+    public InstanceCreationClassException(final Throwable cause) {
+        super(cause);
+    }
+
+    public InstanceCreationClassException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationException.java
new file mode 100644
index 0000000..4f7d83b
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceCreationException.java
@@ -0,0 +1,42 @@
+/*
+ *  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.factory;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class InstanceCreationException extends IsisException {
+    private static final long serialVersionUID = 1L;
+
+    public InstanceCreationException() {
+        super();
+    }
+
+    public InstanceCreationException(final String s) {
+        super(s);
+    }
+
+    public InstanceCreationException(final Throwable cause) {
+        super(cause);
+    }
+
+    public InstanceCreationException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceUtil.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceUtil.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceUtil.java
new file mode 100644
index 0000000..54484e5
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/InstanceUtil.java
@@ -0,0 +1,142 @@
+/*
+ *  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.factory;
+
+import org.apache.isis.core.commons.ensure.Assert;
+import org.apache.isis.core.commons.lang.CastUtils;
+
+public final class InstanceUtil {
+
+    private InstanceUtil() {
+    }
+
+    public static Object createInstance(final String className) {
+        return createInstance(className, (Class<?>) null, null);
+    }
+
+    public static Object createInstance(final Class<?> cls) {
+        return createInstance(cls, (Class<?>) null, null);
+    }
+
+    public static <T> T createInstance(final String className, final Class<T> requiredClass) {
+        return createInstance(className, (Class<T>) null, requiredClass);
+    }
+
+    public static <T> T createInstance(final Class<?> cls, final Class<T> requiredClass) {
+        return createInstance(cls, (Class<T>) null, requiredClass);
+    }
+
+    public static <T> T createInstance(final String className, final String defaultTypeName, final Class<T> requiredType) {
+        Class<? extends T> defaultType = null;
+        if (defaultTypeName != null) {
+            try {
+                defaultType = CastUtils.cast(Thread.currentThread().getContextClassLoader().loadClass(defaultTypeName));
+                if (defaultType == null) {
+                    throw new InstanceCreationClassException("Failed to load default type '" + defaultTypeName + "'");
+                }
+            } catch (final ClassNotFoundException e) {
+                throw new UnavailableClassException("The default type '" + defaultTypeName + "' cannot be found");
+            } catch (final NoClassDefFoundError e) {
+                throw new InstanceCreationClassException("Default type '" + defaultTypeName + "' found, but is missing a dependent class: " + e.getMessage(), e);
+            }
+        }
+        return createInstance(className, defaultType, requiredType);
+    }
+
+    public static <T> T createInstance(final Class<?> cls, final String defaultTypeName, final Class<T> requiredType) {
+        Class<? extends T> defaultType = null;
+        if (defaultTypeName != null) {
+            defaultType = loadClass(defaultTypeName, requiredType);
+            try {
+                defaultType = CastUtils.cast(Thread.currentThread().getContextClassLoader().loadClass(defaultTypeName));
+                if (defaultType == null) {
+                    throw new InstanceCreationClassException("Failed to load default type '" + defaultTypeName + "'");
+                }
+            } catch (final ClassNotFoundException e) {
+                throw new UnavailableClassException("The default type '" + defaultTypeName + "' cannot be found");
+            } catch (final NoClassDefFoundError e) {
+                throw new InstanceCreationClassException("Default type '" + defaultTypeName + "' found, but is missing a dependent class: " + e.getMessage(), e);
+            }
+        }
+        return createInstance(cls, defaultType, requiredType);
+    }
+
+    public static <T> T createInstance(final String className, final Class<? extends T> defaultType, final Class<T> requiredType) {
+        Assert.assertNotNull("Class to instantiate must be specified", className);
+        Class<?> cls = null;
+        try {
+            cls = Thread.currentThread().getContextClassLoader().loadClass(className);
+            if (cls == null) {
+                throw new InstanceCreationClassException("Failed to load class '" + className + "'");
+            }
+            return createInstance(cls, defaultType, requiredType);
+        } catch (final ClassNotFoundException e) {
+            if (className.indexOf('.') == -1) {
+                throw new UnavailableClassException("The component '" + className + "' cannot be found");
+            }
+            throw new UnavailableClassException("The class '" + className + "' cannot be found");
+        } catch (final NoClassDefFoundError e) {
+            throw new InstanceCreationClassException("Class '" + className + "' found , but is missing a dependent class: " + e.getMessage(), e);
+        }
+    }
+
+    public static <T> T createInstance(final Class<?> cls, final Class<? extends T> defaultType, final Class<T> requiredType) {
+        Assert.assertNotNull("Class to instantiate must be specified", cls);
+        try {
+            if (requiredType == null || requiredType.isAssignableFrom(cls)) {
+                final Class<T> tClass = CastUtils.cast(cls);
+                return tClass.newInstance();
+            } else {
+                throw new InstanceCreationClassException("Class '" + cls.getName() + "' is not of type '" + requiredType + "'");
+            }
+        } catch (final NoClassDefFoundError e) {
+            throw new InstanceCreationClassException("Class '" + cls + "'found , but is missing a dependent class: " + e.getMessage(), e);
+        } catch (final InstantiationException e) {
+            throw new InstanceCreationException("Could not instantiate an object of class '" + cls.getName() + "'; " + e.getMessage());
+        } catch (final IllegalAccessException e) {
+            throw new InstanceCreationException("Could not access the class '" + cls.getName() + "'; " + e.getMessage());
+        }
+    }
+
+    public static Class<?> loadClass(final String className) {
+        Assert.assertNotNull("Class to instantiate must be specified", className);
+        try {
+            return Thread.currentThread().getContextClassLoader().loadClass(className);
+        } catch (final ClassNotFoundException e) {
+            throw new UnavailableClassException("The default type '" + className + "' cannot be found");
+        } catch (final NoClassDefFoundError e) {
+            throw new InstanceCreationClassException("Default type '" + className + "' found, but is missing a dependent class: " + e.getMessage(), e);
+        }
+    }
+
+    public static <R, T extends R> Class<T> loadClass(final String className, final Class<R> requiredType) {
+        Assert.assertNotNull("Class to instantiate must be specified", className);
+        try {
+            final Class<?> loadedClass = loadClass(className);
+            if (requiredType != null && !requiredType.isAssignableFrom(loadedClass)) {
+                throw new InstanceCreationClassException("Class '" + className + "' is not of type '" + requiredType + "'");
+            }
+            return CastUtils.cast(loadedClass);
+        } catch (final NoClassDefFoundError e) {
+            throw new InstanceCreationClassException("Default type '" + className + "' found, but is missing a dependent class: " + e.getMessage(), e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/UnavailableClassException.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/UnavailableClassException.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/UnavailableClassException.java
new file mode 100644
index 0000000..8362549
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/UnavailableClassException.java
@@ -0,0 +1,42 @@
+/*
+ *  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.factory;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public class UnavailableClassException extends IsisException {
+    private static final long serialVersionUID = 1L;
+
+    public UnavailableClassException() {
+        super();
+    }
+
+    public UnavailableClassException(final String s) {
+        super(s);
+    }
+
+    public UnavailableClassException(final Throwable cause) {
+        super(cause);
+    }
+
+    public UnavailableClassException(final String msg, final Throwable cause) {
+        super(msg, cause);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/package-info.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/package-info.java
new file mode 100644
index 0000000..d8377b0
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/factory/package-info.java
@@ -0,0 +1,29 @@
+/*
+ *  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.
+ */
+
+/**
+ * Provides a {@link org.apache.isis.core.commons.factory.InstanceUtil utility} 
+ * class for instantiating classes, ensuring that 
+ * they are assignable from a specified interface (if supplied).
+ * 
+ * <p>
+ * Used in various places throughout the framework, and specifically by
+ * {@link org.apache.isis.core.commons.components.Installer} implementations.
+ */
+package org.apache.isis.core.commons.factory;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/LazyInputStream.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/LazyInputStream.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/LazyInputStream.java
new file mode 100644
index 0000000..41eeba3
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/LazyInputStream.java
@@ -0,0 +1,183 @@
+/*
+ *  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.io;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.CoreMatchers.nullValue;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.isis.core.commons.ensure.Ensure;
+
+/**
+ * An input stream that reads from an underlying {@link InputStream}, deferring
+ * the interactions until needed.
+ * 
+ * <p>
+ * This other stream is provided as needed by an {@link InputStreamProvider} so
+ * that the underlying stream is not eagerly loaded.
+ */
+public class LazyInputStream extends InputStream {
+
+    /**
+     * An interface to be implemented by clients that wish to utilize
+     * {@link LazyInputStream}s. The implementation of this interface should
+     * defer obtaining the desired input stream until absolutely necessary.
+     */
+    public static interface InputStreamProvider {
+        InputStream getInputStream() throws IOException;
+    }
+
+    private final InputStreamProvider provider;
+
+    private InputStream underlying = null;
+
+    // ///////////////////////////////////////////////////////
+    // Constructor
+    // ///////////////////////////////////////////////////////
+
+    /**
+     * Construct a new lazy stream based off the given provider.
+     * 
+     * @param provider
+     *            the input stream provider. Must not be <code>null</code>.
+     */
+    public LazyInputStream(final InputStreamProvider provider) {
+        Ensure.ensureThatArg(provider, is(not(nullValue())));
+        this.provider = provider;
+    }
+
+    // ///////////////////////////////////////////////////////
+    // InputStream API
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public void close() throws IOException {
+        obtainUnderlyingIfRequired();
+        underlying.close();
+    }
+
+    @Override
+    public int available() throws IOException {
+        obtainUnderlyingIfRequired();
+        return underlying.available();
+    }
+
+    @Override
+    public void mark(final int readlimit) {
+        try {
+            obtainUnderlyingIfRequired();
+            underlying.mark(readlimit);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public boolean markSupported() {
+        try {
+            obtainUnderlyingIfRequired();
+            return underlying.markSupported();
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public int read() throws IOException {
+        obtainUnderlyingIfRequired();
+        return underlying.read();
+    }
+
+    @Override
+    public int read(final byte[] b, final int off, final int len) throws IOException {
+        obtainUnderlyingIfRequired();
+        return underlying.read(b, off, len);
+    }
+
+    @Override
+    public int read(final byte[] b) throws IOException {
+        obtainUnderlyingIfRequired();
+        return underlying.read(b);
+    }
+
+    @Override
+    public long skip(final long n) throws IOException {
+        obtainUnderlyingIfRequired();
+        return underlying.skip(n);
+    }
+
+    @Override
+    public void reset() throws IOException {
+        obtainUnderlyingIfRequired();
+        underlying.reset();
+    }
+
+    // ///////////////////////////////////////////////////////
+    // helpers
+    // ///////////////////////////////////////////////////////
+
+    private void obtainUnderlyingIfRequired() throws IOException {
+        if (underlying == null) {
+            underlying = provider.getInputStream();
+        }
+    }
+
+    // ///////////////////////////////////////////////////////
+    // equals, hashCode
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public boolean equals(final Object obj) {
+        try {
+            obtainUnderlyingIfRequired();
+            return underlying.equals(obj);
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        try {
+            obtainUnderlyingIfRequired();
+            return underlying.hashCode();
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    // ///////////////////////////////////////////////////////
+    // toString
+    // ///////////////////////////////////////////////////////
+
+    @Override
+    public String toString() {
+        try {
+            obtainUnderlyingIfRequired();
+            return underlying.toString();
+        } catch (final IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/package-info.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/package-info.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/package-info.java
new file mode 100644
index 0000000..823a532
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/io/package-info.java
@@ -0,0 +1,23 @@
+/*
+ *  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.
+ */
+
+/**
+ * This package holds a small number of utilities for working with the Java i/o libraries. 
+ */
+package org.apache.isis.core.commons.io;
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtil.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtil.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtil.java
new file mode 100644
index 0000000..643419d
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtil.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.core.commons.lang;
+
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public final class ArrayUtil {
+
+    private ArrayUtil() {
+    }
+
+    public static Object[] getObjectAsObjectArray(final Object option) {
+        final Class<?> arrayType = option.getClass().getComponentType();
+        if (!arrayType.isPrimitive()) {
+            return (Object[]) option;
+        }
+        if (arrayType == char.class) {
+            return ArrayUtils.convertCharToCharacterArray(option);
+        } else {
+            return convertPrimitiveToObjectArray(arrayType, option);
+        }
+    }
+
+    private static Object[] convertPrimitiveToObjectArray(final Class<?> arrayType, final Object originalArray) {
+        Object[] convertedArray;
+        try {
+            final Class<?> wrapperClass = WrapperUtils.wrap(arrayType);
+            final Constructor<?> constructor = wrapperClass.getConstructor(new Class[] { String.class });
+            final int len = Array.getLength(originalArray);
+            convertedArray = (Object[]) Array.newInstance(wrapperClass, len);
+            for (int i = 0; i < len; i++) {
+                convertedArray[i] = constructor.newInstance(new Object[] { Array.get(originalArray, i).toString() });
+            }
+        } catch (final NoSuchMethodException e) {
+            throw new IsisException(e);
+        } catch (final ArrayIndexOutOfBoundsException e) {
+            throw new IsisException(e);
+        } catch (final IllegalArgumentException e) {
+            throw new IsisException(e);
+        } catch (final InstantiationException e) {
+            throw new IsisException(e);
+        } catch (final IllegalAccessException e) {
+            throw new IsisException(e);
+        } catch (final InvocationTargetException e) {
+            throw new IsisException(e);
+        }
+        return convertedArray;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtils.java
new file mode 100644
index 0000000..3d6cf76
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ArrayUtils.java
@@ -0,0 +1,133 @@
+/*
+ *  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.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+public final class ArrayUtils {
+
+    private ArrayUtils() {
+    }
+
+    public static Object[] convertCharToCharacterArray(final Object originalArray) {
+        final char[] original = (char[]) originalArray;
+        final int len = original.length;
+        final Character[] converted = new Character[len];
+        for (int i = 0; i < converted.length; i++) {
+            converted[i] = Character.valueOf(original[i]);
+        }
+        return converted;
+    }
+
+    public static <T> T[] combine(final T[]... arrays) {
+        final List<T> combinedList = new ArrayList<T>();
+        for (final T[] array : arrays) {
+            for (final T t : array) {
+                combinedList.add(t);
+            }
+        }
+        return combinedList.toArray(arrays[0]); // using 1st element of arrays
+                                                // to specify the type
+    }
+
+    /**
+     * Creates a mutable copy of the provided array.
+     */
+    public static <T> List<T> asList(final T[] items) {
+        final List<T> list = new ArrayList<T>();
+        for (final T item : items) {
+            list.add(item);
+        }
+        return list;
+    }
+
+    /**
+     * Creates a mutable copy of the provided array, eliminating duplicates.
+     * 
+     * <p>
+     * The order of the items will be preserved.
+     */
+    public static <T> Set<T> asOrderedSet(final T[] items) {
+        final LinkedHashSet<T> list = new LinkedHashSet<T>();
+        if (items != null) {
+            for (final T item : items) {
+                list.add(item);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * Creates a mutable list of the provided array, also appending the
+     * additional element(s).
+     */
+    public static <T> List<T> concat(final T[] elements, final T... elementsToAppend) {
+        final List<T> result = new ArrayList<T>();
+        for (final T element : elements) {
+            result.add(element);
+        }
+        for (final T element : elementsToAppend) {
+            if (element != null) {
+                result.add(element);
+            }
+        }
+        return result;
+    }
+
+    public static String[] append(final String[] args, final String... moreArgs) {
+        final ArrayList<String> argList = new ArrayList<String>();
+        argList.addAll(Arrays.asList(args));
+        argList.addAll(Arrays.asList(moreArgs));
+        return argList.toArray(new String[] {});
+    }
+
+    /**
+     * Creates a mutable list of the provided array, also appending the
+     * additional element(s).
+     */
+    public static <T> List<T> concat(final T[] elements, final List<T> elementsToAppend) {
+        final List<T> result = new ArrayList<T>();
+        for (final T element : elements) {
+            result.add(element);
+        }
+        for (final T element : elementsToAppend) {
+            if (element != null) {
+                result.add(element);
+            }
+        }
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <D, S> D[] copy(final S[] source, final Class<D> cls) {
+        if (source == null) {
+            throw new IllegalArgumentException("Source array cannot be null");
+        }
+        final D[] destination = (D[]) Array.newInstance(cls, source.length);
+        System.arraycopy(source, 0, destination, 0, source.length);
+        return destination;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/CastUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/CastUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/CastUtils.java
new file mode 100644
index 0000000..0ea6996
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/CastUtils.java
@@ -0,0 +1,92 @@
+/*
+ *  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.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.Vector;
+
+/**
+ * Helpers to co-erce existing (Java 1.1 code) into type-safe generics without
+ * having to suppress compiler warnings all over the place.
+ * 
+ */
+public final class CastUtils {
+
+    private CastUtils() {
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T cast(final Object obj) {
+        return (T) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Enumeration<T> enumerationOver(final Object obj, final Class<T> castTo) {
+        return (Enumeration<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Iterator<T> iteratorOver(final Object obj, final Class<T> castTo) {
+        return (Iterator<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Collection<T> collectionOf(final Object obj, final Class<T> castTo) {
+        return (Collection<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> listOf(final Object obj, final Class<T> castTo) {
+        return (List<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Vector<T> vectorOf(final Object obj, final Class<T> castTo) {
+        return (Vector<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> Set<T> setOf(final Object obj, final Class<T> castTo) {
+        return (Set<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> SortedSet<T> sortedSetOf(final Object obj, final Class<T> castTo) {
+        return (SortedSet<T>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <K, V> Map<K, V> mapOf(final Object obj, final Class<K> keyCastTo, final Class<V> valueCastTo) {
+        return (Map<K, V>) obj;
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <K, V> SortedMap<K, V> sortedMapOf(final Object obj, final Class<K> keyCastTo, final Class<V> valueCastTo) {
+        return (SortedMap<K, V>) obj;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassUtil.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassUtil.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassUtil.java
new file mode 100644
index 0000000..3dc791d
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ClassUtil.java
@@ -0,0 +1,68 @@
+/*
+ *  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.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.isis.core.commons.exceptions.IsisException;
+
+public final class ClassUtil {
+
+    private ClassUtil() {
+    }
+
+    public static Object newInstance(final Class<?> type, final Class<?> constructorParamType, final Object constructorArg) {
+        return ClassUtil.newInstance(type, new Class[] { constructorParamType }, new Object[] { constructorArg });
+    }
+
+    /**
+     * Tries to instantiate using a constructor accepting the supplied
+     * arguments; if no such constructor then falls back to trying the no-arg
+     * constructor.
+     */
+    public static Object newInstance(final Class<?> type, final Class<?>[] constructorParamTypes, final Object[] constructorArgs) {
+        try {
+            Constructor<?> constructor;
+            try {
+                constructor = type.getConstructor(constructorParamTypes);
+                return constructor.newInstance(constructorArgs);
+            } catch (final NoSuchMethodException ex) {
+                try {
+                    constructor = type.getConstructor();
+                    return constructor.newInstance();
+                } catch (final NoSuchMethodException e) {
+                    throw new IsisException(e);
+                }
+            }
+        } catch (final SecurityException ex) {
+            throw new IsisException(ex);
+        } catch (final IllegalArgumentException e) {
+            throw new IsisException(e);
+        } catch (final InstantiationException e) {
+            throw new IsisException(e);
+        } catch (final IllegalAccessException e) {
+            throw new IsisException(e);
+        } catch (final InvocationTargetException e) {
+            throw new IsisException(e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/HashCodeUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/HashCodeUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/HashCodeUtils.java
new file mode 100644
index 0000000..a01fdcf
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/HashCodeUtils.java
@@ -0,0 +1,135 @@
+/*
+ *  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.lang.reflect.Array;
+
+/**
+ * Collected methods which allow easy implementation of <code>hashCode</code>,
+ * based on Josh Bloch's Effective Java.
+ * 
+ * <p>
+ * Example use case:
+ * 
+ * <pre>
+ * public int hashCode() {
+ *     int result = HashCodeUtil.SEED;
+ *     // collect the contributions of various fields
+ *     result = HashCodeUtil.hash(result, fPrimitive);
+ *     result = HashCodeUtil.hash(result, fObject);
+ *     result = HashCodeUtil.hash(result, fArray);
+ *     return result;
+ * }
+ * </pre>
+ * 
+ * @see http://www.javapractices.com/Topic28.cjp
+ */
+public final class HashCodeUtils {
+
+    private HashCodeUtils() {
+    }
+
+    /**
+     * An initial value for a <code>hashCode</code>, to which is added
+     * contributions from fields. Using a non-zero value decreases collisons of
+     * <code>hashCode</code> values.
+     */
+    public static final int SEED = 23;
+
+    /**
+     * booleans.
+     */
+    public static int hash(final int aSeed, final boolean aBoolean) {
+        return firstTerm(aSeed) + (aBoolean ? 1 : 0);
+    }
+
+    /**
+     * chars.
+     */
+    public static int hash(final int aSeed, final char aChar) {
+        return firstTerm(aSeed) + aChar;
+    }
+
+    /**
+     * ints.
+     * 
+     * <p>
+     * Note that byte and short are handled by this method, through implicit
+     * conversion.
+     */
+    public static int hash(final int aSeed, final int aInt) {
+        return firstTerm(aSeed) + aInt;
+    }
+
+    /**
+     * longs.
+     */
+    public static int hash(final int aSeed, final long aLong) {
+        return firstTerm(aSeed) + (int) (aLong ^ (aLong >>> 32));
+    }
+
+    /**
+     * floats.
+     */
+    public static int hash(final int aSeed, final float aFloat) {
+        return hash(aSeed, Float.floatToIntBits(aFloat));
+    }
+
+    /**
+     * doubles.
+     */
+    public static int hash(final int aSeed, final double aDouble) {
+        return hash(aSeed, Double.doubleToLongBits(aDouble));
+    }
+
+    /**
+     * <code>aObject</code> is a possibly-null object field, and possibly an
+     * array.
+     * 
+     * If <code>aObject</code> is an array, then each element may be a primitive
+     * or a possibly-null object.
+     */
+    public static int hash(final int aSeed, final Object aObject) {
+        int result = aSeed;
+        if (aObject == null) {
+            result = hash(result, 0);
+        } else if (!isArray(aObject)) {
+            result = hash(result, aObject.hashCode());
+        } else {
+            final int length = Array.getLength(aObject);
+            for (int idx = 0; idx < length; ++idx) {
+                final Object item = Array.get(aObject, idx);
+                // recursive call!
+                result = hash(result, item);
+            }
+        }
+        return result;
+    }
+
+    private static final int ODD_PRIME_NUMBER = 37;
+
+    private static int firstTerm(final int aSeed) {
+        return ODD_PRIME_NUMBER * aSeed;
+    }
+
+    private static boolean isArray(final Object aObject) {
+        return aObject.getClass().isArray();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/IoUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/IoUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/IoUtils.java
new file mode 100644
index 0000000..67586a8
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/IoUtils.java
@@ -0,0 +1,86 @@
+/*
+ *  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.io.ByteArrayInputStream;
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+
+public final class IoUtils {
+
+    private static final int DEFAULT_BUFFER_SIZE = 1024;
+
+    private IoUtils() {
+    }
+
+    /**
+     * Copy bytes from an <code>InputStream</code> to an
+     * <code>OutputStream</code>.
+     * <p>
+     * This method buffers the input internally, so there is no need to use a
+     * <code>BufferedInputStream</code>.
+     * 
+     * @param input
+     *            the <code>InputStream</code> to read from
+     * @param output
+     *            the <code>OutputStream</code> to write to
+     * @return the number of bytes copied
+     * @throws IllegalArgumentException
+     *             if the input or output is null
+     * @throws IOException
+     *             if an I/O error occurs
+     * @since Commons IO 1.1
+     */
+    public static int copy(final InputStream input, final OutputStream output) throws IOException {
+        if (input == null) {
+            throw new IllegalArgumentException("InputStream cannot be null");
+        }
+        if (output == null) {
+            throw new IllegalArgumentException("OutputStream cannot be null");
+        }
+        final byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
+        int count = 0;
+        int n = 0;
+        while (-1 != (n = input.read(buffer))) {
+            output.write(buffer, 0, n);
+            count += n;
+        }
+        return count;
+    }
+
+    public static InputStream asUtf8ByteStream(final String string) throws UnsupportedEncodingException {
+        final byte[] data = string.getBytes("utf-8");
+        final InputStream in = new ByteArrayInputStream(data);
+        return in;
+    }
+
+    public static void closeSafely(final Closeable reader) {
+        if (reader != null) {
+            try {
+                reader.close();
+            } catch (final IOException ignore) {
+            }
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/JavaClassUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/JavaClassUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/JavaClassUtils.java
new file mode 100644
index 0000000..1f4c1a2
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/JavaClassUtils.java
@@ -0,0 +1,151 @@
+/*
+ *  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.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public final class JavaClassUtils {
+
+    private static final String JAVA_CLASS_PREFIX = "java.";
+
+    private static Map<String, Class<?>> builtInClasses = new HashMap<String, Class<?>>();
+
+    static {
+        put(void.class);
+        put(boolean.class);
+        put(char.class);
+        put(byte.class);
+        put(short.class);
+        put(int.class);
+        put(long.class);
+        put(float.class);
+        put(double.class);
+    }
+
+    private static void put(final Class<?> cls) {
+        builtInClasses.put(cls.getName(), cls);
+    }
+
+    private JavaClassUtils() {
+    }
+
+    public static Class<?> getBuiltIn(final String name) {
+        return builtInClasses.get(name);
+    }
+
+    public static String getSuperclass(final Class<?> type) {
+        final Class<?> superType = type.getSuperclass();
+
+        if (superType == null) {
+            return null;
+        }
+        return superType.getName();
+    }
+
+    public static boolean isAbstract(final Class<?> type) {
+        return Modifier.isAbstract(type.getModifiers());
+    }
+
+    public static boolean isFinal(final Class<?> type) {
+        return Modifier.isFinal(type.getModifiers());
+    }
+
+    public static boolean isPublic(final Class<?> type) {
+        return Modifier.isPublic(type.getModifiers());
+    }
+
+    public static boolean isJavaClass(final Class<?> type) {
+        return type.getName().startsWith(JAVA_CLASS_PREFIX) || type.getName().startsWith("sun.");
+    }
+
+    public static boolean isPublic(final Method method) {
+        return Modifier.isPublic(method.getModifiers());
+    }
+
+    public static List<Class<?>> toClasses(final List<Object> objectList) {
+        final List<Class<?>> classList = new ArrayList<Class<?>>();
+        for (final Object service : objectList) {
+            classList.add(service.getClass());
+        }
+        return classList;
+    }
+
+    /**
+     * Returns the supplied Class so long as it implements (or is a subclass of)
+     * the required class, and also has either a constructor accepting the
+     * specified param type, or has a no-arg constructor.
+     */
+    public static Class<?> implementingClassOrNull(final Class<?> classCandidate, final Class<?> requiredClass, final Class<?> constructorParamType) {
+        if (classCandidate == null) {
+            return null;
+        }
+        if (!requiredClass.isAssignableFrom(classCandidate)) {
+            return null;
+        }
+        try {
+            classCandidate.getConstructor(new Class[] { constructorParamType });
+        } catch (final NoSuchMethodException ex) {
+            try {
+                classCandidate.getConstructor(new Class[] {});
+            } catch (final NoSuchMethodException e) {
+                return null;
+            }
+        } catch (final SecurityException e) {
+            return null;
+        }
+        final int modifiers = classCandidate.getModifiers();
+        if (!Modifier.isPublic(modifiers)) {
+            return null;
+        }
+        return classCandidate;
+    }
+
+    public static Class<?> implementingClassOrNull(final String classCandidateName, final Class<?> requiredClass, final Class<?> constructorParamType) {
+        if (classCandidateName == null) {
+            return null;
+        }
+        Class<?> classCandidate = null;
+        try {
+            classCandidate = Class.forName(classCandidateName);
+            return implementingClassOrNull(classCandidate, requiredClass, constructorParamType);
+        } catch (final ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    public static boolean directlyImplements(final Class<?> cls, final Class<?> interfaceType) {
+        for (final Class<?> directlyImplementedInterface : cls.getInterfaces()) {
+            if (directlyImplementedInterface == interfaceType) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public static boolean isStatic(final Method method) {
+        return Modifier.isStatic(method.getModifiers());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
new file mode 100644
index 0000000..4c7f337
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/ListUtils.java
@@ -0,0 +1,142 @@
+/*
+ *  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.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+public final class ListUtils {
+    private static final String DEFAULT_DELIMITER = ",";
+
+    private ListUtils() {
+    }
+
+    public static <T> List<T> combine(final List<T> list, final List<T> list2) {
+        final List<T> combinedList = new ArrayList<T>();
+        combinedList.addAll(list);
+        combinedList.addAll(list2);
+        return combinedList;
+    }
+
+    /**
+     * Returns list1 with everything in list2, ignoring duplicates.
+     */
+    public static <T> List<T> merge(final List<T> list1, final List<T> list2) {
+        for (final T obj : list2) {
+            if (!(list1.contains(obj))) {
+                list1.add(obj);
+            }
+        }
+        return list1;
+    }
+
+    public static List<String> merge(final String[] array1, final String[] array2) {
+        final List<String> prefixes = new ArrayList<String>();
+        addNoDuplicates(array1, prefixes);
+        addNoDuplicates(array2, prefixes);
+        return prefixes;
+    }
+
+    private static void addNoDuplicates(final String[] array, final List<String> list) {
+        for (int i = 0; i < array.length; i++) {
+            if (!list.contains(array[i])) {
+                list.add(array[i]);
+            }
+        }
+    }
+
+    public static List<Object> asList(final Object[] objectArray) {
+        final List<Object> list = new ArrayList<Object>();
+        for (final Object element : objectArray) {
+            if (Collection.class.isAssignableFrom(element.getClass())) {
+                @SuppressWarnings("rawtypes")
+                final Collection collection = (Collection) element;
+                list.addAll(asList(collection.toArray()));
+            } else {
+                list.add(element);
+            }
+        }
+        return list;
+    }
+
+    /**
+     * @see #listToString(List, String)
+     * @see #stringToList(String)
+     */
+    public static String listToString(final List<String> list) {
+        return listToString(list, DEFAULT_DELIMITER);
+    }
+
+    /**
+     * @see #listToString(List, String)
+     * @see #stringToList(String)
+     */
+    public static String listToString(final List<String> list, final String delimiter) {
+        if (list.size() == 0) {
+            return null;
+        }
+        final StringBuilder buf = new StringBuilder();
+        boolean first = true;
+        for (final String str : list) {
+            if (first) {
+                first = false;
+            } else {
+                buf.append(delimiter);
+            }
+            buf.append(str);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * @see #stringToList(String, String)
+     * @see #listToString(List)
+     */
+    public static List<String> stringToList(final String commaSeparated) {
+        return appendDelimitedStringToList(commaSeparated, new ArrayList<String>());
+    }
+
+    /**
+     * @see #stringToList(String)
+     * @see #listToString(List, String)
+     */
+    public static List<String> stringToList(final String delimited, final String delimiter) {
+        return appendDelimitedStringToList(delimited, delimiter, new ArrayList<String>());
+    }
+
+    /**
+     * @see #appendDelimitedStringToList(String, String, List)
+     */
+    public static List<String> appendDelimitedStringToList(final String commaSeparated, final List<String> list) {
+        return appendDelimitedStringToList(commaSeparated, DEFAULT_DELIMITER, list);
+    }
+
+    public static List<String> appendDelimitedStringToList(final String delimited, final String delimiter, final List<String> list) {
+        if (delimited == null) {
+            return list;
+        }
+        final String[] optionValues = delimited.split(delimiter);
+        list.addAll(Arrays.asList(optionValues));
+        return list;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/LocaleUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/LocaleUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/LocaleUtils.java
new file mode 100644
index 0000000..8cab421
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/LocaleUtils.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 java.util.Locale;
+
+public class LocaleUtils {
+
+    public static Locale findLocale(final String localeStr) {
+        if (localeStr != null) {
+            final Locale[] availableLocales = Locale.getAvailableLocales();
+            for (final Locale locale : availableLocales) {
+                if (locale.toString().equals(localeStr)) {
+                    return locale;
+                }
+            }
+        }
+        return null;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/e4735c72/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
----------------------------------------------------------------------
diff --git a/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
new file mode 100644
index 0000000..9700832
--- /dev/null
+++ b/framework/core/metamodel/src/main/java/org/apache/isis/core/commons/lang/MapUtils.java
@@ -0,0 +1,53 @@
+/*
+ *  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.HashMap;
+import java.util.Map;
+
+public final class MapUtils {
+
+    private MapUtils() {
+    }
+
+    /**
+     * Converts a list of objects [a, 1, b, 2] into a map {a -> 1; b -> 2}
+     */
+    public static Map<String, String> asMap(final String... paramArgs) {
+        final HashMap<String, String> map = new HashMap<String, String>();
+        boolean param = true;
+        String paramStr = null;
+        for (final String paramArg : paramArgs) {
+            if (param) {
+                paramStr = paramArg;
+            } else {
+                final String arg = paramArg;
+                map.put(paramStr, arg);
+                paramStr = null;
+            }
+            param = !param;
+        }
+        if (paramStr != null) {
+            throw new IllegalArgumentException("Must have equal number of parameters and arguments");
+        }
+        return map;
+    }
+
+}