Merge "Add generic IArtifactHandler, convert all handlers accordingly" into develop
diff --git a/org.eclipse.capra.core/schema/org.eclipse.capra.configuration.artifactHandlers.exsd b/org.eclipse.capra.core/schema/org.eclipse.capra.configuration.artifactHandlers.exsd
index 60b1486..5df15e9 100644
--- a/org.eclipse.capra.core/schema/org.eclipse.capra.configuration.artifactHandlers.exsd
+++ b/org.eclipse.capra.core/schema/org.eclipse.capra.configuration.artifactHandlers.exsd
@@ -55,7 +55,7 @@
                   
                </documentation>
                <appinfo>
-                  <meta.attribute kind="java" basedOn=":org.eclipse.capra.core.handlers.ArtifactHandler"/>
+                  <meta.attribute kind="java" basedOn=":org.eclipse.capra.core.handlers.IArtifactHandler"/>
                </appinfo>
             </annotation>
          </attribute>
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/AbstractArtifactMetaModelAdapter.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/AbstractArtifactMetaModelAdapter.java
index f4cb09f..b79f409 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/AbstractArtifactMetaModelAdapter.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/AbstractArtifactMetaModelAdapter.java
@@ -1,6 +1,16 @@
+/*******************************************************************************
+ * 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.adapters;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.emf.ecore.EObject;
 
@@ -12,7 +22,7 @@
 public abstract class AbstractArtifactMetaModelAdapter implements ArtifactMetaModelAdapter {
 
 	@Override
-	public ArtifactHandler getArtifactHandlerInstance(EObject artifact) {
+	public IArtifactHandler<Object> getArtifactHandlerInstance(EObject artifact) {
 		String handler = getArtifactHandler(artifact);
 		return ExtensionPointHelper.getArtifactHandler(handler).orElse(null);
 	}
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/ArtifactMetaModelAdapter.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/ArtifactMetaModelAdapter.java
index 1469011..3bfb17a 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/ArtifactMetaModelAdapter.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/adapters/ArtifactMetaModelAdapter.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.capra.core.adapters;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.emf.ecore.EObject;
 
 /**
@@ -82,6 +82,6 @@
 	 * @param artifact
 	 * @return artifact handler instance
 	 */
-	ArtifactHandler getArtifactHandlerInstance(EObject artifact);
+	IArtifactHandler<Object> getArtifactHandlerInstance(EObject artifact);
 
 }
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
new file mode 100644
index 0000000..64db703
--- /dev/null
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/AbstractArtifactHandler.java
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * 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;
+
+import java.lang.reflect.ParameterizedType;
+
+public abstract class AbstractArtifactHandler<T> implements IArtifactHandler<T> {
+
+	@Override
+	public boolean canHandleArtifact(T artifact) {
+		try {
+			Class<?> genericType = ((Class<?>) ((ParameterizedType) this.getClass().getGenericSuperclass())
+					.getActualTypeArguments()[0]);
+
+			return genericType.isAssignableFrom(artifact.getClass());
+		} catch (NoClassDefFoundError e) {
+			return false;
+		}
+	}
+
+}
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/ArtifactHandler.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/ArtifactHandler.java
deleted file mode 100644
index 910c27f..0000000
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/ArtifactHandler.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2016 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;
-
-import org.eclipse.capra.core.helpers.EMFHelper;
-import org.eclipse.emf.ecore.EObject;
-
-/**
- * This interface defines functionality required to map chosen Objects in the
- * Eclipse workspace to EObjects of some kind, which can then be traced and
- * persisted in EMF models.
- * 
- * Implementations can use the provided concepts of an {@link ArtifactWrapper}
- * if this is suitable.
- * 
- * @author Anthony Anjorin, Salome Maro
- */
-public interface ArtifactHandler {
-
-	/**
-	 * Can the handler map selection to an EObject as required?
-	 * 
-	 * @param selection
-	 *            The object to be mapped to an EObject
-	 * @return <code>true</code> if selection can be handled, <code>false</code>
-	 *         otherwise.
-	 */
-	boolean canHandleSelection(Object selection);
-
-	/**
-	 * Map the object selection to an EObject.
-	 * 
-	 * @param selection
-	 *            The object to be mapped
-	 * @param artifactModel
-	 * @return
-	 */
-	EObject getEObjectForSelection(Object selection, EObject artifactModel);
-
-	/**
-	 * Resolve the persisted EObject to the originally selected Object from the
-	 * Eclipse workspace. This is essentially the inverse of the
-	 * getEObjectForSelection operation.
-	 * 
-	 * @param artifact
-	 *            The persisted EObject
-	 * @return originally selected object
-	 */
-	Object resolveArtifact(EObject artifact);
-
-	/**
-	 * Provide the display name to be displayed in the selection view when an
-	 * object is dropped. This is a default implementation but gives flexibility
-	 * for each handler to decide how its objects should look like when dropped
-	 * to the selection view.
-	 * 
-	 * @param selection
-	 *            The selected object to be added to the selection view
-	 * @return The string that should be displayed in the selection view.
-	 */
-	default String getDisplayName(Object selection) {
-		if (selection instanceof EObject) {
-			return EMFHelper.getIdentifier((EObject) selection);
-		} else
-			return selection.toString();
-	}
-
-}
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IAnnotateArtifact.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IAnnotateArtifact.java
index 55dd5cb..39962d1 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IAnnotateArtifact.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IAnnotateArtifact.java
@@ -21,12 +21,12 @@
 	/**
 	 * Annotate artifact with given text
 	 *
-	 * @param artifact
-	 *            Artifact to be annotated
+	 * @param wrapper
+	 *            Wrapper for artifact to be annotated
 	 * @param annotation
 	 *            Annotation text
 	 * @throws AnnotationException
 	 *             Exception thrown by handler if annotation fails
 	 */
-	void annotateArtifact(EObject artifact, String annotation) throws AnnotationException;
+	void annotateArtifact(EObject wrapper, String annotation) throws AnnotationException;
 }
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactHandler.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactHandler.java
new file mode 100644
index 0000000..3da68f7
--- /dev/null
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/IArtifactHandler.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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;
+
+import org.eclipse.emf.ecore.EObject;
+
+/**
+ * This interface defines functionality required to map chosen Objects in the
+ * Eclipse workspace to wrappers which can then be traced and
+ * persisted in EMF models.
+ */
+public interface IArtifactHandler<T> {
+
+	/**
+	 * Does the handler support this object?
+	 *
+	 * @param artifact
+	 *            The object to be wrapped
+	 * @return <code>true</code> if object can be handled, <code>false</code>
+	 *         otherwise.
+	 */
+	boolean canHandleArtifact(T artifact);
+
+	/**
+	 * Create a wrapper for the object
+	 *
+	 * @param artifact
+	 *            The object to be wrapped
+	 * @param artifactModel
+	 * @return
+	 */
+	EObject createWrapper(T artifact, EObject artifactModel);
+
+	/**
+	 * Resolve the wrapper to the originally selected Object from the
+	 * Eclipse workspace. This is essentially the inverse of the
+	 * createWrapper operation.
+	 *
+	 * @param wrapper
+	 *            The wrapped object
+	 * @return originally selected object
+	 */
+	T resolveWrapper(EObject wrapper);
+
+	/**
+	 * Provide a name for the artifact to be used for display purposes.
+	 * @param artifact
+	 */
+	String getDisplayName(T artifact);
+}
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/PriorityHandler.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/PriorityHandler.java
index 4e431a1..9f8a08b 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/PriorityHandler.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/handlers/PriorityHandler.java
@@ -31,6 +31,6 @@
 	 * @return one handler
 	 * 
 	 */
-	ArtifactHandler getSelectedHandler(Collection<ArtifactHandler> handlers, Object selectedElement);
+	IArtifactHandler<Object> getSelectedHandler(Collection<IArtifactHandler<Object>> handlers, Object selectedElement);
 
 }
diff --git a/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/ExtensionPointHelper.java b/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/ExtensionPointHelper.java
index 5e2e902..50cf354 100644
--- a/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/ExtensionPointHelper.java
+++ b/org.eclipse.capra.core/src/org/eclipse/capra/core/helpers/ExtensionPointHelper.java
@@ -4,7 +4,7 @@
  * 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
  *******************************************************************************/
@@ -20,7 +20,7 @@
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
 import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
 import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.handlers.PriorityHandler;
 import org.eclipse.core.runtime.IConfigurationElement;
 import org.eclipse.core.runtime.IExtension;
@@ -45,13 +45,13 @@
 
 	/**
 	 * Gets all extensions from the extension point ID and attribute passed.
-	 * 
+	 *
 	 * @param ID
 	 *            the ID of the extension point
-	 * 
+	 *
 	 * @param CONFIG
 	 *            the name of the attribute
-	 * 
+	 *
 	 * @return List of extensions
 	 */
 	public static List<Object> getExtensions(final String ID, final String CONFIG) {
@@ -70,17 +70,19 @@
 
 	/**
 	 * Get the executable extension for the extension ID.
-	 * 
+	 *
 	 * @param extensionID
 	 *            The ID of the extension
 	 * @return extension
 	 */
-	public static Optional<ArtifactHandler> getExtension(String extensionID, String ID, String CONFIG) {
+	public static Optional<IArtifactHandler<Object>> getExtension(String extensionID, String ID, String CONFIG) {
 		try {
 			IExtensionRegistry registry = Platform.getExtensionRegistry();
 			IExtension extension = registry.getExtension(ID, extensionID);
 			IConfigurationElement[] elements = extension.getConfigurationElements();
-			return Optional.of((ArtifactHandler) elements[0].createExecutableExtension(CONFIG));
+			@SuppressWarnings("unchecked")
+			IArtifactHandler<Object> handler = (IArtifactHandler<Object>) elements[0].createExecutableExtension(CONFIG);
+			return Optional.of(handler);
 		} catch (Exception e) {
 			return Optional.empty();
 		}
@@ -88,7 +90,7 @@
 
 	/**
 	 * Gets the configured {@link TraceMetaModelAdapter}.
-	 * 
+	 *
 	 * @return The configured {@code TraceMetaModelAdapter}. If none is
 	 *         configured, an empty instance of {@link Optional} is returned.
 	 */
@@ -103,7 +105,7 @@
 
 	/**
 	 * Gets the configured {@link TracePersistenceAdapter}.
-	 * 
+	 *
 	 * @return The configured {@code TracePersistenceAdapter}. If none is
 	 *         configured, an empty instance of {@link Optional} is returned.
 	 */
@@ -118,7 +120,7 @@
 
 	/**
 	 * Gets the configured {@link ArtifactMetaModelAdapter}.
-	 * 
+	 *
 	 * @return The configured {@code ArtifactMetaModelAdapter}. If none is
 	 *         configured, an empty instance of {@link Optional} is returned.
 	 */
@@ -133,33 +135,33 @@
 
 	/**
 	 * Gets the available {@link ArtifactHandler} instances.
-	 * 
+	 *
 	 * @return A collection of all the artifact handlers available. This method
 	 *         collects all plugins that have an extension to the
 	 *         ArtifactHandler Extension point
 	 */
-	public static Collection<ArtifactHandler> getArtifactHandlers() {
+	public static Collection<IArtifactHandler<Object>> getArtifactHandlers() {
 		try {
-			return getExtensions(ARTIFACT_HANDLER_ID, ARTIFACT_HANDLER_CONFIG).stream().map(ArtifactHandler.class::cast)
+			return getExtensions(ARTIFACT_HANDLER_ID, ARTIFACT_HANDLER_CONFIG).stream().map(IArtifactHandler.class::cast)
 					.collect(Collectors.toList());
 		} catch (Exception e) {
-			return Collections.<ArtifactHandler>emptyList();
+			return Collections.<IArtifactHandler<Object>>emptyList();
 		}
 	}
 
 	/**
 	 * Return the artifact handler with the given ID.
-	 * 
+	 *
 	 * @param ID
 	 * @return ArtifactHandler
 	 */
-	public static Optional<ArtifactHandler> getArtifactHandler(String ID) {
+	public static Optional<IArtifactHandler<Object>> getArtifactHandler(String ID) {
 		return getExtension(ID, ARTIFACT_HANDLER_ID, ARTIFACT_CONFIG);
 	}
 
 	/**
 	 * Gets the configured {@link PriorityHandler}.
-	 * 
+	 *
 	 * @return The configured {@code PriorityHandler}. If none is configured, an
 	 *         empty instance of {@link Optional} is returned.
 	 */
diff --git a/org.eclipse.capra.generic.priority/src/org/eclipse/capra/generic/priority/DefaultPriorityHandler.java b/org.eclipse.capra.generic.priority/src/org/eclipse/capra/generic/priority/DefaultPriorityHandler.java
index 46f715b..8a06770 100644
--- a/org.eclipse.capra.generic.priority/src/org/eclipse/capra/generic/priority/DefaultPriorityHandler.java
+++ b/org.eclipse.capra.generic.priority/src/org/eclipse/capra/generic/priority/DefaultPriorityHandler.java
@@ -12,7 +12,7 @@
 
 import java.util.Collection;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.handlers.PriorityHandler;
 import org.eclipse.capra.handler.hudson.BuildElementHandler;
 import org.eclipse.capra.handler.hudson.TestElementHandler;
@@ -27,13 +27,13 @@
 public class DefaultPriorityHandler implements PriorityHandler {
 
 	@Override
-	public ArtifactHandler getSelectedHandler(Collection<ArtifactHandler> handlers, Object selectedElement) {
+	public IArtifactHandler<Object> getSelectedHandler(Collection<IArtifactHandler<Object>> handlers, Object selectedElement) {
 		// TODO: is this needed if HudsonHandler is split into Build/TestElementHandler?
 		if (selectedElement instanceof TestElement) {
-			return handlers.stream().filter(h -> h instanceof TestElementHandler).findAny().get();
-		}
-		else if (selectedElement instanceof BuildElement) {
-			return handlers.stream().filter(h -> h instanceof BuildElementHandler).findAny().get();
+			return handlers.stream().filter(h -> h.getClass().isAssignableFrom(TestElementHandler.class)).findAny().get();
+
+		} else if (selectedElement instanceof BuildElement) {
+			return handlers.stream().filter(h -> h.getClass().isAssignableFrom(BuildElementHandler.class)).findAny().get();
 		}
 		return null;
 	}
diff --git a/org.eclipse.capra.handler.cdt/src/org/eclipse/capra/handler/cdt/CDTHandler.java b/org.eclipse.capra.handler.cdt/src/org/eclipse/capra/handler/cdt/CDTHandler.java
index 47bf0e8..790d851 100644
--- a/org.eclipse.capra.handler.cdt/src/org/eclipse/capra/handler/cdt/CDTHandler.java
+++ b/org.eclipse.capra.handler.cdt/src/org/eclipse/capra/handler/cdt/CDTHandler.java
@@ -11,8 +11,8 @@
 package org.eclipse.capra.handler.cdt;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.handlers.AnnotationException;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
 import org.eclipse.capra.core.handlers.IAnnotateArtifact;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.handler.cdt.preferences.CDTPreferences;
@@ -25,40 +25,33 @@
  * Handler to allow tracing to and from elements of C such as files and
  * functions. Uses CDT as the foundation.
  */
-public class CDTHandler implements ArtifactHandler, IAnnotateArtifact {
+public class CDTHandler extends AbstractArtifactHandler<ICElement> implements IAnnotateArtifact {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return selection instanceof ICElement;
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		ICElement cu = (ICElement) selection;
+	public EObject createWrapper(ICElement element, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), cu.getHandleIdentifier(),
-				cu.getElementName());
+		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(),
+				element.getHandleIdentifier(), element.getElementName());
 		return wrapper;
 	}
 
 	@Override
-	public ICElement resolveArtifact(EObject artifact) {
+	public ICElement resolveWrapper(EObject wrapper) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		String uri = adapter.getArtifactUri(artifact);
+		String uri = adapter.getArtifactUri(wrapper);
 		return CoreModel.create(uri);
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		ICElement cu = (ICElement) selection;
-		return cu.getElementName();
+	public String getDisplayName(ICElement element) {
+		return element.getElementName();
 	}
 
 	@Override
-	public void annotateArtifact(EObject artifact, String annotation) throws AnnotationException {
+	public void annotateArtifact(EObject wrapper, String annotation) throws AnnotationException {
 		IEclipsePreferences preferences = CDTPreferences.getPreferences();
 		if (preferences.getBoolean(CDTPreferences.ANNOTATE_CDT, CDTPreferences.ANNOTATE_CDT_DEFAULT)) {
-			ICElement handle = resolveArtifact(artifact);
+			ICElement handle = resolveWrapper(wrapper);
 			CDTAnnotate.annotateArtifact(handle, annotation);
 		}
 	}
diff --git a/org.eclipse.capra.handler.emf/src/org/eclipse/capra/handler/emf/EMFHandler.java b/org.eclipse.capra.handler.emf/src/org/eclipse/capra/handler/emf/EMFHandler.java
index e4ae209..2a171ac 100644
--- a/org.eclipse.capra.handler.emf/src/org/eclipse/capra/handler/emf/EMFHandler.java
+++ b/org.eclipse.capra.handler.emf/src/org/eclipse/capra/handler/emf/EMFHandler.java
@@ -4,33 +4,33 @@
  * 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.handler.emf;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
+import org.eclipse.capra.core.helpers.EMFHelper;
 import org.eclipse.emf.ecore.EObject;
 
 /**
  * Handler to allow tracing to and from arbitrary model elements handled by EMF.
  */
-public class EMFHandler implements ArtifactHandler {
+public class EMFHandler extends AbstractArtifactHandler<EObject> {
 
-	public boolean canHandleSelection(Object selection) {
-		return selection instanceof EObject;
-
+	@Override
+	public EObject createWrapper(EObject artifact, EObject artifactModel) {
+		return artifact;
 	}
 
 	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		return EObject.class.cast(selection);
+	public EObject resolveWrapper(EObject wrapper) {
+		return wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
-		// TODO Auto-generated method stub
-		return null;
+	public String getDisplayName(EObject artifact) {
+		return EMFHelper.getIdentifier(artifact);
 	}
 }
diff --git a/org.eclipse.capra.handler.file/src/org/eclipse/capra/handler/file/IFileHandler.java b/org.eclipse.capra.handler.file/src/org/eclipse/capra/handler/file/IFileHandler.java
index e74eb93..647cf8a 100644
--- a/org.eclipse.capra.handler.file/src/org/eclipse/capra/handler/file/IFileHandler.java
+++ b/org.eclipse.capra.handler.file/src/org/eclipse/capra/handler/file/IFileHandler.java
@@ -11,7 +11,7 @@
 package org.eclipse.capra.handler.file;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.ResourcesPlugin;
@@ -21,33 +21,28 @@
 /**
  * Handler to allow tracing to and from arbitrary files in the file system.
  */
-public class IFileHandler implements ArtifactHandler {
+public class IFileHandler extends AbstractArtifactHandler<IFile> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return selection instanceof IFile;
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		IFile selectionAsFile = (IFile) selection;
+	public EObject createWrapper(IFile file, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
 		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(),
-				selectionAsFile.getFullPath().toString(), selectionAsFile.getName());
+				file.getFullPath().toString(), file.getName());
 		return wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
+
+	public IFile resolveWrapper(EObject wrapper) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		String uri = adapter.getArtifactUri(artifact);
+		String uri = adapter.getArtifactUri(wrapper);
 		IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(uri));
 		return file;
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		IFile selectionAsFile = (IFile) selection;
-		return selectionAsFile.getName();
+	public String getDisplayName(IFile file) {
+		return file.getName();
 	}
+
 }
diff --git a/org.eclipse.capra.handler.gef/src/org/eclipse/capra/handler/gef/GEFHandler.java b/org.eclipse.capra.handler.gef/src/org/eclipse/capra/handler/gef/GEFHandler.java
index b0ec0e8..1aea4f6 100644
--- a/org.eclipse.capra.handler.gef/src/org/eclipse/capra/handler/gef/GEFHandler.java
+++ b/org.eclipse.capra.handler.gef/src/org/eclipse/capra/handler/gef/GEFHandler.java
@@ -10,7 +10,7 @@
  *******************************************************************************/
 package org.eclipse.capra.handler.gef;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.gef.EditPart;
 import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
@@ -19,28 +19,22 @@
  * Handler to allow tracing to and from visual model representations handled by
  * editors built with GEF.
  */
-public class GEFHandler implements ArtifactHandler {
+public class GEFHandler extends AbstractArtifactHandler<EditPart> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		// TODO Auto-generated method stub
-		return selection instanceof EditPart;
-
+	public EObject createWrapper(EditPart artifact, EObject artifactModel) {
+		return EMFHelper.getEObject(artifact);
 	}
 
 	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		// TODO Auto-generated method stub
-		EditPart sel = (EditPart) selection;
-
-		return EMFHelper.getEObject(sel);
-
-	}
-
-	@Override
-	public Object resolveArtifact(EObject artifact) {
+	public EditPart resolveWrapper(EObject wrapper) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
+	@Override
+	public String getDisplayName(EditPart artifact) {
+		return org.eclipse.capra.core.helpers.EMFHelper.getIdentifier((EObject) artifact);
+	}
+
 }
diff --git a/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/BuildElementHandler.java b/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/BuildElementHandler.java
index 997f341..0d9ccbe 100644
--- a/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/BuildElementHandler.java
+++ b/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/BuildElementHandler.java
@@ -11,42 +11,33 @@
 package org.eclipse.capra.handler.hudson;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.mylyn.builds.internal.core.BuildElement;
 
 /**
- * A handler to allow tracing to and from elements handled by the continuous
- * integration server Hudson via the integrated Mylyn facilities. In particular,
- * it is possible to trace to tests and to builds.
+ * A handler to allow tracing to and from build elements handled by the continuous
+ * integration server Hudson via the integrated Mylyn facilities.
  */
-public class BuildElementHandler implements ArtifactHandler {
+public class BuildElementHandler extends AbstractArtifactHandler<BuildElement> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return (selection instanceof BuildElement);
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
+	public EObject createWrapper(BuildElement build, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		BuildElement build = (BuildElement) selection;
-
-		EObject buildWrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), build.getUrl(),
+		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), build.getUrl(),
 				build.getLabel());
-		return buildWrapper;
+		return wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
+	public BuildElement resolveWrapper(EObject wrapper) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		BuildElement build = (BuildElement) selection;
+	public String getDisplayName(BuildElement build) {
 		return build.getName();
 	}
 
diff --git a/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/TestElementHandler.java b/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/TestElementHandler.java
index 847a003..71e7328 100644
--- a/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/TestElementHandler.java
+++ b/org.eclipse.capra.handler.hudson/src/org/eclipse/capra/handler/hudson/TestElementHandler.java
@@ -11,43 +11,34 @@
 package org.eclipse.capra.handler.hudson;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.mylyn.builds.internal.core.TestElement;
 
 /**
- * A handler to allow tracing to and from elements handled by the continuous
- * integration server Hudson via the integrated Mylyn facilities. In particular,
- * it is possible to trace to tests and to builds.
+ * A handler to allow tracing to and from test elements handled by the continuous
+ * integration server Hudson via the integrated Mylyn facilities.
  */
-public class TestElementHandler implements ArtifactHandler {
+public class TestElementHandler extends AbstractArtifactHandler<TestElement> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return (selection instanceof TestElement);
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
+	public EObject createWrapper(TestElement test, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		TestElement test = (TestElement) selection;
-
 		// TODO Need to get the URI for where the test is
-		EObject testWrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), test.getLabel(),
+		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), test.getLabel(),
 				test.getLabel());
-		return testWrapper;
+		return wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
+	public TestElement resolveWrapper(EObject wrapper) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		TestElement test = (TestElement) selection;
+	public String getDisplayName(TestElement test) {
 		return test.getLabel();
 	}
 
diff --git a/org.eclipse.capra.handler.jdt/src/org/eclipse/capra/handler/jdt/JavaElementHandler.java b/org.eclipse.capra.handler.jdt/src/org/eclipse/capra/handler/jdt/JavaElementHandler.java
index 7824b2d..3c2163d 100644
--- a/org.eclipse.capra.handler.jdt/src/org/eclipse/capra/handler/jdt/JavaElementHandler.java
+++ b/org.eclipse.capra.handler.jdt/src/org/eclipse/capra/handler/jdt/JavaElementHandler.java
@@ -11,8 +11,8 @@
 package org.eclipse.capra.handler.jdt;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.handlers.AnnotationException;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
 import org.eclipse.capra.core.handlers.IAnnotateArtifact;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.handler.jdt.preferences.JDTPreferences;
@@ -25,45 +25,35 @@
  * A handler to allow creating traces to and from java elements such as classes
  * and methods based on JDT.
  */
-public class JavaElementHandler implements ArtifactHandler, IAnnotateArtifact {
+public class JavaElementHandler extends AbstractArtifactHandler<IJavaElement> implements IAnnotateArtifact {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		if (selection instanceof IJavaElement) {
-			return true;
-		}
-
-		return false;
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		IJavaElement cu = (IJavaElement) selection;
+	public EObject createWrapper(IJavaElement element, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), cu.getHandleIdentifier(),
-				cu.getElementName());
+		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), element.getHandleIdentifier(),
+				element.getElementName());
 		return wrapper;
 	}
 
 	@Override
-	public IJavaElement resolveArtifact(EObject artifact) {
+	public IJavaElement resolveWrapper(EObject wrapper) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-		String uri = adapter.getArtifactUri(artifact);
+		String uri = adapter.getArtifactUri(wrapper);
 		return JavaCore.create(uri);
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		IJavaElement cu = (IJavaElement) selection;
-		return cu.getElementName();
+	public String getDisplayName(IJavaElement element) {
+		return element.getElementName();
 	}
 
 	@Override
-	public void annotateArtifact(EObject artifact, String annotation) throws AnnotationException {
+	public void annotateArtifact(EObject wrapper, String annotation) throws AnnotationException {
 		IEclipsePreferences preferences = JDTPreferences.getPreferences();
 		if (preferences.getBoolean(JDTPreferences.ANNOTATE_JDT, JDTPreferences.ANNOTATE_JDT_DEFAULT)) {
-			IJavaElement handle = resolveArtifact(artifact);
+			IJavaElement handle = resolveWrapper(wrapper);
 			JDTAnnotate.annotateArtifact(handle, annotation);
 		}
 	}
+
 }
diff --git a/org.eclipse.capra.handler.mylyn/src/org/eclipse/capra/handler/mylyn/MylynHandler.java b/org.eclipse.capra.handler.mylyn/src/org/eclipse/capra/handler/mylyn/MylynHandler.java
index 03ed56e..6dec163 100644
--- a/org.eclipse.capra.handler.mylyn/src/org/eclipse/capra/handler/mylyn/MylynHandler.java
+++ b/org.eclipse.capra.handler.mylyn/src/org/eclipse/capra/handler/mylyn/MylynHandler.java
@@ -11,7 +11,7 @@
 package org.eclipse.capra.handler.mylyn;
 
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.mylyn.tasks.core.ITask;
@@ -19,16 +19,10 @@
 /**
  * A handler to allow tracing from and to tasks handled by Mylyn.
  */
-public class MylynHandler implements ArtifactHandler {
+public class MylynHandler extends AbstractArtifactHandler<ITask> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return selection instanceof ITask;
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		ITask task = (ITask) selection;
+	public EObject createWrapper(ITask task, EObject artifactModel) {
 		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
 		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), task.getUrl(),
 				task.getSummary());
@@ -36,14 +30,13 @@
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
+	public ITask resolveWrapper(EObject wrapper) {
 		// TODO Auto-generated method stub
 		return null;
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		ITask task = (ITask) selection;
+	public String getDisplayName(ITask task) {
 		return task.getTaskId() + " : " + task.getSummary();
 	}
 
diff --git a/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java b/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
index db39432..9eb58a0 100644
--- a/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
+++ b/org.eclipse.capra.handler.office/src/org/eclipse/capra/handler/office/OfficeHandler.java
@@ -11,9 +11,8 @@
 
 package org.eclipse.capra.handler.office;
 
-import org.eclipse.capra.GenericArtifactMetaModel.ArtifactWrapper;
 import org.eclipse.capra.core.adapters.ArtifactMetaModelAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.capra.ui.office.objects.CapraOfficeObject;
 import org.eclipse.emf.ecore.EObject;
@@ -24,49 +23,32 @@
  * @author Dusan Kalanj
  * 
  */
-public class OfficeHandler implements ArtifactHandler {
+public class OfficeHandler extends AbstractArtifactHandler<CapraOfficeObject> {
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		return selection instanceof CapraOfficeObject;
-	}
-
-	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
+	public EObject createWrapper(CapraOfficeObject officeObject, EObject artifactModel) {
 		// Returns the EObject corresponding to the input object if the input is
 		// an EObject, or if it is Adaptable to an EObject
-		CapraOfficeObject officeObject = (CapraOfficeObject) selection;
-		if (officeObject != null) {
-			ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
-			// TODO here artifactName is the same as the row/paragraph
-			// description. Should it be different?
-			EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), officeObject.getUri(),
-					officeObject.getName());
-			return wrapper;
-		} else {
-			return null;
-		}
+		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
+		// TODO here artifactName is the same as the row/paragraph
+		// description. Should it be different?
+		EObject wrapper = adapter.createArtifact(artifactModel, this.getClass().getName(), officeObject.getUri(),
+				officeObject.getName());
+		return wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
-		if (artifact instanceof ArtifactWrapper) {
-			ArtifactWrapper wrapper = (ArtifactWrapper) artifact;
-			String uri = wrapper.getUri();
-			CapraOfficeObject object = new CapraOfficeObject();
-			object.setUri(uri);
-			return object;
-		} else
-			return null;
+	public CapraOfficeObject resolveWrapper(EObject wrapper) {
+		ArtifactMetaModelAdapter adapter = ExtensionPointHelper.getArtifactWrapperMetaModelAdapter().get();
+		String uri = adapter.getArtifactUri(wrapper);
+		CapraOfficeObject object = new CapraOfficeObject();
+		object.setUri(uri);
+		return object;
 	}
 
 	@Override
-	public String getDisplayName(Object selection) {
-		if (selection instanceof CapraOfficeObject) {
-			CapraOfficeObject officeObject = (CapraOfficeObject) selection;
-			return officeObject.getName();
-		} else
-			return null;
+	public String getDisplayName(CapraOfficeObject officeObject) {
+		return officeObject.getName();
 	}
 
 }
diff --git a/org.eclipse.capra.handler.papyrus/src/org/eclipse/capra/handler/papyrus/PapyrusHandler.java b/org.eclipse.capra.handler.papyrus/src/org/eclipse/capra/handler/papyrus/PapyrusHandler.java
index adfd09a..6ead603 100644
--- a/org.eclipse.capra.handler.papyrus/src/org/eclipse/capra/handler/papyrus/PapyrusHandler.java
+++ b/org.eclipse.capra.handler.papyrus/src/org/eclipse/capra/handler/papyrus/PapyrusHandler.java
@@ -1,47 +1,43 @@
-/*******************************************************************************

- * Copyright (c) 2016 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.handler.papyrus;

-

-import org.eclipse.capra.core.handlers.ArtifactHandler;

-import org.eclipse.emf.ecore.EObject;

-import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EObjectTreeElement;

-import org.eclipse.papyrus.infra.emf.utils.EMFHelper;

-

-/**

- * A handler to create trace links from and to model elements created in

- * Papyrus.

- */

-public class PapyrusHandler implements ArtifactHandler {

-

-	@Override

-	public boolean canHandleSelection(Object selection) {

-		return selection instanceof EObjectTreeElement;

-	}

-

-	@Override

-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {

-		// Returns the EObject corresponding to the input object if the input is

-		// an EObject, or if it is Adaptable to an EObject

-		return EMFHelper.getEObject(selection);

-	}

-

-	@Override

-	public Object resolveArtifact(EObject artifact) {

-		return artifact;

-	}

-

-	@Override

-	public String getDisplayName(Object selection) {

-		EObject sel = EMFHelper.getEObject(selection);

-		return ArtifactHandler.super.getDisplayName(sel);

-	}

-

-}

+/*******************************************************************************
+ * Copyright (c) 2016 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.handler.papyrus;
+
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.emf.facet.custom.metamodel.v0_2_0.internal.treeproxy.EObjectTreeElement;
+import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
+
+/**
+ * A handler to create trace links from and to model elements created in
+ * Papyrus.
+ */
+public class PapyrusHandler extends AbstractArtifactHandler<EObjectTreeElement> {
+
+
+	@Override
+	public EObject createWrapper(EObjectTreeElement artifact, EObject artifactModel) {
+		// Returns the EObject corresponding to the input object if the input is
+		// an EObject, or if it is Adaptable to an EObject
+		return EMFHelper.getEObject(artifact);
+	}
+
+	@Override
+	public EObjectTreeElement resolveWrapper(EObject wrapper) {
+		return (EObjectTreeElement) wrapper; // TODO
+	}
+
+	@Override
+	public String getDisplayName(EObjectTreeElement artifact) {
+		EObject sel = EMFHelper.getEObject(artifact);
+		return org.eclipse.capra.core.helpers.EMFHelper.getIdentifier(sel); // TODO
+	}
+
+}
diff --git a/org.eclipse.capra.handler.reqIf/src/org/eclipse/capra/handler/reqif/ReqIfHandler.java b/org.eclipse.capra.handler.reqIf/src/org/eclipse/capra/handler/reqif/ReqIfHandler.java
index af625aa..0e4ce46 100644
--- a/org.eclipse.capra.handler.reqIf/src/org/eclipse/capra/handler/reqif/ReqIfHandler.java
+++ b/org.eclipse.capra.handler.reqIf/src/org/eclipse/capra/handler/reqif/ReqIfHandler.java
@@ -10,50 +10,28 @@
  *******************************************************************************/
 package org.eclipse.capra.handler.reqif;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.AbstractArtifactHandler;
 import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.rmf.reqif10.SpecHierarchy;
 import org.eclipse.rmf.reqif10.SpecObject;
-import org.eclipse.rmf.reqif10.impl.SpecHierarchyImpl;
 
-public class ReqIfHandler implements ArtifactHandler {
+public class ReqIfHandler extends AbstractArtifactHandler<SpecHierarchy> {
+
+	// TODO: This used to expect IStructuredSelection input, why?
 
 	@Override
-	public boolean canHandleSelection(Object selection) {
-		if (selection instanceof IStructuredSelection) {
-			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
-			if (!(structuredSelection.getFirstElement() == null)) {
-				Object element = structuredSelection.getFirstElement();
-				if (element instanceof SpecHierarchyImpl) {
-					return true;
-				}
-			}
-		}
-		return false;
-
+	public EObject createWrapper(SpecHierarchy spec, EObject artifactModel) {
+		return spec;
 	}
 
 	@Override
-	public EObject getEObjectForSelection(Object selection, EObject artifactModel) {
-		IStructuredSelection structuredSelection = (IStructuredSelection) selection;
-		Object element = structuredSelection.getFirstElement();
-		SpecHierarchyImpl specification = (SpecHierarchyImpl) element;
-		return specification;
-
+	public SpecHierarchy resolveWrapper(EObject wrapper) {
+		return (SpecHierarchy) wrapper;
 	}
 
 	@Override
-	public Object resolveArtifact(EObject artifact) {
-		return artifact;
-	}
-
-	@Override
-	public String getDisplayName(Object selection) {
-		IStructuredSelection structuredSelection = (IStructuredSelection) selection;
-		Object element = structuredSelection.getFirstElement();
-		SpecHierarchyImpl specification = (SpecHierarchyImpl) element;
-		SpecObject specObject = specification.getObject();
-
+	public String getDisplayName(SpecHierarchy spec) {
+		SpecObject specObject = spec.getObject();
 		return specObject.getIdentifier();
 	}
 
diff --git a/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/Connections.java b/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/Connections.java
index 5f923e5..93479ec 100644
--- a/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/Connections.java
+++ b/org.eclipse.capra.ui.plantuml/src/org/eclipse/capra/ui/plantuml/Connections.java
@@ -20,7 +20,7 @@
 
 import org.eclipse.capra.GenericArtifactMetaModel.ArtifactWrapper;
 import org.eclipse.capra.core.adapters.Connection;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.helpers.EMFHelper;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.emf.ecore.EObject;
@@ -110,12 +110,12 @@
 		String artifactLabel = null;
 		if (object instanceof ArtifactWrapper) {
 			ArtifactWrapper wrapper = (ArtifactWrapper) object;
-			Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+			Collection<IArtifactHandler<Object>> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
 
-			for (ArtifactHandler handler : artifactHandlers) {
+			for (IArtifactHandler<Object> handler : artifactHandlers) {
 				String handlerName = handler.toString().substring(0, handler.toString().indexOf('@'));
 				if (handlerName.equals(wrapper.getArtifactHandler())) {
-					Object originalObject = handler.resolveArtifact(object);
+					Object originalObject = handler.resolveWrapper(object);
 					if (originalObject != null) {
 						artifactLabel = handler.getDisplayName(originalObject);
 					} else { // original object cannot be resolved
diff --git a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java
index 1b9a1e3..1cb9248 100644
--- a/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java
+++ b/org.eclipse.capra.ui.zest/src/org/eclipse/capra/ui/zest/TraceNodeLabelProvider.java
@@ -14,7 +14,7 @@
 import java.util.List;
 import java.util.stream.Collectors;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.jface.viewers.LabelProvider;
 
@@ -29,9 +29,9 @@
 	@Override
 	public String getText(Object element) {
 
-		Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
-		List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
-				.filter(handler -> handler.canHandleSelection(element)).collect(Collectors.toList());
+		Collection<IArtifactHandler<Object>> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+		List<IArtifactHandler<Object>> availableHandlers = artifactHandlers.stream()
+				.filter(handler -> handler.canHandleArtifact(element)).collect(Collectors.toList());
 		if (availableHandlers.size() >= 1) {
 			return availableHandlers.get(0).getDisplayName(element);
 		} else
diff --git a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
index 70712f1..fb86b82 100644
--- a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
+++ b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/handlers/TraceCreationHandler.java
@@ -22,8 +22,8 @@
 import org.eclipse.capra.core.adapters.Connection;
 import org.eclipse.capra.core.adapters.TraceMetaModelAdapter;
 import org.eclipse.capra.core.adapters.TracePersistenceAdapter;
-import org.eclipse.capra.core.handlers.ArtifactHandler;
 import org.eclipse.capra.core.handlers.IAnnotateArtifact;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.handlers.PriorityHandler;
 import org.eclipse.capra.core.helpers.EMFHelper;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
@@ -64,7 +64,7 @@
 		// add artifact model to resource set
 		EObject artifactModel = persistenceAdapter.getArtifactWrappers(resourceSet);
 
-		Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+		Collection<IArtifactHandler<Object>> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
 
 		List<EObject> selectionAsEObjects = mapSelectionToEObjects(window, artifactModel, artifactHandlers, selection);
 
@@ -84,7 +84,7 @@
 
 		// Annotate if possible
 		for (EObject artifact : artifacts) {
-			ArtifactHandler handler = adapter.getArtifactHandlerInstance(artifact);
+			IArtifactHandler<Object> handler = adapter.getArtifactHandlerInstance(artifact);
 			if (handler instanceof IAnnotateArtifact) {
 				IAnnotateArtifact h = (IAnnotateArtifact) handler;
 				try {
@@ -119,22 +119,22 @@
 	}
 
 	private List<EObject> mapSelectionToEObjects(IWorkbenchWindow window, EObject artifactModel,
-			Collection<ArtifactHandler> artifactHandlers, List<Object> selection) {
+			Collection<IArtifactHandler<Object>> artifactHandlers, List<Object> selection) {
 		return selection.stream().map(sel -> convertToEObject(window, sel, artifactHandlers, artifactModel))
 				.filter(Optional::isPresent).map(Optional::get).collect(Collectors.toList());
 	}
 
 	private Optional<EObject> convertToEObject(IWorkbenchWindow window, Object sel,
-			Collection<ArtifactHandler> artifactHandlers, EObject artifactModel) {
-		List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
-				.filter(handler -> handler.canHandleSelection(sel)).collect(Collectors.toList());
+			Collection<IArtifactHandler<Object>> artifactHandlers, EObject artifactModel) {
+		List<IArtifactHandler<Object>> availableHandlers = artifactHandlers.stream()
+				.filter(handler -> handler.canHandleArtifact(sel)).collect(Collectors.toList());
 		Optional<PriorityHandler> priorityHandler = ExtensionPointHelper.getPriorityHandler();
 
 		if (availableHandlers.size() == 1) {
-			return Optional.of(availableHandlers.get(0).getEObjectForSelection(sel, artifactModel));
+			return Optional.of(availableHandlers.get(0).createWrapper(sel, artifactModel));
 		} else if (availableHandlers.size() > 1 && priorityHandler.isPresent()) {
-			ArtifactHandler selectedHandler = priorityHandler.get().getSelectedHandler(availableHandlers, sel);
-			return Optional.of(selectedHandler.getEObjectForSelection(sel, artifactModel));
+			IArtifactHandler<Object> selectedHandler = priorityHandler.get().getSelectedHandler(availableHandlers, sel);
+			return Optional.of(selectedHandler.createWrapper(sel, artifactModel));
 		} else {
 			MessageDialog.openWarning(window.getShell(), "No handler for selected item",
 					"There is no handler for " + sel + " so it will be ignored.");
diff --git a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
index bcabd56..f7e84c2 100644
--- a/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
+++ b/org.eclipse.capra.ui/src/org/eclipse/capra/ui/views/SelectionView.java
@@ -19,7 +19,7 @@
 import java.util.Set;
 import java.util.stream.Collectors;
 
-import org.eclipse.capra.core.handlers.ArtifactHandler;
+import org.eclipse.capra.core.handlers.IArtifactHandler;
 import org.eclipse.capra.core.handlers.PriorityHandler;
 import org.eclipse.capra.core.helpers.ExtensionPointHelper;
 import org.eclipse.jface.action.IMenuListener;
@@ -91,9 +91,9 @@
 
 		@Override
 		public String getText(Object element) {
-			Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
-			List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
-					.filter(handler -> handler.canHandleSelection(element)).collect(Collectors.toList());
+			Collection<IArtifactHandler<Object>> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+			List<IArtifactHandler<Object>> availableHandlers = artifactHandlers.stream()
+					.filter(handler -> handler.canHandleArtifact(element)).collect(Collectors.toList());
 			if (availableHandlers.size() > 1) {
 				return availableHandlers.get(0).getDisplayName(element);
 			} else
@@ -209,9 +209,9 @@
 	}
 
 	private boolean validateSelection(Object target) {
-		Collection<ArtifactHandler> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
-		List<ArtifactHandler> availableHandlers = artifactHandlers.stream()
-				.filter(handler -> handler.canHandleSelection(target)).collect(Collectors.toList());
+		Collection<IArtifactHandler<Object>> artifactHandlers = ExtensionPointHelper.getArtifactHandlers();
+		List<IArtifactHandler<Object>> availableHandlers = artifactHandlers.stream()
+				.filter(handler -> handler.canHandleArtifact(target)).collect(Collectors.toList());
 		Optional<PriorityHandler> priorityHandler = ExtensionPointHelper.getPriorityHandler();
 		if (availableHandlers.size() == 0) {
 			MessageDialog.openWarning(getSite().getShell(), "No handler for selected item",