diff --git a/lib/spack/spack/build_environment.py b/lib/spack/spack/build_environment.py
index 70b5c89411b381cd136fcacd5c8d13889a4da370..5e8c52cb3ca20edb0373b0b64583e27e9885aa67 100644
--- a/lib/spack/spack/build_environment.py
+++ b/lib/spack/spack/build_environment.py
@@ -221,3 +221,8 @@ def setup_package(pkg):
     set_compiler_environment_variables(pkg)
     set_build_environment_variables(pkg)
     set_module_variables_for_package(pkg)
+
+    # Allow dependencies to set up environment as well.
+    for dep_spec in pkg.spec.traverse(root=False):
+        dep_spec.package.setup_dependent_environment(
+            pkg.module, dep_spec, pkg.spec)
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index 79dd91c5bf3de853e2ff72edf1baf9df090d4e6f..ec3b221988aaef5cabf5f72626beca3802b9248a 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -23,6 +23,7 @@
 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from external import argparse
+import subprocess
 
 import llnl.util.tty as tty
 
diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
index f6ccd7b5151e6620b1c4f21080c7e7e45950e354..ae73d8ac55328c9f40739c300740f74fdaca6978 100644
--- a/lib/spack/spack/cmd/extensions.py
+++ b/lib/spack/spack/cmd/extensions.py
@@ -75,14 +75,15 @@ def extensions(parser, args):
     if not extensions:
         tty.msg("%s has no extensions." % spec.cshort_spec)
         return
-    tty.msg("%s extensions:" % spec.cshort_spec)
+    tty.msg(spec.cshort_spec)
+    tty.msg("%d extensions:" % len(extensions))
     colify(ext.name for ext in extensions)
 
     # List specs of installed extensions.
     installed  = [s.spec for s in spack.db.installed_extensions_for(spec)]
     print
     if not installed:
-        tty.msg("None activated.")
+        tty.msg("None installed.")
         return
     tty.msg("%d installed:" % len(installed))
     spack.cmd.find.display_specs(installed, mode=args.mode)
@@ -93,5 +94,5 @@ def extensions(parser, args):
     if not activated:
         tty.msg("None activated.")
         return
-    tty.msg("%d currently activated:" % len(exts))
-    spack.cmd.find.display_specs(installed, mode=args.mode)
+    tty.msg("%d currently activated:" % len(activated))
+    spack.cmd.find.display_specs(activated, mode=args.mode)
diff --git a/lib/spack/spack/directory_layout.py b/lib/spack/spack/directory_layout.py
index efc40a17a4f07ea7ab2ac3d03b2fabaf4e832716..37740720a205a3e4bb3afc8c2d9679353f38f767 100644
--- a/lib/spack/spack/directory_layout.py
+++ b/lib/spack/spack/directory_layout.py
@@ -109,12 +109,17 @@ def path_for_spec(self, spec):
 
 
     def remove_path_for_spec(self, spec):
-        """Removes a prefix and any empty parent directories from the root."""
+        """Removes a prefix and any empty parent directories from the root.
+           Raised RemoveFailedError if something goes wrong.
+        """
         path = self.path_for_spec(spec)
         assert(path.startswith(self.root))
 
         if os.path.exists(path):
-            shutil.rmtree(path, True)
+            try:
+                shutil.rmtree(path)
+            except exceptions.OSError, e:
+                raise RemoveFailedError(spec, path, e)
 
         path = os.path.dirname(path)
         while path != self.root:
@@ -330,6 +335,15 @@ def __init__(self, installed_spec, new_spec):
             % installed_spec, new_spec)
 
 
+class RemoveFailedError(DirectoryLayoutError):
+    """Raised when a DirectoryLayout cannot remove an install prefix."""
+    def __init__(self, installed_spec, prefix, error):
+        super(RemoveFailedError, self).__init__(
+            'Could not remove prefix %s for %s : %s'
+            % prefix, installed_spec.short_spec, error)
+        self.cause = error
+
+
 class InconsistentInstallDirectoryError(DirectoryLayoutError):
     """Raised when a package seems to be installed to the wrong place."""
     def __init__(self, message):
@@ -370,3 +384,5 @@ def __init__(self, spec, extension_spec):
         super(NoSuchExtensionError, self).__init__(
             "%s cannot be removed from %s because it's not installed."% (
                 extension_spec.short_spec, spec.short_spec))
+
+
diff --git a/lib/spack/spack/hooks/extensions.py b/lib/spack/spack/hooks/extensions.py
index 718b24b9655d0d41f382ea2ea7ad3a215c4eb09c..9d6fa23d03467d925d202a4974aa48e89024e55c 100644
--- a/lib/spack/spack/hooks/extensions.py
+++ b/lib/spack/spack/hooks/extensions.py
@@ -26,15 +26,11 @@
 import spack
 
 
-def post_install(pkg):
-    if pkg.is_extension:
-        pkg.do_activate()
-
-
 def pre_uninstall(pkg):
     # Need to do this b/c uninstall does not automatically do it.
     # TODO: store full graph info in stored .spec file.
     pkg.spec.normalize()
 
     if pkg.is_extension:
-        pkg.do_deactivate()
+        if pkg.activated:
+            pkg.do_deactivate()
diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py
index b90596854054e41e8c8ffca3438916f4f7350a42..b18d0549901b0f207adfbe4a5e0e677c57d2684a 100644
--- a/lib/spack/spack/package.py
+++ b/lib/spack/spack/package.py
@@ -829,11 +829,6 @@ def do_install(self, **kwargs):
                 self.stage.chdir_to_source()
                 build_env.setup_package(self)
 
-                # Allow extendees to further set up the environment.
-                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()
                 else:
@@ -910,8 +905,8 @@ def module(self):
                           fromlist=[self.__class__.__name__])
 
 
-    def setup_extension_environment(self, module, spec, ext_spec):
-        """Called before the install() method of extensions.
+    def setup_dependent_environment(self, module, spec, dependent_spec):
+        """Called before the install() method of dependents.
 
         Default implementation does nothing, but this can be
         overridden by an extendable package to set up the install
@@ -930,6 +925,8 @@ def setup_extension_environment(self, module, spec, ext_spec):
            put a 'python' Execuable object in the module scope for the
            extension package to simplify extension installs.
 
+        3. A lot of Qt extensions need QTDIR set.  This can be used to do that.
+
         """
         pass
 
diff --git a/var/spack/packages/geos/package.py b/var/spack/packages/geos/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..4a2657e32f21b5e60048df62f9b9eee94193a536
--- /dev/null
+++ b/var/spack/packages/geos/package.py
@@ -0,0 +1,31 @@
+from spack import *
+
+class Geos(Package):
+    """GEOS (Geometry Engine - Open Source) is a C++ port of the Java
+       Topology Suite (JTS). As such, it aims to contain the complete
+       functionality of JTS in C++. This includes all the OpenGIS
+       Simple Features for SQL spatial predicate functions and spatial
+       operators, as well as specific JTS enhanced topology functions."""
+
+    homepage = "http://trac.osgeo.org/geos/"
+    url      = "http://download.osgeo.org/geos/geos-3.4.2.tar.bz2"
+
+    version('3.4.2', 'fc5df2d926eb7e67f988a43a92683bae')
+    version('3.4.1', '4c930dec44c45c49cd71f3e0931ded7e')
+    version('3.4.0', 'e41318fc76b5dc764a69d43ac6b18488')
+    version('3.3.9', '4794c20f07721d5011c93efc6ccb8e4e')
+    version('3.3.8', '75be476d0831a2d14958fed76ca266de')
+    version('3.3.7', '95ab996d22672b067d92c7dee2170460')
+    version('3.3.6', '6fadfb941541875f4976f75fb0bbc800')
+    version('3.3.5', '2ba61afb7fe2c5ddf642d82d7b16e75b')
+    version('3.3.4', '1bb9f14d57ef06ffa41cb1d67acb55a1')
+    version('3.3.3', '8454e653d7ecca475153cc88fd1daa26')
+
+    extends('python')
+    depends_on('swig')
+
+    def install(self, spec, prefix):
+        configure("--prefix=%s" % prefix,
+                  "--enable-python")
+        make()
+        make("install")
diff --git a/var/spack/packages/py-basemap/package.py b/var/spack/packages/py-basemap/package.py
index 7b6d8e7e657d943a0bb41dee8c7f369c9c8c64cd..45f1085ba1ad98aafbd81619c3ccd95a53613784 100644
--- a/var/spack/packages/py-basemap/package.py
+++ b/var/spack/packages/py-basemap/package.py
@@ -8,18 +8,13 @@ class PyBasemap(Package):
 
     version('1.0.7', '48c0557ced9e2c6e440b28b3caff2de8')
 
-    geos_version = {'1.0.7' : '3.3.3'}
-
     extends('python')
     depends_on('py-setuptools')
     depends_on('py-numpy')
     depends_on('py-matplotlib')
     depends_on('py-pil')
+    depends_on("geos")
 
     def install(self, spec, prefix):
-        with working_dir('geos-%s' % self.geos_version[str(self.version)]):
-            configure("--prefix=" + prefix)
-            make()
-            make("install")
-        os.environ['GEOS_DIR'] = prefix
+        env['GEOS_DIR'] = spec['geos'].prefix
         python('setup.py', 'install', '--prefix=%s' % prefix)
diff --git a/var/spack/packages/py-biopython/package.py b/var/spack/packages/py-biopython/package.py
index 2ed04c389e705e04f7fa08b918bc36d456442676..8ecaf486262cf664446dd5a661add8a54d28d5ac 100644
--- a/var/spack/packages/py-biopython/package.py
+++ b/var/spack/packages/py-biopython/package.py
@@ -9,6 +9,7 @@ class PyBiopython(Package):
 
     extends('python')
     depends_on('py-mx')
+    depends_on('py-numpy')
 
     def install(self, spec, prefix):
         python('setup.py', 'install', '--prefix=%s' % prefix)
diff --git a/var/spack/packages/py-gnuplot/package.py b/var/spack/packages/py-gnuplot/package.py
index 0a2c073a491af6aa789d6839756301614baeeb2a..ede4472c03416ed02266a4259b5e7e6a3be6adde 100644
--- a/var/spack/packages/py-gnuplot/package.py
+++ b/var/spack/packages/py-gnuplot/package.py
@@ -8,6 +8,7 @@ class PyGnuplot(Package):
     version('1.8', 'abd6f571e7aec68ae7db90a5217cd5b1')
 
     extends('python')
+    depends_on('py-numpy')
 
     def install(self, spec, prefix):
         python('setup.py', 'install', '--prefix=%s' % prefix)
diff --git a/var/spack/packages/py-libxml2/package.py b/var/spack/packages/py-libxml2/package.py
index 0dcefbd9cf897ba088aec5f663d92b2b49db9d30..e645acb5dd8303180c0773178b93139ed4104ec2 100644
--- a/var/spack/packages/py-libxml2/package.py
+++ b/var/spack/packages/py-libxml2/package.py
@@ -8,6 +8,7 @@ class PyLibxml2(Package):
     version('2.6.21', '229dd2b3d110a77defeeaa73af83f7f3')
 
     extends('python')
+    depends_on('libxml2')
 
     def install(self, spec, prefix):
         python('setup.py', 'install', '--prefix=%s' % prefix)
diff --git a/var/spack/packages/py-matplotlib/package.py b/var/spack/packages/py-matplotlib/package.py
index 5979ceeab0d602cf6c89553b96ff24db5da9daf5..8b8684c5632784b536e2bc80f7fe663185ae8ca9 100644
--- a/var/spack/packages/py-matplotlib/package.py
+++ b/var/spack/packages/py-matplotlib/package.py
@@ -17,9 +17,12 @@ class PyMatplotlib(Package):
     depends_on('py-pytz')
     depends_on('py-nose')
     depends_on('py-numpy')
+    depends_on('qt')
+
 
     def install(self, spec, prefix):
         python('setup.py', 'install', '--prefix=%s' % prefix)
+
         if str(self.version) == '1.4.2':
             # hack to fix configuration file
             config_file = None
diff --git a/var/spack/packages/py-pyside/package.py b/var/spack/packages/py-pyside/package.py
index b01e16d7e6ccf32d6b2a393e71206836ec3df4a0..1fd037d75f560c093911bb3f1a46011a78d4aa6b 100644
--- a/var/spack/packages/py-pyside/package.py
+++ b/var/spack/packages/py-pyside/package.py
@@ -10,9 +10,32 @@ class PyPyside(Package):
     version('1.2.2', 'c45bc400c8a86d6b35f34c29e379e44d')
 
     extends('python')
+    depends_on('py-setuptools')
+    depends_on('qt@:4')
+
+
+    def patch(self):
+        """Undo PySide RPATH handling and add Spack RPATH."""
+        # Add Spack's standard CMake args to the sub-builds.
+        # They're called BY setup.py so we have to patch it.
+        filter_file(
+            r'OPTION_CMAKE,',
+            r'OPTION_CMAKE, ' + (
+                '"-DCMAKE_INSTALL_RPATH_USE_LINK_PATH=FALSE", '
+                '"-DCMAKE_INSTALL_RPATH=%s",' % ':'.join(self.rpath)),
+            'setup.py')
+
+        # PySide tries to patch ELF files to remove RPATHs
+        # Disable this and go with the one we set.
+        filter_file(
+            r'rpath_cmd\(pyside_path, srcpath\)',
+            r'#rpath_cmd(pyside_path, srcpath)',
+            'pyside_postinstall.py')
+
 
     def install(self, spec, prefix):
-        qmake_path = '/usr/lib64/qt4/bin/qmake'
-        if not os.path.exists(qmake_path):
-            raise spack.package.InstallError("Failed to find qmake in %s" % qmake_path)
-        python('setup.py', 'install', '--prefix=%s' % prefix, '--qmake=%s' % qmake_path)
+        python('setup.py', 'install',
+               '--prefix=%s' % prefix,
+               '--jobs=%s' % make_jobs)
+
+
diff --git a/var/spack/packages/py-shiboken/package.py b/var/spack/packages/py-shiboken/package.py
new file mode 100644
index 0000000000000000000000000000000000000000..47abe64e6515567e39be3f7cbedf4bf6fcdceba0
--- /dev/null
+++ b/var/spack/packages/py-shiboken/package.py
@@ -0,0 +1,21 @@
+from spack import *
+
+class PyShiboken(Package):
+    """Shiboken generates bindings for C++ libraries using CPython source code."""
+    homepage = "https://shiboken.readthedocs.org/"
+    url      = "https://pypi.python.org/packages/source/S/Shiboken/Shiboken-1.2.2.tar.gz"
+
+    version('1.2.2', '345cfebda221f525842e079a6141e555')
+
+    # TODO: make build dependency
+    # depends_on("cmake")
+
+    extends('python')
+    depends_on("py-setuptools")
+    depends_on("libxml2")
+    depends_on("qt@:4.8")
+
+    def install(self, spec, prefix):
+        python('setup.py', 'install',
+               '--prefix=%s' % prefix,
+               '--jobs=%s' % make_jobs)
diff --git a/var/spack/packages/python/package.py b/var/spack/packages/python/package.py
index 8a6d574d9b26695ec27105527a6e2a73d026d765..4b3b31eb6bbae6b60325537b765c9b3bf065a702 100644
--- a/var/spack/packages/python/package.py
+++ b/var/spack/packages/python/package.py
@@ -1,9 +1,10 @@
-from spack import *
-import spack
 import os
 import re
 from contextlib import closing
 
+from spack import *
+import spack
+
 
 class Python(Package):
     """The Python programming language."""
@@ -46,7 +47,7 @@ def site_packages_dir(self):
         return os.path.join(self.python_lib_dir, 'site-packages')
 
 
-    def setup_extension_environment(self, module, spec, ext_spec):
+    def setup_dependent_environment(self, module, spec, ext_spec):
         """Called before python modules' install() methods.
 
         In most cases, extensions will only need to have one line::
@@ -60,12 +61,17 @@ def setup_extension_environment(self, module, spec, ext_spec):
         module.python_lib_dir = os.path.join(ext_spec.prefix, self.python_lib_dir)
         module.site_packages_dir = os.path.join(ext_spec.prefix, self.site_packages_dir)
 
-        # Add site packages directory to the PYTHONPATH
-        os.environ['PYTHONPATH'] = module.site_packages_dir
-
         # Make the site packages directory if it does not exist already.
         mkdirp(module.site_packages_dir)
 
+        # Set PYTHONPATH to include site-packages dir for the
+        # extension and any other python extensions it depends on.
+        python_paths = []
+        for d in ext_spec.traverse():
+            if d.package.extends(self.spec):
+                python_paths.append(os.path.join(d.prefix, self.site_packages_dir))
+        os.environ['PYTHONPATH'] = ':'.join(python_paths)
+
 
     # ========================================================================
     # Handle specifics of activating and deactivating python modules.
diff --git a/var/spack/packages/qt/package.py b/var/spack/packages/qt/package.py
index c8b19d07f5c7e94870b16cf4bf574cb250e93293..446f7b67a4428606895419c56a2e2704988f7ec9 100644
--- a/var/spack/packages/qt/package.py
+++ b/var/spack/packages/qt/package.py
@@ -1,3 +1,4 @@
+import os
 from spack import *
 import os
 
@@ -30,7 +31,7 @@ class Qt(Package):
     depends_on("libmng")
     depends_on("jpeg")
 
-     # Webkit
+    # Webkit
     # depends_on("gperf")
     # depends_on("flex")
     # depends_on("bison")
@@ -41,6 +42,12 @@ class Qt(Package):
     depends_on("mesa")
     depends_on("libxcb")
 
+
+    def setup_dependent_environment(self, module, spec, dep_spec):
+        """Dependencies of Qt find it using the QTDIR environment variable."""
+        os.environ['QTDIR'] = self.prefix
+
+
     def patch(self):
         if self.spec.satisfies('@4'):
             qmake_conf = 'mkspecs/common/g++-base.conf'
@@ -56,7 +63,7 @@ def patch(self):
 
 
     def install(self, spec, prefix):
-        # Apparently this is the only way to 
+        # Apparently this is the only way to
         # "truly" get rid of webkit compiles now...
         os.rename("qtwebkit","no-qtwebkit")
         os.rename("qtwebkit-examples","no-qtwebkit-examples")