diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py
index 537db536ddd8954171205fa88382b1c8e6289981..b96ac5af510a1f46c1aa3bea5692e00fb6f110e1 100644
--- a/lib/spack/spack/cmd/__init__.py
+++ b/lib/spack/spack/cmd/__init__.py
@@ -121,3 +121,18 @@ def elide_list(line_list, max_num=10):
         return line_list[:max_num-1] + ['...'] + line_list[-1:]
     else:
         return line_list
+
+
+def disambiguate_spec(spec):
+    matching_specs = spack.db.get_installed(spec)
+    if not matching_specs:
+        tty.die("Spec '%s' matches no installed packages." % spec)
+
+    elif len(matching_specs) > 1:
+        args =  ["%s matches multiple packages." % spec,
+                 "Matching packages:"]
+        args += ["  " + str(s) for s in matching_specs]
+        args += ["Use a more specific spec."]
+        tty.die(*args)
+
+    return matching_specs[0]
diff --git a/lib/spack/spack/cmd/location.py b/lib/spack/spack/cmd/location.py
index 509c336b69da2d2467f4a52a231a9968238e38a5..810c34d0a617a123ca1655eec18f6e5fb0cb93d1 100644
--- a/lib/spack/spack/cmd/location.py
+++ b/lib/spack/spack/cmd/location.py
@@ -77,37 +77,30 @@ def location(parser, args):
             tty.die("You must supply a spec.")
         if len(specs) != 1:
             tty.die("Too many specs.  Supply only one.")
-        spec = specs[0]
 
         if args.install_dir:
             # install_dir command matches against installed specs.
-            matching_specs = spack.db.get_installed(spec)
-            if not matching_specs:
-                tty.die("Spec '%s' matches no installed packages." % spec)
+            spec = spack.cmd.disambiguate_spec(specs[0])
+            print spec.prefix
 
-            elif len(matching_specs) > 1:
-                args =  ["%s matches multiple packages." % spec,
-                         "Matching packages:"]
-                args += ["  " + str(s) for s in matching_specs]
-                args += ["Use a more specific spec."]
-                tty.die(*args)
+        else:
+            spec = specs[0]
 
-            print matching_specs[0].prefix
+            if args.package_dir:
+                # This one just needs the spec name.
+                print join_path(spack.db.root, spec.name)
 
-        elif args.package_dir:
-            # This one just needs the spec name.
-            print join_path(spack.db.root, spec.name)
+            else:
+                # These versions need concretized specs.
+                spec.concretize()
+                pkg = spack.db.get(spec)
+
+                if args.stage_dir:
+                    print pkg.stage.path
+
+                else:  #  args.build_dir is the default.
+                    if not pkg.stage.source_path:
+                        tty.die("Build directory does not exist yet. Run this to create it:",
+                                "spack stage " + " ".join(args.spec))
+                    print pkg.stage.source_path
 
-        else:
-            # These versions need concretized specs.
-            spec.concretize()
-            pkg = spack.db.get(spec)
-
-            if args.stage_dir:
-                print pkg.stage.path
-
-            else:  #  args.build_dir is the default.
-                if not pkg.stage.source_path:
-                    tty.die("Build directory does not exist yet. Run this to create it:",
-                            "spack stage " + " ".join(args.spec))
-                print pkg.stage.source_path
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index e787c460ad31325deeed0586617a5a87c83eecdc..0962942f4376cf733209b5f4b340e01abdd5e2aa 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -65,7 +65,6 @@ def uninstall(parser, args):
                      "  b) use a more specific spec."]
             tty.die(*args)
 
-
         if len(matching_specs) == 0:
             tty.die("%s does not match any installed packages." % spec)
 
diff --git a/lib/spack/spack/hooks/extensions.py b/lib/spack/spack/hooks/extensions.py
index 444472bffa1abc267343699489c5db28375ec585..2cf506beed6acc4d7ccd2d811fac19e07e546347 100644
--- a/lib/spack/spack/hooks/extensions.py
+++ b/lib/spack/spack/hooks/extensions.py
@@ -27,23 +27,12 @@
 
 
 def post_install(pkg):
-    assert(pkg.spec.concrete)
-    for name, spec in pkg.extendees.items():
-        ext = pkg.spec[name]
-        epkg = ext.package
-        if epkg.installed:
-            epkg.do_activate(pkg)
+    pkg.do_activate()
 
 
 def pre_uninstall(pkg):
-    assert(pkg.spec.concrete)
-
     # Need to do this b/c uninstall does not automatically do it.
     # TODO: store full graph info in stored .spec file.
     pkg.spec.normalize()
 
-    for name, spec in pkg.extendees.items():
-        ext = pkg.spec[name]
-        epkg = ext.package
-        if epkg.installed:
-            epkg.do_deactivate(pkg)
+    pkg.do_deactivate()
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index 8504b96fcf5cd27571b5dbac2f26e83b0027f2a1..ae34f8ae455fb0705bcda210c0280c150d850b25 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -315,15 +315,18 @@ class SomePackage(Package):
     """Specs of virtual packages provided by this package, keyed by name."""
     provided = {}
 
-    """Specs of packages this one extends, keyed by name."""
-    extendees = {}
-
     """Specs of conflicting packages, keyed by name. """
     conflicted = {}
 
     """Patches to apply to newly expanded source, if any."""
     patches = {}
 
+    """Specs of package this one extends, or None.
+
+    Currently, ppackages can extend at most one other package.
+    """
+    extendees = {}
+
     #
     # These are default values for instance variables.
     #
@@ -402,8 +405,8 @@ def ensure_has_dict(attr_name):
         self._fetch_time = 0.0
         self._total_time = 0.0
 
-        for name, spec in self.extendees.items():
-            spack.db.get(spec)._check_extendable()
+        if self.is_extension:
+            spack.db.get(self.extendee_spec)._check_extendable()
 
 
     @property
@@ -491,6 +494,34 @@ def fetcher(self, f):
         self._fetcher = f
 
 
+    @property
+    def extendee_spec(self):
+        """Spec of the extendee of this package, or None if it is not an extension."""
+        if not self.extendees:     return None
+
+        name = next(iter(self.extendees))
+        if not name in self.spec:
+            return self.extendees[name]
+
+        # Need to do this to get the concrete version of the spec
+        return self.spec[name]
+
+
+    @property
+    def is_extension(self):
+        return len(self.extendees) > 0
+
+
+    @property
+    def activated(self):
+        if not self.spec.concrete:
+            raise ValueError("Only concrete package extensions can be activated.")
+        if not self.is_extension:
+            raise ValueError("is_extension called on package that is not an extension.")
+
+        return self.spec in spack.install_layout.get_extensions(self.extendee_spec)
+
+
     def preorder_traversal(self, visited=None, **kwargs):
         """This does a preorder traversal of the package's dependence DAG."""
         virtual = kwargs.get("virtual", False)
@@ -784,10 +815,9 @@ def do_install(self, **kwargs):
                 build_env.setup_package(self)
 
                 # Allow extendees to further set up the environment.
-                for ext_name in self.extendees:
-                    ext_spec = self.spec[ext_name]
-                    ext_spec.package.setup_extension_environment(
-                        self.module, ext_spec, self.spec)
+                if self.is_extension:
+                    self.extendee_spec.package.setup_extension_environment(
+                        self.module, self.extendee_spec, self.spec)
 
                 if fake_install:
                     self.do_fake_install()
@@ -840,7 +870,6 @@ def do_install(self, **kwargs):
         if returncode != 0:
             sys.exit(1)
 
-
         # Once everything else is done, run post install hooks
         spack.hooks.post_install(self)
 
@@ -919,25 +948,30 @@ def _check_extendable(self):
             raise ValueError("Package %s is not extendable!" % self.name)
 
 
-    def _sanity_check_extension(self, extension):
-        self._check_extendable()
-        if not self.installed:
+    def _sanity_check_extension(self):
+        extendee_package = self.extendee_spec.package
+        extendee_package._check_extendable()
+
+        if not extendee_package.installed:
             raise ValueError("Can only (de)activate extensions for installed packages.")
-        if not extension.installed:
+        if not self.installed:
             raise ValueError("Extensions must first be installed.")
-        if not self.name in extension.extendees:
-            raise ValueError("%s does not extend %s!" % (extension.name, self.name))
-        if not self.spec.satisfies(extension.extendees[self.name]):
-            raise ValueError("%s does not satisfy %s!" % (self.spec, extension.spec))
+        if not self.extendee_spec.name in self.extendees:
+            raise ValueError("%s does not extend %s!" % (self.name, self.extendee.name))
+
 
+    def do_activate(self):
+        """Called on an etension to invoke the extendee's activate method.
 
-    def do_activate(self, extension):
-        self._sanity_check_extension(extension)
+        Commands should call this routine, and should not call
+        activate() directly.
+        """
+        self._sanity_check_extension()
+        self.extendee_spec.package.activate(self)
 
-        self.activate(extension)
-        spack.install_layout.add_extension(self.spec, extension.spec)
+        spack.install_layout.add_extension(self.extendee_spec, self.spec)
         tty.msg("Activated extension %s for %s."
-                % (extension.spec.short_spec, self.spec.short_spec))
+                % (self.spec.short_spec, self.extendee_spec.short_spec))
 
 
     def activate(self, extension):
@@ -957,20 +991,19 @@ def activate(self, extension):
         tree.merge(self.prefix, ignore=spack.install_layout.hidden_file_paths)
 
 
-    def do_deactivate(self, extension):
-        self._sanity_check_extension(extension)
-        self.deactivate(extension)
+    def do_deactivate(self):
+        self._sanity_check_extension()
+        self.extendee_spec.package.deactivate(self)
 
-        ext = extension.spec
-        if ext in spack.install_layout.get_extensions(self.spec):
-            spack.install_layout.remove_extension(self.spec, ext)
+        if self.spec in spack.install_layout.get_extensions(self.extendee_spec):
+            spack.install_layout.remove_extension(self.extendee_spec, self.spec)
 
         tty.msg("Deactivated extension %s for %s."
-                % (extension.spec.short_spec, self.spec.short_spec))
+                % (self.spec.short_spec, self.extendee_spec.short_spec))
 
 
     def deactivate(self, extension):
-        """Unlinks all files from extension out of extendee's install dir.
+        """Unlinks all files from extension out of this package's install dir.
 
         Package authors can override this method to support other
         extension mechanisms.  Spack internals (commands, hooks, etc.)
@@ -980,8 +1013,6 @@ def deactivate(self, extension):
         """
         tree = LinkTree(extension.prefix)
         tree.unmerge(self.prefix, ignore=spack.install_layout.hidden_file_paths)
-        tty.msg("Deactivated %s as extension of %s."
-                % (extension.spec.short_spec, self.spec.short_spec))
 
 
     def do_clean(self):
diff --git a/lib/spack/spack/packages.py b/lib/spack/spack/packages.py
index db43d3909adc3eb78d347f2d5fe71bcdd873f02f..bb5a94bcab95ad1715ddd745026de2cb8866de9c 100644
--- a/lib/spack/spack/packages.py
+++ b/lib/spack/spack/packages.py
@@ -77,6 +77,8 @@ def get(self, spec, **kwargs):
                 copy = spec.copy()
                 self.instances[copy] = package_class(copy)
             except Exception, e:
+                if spack.debug:
+                    sys.excepthook(*sys.exc_info())
                 raise FailedConstructorError(spec.name, e)
 
         return self.instances[spec]
diff --git a/lib/spack/spack/relations.py b/lib/spack/spack/relations.py
index 17bec1664f63fbc0187194b37020ffa11b53ef33..60ff5bef34eee4b2c8789948d61a854e6887a982 100644
--- a/lib/spack/spack/relations.py
+++ b/lib/spack/spack/relations.py
@@ -131,6 +131,8 @@ def extends(*specs):
     clocals = caller_locals()
     dependencies = clocals.setdefault('dependencies', {})
     extendees = clocals.setdefault('extendees', {})
+    if extendees:
+        raise RelationError("Packages can extend at most one other package.")
 
     for string in specs:
         for spec in spack.spec.parse(string):