diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py
index d5bd4bb7112c654b11b0939957814e4cb4d02211..1470ea035d615c35e6fddb7cd824d3a922f96ea0 100644
--- a/lib/spack/spack/cmd/common/arguments.py
+++ b/lib/spack/spack/cmd/common/arguments.py
@@ -89,3 +89,11 @@ def _specs(self, **kwargs):
 _arguments['dirty'] = Args(
     '--dirty', action='store_true', dest='dirty',
     help='Do NOT clean environment before installing.')
+
+_arguments['long'] = Args(
+    '-l', '--long', action='store_true',
+    help='Show dependency hashes as well as versions.')
+
+_arguments['very_long'] = Args(
+    '-L', '--very-long', action='store_true',
+    help='Show full dependency hashes as well as versions.')
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 29bf263f51fd5f9f6a579cbc75aace0bd19f8f15..27949ef5db2478291e0ba7f51b0595ea760c4cb3 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -52,14 +52,8 @@ def setup_parser(subparser):
         const='deps',
         help='Show full dependency DAG of installed packages')
 
-    subparser.add_argument('-l', '--long',
-                           action='store_true',
-                           dest='long',
-                           help='Show dependency hashes as well as versions.')
-    subparser.add_argument('-L', '--very-long',
-                           action='store_true',
-                           dest='very_long',
-                           help='Show dependency hashes as well as versions.')
+    arguments.add_common_arguments(subparser, ['long', 'very_long'])
+
     subparser.add_argument('-f', '--show-flags',
                            action='store_true',
                            dest='show_flags',
diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py
index 6e6d1c1277e75f960fd4126bf3d0d04f1f2b54d4..0a6fb330acd60747cf06be4e4ea8b69033873445 100644
--- a/lib/spack/spack/cmd/spec.py
+++ b/lib/spack/spack/cmd/spec.py
@@ -23,36 +23,57 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import argparse
-import spack.cmd
 
 import spack
+import spack.cmd
+import spack.cmd.common.arguments as arguments
 
 description = "print out abstract and concrete versions of a spec."
 
 
 def setup_parser(subparser):
-    subparser.add_argument('-i', '--ids', action='store_true',
-                           help="show numerical ids for dependencies.")
+    arguments.add_common_arguments(subparser, ['long', 'very_long'])
+    subparser.add_argument(
+        '-y', '--yaml', action='store_true', default=False,
+        help='Print concrete spec as YAML.')
+    subparser.add_argument(
+        '-c', '--cover', action='store',
+        default='nodes', choices=['nodes', 'edges', 'paths'],
+        help='How extensively to traverse the DAG. (default: nodes).')
+    subparser.add_argument(
+        '-I', '--install-status', action='store_true', default=False,
+        help='Show install status of packages.  Packages can be: '
+             'installed [+], missing and needed by an installed package [-], '
+             'or not installed (no annotation).')
     subparser.add_argument(
         'specs', nargs=argparse.REMAINDER, help="specs of packages")
 
 
 def spec(parser, args):
-    kwargs = {'ids': args.ids,
-              'indent': 2,
-              'color': True}
+    kwargs = {'color': True,
+              'cover': args.cover,
+              'install_status': args.install_status,
+              'hashes': args.long or args.very_long,
+              'hashlen': None if args.very_long else 7}
 
     for spec in spack.cmd.parse_specs(args.specs):
+        # With -y, just print YAML to output.
+        if args.yaml:
+            spec.concretize()
+            print spec.to_yaml()
+            continue
+
+        # Print some diagnostic info by default.
         print "Input spec"
-        print "------------------------------"
+        print "--------------------------------"
         print spec.tree(**kwargs)
 
         print "Normalized"
-        print "------------------------------"
+        print "--------------------------------"
         spec.normalize()
         print spec.tree(**kwargs)
 
         print "Concretized"
-        print "------------------------------"
+        print "--------------------------------"
         spec.concretize()
         print spec.tree(**kwargs)
diff --git a/lib/spack/spack/spec.py b/lib/spack/spack/spec.py
index cbcb2199f64125dc14e7a56a67587e04561d56c7..f830b73fa0c1944285aca44a73bacec0f191b14e 100644
--- a/lib/spack/spack/spec.py
+++ b/lib/spack/spack/spec.py
@@ -2396,12 +2396,24 @@ def __cmp__(self, other):
     def __str__(self):
         return self.format() + self.dep_string()
 
+    def _install_status(self):
+        """Helper for tree to print DB install status."""
+        if not self.concrete:
+            return None
+        try:
+            record = spack.store.db.get_record(self)
+            return record.installed
+        except KeyError:
+            return None
+
     def tree(self, **kwargs):
         """Prints out this spec and its dependencies, tree-formatted
            with indentation."""
         color = kwargs.pop('color', False)
         depth = kwargs.pop('depth', False)
-        showid = kwargs.pop('ids',   False)
+        hashes = kwargs.pop('hashes', True)
+        hlen = kwargs.pop('hashlen', None)
+        install_status = kwargs.pop('install_status', True)
         cover = kwargs.pop('cover', 'nodes')
         indent = kwargs.pop('indent', 0)
         fmt = kwargs.pop('format', '$_$@$%@+$+$=')
@@ -2410,8 +2422,6 @@ def tree(self, **kwargs):
         check_kwargs(kwargs, self.tree)
 
         out = ""
-        cur_id = 0
-        ids = {}
         for d, node in self.traverse(
                 order='pre', cover=cover, depth=True, deptypes=deptypes):
             if prefix is not None:
@@ -2419,11 +2429,17 @@ def tree(self, **kwargs):
             out += " " * indent
             if depth:
                 out += "%-4d" % d
-            if not id(node) in ids:
-                cur_id += 1
-                ids[id(node)] = cur_id
-            if showid:
-                out += "%-4d" % ids[id(node)]
+            if install_status:
+                status = node._install_status()
+                if status is None:
+                    out += "     "  # Package isn't installed
+                elif status:
+                    out += colorize("@g{[+]}  ", color=color)  # installed
+                else:
+                    out += colorize("@r{[-]}  ", color=color)  # missing
+
+            if hashes:
+                out += colorize('@K{%s}  ', color=color) % node.dag_hash(hlen)
             out += ("    " * d)
             if d > 0:
                 out += "^"
diff --git a/lib/spack/spack/test/spack_yaml.py b/lib/spack/spack/test/spack_yaml.py
index 30ed1672e232823bb4f3965ec6205faeedc45448..fbbb7b8e6056d6e49a033b78866d1cc2a90ea855 100644
--- a/lib/spack/spack/test/spack_yaml.py
+++ b/lib/spack/spack/test/spack_yaml.py
@@ -90,3 +90,19 @@ def check(obj, start_line, end_line):
         check(self.data['config_file']['some_list'][2],   8,  8)
         check(self.data['config_file']['another_list'],  10, 10)
         check(self.data['config_file']['some_key'],      11, 11)
+
+    def test_yaml_aliases(self):
+        aliased_list_1 = ['foo']
+        aliased_list_2 = []
+        dict_with_aliases = {
+            'a': aliased_list_1,
+            'b': aliased_list_1,
+            'c': aliased_list_1,
+            'd': aliased_list_2,
+            'e': aliased_list_2,
+            'f': aliased_list_2,
+        }
+        string = syaml.dump(dict_with_aliases)
+
+        # ensure no YAML aliases appear in syaml dumps.
+        self.assertFalse('*id' in string)
diff --git a/lib/spack/spack/util/spack_yaml.py b/lib/spack/spack/util/spack_yaml.py
index 674c79bca1d2847714d27088408c79da22b7cc4e..c27db520663aacd2877ba7fe4a40712bc40b6e7c 100644
--- a/lib/spack/spack/util/spack_yaml.py
+++ b/lib/spack/spack/util/spack_yaml.py
@@ -202,6 +202,11 @@ def represent_mapping(self, tag, mapping, flow_style=None):
                 node.flow_style = best_style
         return node
 
+    def ignore_aliases(self, _data):
+        """Make the dumper NEVER print YAML aliases."""
+        return True
+
+
 # Make our special objects look like normal YAML ones.
 OrderedLineDumper.add_representer(syaml_dict, OrderedLineDumper.represent_dict)
 OrderedLineDumper.add_representer(syaml_list, OrderedLineDumper.represent_list)