diff --git a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag
index c0aa6077129c779861bd24eb60b25765079a69b7..4de33186757abf83e4634daefc6facaca6f0114f 100644
--- a/scope4j/src/main/jastadd/ProgramToScopeTree.jrag
+++ b/scope4j/src/main/jastadd/ProgramToScopeTree.jrag
@@ -4,43 +4,42 @@ aspect ProgramToScopeTree {
     tree.setProgram(this);
 
     for (CompilationUnit compilationUnit : getCompilationUnitList())
-      for (TypeDecl typeDecl : compilationUnit.getTypeDeclList())
-        tree.addElement(typeDecl.scope());
+      for (TypeDecl typeDecl : compilationUnit.getTypeDeclList()) {
+        if (typeDecl.isClassDecl()) {
+          tree.addElement(((ClassDecl)typeDecl).publicScope());
+        } else {
+          tree.addElement(typeDecl.scope());
+        }
+      }
 
     return tree;
   }
 
   /** a relational nta collection attribute to compute the scope tree */
   coll Scope ASTNode.scope() [asScope()] with addElement root Program;
+  coll TypeDeclScope ClassDecl.packageScope() [asPackageScope()] with addElement root Program;
+  coll TypeDeclScope ClassDecl.protectedScope() [asProtectedScope()] with addElement root Program;
+  coll TypeDeclScope ClassDecl.publicScope() [asPublicScope()] with addElement root Program;
 
   // collect all scopes
-  TypeDecl contributes scope() to ASTNode.scope() for containingScope();
+  TypeDecl contributes scope() when !isClassDecl() to ASTNode.scope() for containingScope();
+  ClassDecl contributes publicScope() to ASTNode.scope() for containingScope();
   Block contributes scope() to ASTNode.scope() for containingScope();
   ForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope();
   EnhancedForStmt contributes scope() when !(getStmt() instanceof Block) to ASTNode.scope() for containingScope();
 
   // collect all elements
-  Declarator contributes asDeclaration() to ASTNode.scope() for containingScope();
+  Declarator contributes asDeclaration() when !isField() || isPrivate() to ASTNode.scope() for containingScope();
+  Declarator contributes asDeclaration() when isField() && !(isPrivate() || isProtected() || isPublic()) to ClassDecl.packageScope() for containingScope();
+  Declarator contributes asDeclaration() when isField() && isProtected() to ClassDecl.protectedScope() for containingScope();
+  Declarator contributes asDeclaration() when isField() && isPublic() to ClassDecl.publicScope() for containingScope();
   ParameterDeclaration contributes asDeclaration() to ASTNode.scope() for containingScope();
 
-  Collection<Declaration> ClassDecl.createSuperClassFieldDeclarators() {
-    ArrayList<Declaration> result = new ArrayList<>();
-    TypeDecl supertype = superclass();
-
-    System.out.println("supertype " + supertype.getID());
-    while (supertype.isClassDecl() && supertype != unknownType()) {
-      for (BodyDecl bodyDecl : supertype.getBodyDeclList()) {
-        if (bodyDecl instanceof FieldDecl) {
-          for (FieldDeclarator declarator : ((FieldDecl)bodyDecl).getDeclaratorList()) {
-            JavaDeclaration declaration = new JavaDeclaration(declarator.getID());
-            declaration.setDeclarator(declarator);
-            result.add(declaration);
-          }
-        }
-      }
-      supertype = ((ClassDecl)supertype).superclass();
-    }
-    return result;
+  syn lazy ScopeTree Program.asScopeTree() {
+    ScopeTree tree = new ScopeTree();
+    tree.setProgram(this);
+
+    return tree;
   }
 
   /** fallback attribute to ensure every AST element could pontentially be a scope */
@@ -51,11 +50,27 @@ aspect ProgramToScopeTree {
   syn lazy TypeDeclScope TypeDecl.asScope() {
     TypeDeclScope scope = new TypeDeclScope();
     scope.setTypeDecl(this);
-    if (isClassDecl()) {
-      for (Declaration declaration : ((ClassDecl)this).createSuperClassFieldDeclarators()) {
-        scope.addElement(declaration);
-      }
-    }
+    return scope;
+  }
+
+  syn lazy TypeDeclScope ClassDecl.asPublicScope() {
+    TypeDeclScope scope = new TypeDeclScope();
+    scope.setTypeDecl(this);
+    scope.addElement(protectedScope());
+    return scope;
+  }
+
+  syn lazy TypeDeclScope ClassDecl.asProtectedScope() {
+    TypeDeclScope scope = new TypeDeclScope();
+    scope.setTypeDecl(this);
+    scope.addElement(packageScope());
+    return scope;
+  }
+
+  syn lazy TypeDeclScope ClassDecl.asPackageScope() {
+    TypeDeclScope scope = new TypeDeclScope();
+    scope.setTypeDecl(this);
+    scope.addElement(scope());
     return scope;
   }