diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag
index 21456331346ac897ee8f597c52e93c1ac8edb498..41572756a45d2c14eb763e280075d3c2b03d256d 100644
--- a/src/main/jastadd/Analysis.jrag
+++ b/src/main/jastadd/Analysis.jrag
@@ -160,11 +160,39 @@ aspect ComponentAnalysis {
     return set;
   }
 
-  //--- needUnresolvedClass ---
-  syn boolean TypeDecl.needUnresolvedClass() {
-    // a TypeDecl needs an unresolved class, if it can appear in a relation
-    // TODO
-    return true;
+  /**
+   * @return a set of all types that refer to this type using a non-containment relation
+   */
+  coll Set<TypeDecl> TypeDecl.referencingTypes() [new HashSet<TypeDecl>()];
+  RelationComponent contributes opposite().getTypeUse().decl()
+    when opposite().isNavigable()
+    to TypeDecl.referencingTypes()
+    for getTypeUse().decl();
+
+  /**
+   * @return true, if the type can be the target of a non-containment relation
+   */
+  syn boolean TypeDecl.isReferenceTarget() {
+    return !referencingTypes().isEmpty();
+  }
+
+  /**
+   * @return true, if the type or one of its abstract supertypes can be the target of a non-containment relation
+   */
+  syn boolean TypeDecl.requiresUresolvedClass() {
+    if (referencingTypes().isEmpty()) {
+      // if the type is not referenced itself, it may still be required by an abstract supertype that is referenced
+      TypeDecl decl = this;
+      while (decl.hasSuper()) {
+        decl = decl.getSuper().decl();
+        if (decl.getAbstract() && !decl.referencingTypes().isEmpty()) {
+          return true;
+        }
+      }
+      return false;
+    } else {
+      return true;
+    }
   }
 
   //--- isList ---
@@ -201,6 +229,8 @@ aspect InstanceSupplier {
     return subDecls;
   }
 
+  syn boolean TypeDecl.instantiable() = instantiableSubType() != null;
+
   //--- instantiableSubType ---
   syn TypeDecl TypeDecl.instantiableSubType() {
     if (getAbstract() == false) {
diff --git a/src/main/jastadd/backend/NameResolution.jadd b/src/main/jastadd/backend/NameResolution.jadd
index 9b47dc1cee3a14f4ad114c8028b0f446392ad064..8080fa0450cc08da31eca31222144a78199a25b7 100644
--- a/src/main/jastadd/backend/NameResolution.jadd
+++ b/src/main/jastadd/backend/NameResolution.jadd
@@ -149,7 +149,9 @@ aspect NameResolutionHelper {
     sb.append("aspect ReferenceCreation {\n\n");
 
     for (TypeDecl decl : getTypeDeclList()) {
-      decl.createReferenceCreator(sb);
+      if (decl.isReferenceTarget()) {
+        decl.createReferenceCreator(sb);
+      }
     }
 
     sb.append("}\n\n");
@@ -172,7 +174,7 @@ aspect NameResolutionHelper {
     sb.append(ind(1) + "}\n\n");
 
     for (TypeDecl td: getTypeDecls()) {
-      if (td.needUnresolvedClass()) {
+      if (td.requiresUresolvedClass()) {
         td.generateUnresolvedClass(sb);
       }
     }
@@ -182,24 +184,24 @@ aspect NameResolutionHelper {
 
   public void TypeDecl.createReferenceCreator(StringBuilder sb) {
 
-    TypeDecl instantiableSubType = instantiableSubType();
-    if (instantiableSubType == null) {
-      throw new RuntimeException("unable to find instantiable subtype for " + getID());
-    }
-
-    sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n");
-      sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
-      sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
-      sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n");
-      sb.append(ind(2) + "return unresolvedNode;\n");
-    sb.append(ind(1) + "}\n");
+    if (!instantiable()) {
+      System.out.println("WARNING: unable to find instantiable subtype for " + getID() + "! Skipping the creation of reference creator methods.");
+    } else {
+      TypeDecl instantiableSubType = instantiableSubType();
+      sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefMethod + "(String ref) {\n");
+        sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
+        sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
+        sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(true);\n");
+        sb.append(ind(2) + "return unresolvedNode;\n");
+      sb.append(ind(1) + "}\n");
 
-    sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n");
-      sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
-      sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
-      sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n");
-      sb.append(ind(2) + "return unresolvedNode;\n");
-    sb.append(ind(1) + "}\n");
+      sb.append(ind(1) + "public static " + getID() + " " + getID() + "." + createRefDirectionMethod + "(String ref) {\n");
+        sb.append(ind(2) + unresolvedPrefix + instantiableSubType.getID() + " unresolvedNode = new " + unresolvedPrefix + instantiableSubType.getID() + "();\n");
+        sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "Token(ref);\n");
+        sb.append(ind(2) + "unresolvedNode.set" + unresolvedPrefix + "ResolveOpposite(false);\n");
+        sb.append(ind(2) + "return unresolvedNode;\n");
+      sb.append(ind(1) + "}\n");
+    }
   }
 
   public void TypeDecl.generateContextIndependentNameResolution(StringBuilder sb) {
diff --git a/src/main/jastadd/backend/Serializer.jadd b/src/main/jastadd/backend/Serializer.jadd
index 21db37f69f93f2c852528ab334245ce5f3e3d9e0..ac811f1598a2fd0578ae3618c2510e27190cb09a 100644
--- a/src/main/jastadd/backend/Serializer.jadd
+++ b/src/main/jastadd/backend/Serializer.jadd
@@ -268,67 +268,73 @@ aspect Serializer {
   public void TypeDecl.deserialize(StringBuilder sb) {
 
     sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(java.io.File file) throws DeserializationException {\n");
-    sb.append(ind(2) + "try {\n");
-    sb.append(ind(3) + "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n");
-    sb.append(ind(3) + "com.fasterxml.jackson.core.JsonFactory factory = mapper.getFactory();\n");
-    sb.append(ind(3) + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(file);\n");
-    sb.append(ind(3) + getID() + " result = deserialize((com.fasterxml.jackson.databind.JsonNode)mapper.readTree(parser));\n");
-    sb.append(ind(3) + "parser.close();\n");
-    sb.append(ind(3) + "return result;\n");
-    sb.append(ind(2) + "} catch (java.io.IOException e) {\n");
-    sb.append(ind(3) + "throw new DeserializationException(\"unable to deserialize \" + file.getAbsolutePath(), e);\n");
-    sb.append(ind(2) + "}\n");
-    sb.append(ind(1) + "}\n");
 
-    sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(" + jsonNodeType + " node) throws DeserializationException {\n");
-    sb.append(ind(2) + getID() + " element;\n");
-    if (getAbstract()) {
-      // switch case between all implementations of the abstract class
-      sb.append(ind(2) + "switch (node" + jsonNodeTypeAccessor + ") {\n");
-      for (TypeDecl subType : subTypeDecls()) {
-        sb.append(ind(3) + "case \"" + subType.getID() + "\":\n");
-        sb.append(ind(4) + "element = " + subType.getID() + ".deserialize(node);\n");
-        sb.append(ind(4) + "break;\n");
-      }
-      sb.append(ind(3) + "default:\n");
-      sb.append(ind(4) + "throw new DeserializationException(\"Unable to deserialize child of unexpected type \" + node" + jsonNodeTypeAccessor + " + \"(" + getID() + " expected)\");\n");
+    if (instantiable()) {
+
+      sb.append(ind(2) + "try {\n");
+      sb.append(ind(3) + "com.fasterxml.jackson.databind.ObjectMapper mapper = new com.fasterxml.jackson.databind.ObjectMapper();\n");
+      sb.append(ind(3) + "com.fasterxml.jackson.core.JsonFactory factory = mapper.getFactory();\n");
+      sb.append(ind(3) + "com.fasterxml.jackson.core.JsonParser parser = factory.createParser(file);\n");
+      sb.append(ind(3) + getID() + " result = deserialize((com.fasterxml.jackson.databind.JsonNode)mapper.readTree(parser));\n");
+      sb.append(ind(3) + "parser.close();\n");
+      sb.append(ind(3) + "return result;\n");
+      sb.append(ind(2) + "} catch (java.io.IOException e) {\n");
+      sb.append(ind(3) + "throw new DeserializationException(\"unable to deserialize \" + file.getAbsolutePath(), e);\n");
       sb.append(ind(2) + "}\n");
-    } else {
-      sb.append(ind(2) + "element = new " + getID() + "();\n");
-    }
+      sb.append(ind(1) + "}\n");
+
+      sb.append(ind(1) + "public static " + getID() + " " + getID() + ".deserialize(" + jsonNodeType + " node) throws DeserializationException {\n");
+      sb.append(ind(2) + getID() + " element;\n");
+      if (getAbstract()) {
+        // switch case between all implementations of the abstract class
+        sb.append(ind(2) + "switch (node" + jsonNodeTypeAccessor + ") {\n");
+        for (TypeDecl subType : subTypeDecls()) {
+          sb.append(ind(3) + "case \"" + subType.getID() + "\":\n");
+          sb.append(ind(4) + "element = " + subType.getID() + ".deserialize(node);\n");
+          sb.append(ind(4) + "break;\n");
+        }
+        sb.append(ind(3) + "default:\n");
+        sb.append(ind(4) + "throw new DeserializationException(\"Unable to deserialize child of unexpected type \" + node" + jsonNodeTypeAccessor + " + \"(" + getID() + " expected)\");\n");
+        sb.append(ind(2) + "}\n");
+      } else {
+        sb.append(ind(2) + "element = new " + getID() + "();\n");
+      }
 
-    if (!jsonPointer && !manualReferences) {
-      // deserialize id
-      sb.append(ind(2) + "if (node.has(\"id\")) {\n");
-      sb.append(ind(3) + "element.unique$Id = node.get(\"id\").asText();\n");
-      sb.append(ind(2) + "}\n");
-    }
+      if (!jsonPointer && !manualReferences) {
+        // deserialize id
+        sb.append(ind(2) + "if (node.has(\"id\")) {\n");
+        sb.append(ind(3) + "element.unique$Id = node.get(\"id\").asText();\n");
+        sb.append(ind(2) + "}\n");
+      }
 
-    // deserialize containment children
-    if (componentsTransitive().size() > 0) {
-      sb.append(ind(2) + "if (node.has(\"children\")) {\n");
-      sb.append(ind(3) + jsonNodeType + " children = node.get(\"children\");\n");
-      for (Component component : componentsTransitive()) {
-        sb.append(ind(3) + "if (children.has(\"" + component.getID() + "\")) {\n");
-        component.deserialize(sb, 4);
-        sb.append(ind(3) + "}\n");
+      // deserialize containment children
+      if (componentsTransitive().size() > 0) {
+        sb.append(ind(2) + "if (node.has(\"children\")) {\n");
+        sb.append(ind(3) + jsonNodeType + " children = node.get(\"children\");\n");
+        for (Component component : componentsTransitive()) {
+          sb.append(ind(3) + "if (children.has(\"" + component.getID() + "\")) {\n");
+          component.deserialize(sb, 4);
+          sb.append(ind(3) + "}\n");
+        }
+        sb.append(ind(2) + "}\n");
       }
-      sb.append(ind(2) + "}\n");
-    }
-    // deserialize non-containment children
-    Set<RelationComponent> relationComponents = relationComponents();
-    if (relationComponents.size() > 0) {
-      sb.append(ind(2) + "if (node.has(\"relations\")) {\n");
-      sb.append(ind(3) + jsonNodeType + " relations = node.get(\"relations\");\n");
-      for (RelationComponent component : relationComponents) {
-        sb.append(ind(3) + "if (relations.has(\"" + component.getID() + "\")) {\n");
-        component.deserialize(sb, 4);
-        sb.append(ind(3) + "}\n");
+      // deserialize non-containment children
+      Set<RelationComponent> relationComponents = relationComponents();
+      if (relationComponents.size() > 0) {
+        sb.append(ind(2) + "if (node.has(\"relations\")) {\n");
+        sb.append(ind(3) + jsonNodeType + " relations = node.get(\"relations\");\n");
+        for (RelationComponent component : relationComponents) {
+          sb.append(ind(3) + "if (relations.has(\"" + component.getID() + "\")) {\n");
+          component.deserialize(sb, 4);
+          sb.append(ind(3) + "}\n");
+        }
+        sb.append(ind(2) + "}\n");
       }
-      sb.append(ind(2) + "}\n");
-    }
 
-    sb.append(ind(2) + "return element;\n");
+      sb.append(ind(2) + "return element;\n");
+    } else {
+      sb.append(ind(2) + "throw new DeserializationException(\"Unable to deserialize type \\\"" + getID() + "\\\" because it is not instantiable.\");\n");
+    }
     sb.append(ind(1) + "}\n");
 
   }
diff --git a/src/test/jastadd/relations/Relations.relast b/src/test/jastadd/relations/Relations.relast
index 12f132e5e58968baff38120d79fde1090151acf8..6df99c3d62d07071dd97599555de011de752a4a4 100644
--- a/src/test/jastadd/relations/Relations.relast
+++ b/src/test/jastadd/relations/Relations.relast
@@ -62,3 +62,5 @@ G : C ::= [D] ;
 
 // line comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/
 /* block comment with special symbols like |, *, ->, <-, <->, [A], B ::= C, :, \n, \r, ~, #, /A/ */
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/resolver/Resolver.relast b/src/test/jastadd/resolver/Resolver.relast
index 5cbaecfeda6d8445cd880245733847721ef4b8b9..b5c34e0716682dcb212c706aee6db82b919dca57 100644
--- a/src/test/jastadd/resolver/Resolver.relast
+++ b/src/test/jastadd/resolver/Resolver.relast
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
 rel A.Bi7* <-> B.Bi7;
 rel A.Bi8* <-> B.Bi8?;
 rel A.Bi9* <-> B.Bi9*;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/resolver2/Resolver.relast b/src/test/jastadd/resolver2/Resolver.relast
index 93a52019c56ee00c4a7af797a3d806f9d80da4ee..c51e717e56e0e0ac0f6eeabbd1646b492c254c73 100644
--- a/src/test/jastadd/resolver2/Resolver.relast
+++ b/src/test/jastadd/resolver2/Resolver.relast
@@ -21,3 +21,5 @@ rel A.Bi6l? <-> B.Bi6*;
 rel A.Bi7l* <-> B.Bi7;
 rel A.Bi8l* <-> B.Bi8?;
 rel A.Bi9l* <-> B.Bi9*;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/serializer-manual-relative/Serializer.relast b/src/test/jastadd/serializer-manual-relative/Serializer.relast
index 0e850a74f81791809b4a80e40be4e4a329d69abb..f6928d1293b2299f1f09914b330163ecc9152e56 100644
--- a/src/test/jastadd/serializer-manual-relative/Serializer.relast
+++ b/src/test/jastadd/serializer-manual-relative/Serializer.relast
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
 rel A.Bi9* <-> B.Bi9*;
 
 rel Root.D <-> D.Root?;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/serializer-manual/Serializer.relast b/src/test/jastadd/serializer-manual/Serializer.relast
index 0e850a74f81791809b4a80e40be4e4a329d69abb..f6928d1293b2299f1f09914b330163ecc9152e56 100644
--- a/src/test/jastadd/serializer-manual/Serializer.relast
+++ b/src/test/jastadd/serializer-manual/Serializer.relast
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
 rel A.Bi9* <-> B.Bi9*;
 
 rel Root.D <-> D.Root?;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/serializer-names/Serializer.relast b/src/test/jastadd/serializer-names/Serializer.relast
index 9106765c6ee6b8016de898c75efa2f3c38903050..aa7e099caa1aeaf7756854995cf9544a51e91b89 100644
--- a/src/test/jastadd/serializer-names/Serializer.relast
+++ b/src/test/jastadd/serializer-names/Serializer.relast
@@ -32,3 +32,5 @@ rel A.Bi5? <-> B.Bi5?;
 rel A.Bi6? <-> B.Bi6*;
 
 rel A.Bi9* <-> B.Bi9*;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/serializer-pointer/Serializer.relast b/src/test/jastadd/serializer-pointer/Serializer.relast
index 0e850a74f81791809b4a80e40be4e4a329d69abb..f6928d1293b2299f1f09914b330163ecc9152e56 100644
--- a/src/test/jastadd/serializer-pointer/Serializer.relast
+++ b/src/test/jastadd/serializer-pointer/Serializer.relast
@@ -21,3 +21,5 @@ rel A.Bi6? <-> B.Bi6*;
 rel A.Bi9* <-> B.Bi9*;
 
 rel Root.D <-> D.Root?;
+
+abstract Uninstantiable:A;
diff --git a/src/test/jastadd/serializer/Serializer.relast b/src/test/jastadd/serializer/Serializer.relast
index 9106765c6ee6b8016de898c75efa2f3c38903050..aa7e099caa1aeaf7756854995cf9544a51e91b89 100644
--- a/src/test/jastadd/serializer/Serializer.relast
+++ b/src/test/jastadd/serializer/Serializer.relast
@@ -32,3 +32,5 @@ rel A.Bi5? <-> B.Bi5?;
 rel A.Bi6? <-> B.Bi6*;
 
 rel A.Bi9* <-> B.Bi9*;
+
+abstract Uninstantiable:A;