diff --git a/scope/src/main/jastadd/Shadowing.jrag b/scope/src/main/jastadd/Shadowing.jrag
index 5c37ee81a752b76949c42dc1184f4c896509bad7..56a1a218138b579846dbab4cb04d0a7616aa1d11 100644
--- a/scope/src/main/jastadd/Shadowing.jrag
+++ b/scope/src/main/jastadd/Shadowing.jrag
@@ -4,7 +4,7 @@ aspect Shadowing {
   Declaration contributes new VariableShadowFinding(shadowed(), this) when isShadowing() to ScopeTree.variableShadowings();
   Declaration contributes new MultipleDeclarationFinding(this) when isShadowingInSameScope() to ScopeTree.variableShadowings();
 
-  syn Declaration Declaration.shadowed() = shadowed(asDeclaration());
+  syn Declaration Declaration.shadowed()= shadowed(asDeclaration());
 
   inh Declaration Element.shadowed(Declaration shadower);
   eq Scope.getElement().shadowed(Declaration shadower) = shadowedLocally(shadower);
@@ -18,9 +18,11 @@ aspect Shadowing {
     }
     // then look in the inherited scopes
     for (Scope inherited : getInheritedScopeList()) {
-      Declaration shadowed = inherited.shadowedLocally(shadower);
-      if (shadowed != null) {
-        return shadowed;
+      if (!inherited.isSuperScopeOf(this)) {
+        Declaration shadowed = inherited.shadowedLocally(shadower);
+        if (shadowed != null) {
+          return shadowed;
+        }
       }
     }
     return (this instanceof ScopeTree) ? null : shadowed(shadower);
@@ -40,6 +42,11 @@ aspect Shadowing {
   syn boolean Declaration.isShadowing() = shadowed() != null;
   syn boolean Declaration.isShadowingInSameScope() = shadowedInSameScope() != null;
 
+  syn boolean Scope.isSuperScopeOf(Scope subScope) = (this==subScope) || isSuperScopeInh(subScope);
+  eq ScopeTree.isSuperScopeOf(Scope subScope) = this==subScope;
+  inh boolean Scope.isSuperScopeInh(Scope subScope);
+  eq Scope.getElement().isSuperScopeInh(Scope subScope) = isSuperScopeOf(subScope);
+
 }
 
 aspect Statictics {
diff --git a/scope4m/src/main/jastadd/ModelicaToScopeTree.jrag b/scope4m/src/main/jastadd/ModelicaToScopeTree.jrag
index d9a6b42e29d38bf56201f0a6ff451605197f1b6c..7c8954aca3882b62b4cbe3d4d7ee8c68d490eda6 100644
--- a/scope4m/src/main/jastadd/ModelicaToScopeTree.jrag
+++ b/scope4m/src/main/jastadd/ModelicaToScopeTree.jrag
@@ -1,15 +1,44 @@
 aspect ModelicaToScopeTree {
-  /** a relational nta collection attribute to compute the scope tree */
-  syn lazy ScopeTree SourceRoot.scopeTree() = (ScopeTree) scope();
+  /** a relational nta attribute to compute the scope tree */
+    syn lazy ScopeTree SourceRoot.scopeTree() {
+    ScopeTree tree = (ScopeTree) scope();
+
+    // add all top-level classes
+    for (SrcClassDecl classDecl : topLevelClasses()) {
+      tree.addElement(classDecl.scope());
+    }
+
+    tree.updateInheritance(); // traverse the tree and add all inheritance relations
+
+    return tree;
+  }
+
+  coll HashSet<SrcClassDecl> SourceRoot.topLevelClasses() root SourceRoot;
+  SrcClassDecl contributes this when !isInnerClass() to SourceRoot.topLevelClasses();
+
+  /** helper method to add inheritance relations */
+  public void Scope.updateInheritance() {
+    for (Element element : getElementList()) {
+      if (element.isScope()) {
+        element.asScope().updateInheritance();
+      }
+    }
+  }
+
+  public void ClassDeclScope.updateInheritance() {
+    for (SrcExtendsClause extendsClause : getClassDecl().superClasses()) {
+      SrcClassDecl superClass = extendsClause.getSuper().findClassDecl();
+      if (superClass != null && superClass != superClass.program().getSrcUnknownClassDecl()) {
+        addInheritedScope(superClass.asScope());
+      }
+    }
+  }
 
   /** a relational nta collection attribute to compute scopes */
   coll Scope ASTNode.scope() [asScope()] with addElement root SourceRoot;
 
-  // collect all scopes
-  SrcClassDecl contributes scope() when !isEncapsulated() to ASTNode.scope() for containingScope();
-  // if a scope is encapsulated, it is added to the top-level, because the inner 
-  SrcClassDecl contributes scope() when  isEncapsulated() to ASTNode.scope() for srcRoot();
-
+  // collect all scopes (except the top-level ones)
+  SrcClassDecl contributes scope() when isInnerClass() to ASTNode.scope() for containingScope();
   SrcForStmt contributes scope() to ASTNode.scope() for containingScope();
 
   // collect all elements
@@ -68,4 +97,13 @@ aspect ScopeGenerationAttributes {
   inh SourceRoot SrcBaseNode.srcRoot();
   eq SourceRoot.getChild().srcRoot() = this;
 
+  inh boolean SrcClassDecl.isInnerClass();
+  eq SourceRoot.getChild().isInnerClass() = false;
+  eq SrcClassDecl.getChild().isInnerClass() = true;
+
+  syn Program ASTNode.program() = programInh();
+  eq SourceRoot.program() = getProgram();
+  inh Program ASTNode.programInh();
+  eq SourceRoot.getChild().programInh() = getProgram();
+
 }
diff --git a/scope4m/src/test/java/org/jmodelica/ForbiddenShadowTest.java b/scope4m/src/test/java/org/jmodelica/ForbiddenShadowTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..6de2d107302da49664d2da3575bd58d533842255
--- /dev/null
+++ b/scope4m/src/test/java/org/jmodelica/ForbiddenShadowTest.java
@@ -0,0 +1,19 @@
+package org.jmodelica;
+
+import org.jmodelica.compiler.AbstractFinding;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+public class ForbiddenShadowTest extends ScopeAnalysisTest {
+
+  @Test
+  void test() {
+
+    ScopeAnalysis scopeAnalysis = new ScopeAnalysis();
+    Set<AbstractFinding> findings = scopeAnalysis.analyze("src/test/resources/forbiddenshadowing/", true, false);
+
+
+  }
+
+}
diff --git a/scope4m/src/test/java/org/jmodelica/MultipleInheritanceTest.java b/scope4m/src/test/java/org/jmodelica/MultipleInheritanceTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b8db94c3a792c43a2fe52299cdc8b1c733b54756
--- /dev/null
+++ b/scope4m/src/test/java/org/jmodelica/MultipleInheritanceTest.java
@@ -0,0 +1,19 @@
+package org.jmodelica;
+
+import org.jmodelica.compiler.AbstractFinding;
+import org.junit.jupiter.api.Test;
+
+import java.util.Set;
+
+public class MultipleInheritanceTest extends ScopeAnalysisTest {
+
+  @Test
+  void test() {
+
+    ScopeAnalysis scopeAnalysis = new ScopeAnalysis();
+    Set<AbstractFinding> findings = scopeAnalysis.analyze("src/test/resources/forbiddenshadowing/", true, false);
+
+
+  }
+
+}
diff --git a/scope4m/src/test/resources/forbiddenshadowing/shadowing.mo b/scope4m/src/test/resources/forbiddenshadowing/shadowing.mo
new file mode 100644
index 0000000000000000000000000000000000000000..66dd99a31814df16393a3db7a11a98352d392f74
--- /dev/null
+++ b/scope4m/src/test/resources/forbiddenshadowing/shadowing.mo
@@ -0,0 +1,27 @@
+within ModelicaCompliance.Scoping.NameLookup.Simple;
+
+
+model EnclosingClassLookupShadowedConstant
+  extends Icons.TestCase;
+
+  constant Real x = 4.0;
+
+  model A
+    Real x = 3.0;
+
+    model B
+      Real y = x;
+    end B;
+
+    B b;
+  end A;
+
+  A a;
+
+  annotation (
+    __ModelicaAssociation(TestCase(shouldPass = false, section = {"5.3.1"})),
+    experiment(StopTime = 0.01),
+    Documentation(
+    info = "<html>Tests that variables found in an enclosing scope must be
+      declared constant, even if there is a constant in a more outer scope.</html>"));
+end EnclosingClassLookupShadowedConstant;
diff --git a/scope4m/src/test/resources/multipleInheritance/inheritance.mo b/scope4m/src/test/resources/multipleInheritance/inheritance.mo
new file mode 100644
index 0000000000000000000000000000000000000000..412c20cbe53c27d27eba8958b95dafd3a9f043d3
--- /dev/null
+++ b/scope4m/src/test/resources/multipleInheritance/inheritance.mo
@@ -0,0 +1,24 @@
+within ModelicaCompliance.Inheritance.Flattening;
+
+model MultipleInheritance
+  extends Icons.TestCase;
+
+  model A
+    Real x = 2;
+  end A;
+
+  model B
+    Real y = 3;
+  end B;
+
+  extends A;
+  extends B;
+
+  Real z = x + y;
+equation
+  annotation (
+    __ModelicaAssociation(TestCase(shouldPass = true, section = {"7.1.1"})),
+    experiment(StopTime = 0.01),
+    Documentation(
+    info = "<html>Tests that multiple inheritance works.</html>"));
+end MultipleInheritance;