diff --git a/AST.py b/AST.py
index c5808276329f955c8c6dae273a0d755b2136651e..45489ad9d141677117ea8bd91094c31ed8b24aca 100644
--- a/AST.py
+++ b/AST.py
@@ -34,6 +34,9 @@ class ASTNode():
     def linkType(self):
         pass
 
+    def checkHierarchy(self):
+        pass
+
     def printNodePretty(self, prefix=0):
         pp = pprint.PrettyPrinter(indent=prefix)
         pp.pprint(self.__class__.__name__)
diff --git a/AstBuilding.py b/AstBuilding.py
index 4422a37b0574e3a3497f77ac4f4b2cbf9be3cbdc..e4c74cd012bc694e71e963f9ece80deacdb7c1e3 100644
--- a/AstBuilding.py
+++ b/AstBuilding.py
@@ -30,6 +30,12 @@ def buildEnvAndLink(ASTs):
         # t[1].buildEnvFromImports(globalEnv)
         t[1].recurseAction("linkType")
 
+    # hierarchy checking
+    print('--------->>> hierarchy checking time!')
+    for t in ASTs:
+        # t[1].buildEnvFromImports(globalEnv)
+        t[1].recurseAction("checkHierarchy")
+
 #######################################################
 
 # # ast: Node
diff --git a/TypeNodes.py b/TypeNodes.py
index c371e2952a88e5412d8e8ff07650762f1ab29f31..2af75cf24e5245ff016dcbd521a7d8dae331e9b9 100644
--- a/TypeNodes.py
+++ b/TypeNodes.py
@@ -66,14 +66,40 @@ class ClassNode(ASTNode):
         # to use: self.env.getNode(name, namespace)
         # print('hello here we go we are in classNode {}'.format(self.name))
         if self.env is not None:
-            if self.superClass is not '':
+            if self.superClass:
                 newSuperClass = self.env.getNode(self.superClass, 'type')
                 self.superClass = newSuperClass
-            if self.superInter is not []:
+            if self.superInter:
                 for (index, inter) in enumerate(self.superInter):
                     newSuperInter = self.env.getNode(inter, 'type')
                     self.superInter[index] = newSuperInter
 
+    def checkHierarchy(self):
+        if self.superClass:
+            # A class must not extend an interface.
+            if isinstance(self.superClass, InterNode):
+                raise Exception("ERROR: Class {} extends interface {}".format(self.name, self.superClass.name))
+            # A class must not extend a final class.
+            if 'final' in self.superClass.mods:
+                raise Exception("ERROR: Class {} extends final class {}".format(self.name, self.superClass.name))
+        # A class must not implement a class.
+        if self.superInter:
+            for inter in self.superInter:
+                if isinstance(inter, ClassNode):
+                    raise Exception("ERROR: Class {} implements class {}".format(self.name, inter.name))
+        
+        # A class or interface must not declare two methods with the same signature (name and parameter types).
+        uniqueMethods = []
+        for method in self.methods:
+            key = (method.name, method.paramTypes)
+            if key in uniqueMethods:
+                raise Exception("ERROR: Class {} declares 2 methods with the same signature {}".format(self.name, key[0]))
+            uniqueMethods.append(key)
+        # A class or interface must not contain (declare or inherit) two methods with the same signature but different return types
+        # A class must not declare two constructors with the same parameter types
+        
+        # A class that contains (declares or inherits) any abstract methods must be abstract.
+
     def getConstructor(self, argTypes):
         for c in self.constructors:
             if c.paramTypes == argTypes:
@@ -113,3 +139,11 @@ class InterNode(ASTNode):
             env.addtoEnv(c)
         self.env = env
         return env
+
+    def linkType(self):
+        # link types to the actual nodes fom the environment (envs already created)
+        if self.env is not None:
+            if self.superInter:
+                for (index, inter) in enumerate(self.superInter):
+                    newSuperInter = self.env.getNode(inter, 'type')
+                    self.superInter[index] = newSuperInter