diff --git a/src/mio.py b/src/mio.py
index 1f239d10f2773f7488a2a0bce8bb75aec25e746b..f749cced0556c61139cf0f82fcc1f015d4c3e28d 100755
--- a/src/mio.py
+++ b/src/mio.py
@@ -8,6 +8,7 @@ import mio.transform
 import mio.parser
 import mio.repository
 import mio.node
+import mio.analyze
 import argparse
 import os
 import os.path
@@ -182,6 +183,10 @@ if __name__ == '__main__':
                            action="append", nargs='*', default=None,
                            metavar="TARGET",
                            help="print dependency tree for TARGET")
+    optParser.add_argument("--dependency-check",
+                           action="append", nargs='*', default=None,
+                           metavar="TARGET",
+                           help="check dependencies for TARGET")
     optParser.add_argument("-v","--verbose",
                            action="count",
                            dest="verbose", default=0,
@@ -310,6 +315,14 @@ if __name__ == '__main__':
             pass
         pass
 
+    if options.dependency_check != None:
+        # Flatten list
+        targets = [i for l in options.dependency_check for i in l ]
+        if len(targets) == 0:
+            tree = parse('hostinfo.xml')
+            targets = [ h.name[0] for h in tree._group_]
+        mio.analyze.dependency_check(rules, options, targets)
+
     if options.dependency_tree != None:
         def dump_tree(name, indent=0):
             def command_or_script(cos, prefix=''):
@@ -317,7 +330,6 @@ if __name__ == '__main__':
                     print("%s  [%s command] %s" % (
                         ('  '*indent, prefix, cos.command[0])))
                     pass
-                pass
                 if cos.script[0] != None:
                     print("%s  [%s script] %s" % (
                         ('  '*indent, prefix, cos.script[0])))
@@ -327,6 +339,7 @@ if __name__ == '__main__':
             tree = rules.get(name)
             for p in tree._pre_:
                 command_or_script(p, 'pre')
+                pass
             if not options.noyum:
                 for r in tree._rpm_:
                     print("%s[r] %s" % ('  '*(indent+1), r.name[0]))
diff --git a/src/mio/analyze.py b/src/mio/analyze.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8b314dfb2819abab5de54d3eedf8f5946525371
--- /dev/null
+++ b/src/mio/analyze.py
@@ -0,0 +1,74 @@
+import os
+import mio.util
+from mio.node import *
+
+def get_dependencies(rules, name, path, dependencies=None, exclude=[]):
+    result = dependencies or dict()
+    if  group_node(name) in exclude:
+        # Exclude this group
+        return result
+    def add_dependency(dest, kind, source=''):
+        if not dest in result:
+            result[dest] = dict()
+            pass
+        if not (kind,source) in result[dest]:
+            result[dest][(kind,source)] = set()
+            pass
+        result[dest][(kind,source)].add(path)
+        pass
+
+    tree = rules.get(name)
+    for s in tree._symlink_:
+        if symlink_node(s.name[0], s) in exclude:
+            # Exclude symlink
+            continue
+        if s.delete[0] == 'yes':
+            add_dependency(s.name[0], 'delete')
+            pass
+        else:
+            add_dependency(s.name[0], 'symlink', s.value[0])
+            pass
+        pass
+    for f in tree._file_:
+        if file_node(f.name[0], f) in exclude:
+            # Exclude file
+            continue
+        if f.delete[0] == 'yes':
+            add_dependency(f.name[0], 'delete')
+            pass
+        elif f.source[0] == '':
+            add_dependency(f.name[0], 'chmod')
+            pass
+        else:
+            src = os.path.normpath('%s/%s' % (f.files[0:],
+                                              f.source[0] or f.name[0]))
+            add_dependency(f.name[0], 'file', src)
+            pass
+        pass
+    for d in tree._dependency_:
+        result = get_dependencies(rules=rules,
+                                  name=d.name[0],
+                                  path=path + (d.name[0],),
+                                  dependencies=result,
+                                  exclude=mio.util.exclusion_closure(
+                                      exclude, d))
+        pass
+    return result
+
+def dependency_check(rules, options, targets):
+    errors = 0
+    for t in targets:
+        dep = get_dependencies(rules, t, (t,))
+        for dk in [ k for k in sorted(dep) if len(dep[k]) > 1 ]:
+            errors += 1
+            print(t)
+            print('  %s' % dk)
+            for sk in sorted(dep[dk]):
+                print('    %s' % str(sk))
+                for p in sorted(dep[dk][sk]):
+                    print('      %s' % str(p))
+            pass
+        pass
+    if errors:
+        raise Exception('Dependency check failed')
+    pass
diff --git a/src/mio/util.py b/src/mio/util.py
index 72202189ebb247c4f0e51398e55eef3cba0489cb..1a09fe712c5f98a026cdb94ad3115e95400ba3bc 100755
--- a/src/mio/util.py
+++ b/src/mio/util.py
@@ -3,6 +3,7 @@ import os
 import pwd
 import re
 from mio.log import log, NORMAL, VERBOSE
+from mio.node import *
 
 try:
     # Python 2
@@ -119,3 +120,23 @@ def owner(decl):
 def group(decl):
     return decl.group[0:]
 
+def exclusion_closure(exclude, target):
+    if not target._exclude_:
+        return exclude
+    else:
+        result = list(exclude) # Create exclusion closure
+        for e in target._exclude_:
+            for (key, value) in e._attribute.items():
+                if key == 'dependency':
+                    result.append(group_node(value))
+                elif key == 'file':
+                    result.append(file_node(value))
+                elif key == 'dir':
+                    result.append(dir_node(value))
+                elif key == 'rpm':
+                    result.append(rpm_node(value))
+                elif key == 'symlink':
+                    result.append(symlink_node(value))
+                else:
+                    raise BadExclude(e, key)
+        return result