Added ability to transparently unpack artifacts
via an IArtifactUnpacker interface

This allows handlers that receive an object that is not the
artifact itself, but, e.g., a wrapper from which the actual
artifact can be derived.
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/AbstractArtifactHandler.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/AbstractArtifactHandler.java
index bb19459..be9899a 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/AbstractArtifactHandler.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/AbstractArtifactHandler.java
@@ -16,8 +16,26 @@
 
 public abstract class AbstractArtifactHandler<T> implements IArtifactHandler<T> {
 
+	private Object unpack(Object artifact) {
+		Object result = artifact;
+		if (IArtifactUnpacker.class.isAssignableFrom(this.getClass())) {
+			try {
+				result = IArtifactUnpacker.class.cast(this).unpack(artifact);
+			} catch (ClassCastException ex) {
+				/*
+				 * Deliberately do nothing. This is not uncommon when trying to
+				 * find the right handler. In such cases, canHandleArtifact() is
+				 * called on all handlers, but for most the artifact can not be
+				 * casted.
+				 */
+			}
+		}
+		return result;
+	}
+
 	@Override
 	public <R> Optional<R> withCastedHandler(Object artifact, BiFunction<IArtifactHandler<T>, T, R> handleFunction) {
+		artifact = unpack(artifact);
 		if (canHandleArtifact(artifact)) {
 			@SuppressWarnings("unchecked")
 			T a = (T) artifact;
@@ -30,12 +48,13 @@
 	@Override
 	public <R> R withCastedHandlerUnchecked(Object artifact, BiFunction<IArtifactHandler<T>, T, R> handleFunction) {
 		return withCastedHandler(artifact, handleFunction).orElseThrow(
-			() -> new IllegalArgumentException("withCastedHanderUnchecked called with unhandleble artifact."
-				+ " Artifact: " + artifact + ", handler: " + this));
+				() -> new IllegalArgumentException("withCastedHanderUnchecked called with unhandleble artifact."
+						+ " Artifact: " + artifact + ", handler: " + this));
 	}
 
 	@Override
 	public boolean canHandleArtifact(Object artifact) {
+		artifact = unpack(artifact);
 		try {
 			Class<?> genericType = ((Class<?>) ((ParameterizedType) this.getClass().getGenericSuperclass())
 					.getActualTypeArguments()[0]);
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactUnpacker.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactUnpacker.java
new file mode 100644
index 0000000..43a3d92
--- /dev/null
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactUnpacker.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Chalmers | University of Gothenburg, rt-labs and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    Chalmers | University of Gothenburg and rt-labs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+package org.eclipse.capra.core.handlers;
+
+/**
+ * Defines functions to unpack the artifact from a surrounding container. This
+ * can be helpful if the artifact is wrapped by another class and Eclipse calls
+ * the methods of an {@link IArtifactHandler} with the wrapper instead of the
+ * actual object the wrapper is able to handle.
+ * 
+ * @param <T>
+ *            the type of the container
+ * @param <K>
+ *            the type of the artifact
+ */
+public interface IArtifactUnpacker<T, K> {
+
+	/**
+	 * Unpacks an artifact from a container.
+	 * 
+	 * @param container
+	 *            the container containing the artifact
+	 * @return an artifact unpacked from the container
+	 */
+	K unpack(T container);
+
+}