diff --git a/src/main/jastadd/Analysis.jrag b/src/main/jastadd/Analysis.jrag
index c25ccdc6c9f36568ccf451af47c87157bdaed30e..93573c901609d061763e96b516b8069372fbcecb 100644
--- a/src/main/jastadd/Analysis.jrag
+++ b/src/main/jastadd/Analysis.jrag
@@ -105,6 +105,51 @@ aspect ComponentAnalysis {
   }
 }
 
+aspect InstanceSupplier {
+
+  inh Program TypeDecl.program();
+  eq Program.getTypeDecl(int i).program() = this;
+
+  syn Collection<TypeDecl> TypeDecl.subTypeDecls() {
+    java.util.List<TypeDecl> subDecls = new ArrayList();
+    for (TypeDecl decl : program().getTypeDeclList()) {
+      if (decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
+        subDecls.add(decl);
+      }
+    }
+    return subDecls;
+  }
+
+  syn UnresolvedTypeDecl TypeDecl.instantiableUnresolved() {
+    if (getAbstract() == false) {
+      return this.getUnresolved();
+    } else {
+      for (TypeDecl sub : subTypeDecls()) {
+        if (sub.getAbstract() == false) {
+          return sub.getUnresolved();
+        } else {
+          TypeDecl subInstance = sub.instantiableUnresolved();
+          if (subInstance != null) {
+            return subInstance.getUnresolved();
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  syn UnresolvedTypeDecl TypeDecl.getUnresolved() {
+    java.util.List<TypeDecl> subDecls = new ArrayList();
+    for (TypeDecl decl : program().getTypeDeclList()) {
+      if (decl.isUnresolved() && decl.hasSuper() && decl.getSuper().getID().equals(getID())) {
+        return decl.asUnresolved();
+      }
+    }
+    // this should not happen
+    return null;
+  }
+}
+
 aspect Constructors {
   syn Collection<Component> TypeDecl.componentsTransitive() {
     ArrayList<Component> list = new ArrayList<>();
diff --git a/src/main/jastadd/Backend.jadd b/src/main/jastadd/Backend.jadd
index 2a43b1154f180a0f277b3de06629de3e14cb4fb1..db6e1bce2665b1f078dc8fa073117ca786a8f6b6 100644
--- a/src/main/jastadd/Backend.jadd
+++ b/src/main/jastadd/Backend.jadd
@@ -217,7 +217,7 @@ aspect BackendDirectedAPI {
     sb.append(".get" + nameCapitalized() + "() {\n");
     if (resolverHelper) {
       sb.append(ind(2) + "if (get" + getImplAttributeName() + "() != null && get" + getImplAttributeName() + "().unresolved()) {\n");
-      sb.append(ind(3) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "(get" + getImplAttributeName() + "().asUnresolved" + ofTypeDecl() + "().get__token()));\n");
+      sb.append(ind(3) + "set" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(get" + getImplAttributeName() + "().asUnresolved().get__token()));\n");
       sb.append(ind(2) + "}\n");
     }
     sb.append(ind(2) + "return get" + getImplAttributeName() + "();\n");
@@ -257,7 +257,7 @@ aspect BackendDirectedAPI {
         sb.append(ind(3) + "for (int i = 0; i < l.size() - removedElements; i++) {\n");
           sb.append(ind(4) + "if (get" + getImplAttributeName() + "().get(i) != null && get" + getImplAttributeName() + "().get(i).unresolved()) {\n");
             sb.append(ind(5) + ofTypeDecl() + " element = l.remove(i);\n");
-            sb.append(ind(5) + "add" + nameCapitalized() + "(resolve" + nameCapitalized() + "(element.asUnresolved" + ofTypeDecl() + "().get__token(), i));\n");
+            sb.append(ind(5) + "add" + nameCapitalized() + "(resolve" + nameCapitalized() + "ByToken(element.asUnresolved().get__token(), i));\n");
             sb.append(ind(5) + "i--; // go back an index, because we removed an element\n");
             sb.append(ind(5) + "removedElements++; // no need to iterate over the removed elements again\n");
           sb.append(ind(4) + "}\n");
@@ -608,6 +608,16 @@ aspect NameResolutionHelper {
 
     sb.append("aspect RefResolverHelpers {\n\n");
 
+    sb.append(ind(1) + "public interface __Unresolved {\n");
+    sb.append(ind(2) + "abstract String get__token();\n");
+    sb.append(ind(1) + "}\n\n");
+
+    for (TypeDecl decl : getTypeDeclList()) {
+      if (decl.isUnresolved()) {
+        sb.append(ind(1) + decl.getID() + " implements __Unresolved;\n");
+      }
+    }
+
     sb.append(ind(1) + "syn boolean ASTNode.unresolved() = false;\n");
     for (TypeDecl decl : getTypeDeclList()) {
       if (decl.isUnresolved()) {
@@ -615,10 +625,10 @@ aspect NameResolutionHelper {
       }
     }
     sb.append("\n");
+    sb.append(ind(1) + "syn __Unresolved ASTNode.asUnresolved() = null;\n");
     for (TypeDecl decl : getTypeDeclList()) {
       if (decl.isUnresolved()) {
-        sb.append(ind(1) + "syn " + decl.getID() + " " + decl.getSuper().decl().getID() + ".asUnresolved" + decl.getSuper().decl().getID() + "() = null;\n");
-        sb.append(ind(1) + "eq " + decl.getID() + ".asUnresolved" + decl.getSuper().decl().getID() + "() = this;\n");
+        sb.append(ind(1) + "eq " + decl.getID() + ".asUnresolved() = this;\n");
       }
     }
 
@@ -629,8 +639,13 @@ aspect NameResolutionHelper {
 
     String superType = this.getSuper().getID();
 
+    TypeDecl instantiableUnresolved = this.getSuper().decl().instantiableUnresolved();
+    if (instantiableUnresolved == null) {
+      System.out.println(getID());
+    }
+
     sb.append(ind(1) + "public static " + superType + " " + superType + ".createRef(String ref) {\n");
-      sb.append(ind(2) + getID() + " unresolvedNode = new " + getID() + "();\n");
+      sb.append(ind(2) + instantiableUnresolved.getID() + " unresolvedNode = new " + instantiableUnresolved.getID() + "();\n");
       sb.append(ind(2) + "unresolvedNode.set__token(ref);\n");
       sb.append(ind(2) + "return unresolvedNode;\n");
     sb.append(ind(1) + "}\n");
@@ -641,7 +656,7 @@ aspect NameResolutionHelper {
     String superType = this.getSuper().getID();
 
     sb.append(ind(1) + "// context-independent name resolution\n");
-    sb.append(ind(1) + "syn " + superType + " ASTNode.resolve" + superType + "(String id) {\n");
+    sb.append(ind(1) + "syn " + superType + " ASTNode.resolve" + superType + "ByToken(String id) {\n");
       sb.append(ind(2) + "// perform context independent name resolution here using the id\n");
       sb.append(ind(2) + "throw new RuntimeException(\"Context-independent name resolution for "+ superType + " not implemented.\");\n");
     sb.append(ind(1) + "}\n");
@@ -673,9 +688,9 @@ aspect NameResolutionHelper {
   }
   public void ManyRelationComponent.generateContextDependentNameResolution(StringBuilder sb) {
     sb.append(ind(1) + "// context-dependent name resolution\n");
-    sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "(String id, int position) {\n");
+    sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id, int position) {\n");
       sb.append(ind(2) + "// default to context-independent name resolution\n");
-      sb.append(ind(2) + "return resolve" + ofTypeDecl() + "(id);\n");
+      sb.append(ind(2) + "return resolve" + ofTypeDecl() + "ByToken(id);\n");
     sb.append(ind(1) + "}\n");
   }
 
@@ -686,9 +701,9 @@ aspect NameResolutionHelper {
     //   return resolveNamedElement(id);
     // }
     sb.append(ind(1) + "// context-dependent name resolution\n");
-    sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "(String id) {\n");
+    sb.append(ind(1) + "syn " + ofTypeDecl() + " " + toTypeDecl() + ".resolve" + nameCapitalized() + "ByToken(String id) {\n");
       sb.append(ind(2) + "// default to context-independent name resolution\n");
-      sb.append(ind(2) + "return resolve" + ofTypeDecl() + "(id);\n");
+      sb.append(ind(2) + "return resolve" + ofTypeDecl() + "ByToken(id);\n");
     sb.append(ind(1) + "}\n");
   }
 
diff --git a/src/main/java/org/jastadd/relast/compiler/Compiler.java b/src/main/java/org/jastadd/relast/compiler/Compiler.java
index 84fb2a7480536a8689be5153ffb293ca18be609a..ab8b0b531929a0f687f80977d2caec9761503d01 100644
--- a/src/main/java/org/jastadd/relast/compiler/Compiler.java
+++ b/src/main/java/org/jastadd/relast/compiler/Compiler.java
@@ -56,7 +56,7 @@ public class Compiler {
       for (TypeDecl typeDecl : nonTerminals) {
         UnresolvedTypeDecl unresolvedDecl = new UnresolvedTypeDecl();
         unresolvedDecl.setID("__unresolved" + typeDecl.getID());
-        unresolvedDecl.setAbstract(false);
+        unresolvedDecl.setAbstract(typeDecl.getAbstract());
         unresolvedDecl.setSuper(new SimpleTypeUse(typeDecl.getID()));
         unresolvedDecl.addComponent(new TokenComponent("__token", new SimpleTypeUse("String")));
         p.addTypeDecl(unresolvedDecl);
diff --git a/src/test/jastadd/resolver/MyRefResolver.jadd b/src/test/jastadd/resolver/MyRefResolver.jadd
index a6114c629f0e057f360bd8ba8b86764d6304598f..e45c5a91e0f1a3db05590b3abc82a824579a0102 100644
--- a/src/test/jastadd/resolver/MyRefResolver.jadd
+++ b/src/test/jastadd/resolver/MyRefResolver.jadd
@@ -1,19 +1,19 @@
 aspect MyRewrites {
 
   // context-independent name resolution
-  refine RefResolverStubs eq ASTNode.resolveNamedElement(String id) {
+  refine RefResolverStubs eq ASTNode.resolveNamedElementByToken(String id) {
     System.out.println("resolving " + id + " to " + root().findNamedElement(id));
     return root().findNamedElement(id);
   }
 
   // context-independent name resolution
-  refine RefResolverStubs eq ASTNode.resolveA(String id) {
+  refine RefResolverStubs eq ASTNode.resolveAByToken(String id) {
     System.out.println("resolving " + id + " to " + root().findNamedElement(id));
     return root().findA(id);
   }
 
   // context-independent name resolution
-  refine RefResolverStubs eq ASTNode.resolveB(String id) {
+  refine RefResolverStubs eq ASTNode.resolveBByToken(String id) {
     System.out.println("resolving " + id + " to " + root().findNamedElement(id));
     return root().findB(id);
   }