diff --git a/src/mio.py b/src/mio.py
index a64ac6a1d18cac0a48dc74174ef597e6197a4be1..4ac6fd9c2366d605c30b4fe4adae776effa9cc86 100755
--- a/src/mio.py
+++ b/src/mio.py
@@ -114,6 +114,10 @@ if __name__ == '__main__':
                          action="append", default=[],
                          metavar="XML",
                          help="list files reachable from XML")
+    optParser.add_option("--reachable-rpms",
+                         action="append", default=[],
+                         metavar="XML",
+                         help="list RPMs reachable from XML")
     optParser.add_option("--test",
                          action="append", default=[],
                          metavar="TARGET",
@@ -212,6 +216,43 @@ if __name__ == '__main__':
             pass
         pass
 
+    if options.reachable_rpms:
+        # List all RPMs reachable from the given source files
+        reachable_rules = mio.repository.Repository(find_and_parse,
+                                                    lambda x:x.startswith('@'))
+        for url in options.reachable_rpms:
+            parse(url, reachable_rules)
+            pass
+        
+        error = {}
+        log(VERBOSE, "Reachable targets:")
+        rpms = {}
+        for g in reachable_rules.get_all(error):
+            installer = mio.installer.Installer(reachable_rules)
+            log(VERBOSE, "Scanning: %s" % g.name[0])
+            installer.add_group(g.name[0])
+            for r in installer.rpm:
+                rpms[r.name] = r.name
+                pass
+            pass
+        
+        if not error:
+            keys = rpms.keys()
+            keys.sort()
+            for k in keys:
+                print k
+            pass
+        else:
+            for e in error:
+                print "Unresolved group: '%s'" % e
+                for r in error[e]:
+                    print "  from: '%s' in %s:%s" % (r.name[0],
+                                                     r._url, r._line)
+                    pass
+                pass
+            pass
+        pass
+
     if options.test:
         installer = mio.installer.Installer(rules)
         for g in options.test:
diff --git a/src/mio/exception.py b/src/mio/exception.py
index 34a79af4ccc98f08c0cc80f789943e6a77418673..fc3efbaf6d421d1352589ca2560b196f131b3ab1 100755
--- a/src/mio/exception.py
+++ b/src/mio/exception.py
@@ -78,6 +78,14 @@ class TargetException(MioException):
                               "Excludes differ for '%s'" % group_1.name,
                               [(group_1.decl, details)])
 
+class SymlinkValueException(InstallerException):
+    def __init__(self, decl_1, decl_2):
+        self._1 = decl_1
+        self._2 = decl_2
+        self.value_1 = "'%s'" % (decl_1.decl.value[0:] or "")
+        self.value_2 = "'%s'" % (decl_2.decl.value[0:] or "")
+
+
 class BadExclude(MioException):
     def __init__(self, key, decl):
         MioException.__init__(self, "Illegal exclude", [(decl, key)])