diff --git a/lib/spack/llnl/util/filesystem.py b/lib/spack/llnl/util/filesystem.py
index ace6cfded6c3b5a03354ceb39625476be66d4c45..40eb6a7aa8ca638904140cd34919fc7ae21341bb 100644
--- a/lib/spack/llnl/util/filesystem.py
+++ b/lib/spack/llnl/util/filesystem.py
@@ -60,7 +60,9 @@
     'fix_darwin_install_name',
     'force_remove',
     'force_symlink',
+    'copy',
     'install',
+    'copy_tree',
     'install_tree',
     'is_exe',
     'join_path',
@@ -264,27 +266,98 @@ def unset_executable_mode(path):
     os.chmod(path, mode)
 
 
-def install(src, dest):
-    """Manually install a file to a particular location."""
-    tty.debug("Installing %s to %s" % (src, dest))
+def copy(src, dest, _permissions=False):
+    """Copies the file *src* to the file or directory *dest*.
+
+    If *dest* specifies a directory, the file will be copied into *dest*
+    using the base filename from *src*.
+
+    Parameters:
+        src (str): the file to copy
+        dest (str): the destination file or directory
+        _permissions (bool): for internal use only
+    """
+    if _permissions:
+        tty.debug('Installing {0} to {1}'.format(src, dest))
+    else:
+        tty.debug('Copying {0} to {1}'.format(src, dest))
 
     # Expand dest to its eventual full path if it is a directory.
     if os.path.isdir(dest):
         dest = join_path(dest, os.path.basename(src))
 
     shutil.copy(src, dest)
-    set_install_permissions(dest)
-    copy_mode(src, dest)
+
+    if _permissions:
+        set_install_permissions(dest)
+        copy_mode(src, dest)
+
+
+def install(src, dest):
+    """Installs the file *src* to the file or directory *dest*.
+
+    Same as :py:func:`copy` with the addition of setting proper
+    permissions on the installed file.
+
+    Parameters:
+        src (str): the file to install
+        dest (str): the destination file or directory
+    """
+    copy(src, dest, _permissions=True)
 
 
-def install_tree(src, dest, **kwargs):
-    """Manually install a directory tree to a particular location."""
-    tty.debug("Installing %s to %s" % (src, dest))
-    shutil.copytree(src, dest, **kwargs)
+def copy_tree(src, dest, symlinks=True, _permissions=False):
+    """Recursively copy an entire directory tree rooted at *src*.
 
-    for s, d in traverse_tree(src, dest, follow_nonexisting=False):
-        set_install_permissions(d)
-        copy_mode(s, d)
+    If the destination directory *dest* does not already exist, it will
+    be created as well as missing parent directories.
+
+    If *symlinks* is true, symbolic links in the source tree are represented
+    as symbolic links in the new tree and the metadata of the original links
+    will be copied as far as the platform allows; if false, the contents and
+    metadata of the linked files are copied to the new tree.
+
+    Parameters:
+        src (str): the directory to copy
+        dest (str): the destination directory
+        symlinks (bool): whether or not to preserve symlinks
+        _permissions (bool): for internal use only
+    """
+    if _permissions:
+        tty.debug('Installing {0} to {1}'.format(src, dest))
+    else:
+        tty.debug('Copying {0} to {1}'.format(src, dest))
+
+    mkdirp(dest)
+
+    for s, d in traverse_tree(src, dest, order='pre', follow_nonexisting=True):
+        if symlinks and os.path.islink(s):
+            # Note that this won't rewrite absolute links into the old
+            # root to point at the new root. Should we handle that case?
+            target = os.readlink(s)
+            os.symlink(os.path.abspath(target), d)
+        elif os.path.isdir(s):
+            mkdirp(d)
+        else:
+            shutil.copyfile(s, d)
+
+        if _permissions:
+            set_install_permissions(d)
+            copy_mode(s, d)
+
+
+def install_tree(src, dest, symlinks=True):
+    """Recursively install an entire directory tree rooted at *src*.
+
+    Same as :py:func:`copy_tree` with the addition of setting proper
+    permissions on the installed files and directories.
+
+    Parameters:
+        src (str): the directory to install
+        dest (str): the destination directory
+        symlinks (bool): whether or not to preserve symlinks
+    """
+    copy_tree(src, dest, symlinks, _permissions=True)
 
 
 def is_exe(path):
diff --git a/lib/spack/spack/test/llnl/util/filesystem.py b/lib/spack/spack/test/llnl/util/filesystem.py
new file mode 100644
index 0000000000000000000000000000000000000000..7701185dbe61598c9ae01781dc2f2deed0fd8035
--- /dev/null
+++ b/lib/spack/spack/test/llnl/util/filesystem.py
@@ -0,0 +1,209 @@
+##############################################################################
+# Copyright (c) 2013-2018, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/spack/spack
+# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+##############################################################################
+"""Tests for ``llnl/util/filesystem.py``"""
+
+import llnl.util.filesystem as fs
+import os
+import pytest
+
+
+@pytest.fixture()
+def stage(tmpdir_factory):
+    """Creates a stage with the directory structure for the tests."""
+
+    s = tmpdir_factory.mktemp('filesystem_test')
+
+    with s.as_cwd():
+        # Create source file hierarchy
+        fs.touchp('source/1')
+        fs.touchp('source/a/b/2')
+        fs.touchp('source/a/b/3')
+        fs.touchp('source/c/4')
+        fs.touchp('source/c/d/5')
+        fs.touchp('source/c/d/6')
+        fs.touchp('source/c/d/e/7')
+
+        # Create symlink
+        os.symlink(os.path.abspath('source/1'), 'source/2')
+
+        # Create destination directory
+        fs.mkdirp('dest')
+
+    yield s
+
+
+class TestCopy:
+    """Tests for ``filesystem.copy``"""
+
+    def test_file_dest(self, stage):
+        """Test using a filename as the destination."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy('source/1', 'dest/1')
+
+            assert os.path.exists('dest/1')
+            assert os.stat('source/1').st_mode == os.stat('dest/1').st_mode
+
+    def test_dir_dest(self, stage):
+        """Test using a directory as the destination."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy('source/1', 'dest')
+
+            assert os.path.exists('dest/1')
+            assert os.stat('source/1').st_mode == os.stat('dest/1').st_mode
+
+
+class TestInstall:
+    """Tests for ``filesystem.install``"""
+
+    def test_file_dest(self, stage):
+        """Test using a filename as the destination."""
+
+        with fs.working_dir(str(stage)):
+            fs.install('source/1', 'dest/1')
+
+            assert os.path.exists('dest/1')
+            assert os.stat('source/1').st_mode == os.stat('dest/1').st_mode
+
+    def test_dir_dest(self, stage):
+        """Test using a directory as the destination."""
+
+        with fs.working_dir(str(stage)):
+            fs.install('source/1', 'dest')
+
+            assert os.path.exists('dest/1')
+            assert os.stat('source/1').st_mode == os.stat('dest/1').st_mode
+
+
+class TestCopyTree:
+    """Tests for ``filesystem.copy_tree``"""
+
+    def test_existing_dir(self, stage):
+        """Test copying to an existing directory."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy_tree('source', 'dest')
+
+            assert os.path.exists('dest/a/b/2')
+
+    def test_non_existing_dir(self, stage):
+        """Test copying to a non-existing directory."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy_tree('source', 'dest/sub/directory')
+
+            assert os.path.exists('dest/sub/directory/a/b/2')
+
+    def test_symlinks_true(self, stage):
+        """Test copying with symlink preservation."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy_tree('source', 'dest', symlinks=True)
+
+            assert os.path.exists('dest/2')
+            assert os.path.islink('dest/2')
+
+    def test_symlinks_false(self, stage):
+        """Test copying without symlink preservation."""
+
+        with fs.working_dir(str(stage)):
+            fs.copy_tree('source', 'dest', symlinks=False)
+
+            assert os.path.exists('dest/2')
+            assert not os.path.islink('dest/2')
+
+
+class TestInstallTree:
+    """Tests for ``filesystem.install_tree``"""
+
+    def test_existing_dir(self, stage):
+        """Test installing to an existing directory."""
+
+        with fs.working_dir(str(stage)):
+            fs.install_tree('source', 'dest')
+
+            assert os.path.exists('dest/a/b/2')
+
+    def test_non_existing_dir(self, stage):
+        """Test installing to a non-existing directory."""
+
+        with fs.working_dir(str(stage)):
+            fs.install_tree('source', 'dest/sub/directory')
+
+            assert os.path.exists('dest/sub/directory/a/b/2')
+
+    def test_symlinks_true(self, stage):
+        """Test installing with symlink preservation."""
+
+        with fs.working_dir(str(stage)):
+            fs.install_tree('source', 'dest', symlinks=True)
+
+            assert os.path.exists('dest/2')
+            assert os.path.islink('dest/2')
+
+    def test_symlinks_false(self, stage):
+        """Test installing without symlink preservation."""
+
+        with fs.working_dir(str(stage)):
+            fs.install_tree('source', 'dest', symlinks=False)
+
+            assert os.path.exists('dest/2')
+            assert not os.path.islink('dest/2')
+
+
+def test_move_transaction_commit(tmpdir):
+
+    fake_library = tmpdir.mkdir('lib').join('libfoo.so')
+    fake_library.write('Just some fake content.')
+
+    old_md5 = fs.hash_directory(str(tmpdir))
+
+    with fs.replace_directory_transaction(str(tmpdir.join('lib'))):
+        fake_library = tmpdir.mkdir('lib').join('libfoo.so')
+        fake_library.write('Other content.')
+        new_md5 = fs.hash_directory(str(tmpdir))
+
+    assert old_md5 != fs.hash_directory(str(tmpdir))
+    assert new_md5 == fs.hash_directory(str(tmpdir))
+
+
+def test_move_transaction_rollback(tmpdir):
+
+    fake_library = tmpdir.mkdir('lib').join('libfoo.so')
+    fake_library.write('Just some fake content.')
+
+    h = fs.hash_directory(str(tmpdir))
+
+    try:
+        with fs.replace_directory_transaction(str(tmpdir.join('lib'))):
+            assert h != fs.hash_directory(str(tmpdir))
+            fake_library = tmpdir.mkdir('lib').join('libfoo.so')
+            fake_library.write('Other content.')
+            raise RuntimeError('')
+    except RuntimeError:
+        pass
+
+    assert h == fs.hash_directory(str(tmpdir))
diff --git a/lib/spack/spack/test/util/filesystem.py b/lib/spack/spack/test/util/filesystem.py
deleted file mode 100644
index 86c3332bb532be4b16b4b4b6f16992bf5ef32e56..0000000000000000000000000000000000000000
--- a/lib/spack/spack/test/util/filesystem.py
+++ /dev/null
@@ -1,61 +0,0 @@
-##############################################################################
-# Copyright (c) 2013-2018, Lawrence Livermore National Security, LLC.
-# Produced at the Lawrence Livermore National Laboratory.
-#
-# This file is part of Spack.
-# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
-# LLNL-CODE-647188
-#
-# For details, see https://github.com/spack/spack
-# Please also see the NOTICE and LICENSE files for our notice and the LGPL.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License (as
-# published by the Free Software Foundation) version 2.1, February 1999.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
-# conditions of the GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this program; if not, write to the Free Software
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-##############################################################################
-
-import llnl.util.filesystem as fs
-
-
-def test_move_transaction_commit(tmpdir):
-
-    fake_library = tmpdir.mkdir('lib').join('libfoo.so')
-    fake_library.write('Just some fake content.')
-
-    old_md5 = fs.hash_directory(str(tmpdir))
-
-    with fs.replace_directory_transaction(str(tmpdir.join('lib'))):
-        fake_library = tmpdir.mkdir('lib').join('libfoo.so')
-        fake_library.write('Other content.')
-        new_md5 = fs.hash_directory(str(tmpdir))
-
-    assert old_md5 != fs.hash_directory(str(tmpdir))
-    assert new_md5 == fs.hash_directory(str(tmpdir))
-
-
-def test_move_transaction_rollback(tmpdir):
-
-    fake_library = tmpdir.mkdir('lib').join('libfoo.so')
-    fake_library.write('Just some fake content.')
-
-    h = fs.hash_directory(str(tmpdir))
-
-    try:
-        with fs.replace_directory_transaction(str(tmpdir.join('lib'))):
-            assert h != fs.hash_directory(str(tmpdir))
-            fake_library = tmpdir.mkdir('lib').join('libfoo.so')
-            fake_library.write('Other content.')
-            raise RuntimeError('')
-    except RuntimeError:
-        pass
-
-    assert h == fs.hash_directory(str(tmpdir))
diff --git a/var/spack/repos/builtin/packages/alglib/package.py b/var/spack/repos/builtin/packages/alglib/package.py
index f5fa8f32fd8d7196315320747aee1ab522644999..ff280fc74788f04252f4bf0775006a6ccac60363 100644
--- a/var/spack/repos/builtin/packages/alglib/package.py
+++ b/var/spack/repos/builtin/packages/alglib/package.py
@@ -26,7 +26,6 @@
 import glob
 import os
 import sys
-import shutil
 
 
 class Alglib(MakefilePackage):
@@ -48,7 +47,7 @@ def edit(self, spec, prefix):
         make_file_src = join_path(os.path.dirname(self.module.__file__),
                                   'Makefile')
         make_file = join_path(self.stage.source_path, 'src', 'Makefile')
-        shutil.copy(make_file_src, make_file)
+        copy(make_file_src, make_file)
         filter_file(r'so', dso_suffix, make_file)
 
     def install(self, spec, prefix):
diff --git a/var/spack/repos/builtin/packages/arlecore/package.py b/var/spack/repos/builtin/packages/arlecore/package.py
index 97d152d28c17b11c91abd15ae5cebd2febc77a4d..31daa17f8521047d59fb46abd93af75d06696045 100644
--- a/var/spack/repos/builtin/packages/arlecore/package.py
+++ b/var/spack/repos/builtin/packages/arlecore/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Arlecore(Package):
@@ -37,4 +36,4 @@ class Arlecore(Package):
     depends_on('r', type=('build', 'run'))
 
     def install(self, spec, prefix):
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/atom-dft/package.py b/var/spack/repos/builtin/packages/atom-dft/package.py
index d16d3283dcfaf83312274c562f9da60ba7854538..644b064fb7256dc53469a89a078ee43b1052cfd7 100644
--- a/var/spack/repos/builtin/packages/atom-dft/package.py
+++ b/var/spack/repos/builtin/packages/atom-dft/package.py
@@ -22,9 +22,7 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-
 from spack import *
-import shutil
 
 
 class AtomDft(MakefilePackage):
@@ -40,7 +38,7 @@ class AtomDft(MakefilePackage):
     depends_on('xmlf90')
 
     def edit(self, spec, prefix):
-        shutil.copyfile('arch.make.sample', 'arch.make')
+        copy('arch.make.sample', 'arch.make')
 
     @property
     def build_targets(self):
diff --git a/var/spack/repos/builtin/packages/autodock-vina/package.py b/var/spack/repos/builtin/packages/autodock-vina/package.py
index c34376bac14756091760d18dadbce0c49f573918..4907854a7324e7b492b71f336542d6dcd21cfc13 100644
--- a/var/spack/repos/builtin/packages/autodock-vina/package.py
+++ b/var/spack/repos/builtin/packages/autodock-vina/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
-from shutil import copymode
 import sys
 
 
@@ -66,7 +64,5 @@ def build(self, spec, prefix):
     def install(self, spec, prefix):
         with working_dir(self.build_directory):
             mkdirp(prefix.bin)
-            copyfile("vina", join_path(prefix.bin, "vina"))
-            copymode("vina", join_path(prefix.bin, "vina"))
-            copyfile("vina_split", join_path(prefix.bin, "vina_split"))
-            copymode("vina_split", join_path(prefix.bin, "vina_split"))
+            install('vina', prefix.bin)
+            install('vina_split', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/bcl2fastq2/package.py b/var/spack/repos/builtin/packages/bcl2fastq2/package.py
index b6e476b55c6ef4033fda84b56431e026076dade9..eb86367fb065b6d80ea2f3251a25f3faa3153ac2 100644
--- a/var/spack/repos/builtin/packages/bcl2fastq2/package.py
+++ b/var/spack/repos/builtin/packages/bcl2fastq2/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import os
-import shutil
 import glob
 import llnl.util.tty as tty
 
@@ -94,7 +93,7 @@ def wrap():
                     tty.msg("cwd sez: {0}".format(os.getcwd()))
                     tarball = glob.glob(join_path('spack-expanded-archive',
                                         'bcl2fastq2*.tar.gz'))[0]
-                    shutil.move(tarball, '.')
+                    copy(tarball, '.')
                     os.rmdir('spack-expanded-archive')
                     tar = which('tar')
                     tarball = os.path.basename(tarball)
diff --git a/var/spack/repos/builtin/packages/bioawk/package.py b/var/spack/repos/builtin/packages/bioawk/package.py
index ae43dff5f5553a1863d6938f499e80b068c33ac9..8ea38bf293075a90f81acdfb2049ba0818d165de 100644
--- a/var/spack/repos/builtin/packages/bioawk/package.py
+++ b/var/spack/repos/builtin/packages/bioawk/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
-from shutil import copymode
 
 
 class Bioawk(MakefilePackage):
@@ -45,7 +43,5 @@ class Bioawk(MakefilePackage):
 
     def install(self, spec, prefix):
         mkdirp(prefix.bin)
-        copyfile("bioawk", join_path(prefix.bin, "bioawk"))
-        copymode("bioawk", join_path(prefix.bin, "bioawk"))
-        copyfile("maketab", join_path(prefix.bin, "maketab"))
-        copymode("maketab", join_path(prefix.bin, "maketab"))
+        install('bioawk',  prefix.bin)
+        install('maketab', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/biopieces/package.py b/var/spack/repos/builtin/packages/biopieces/package.py
index 30435af0e344bb6ad6f5522ddf7cc17b498d5970..c72eba1b688bff7e0a0cf71457206f143e789bb4 100644
--- a/var/spack/repos/builtin/packages/biopieces/package.py
+++ b/var/spack/repos/builtin/packages/biopieces/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Biopieces(Package):
@@ -79,7 +78,7 @@ class Biopieces(Package):
     depends_on('scan-for-matches')
 
     def install(self, spec, prefix):
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         # Note: user will need to set environment variables on their own,
diff --git a/var/spack/repos/builtin/packages/casper/package.py b/var/spack/repos/builtin/packages/casper/package.py
index 2a0f04b64de37ca5ebb6ddabab664407be3b2ecd..1469ec68df4af5cef10699b22032e16625d122e0 100644
--- a/var/spack/repos/builtin/packages/casper/package.py
+++ b/var/spack/repos/builtin/packages/casper/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Casper(MakefilePackage):
@@ -43,7 +42,7 @@ class Casper(MakefilePackage):
     conflicts('%gcc@7.1.0')
 
     def install(self, spec, prefix):
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.prepend_path('PATH', self.spec.prefix)
diff --git a/var/spack/repos/builtin/packages/charm/package.py b/var/spack/repos/builtin/packages/charm/package.py
index 4135fc8ca7e84c0d99b9e09bcf663a59b5d8cc06..b4fc48ae9fdc95c38b2021be1e1c7df6ddfb6378 100644
--- a/var/spack/repos/builtin/packages/charm/package.py
+++ b/var/spack/repos/builtin/packages/charm/package.py
@@ -249,7 +249,7 @@ def install(self, spec, prefix):
                     tmppath = filepath + ".tmp"
                     # Skip dangling symbolic links
                     try:
-                        shutil.copy2(filepath, tmppath)
+                        copy(filepath, tmppath)
                         os.remove(filepath)
                         os.rename(tmppath, filepath)
                     except (IOError, OSError):
diff --git a/var/spack/repos/builtin/packages/chlorop/package.py b/var/spack/repos/builtin/packages/chlorop/package.py
index 96fdf70be4d79857ce2a25112b4daeb026c148cf..96b348c8405edaea6b81908de1193f63f5ddb55f 100644
--- a/var/spack/repos/builtin/packages/chlorop/package.py
+++ b/var/spack/repos/builtin/packages/chlorop/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 import os
 
 
@@ -47,7 +46,7 @@ class Chlorop(Package):
 
     def install(self, spec, prefix):
         os.rename('chlorop', 'bin/chlorop')
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.set('CHLOROP', self.prefix)
diff --git a/var/spack/repos/builtin/packages/chombo/package.py b/var/spack/repos/builtin/packages/chombo/package.py
index 74717b88d488a50e86ef547ee9cf0e1957294377..7136680c4bfdefae7199a2ae2c65f6d60b97dcab 100644
--- a/var/spack/repos/builtin/packages/chombo/package.py
+++ b/var/spack/repos/builtin/packages/chombo/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import glob
 
 
@@ -71,8 +70,8 @@ def edit(self, spec, prefix):
         # Set remaining variables in Make.defs.local
         # Make.defs.local.template.patch ensures lines for USE_TIMER,
         # USE_LAPACK and lapackincflags are present
-        copyfile('./lib/mk/Make.defs.local.template',
-                 './lib/mk/Make.defs.local')
+        copy('./lib/mk/Make.defs.local.template',
+             './lib/mk/Make.defs.local')
 
         defs_file = FileFilter('./lib/mk/Make.defs.local')
 
diff --git a/var/spack/repos/builtin/packages/clapack/package.py b/var/spack/repos/builtin/packages/clapack/package.py
index 73c4414d31593b214335a156920e2a0d89f39c46..dd0076db439c61d5a3227e8631b5ffba81915a3f 100644
--- a/var/spack/repos/builtin/packages/clapack/package.py
+++ b/var/spack/repos/builtin/packages/clapack/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Clapack(MakefilePackage):
@@ -46,7 +45,7 @@ class Clapack(MakefilePackage):
     depends_on('atlas', when='+external-blas')
 
     def edit(self, spec, prefix):
-        install('make.inc.example', 'make.inc')
+        copy('make.inc.example', 'make.inc')
         if '+external-blas' in spec:
             make_inc = FileFilter('make.inc')
             make_inc.filter(r'^BLASLIB.*',
@@ -60,4 +59,4 @@ def build(self, spec, prefix):
         make('lib')
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/codar-cheetah/package.py b/var/spack/repos/builtin/packages/codar-cheetah/package.py
index c2754f5f8adf9628ac2c2ac95cadce1010e18ea5..de9a12eb6e204e91cfc5b6485e886027f6ce5200 100644
--- a/var/spack/repos/builtin/packages/codar-cheetah/package.py
+++ b/var/spack/repos/builtin/packages/codar-cheetah/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class CodarCheetah(Package):
@@ -42,4 +41,4 @@ class CodarCheetah(Package):
     depends_on('savanna')
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/comd/package.py b/var/spack/repos/builtin/packages/comd/package.py
index 2aed00a924df6553e06ba30ef1ac904092998a51..baa9c89d5951aa9d8cce80116561ab10557b4583 100644
--- a/var/spack/repos/builtin/packages/comd/package.py
+++ b/var/spack/repos/builtin/packages/comd/package.py
@@ -22,9 +22,7 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-
 from spack import *
-import shutil
 
 
 class Comd(MakefilePackage):
@@ -58,7 +56,7 @@ class Comd(MakefilePackage):
 
     def edit(self, spec, prefix):
         with working_dir('src-mpi') or working_dir('src-openmp'):
-            shutil.copy('Makefile.vanilla', 'Makefile')
+            copy('Makefile.vanilla', 'Makefile')
 
     @property
     def build_targets(self):
diff --git a/var/spack/repos/builtin/packages/cosp2/package.py b/var/spack/repos/builtin/packages/cosp2/package.py
index 001206132ae0cf86c0e815951a21863860b90df3..5eb59d53e6294dfc3c5bbafa393b54b830d06faa 100644
--- a/var/spack/repos/builtin/packages/cosp2/package.py
+++ b/var/spack/repos/builtin/packages/cosp2/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import shutil
 
 
 class Cosp2(MakefilePackage):
@@ -62,7 +61,7 @@ def edit(self, spec, prefix):
             if '+double' in spec:
                 filter_file('DOUBLE_PRECISION = O.*', 'DOUBLE_PRECISION = OFF',
                             'Makefile.vanilla')
-            shutil.copy('Makefile.vanilla', 'Makefile')
+            copy('Makefile.vanilla', 'Makefile')
 
     def install(self, spec, prefix):
         install_tree('bin/', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/cp2k/package.py b/var/spack/repos/builtin/packages/cp2k/package.py
index 4aa79a45921e2dafa5c2d4655ec443315e1435fe..52eecc61ed99ea172ab021cd5a2601a978d29283 100644
--- a/var/spack/repos/builtin/packages/cp2k/package.py
+++ b/var/spack/repos/builtin/packages/cp2k/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import os
-import shutil
 import copy
 
 from spack import *
@@ -266,8 +265,7 @@ def install(self, spec, prefix):
                 lib_dir = join_path('lib', cp2k_architecture, cp2k_version)
                 mkdirp(lib_dir)
                 try:
-                    shutil.copy(env['LIBSMM_PATH'],
-                                join_path(lib_dir, 'libsmm.a'))
+                    copy(env['LIBSMM_PATH'], join_path(lib_dir, 'libsmm.a'))
                 except KeyError:
                     raise KeyError('Point environment variable LIBSMM_PATH to '
                                    'the absolute path of the libsmm.a file')
@@ -315,4 +313,4 @@ def install(self, spec, prefix):
                  'VERSION={0}'.format(cp2k_version))
             env['PWD'] = pwd_backup
         exe_dir = join_path('exe', cp2k_architecture)
-        shutil.copytree(exe_dir, self.prefix.bin)
+        install_tree(exe_dir, self.prefix.bin)
diff --git a/var/spack/repos/builtin/packages/cppcheck/package.py b/var/spack/repos/builtin/packages/cppcheck/package.py
index 6286941b84b7217a2fb1316d9f78e543338c525b..dfd2adb4eb5e3d03d31c779a39bdf0c52ef14471 100644
--- a/var/spack/repos/builtin/packages/cppcheck/package.py
+++ b/var/spack/repos/builtin/packages/cppcheck/package.py
@@ -23,11 +23,9 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import os
-import shutil
 
 
-class Cppcheck(Package):
+class Cppcheck(MakefilePackage):
     """A tool for static C/C++ code analysis."""
     homepage = "http://cppcheck.sourceforge.net/"
     url      = "https://downloads.sourceforge.net/project/cppcheck/cppcheck/1.78/cppcheck-1.78.tar.bz2"
@@ -41,12 +39,13 @@ class Cppcheck(Package):
 
     depends_on('py-pygments', when='+htmlreport', type='run')
 
+    def build(self, spec, prefix):
+        make('CFGDIR={0}'.format(prefix.cfg))
+
     def install(self, spec, prefix):
-        # cppcheck does not have a configure script
-        make("CFGDIR=%s" % os.path.join(prefix, 'cfg'))
-        # manually install the final cppcheck binary
+        # Manually install the final cppcheck binary
         mkdirp(prefix.bin)
         install('cppcheck', prefix.bin)
-        shutil.copytree('cfg', os.path.join(prefix, 'cfg'))
+        install_tree('cfg', prefix.cfg)
         if spec.satisfies('+htmlreport'):
             install('htmlreport/cppcheck-htmlreport', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/cudnn/package.py b/var/spack/repos/builtin/packages/cudnn/package.py
index 2752a1458f4db5b8b9906057877d9a286b6d7cbd..a9958537c37cdb44cde7a760165bf486ee51cada 100644
--- a/var/spack/repos/builtin/packages/cudnn/package.py
+++ b/var/spack/repos/builtin/packages/cudnn/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Cudnn(Package):
@@ -40,4 +39,4 @@ class Cudnn(Package):
     depends_on('cuda@8:')
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/farmhash/package.py b/var/spack/repos/builtin/packages/farmhash/package.py
index 23c9af82a40c0d81c563184c816a03cd96ca85e1..a8aa8f2c9fb30b1dcc9a621905cfd99abec4ce91 100644
--- a/var/spack/repos/builtin/packages/farmhash/package.py
+++ b/var/spack/repos/builtin/packages/farmhash/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import os.path
-from shutil import copyfile
 
 
 class Farmhash(CMakePackage):
@@ -36,5 +35,5 @@ class Farmhash(CMakePackage):
     version('92e897', commit='92e897b282426729f4724d91a637596c7e2fe28f')
 
     def patch(self):
-        copyfile(join_path(os.path.dirname(__file__), "CMakeLists.txt"),
-                 "CMakeLists.txt")
+        copy(join_path(os.path.dirname(__file__), "CMakeLists.txt"),
+             "CMakeLists.txt")
diff --git a/var/spack/repos/builtin/packages/fastqc/package.py b/var/spack/repos/builtin/packages/fastqc/package.py
index 1b0eb876aee973157b03a5aab143e0a9a7a2d896..c79371361811136f4c91bf66db9878fcc4a9c6f7 100644
--- a/var/spack/repos/builtin/packages/fastqc/package.py
+++ b/var/spack/repos/builtin/packages/fastqc/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree, mkpath
-from distutils.file_util import copy_file
 
 
 class Fastqc(Package):
@@ -43,15 +41,15 @@ class Fastqc(Package):
     patch('fastqc.patch', level=0)
 
     def install(self, spec, prefix):
-        mkpath(self.prefix.bin)
-        mkpath(self.prefix.lib)
-        copy_file('fastqc', self.prefix.bin)
+        mkdir(prefix.bin)
+        mkdir(prefix.lib)
+        install('fastqc', prefix.bin)
         for j in ['cisd-jhdf5.jar', 'jbzip2-0.9.jar', 'sam-1.103.jar']:
-            copy_file(j, self.prefix.lib)
+            install(j, prefix.lib)
         for d in ['Configuration', 'net', 'org', 'Templates', 'uk']:
-            copy_tree(d, join_path(self.prefix.lib, d))
+            install_tree(d, join_path(prefix.lib, d))
         chmod = which('chmod')
-        chmod('+x', join_path(self.prefix.bin, 'fastqc'))
+        chmod('+x', prefix.bin.fastqc)
 
     # In theory the 'run' dependency on 'jdk' above should take
     # care of this for me. In practice, it does not.
@@ -59,5 +57,4 @@ def setup_environment(self, spack_env, run_env):
         """Add <prefix> to the path; the package has a script at the
            top level.
         """
-        run_env.prepend_path('PATH', join_path(self.spec['java'].prefix,
-                             'bin'))
+        run_env.prepend_path('PATH', self.spec['java'].prefix.bin)
diff --git a/var/spack/repos/builtin/packages/fermisciencetools/package.py b/var/spack/repos/builtin/packages/fermisciencetools/package.py
index bdac7867661103bb7cc37d05193f7aae5856b8ee..556123dd094d90b18e2f38b4d2340a97d865f5f7 100644
--- a/var/spack/repos/builtin/packages/fermisciencetools/package.py
+++ b/var/spack/repos/builtin/packages/fermisciencetools/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Fermisciencetools(Package):
@@ -42,4 +41,4 @@ class Fermisciencetools(Package):
     version('11r5p3', 'cf050ddddfe9251b6ebe8d3fd7de3c3f')
 
     def install(self, spec, prefix):
-        copy_tree('x86_64-unknown-linux-gnu-libc2.17', prefix)
+        install_tree('x86_64-unknown-linux-gnu-libc2.17', prefix)
diff --git a/var/spack/repos/builtin/packages/fsl/package.py b/var/spack/repos/builtin/packages/fsl/package.py
index c14865622dc9368c4142bb5c0191233bff9b537e..00d00db220b37a435f34cab1b95cbdca924bfa09 100644
--- a/var/spack/repos/builtin/packages/fsl/package.py
+++ b/var/spack/repos/builtin/packages/fsl/package.py
@@ -25,7 +25,6 @@
 from spack import *
 from spack.environment import EnvironmentModifications
 import os
-import distutils.dir_util
 
 
 class Fsl(Package):
@@ -68,7 +67,7 @@ def install(self, spec, prefix):
         build = Executable('./build')
         build()
 
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         if not self.stage.source_path:
diff --git a/var/spack/repos/builtin/packages/gatk/package.py b/var/spack/repos/builtin/packages/gatk/package.py
index 8ca12f133a339322fc5de1c5f82d66577a06568a..f7ce7c17143855f10e66917075e7d446c93e9667 100644
--- a/var/spack/repos/builtin/packages/gatk/package.py
+++ b/var/spack/repos/builtin/packages/gatk/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import glob
 import os.path
 import re
@@ -62,7 +61,7 @@ def install(self, spec, prefix):
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "gatk.sh")
         script = join_path(prefix.bin, "gatk")
-        copyfile(script_sh, script)
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
diff --git a/var/spack/repos/builtin/packages/gaussian/package.py b/var/spack/repos/builtin/packages/gaussian/package.py
index e928d475add16af2d658cc599e5020ac7dc87310..c14c830b0ebe67da769007a067c12c1245a9a3b3 100644
--- a/var/spack/repos/builtin/packages/gaussian/package.py
+++ b/var/spack/repos/builtin/packages/gaussian/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import os
-import shutil
 
 
 class Gaussian(Package):
@@ -36,7 +35,7 @@ class Gaussian(Package):
     version('09', '7d4c95b535e68e48af183920df427e4e')
 
     def install(self, spec, prefix):
-        shutil.copytree(os.getcwd(), prefix.bin)
+        install_tree('.', prefix.bin)
         patch_install_files = ['flc',
                                'linda8.2/opteron-linux/bin/flc',
                                'linda8.2/opteron-linux/bin/LindaLauncher',
diff --git a/var/spack/repos/builtin/packages/gcc/package.py b/var/spack/repos/builtin/packages/gcc/package.py
index 0bfcd26e2b934b75730361ff9e322fb0993ab707..7bf95acb9419a21c4c9573baa90232561622ce50 100644
--- a/var/spack/repos/builtin/packages/gcc/package.py
+++ b/var/spack/repos/builtin/packages/gcc/package.py
@@ -28,7 +28,6 @@
 
 import glob
 import os
-import shutil
 import sys
 
 
@@ -207,7 +206,7 @@ def patch(self):
                 new_dispatch_dir = join_path(prefix, 'include', 'dispatch')
                 mkdirp(new_dispatch_dir)
                 new_header = join_path(new_dispatch_dir, 'object.h')
-                shutil.copyfile('/usr/include/dispatch/object.h', new_header)
+                install('/usr/include/dispatch/object.h', new_header)
                 filter_file(r'typedef void \(\^dispatch_block_t\)\(void\)',
                             'typedef void* dispatch_block_t',
                             new_header)
diff --git a/var/spack/repos/builtin/packages/genomefinisher/package.py b/var/spack/repos/builtin/packages/genomefinisher/package.py
index 7599c375050d64cb9579cb59f0472ab1acf94c49..2083c3b22b1d8a217d38d440c9065e1fc46cdd95 100644
--- a/var/spack/repos/builtin/packages/genomefinisher/package.py
+++ b/var/spack/repos/builtin/packages/genomefinisher/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import os
 
 
@@ -49,13 +48,13 @@ def install(self, spec, prefix):
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "genomefinisher.sh")
-        script = join_path(prefix.bin, "genomefinisher")
-        copyfile(script_sh, script)
+        script = prefix.bin.genomefinisher
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the jar file
         # jar file.
-        java = join_path(self.spec['jdk'].prefix, 'bin', 'java')
+        java = spec['jdk'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file(jar_file, join_path(prefix.bin, jar_file),
diff --git a/var/spack/repos/builtin/packages/git/package.py b/var/spack/repos/builtin/packages/git/package.py
index 7c3499bfe18af93e7ce8ec055169f529332eb4d8..3e8a11d69e07554d17f997d91b41cfe25855ace8 100644
--- a/var/spack/repos/builtin/packages/git/package.py
+++ b/var/spack/repos/builtin/packages/git/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 import sys
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Git(AutotoolsPackage):
@@ -241,7 +240,7 @@ def check(self):
 
     @run_after('install')
     def install_completions(self):
-        copy_tree('contrib/completion', self.prefix.share)
+        install_tree('contrib/completion', self.prefix.share)
 
     @run_after('install')
     def install_manpages(self):
diff --git a/var/spack/repos/builtin/packages/glib/package.py b/var/spack/repos/builtin/packages/glib/package.py
index 6a004d8e644b2281744b80f6c2a52b08ab7df88a..87a0286950d2dd678a50c1417805e1b6ad9e1678 100644
--- a/var/spack/repos/builtin/packages/glib/package.py
+++ b/var/spack/repos/builtin/packages/glib/package.py
@@ -25,7 +25,6 @@
 from spack import *
 
 import os.path
-import shutil
 
 
 class Glib(AutotoolsPackage):
@@ -117,7 +116,7 @@ def fix_dtrace_usr_bin_path(self):
         dtrace_copy = join_path(self.dtrace_copy_path, 'dtrace')
 
         with working_dir(self.dtrace_copy_path, create=True):
-            shutil.copy(dtrace, dtrace_copy)
+            copy(dtrace, dtrace_copy)
             filter_file(
                 '^#!/usr/bin/python',
                 '#!/usr/bin/env python',
diff --git a/var/spack/repos/builtin/packages/go-bootstrap/package.py b/var/spack/repos/builtin/packages/go-bootstrap/package.py
index c7794a40e984d8647f9b0cd99263a3e0428bd2ae..730f423d557dbd9641f048fb086818e4409597b4 100644
--- a/var/spack/repos/builtin/packages/go-bootstrap/package.py
+++ b/var/spack/repos/builtin/packages/go-bootstrap/package.py
@@ -22,9 +22,6 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-import os
-import shutil
-import glob
 from spack import *
 
 # THIS PACKAGE SHOULD NOT EXIST
@@ -75,15 +72,7 @@ def install(self, spec, prefix):
         with working_dir('src'):
             bash('{0}.bash'.format('all' if self.run_tests else 'make'))
 
-        try:
-            os.makedirs(prefix)
-        except OSError:
-            pass
-        for f in glob.glob('*'):
-            if os.path.isdir(f):
-                shutil.copytree(f, os.path.join(prefix, f))
-            else:
-                shutil.copy2(f, os.path.join(prefix, f))
+        install_tree('.', prefix)
 
     def setup_dependent_environment(self, spack_env, run_env, dependent_spec):
         spack_env.set('GOROOT_BOOTSTRAP', self.spec.prefix)
diff --git a/var/spack/repos/builtin/packages/go/package.py b/var/spack/repos/builtin/packages/go/package.py
index e7c96af8afa6291eca3f0b7794738cc18a590b14..48055f7722c8054fad8aba63e80512ae10e03975 100644
--- a/var/spack/repos/builtin/packages/go/package.py
+++ b/var/spack/repos/builtin/packages/go/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import os
-import shutil
-import glob
 import llnl.util.tty as tty
 from spack import *
 
@@ -101,15 +99,7 @@ def install(self, spec, prefix):
         with working_dir('src'):
             bash('{0}.bash'.format('all' if self.run_tests else 'make'))
 
-        try:
-            os.makedirs(prefix)
-        except OSError:
-            pass
-        for f in glob.glob('*'):
-            if os.path.isdir(f):
-                shutil.copytree(f, os.path.join(prefix, f))
-            else:
-                shutil.copy2(f, os.path.join(prefix, f))
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         spack_env.set('GOROOT_FINAL', self.spec.prefix)
@@ -123,10 +113,9 @@ def setup_dependent_package(self, module, dependent_spec):
 
         In most cases, extensions will only need to set GOPATH and use go::
 
-        env = os.environ
         env['GOPATH'] = self.source_path + ':' + env['GOPATH']
         go('get', '<package>', env=env)
-        shutil.copytree('bin', os.path.join(prefix, '/bin'))
+        install_tree('bin', prefix.bin)
         """
         #  Add a go command/compiler for extensions
         module.go = self.spec['go'].command
diff --git a/var/spack/repos/builtin/packages/grackle/package.py b/var/spack/repos/builtin/packages/grackle/package.py
index e88041dd8b75963faebaf198d8acaa6f48a2141d..0df3f3bf81a89292c278d98c65ab7f8324aa7040 100644
--- a/var/spack/repos/builtin/packages/grackle/package.py
+++ b/var/spack/repos/builtin/packages/grackle/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import os.path
-import shutil
 import inspect
 
 from spack import *
@@ -78,7 +77,7 @@ def install(self, spec, prefix):
             'clib',
             'Make.mach.{0}'.format(grackle_architecture)
         )
-        shutil.copy(template, makefile)
+        copy(template, makefile)
         for key, value in substitutions.items():
             filter_file(key, value, makefile)
 
diff --git a/var/spack/repos/builtin/packages/gradle/package.py b/var/spack/repos/builtin/packages/gradle/package.py
index 055aac845f8e15607b930fedc0ba55201deaf494..f7ad851e9f3367afdafe624069a3b41ad0649f6b 100644
--- a/var/spack/repos/builtin/packages/gradle/package.py
+++ b/var/spack/repos/builtin/packages/gradle/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Gradle(Package):
@@ -81,4 +80,4 @@ class Gradle(Package):
     depends_on('java')
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/gurobi/package.py b/var/spack/repos/builtin/packages/gurobi/package.py
index aebb6bf6c62128ce2a07c4e49950d27dabea12f7..9720313b7ef7528a53d52b310f88c1cab4e3bc91 100644
--- a/var/spack/repos/builtin/packages/gurobi/package.py
+++ b/var/spack/repos/builtin/packages/gurobi/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 import os
 
 
@@ -58,5 +57,4 @@ def setup_environment(self, spack_env, run_env):
         run_env.set('GUROBI_HOME', self.prefix)
 
     def install(self, spec, prefix):
-        with working_dir('linux64'):
-            copy_tree('.', prefix)
+        install_tree('linux64', prefix)
diff --git a/var/spack/repos/builtin/packages/hdf5-blosc/package.py b/var/spack/repos/builtin/packages/hdf5-blosc/package.py
index b0ff9536c768b636f340e983572aa62df03864bb..0e0d6dd3521d1e0f00c87b5bda6c25be5a4e09f3 100644
--- a/var/spack/repos/builtin/packages/hdf5-blosc/package.py
+++ b/var/spack/repos/builtin/packages/hdf5-blosc/package.py
@@ -34,13 +34,13 @@ def _install_shlib(name, src, dst):
     if sys.platform == "darwin":
         shlib0 = name + ".0.dylib"
         shlib = name + ".dylib"
-        shutil.copyfile(join_path(src, shlib0), join_path(dst, shlib0))
+        install(join_path(src, shlib0), join_path(dst, shlib0))
         os.symlink(shlib0, join_path(dst, shlib))
     else:
         shlib000 = name + ".so.0.0.0"
         shlib0 = name + ".so.0"
         shlib = name + ".dylib"
-        shutil.copyfile(join_path(src, shlib000), join_path(dst, shlib000))
+        install(join_path(src, shlib000), join_path(dst, shlib000))
         os.symlink(shlib000, join_path(dst, shlib0))
         os.symlink(shlib0, join_path(dst, shlib))
 
diff --git a/var/spack/repos/builtin/packages/igvtools/package.py b/var/spack/repos/builtin/packages/igvtools/package.py
index 03e8dee65304372d192e2cb638cdfcc494877e1b..410a409d632661a05bc5a07a3e1d5aa978e211b9 100644
--- a/var/spack/repos/builtin/packages/igvtools/package.py
+++ b/var/spack/repos/builtin/packages/igvtools/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import os
 
 
@@ -47,13 +46,13 @@ def install(self, spec, prefix):
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "igvtools.sh")
-        script = join_path(prefix.bin, "igvtools")
-        copyfile(script_sh, script)
+        script = prefix.bin.igvtools
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['jdk'].prefix, 'bin', 'java')
+        java = spec['jdk'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file(jar_file, join_path(prefix.bin, jar_file),
diff --git a/var/spack/repos/builtin/packages/jdk/package.py b/var/spack/repos/builtin/packages/jdk/package.py
index b39c32bc07925e4dd90810a650d37f059282a759..f6f78b95012d1350ed27c3fe389225089afb545e 100644
--- a/var/spack/repos/builtin/packages/jdk/package.py
+++ b/var/spack/repos/builtin/packages/jdk/package.py
@@ -25,7 +25,6 @@
 #
 # Author: Justin Too <too1@llnl.gov>
 #
-import distutils.dir_util
 from spack import *
 
 
@@ -72,7 +71,7 @@ def url_for_version(self, version):
         return url.format(version, minor_version)
 
     def install(self, spec, prefix):
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.set('JAVA_HOME', self.spec.prefix)
diff --git a/var/spack/repos/builtin/packages/jmol/package.py b/var/spack/repos/builtin/packages/jmol/package.py
index eda8dbe877e71ef84acab52b7627803d365dd0aa..cd9cbf1c837dd650c480d1d4a280531d9b787584 100644
--- a/var/spack/repos/builtin/packages/jmol/package.py
+++ b/var/spack/repos/builtin/packages/jmol/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Jmol(Package):
@@ -38,7 +37,7 @@ class Jmol(Package):
     depends_on('java', type='run')
 
     def install(self, spec, prefix):
-        copy_tree('jmol-{0}'.format(self.version), prefix)
+        install_tree('jmol-{0}'.format(self.version), prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.prepend_path('PATH', self.prefix)
diff --git a/var/spack/repos/builtin/packages/kaldi/package.py b/var/spack/repos/builtin/packages/kaldi/package.py
index 69981c85ca9392f117b1e2caa8447f64d0d3f23c..7dbe7d9a3b50c3f9e14e10306b9e3a8e7e8ca8ef 100644
--- a/var/spack/repos/builtin/packages/kaldi/package.py
+++ b/var/spack/repos/builtin/packages/kaldi/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 from os.path import join
 from fnmatch import fnmatch
 import os
@@ -105,7 +104,7 @@ def install(self, spec, prefix):
                         install(join(root, name), prefix.bin)
 
             mkdir(prefix.lib)
-            copy_tree('lib', prefix.lib)
+            install_tree('lib', prefix.lib)
 
             for root, dirs, files in os.walk('.'):
                 for name in files:
diff --git a/var/spack/repos/builtin/packages/leveldb/package.py b/var/spack/repos/builtin/packages/leveldb/package.py
index cf66732170d8cbed72cccf07d9791bf6e0727e90..75b7b9411e47ce31dbc68620521a2f5ba3cc5b56 100644
--- a/var/spack/repos/builtin/packages/leveldb/package.py
+++ b/var/spack/repos/builtin/packages/leveldb/package.py
@@ -26,7 +26,7 @@
 from spack import *
 
 
-class Leveldb(Package):
+class Leveldb(MakefilePackage):
     """LevelDB is a fast key-value storage library written at Google
     that provides an ordered mapping from string keys to string values."""
 
@@ -39,21 +39,14 @@ class Leveldb(Package):
     depends_on("snappy")
 
     def install(self, spec, prefix):
-        make()
+        mkdirp(prefix.lib.pkgconfig)
 
-        mkdirp(prefix.include)
-        mkdirp(prefix.lib)
-        mkdirp(join_path(prefix.lib, 'pkgconfig'))
+        libraries  = glob.glob('out-shared/libleveldb.*')
+        libraries += glob.glob('out-static/libleveldb.*')
+        for library in libraries:
+            install(library, prefix.lib)
 
-        cp = which('cp')
-
-        # cp --preserve=links libleveldb.* prefix/lib
-        args = glob.glob('out-shared/libleveldb.*') \
-            + glob.glob('out-static/libleveldb.*')
-        args.append(prefix.lib)
-        cp('--preserve=links', *args)
-
-        cp('-r', 'include/leveldb', prefix.include)
+        install_tree('include/leveldb', prefix.include)
 
         with open(join_path(prefix.lib, 'pkgconfig', 'leveldb.pc'), 'w') as f:
             f.write('prefix={0}\n'.format(prefix))
diff --git a/var/spack/repos/builtin/packages/libgridxc/package.py b/var/spack/repos/builtin/packages/libgridxc/package.py
index 42a2a0551755a31395a1e3aed0ce71dcd038e9cd..f2db4ab13f786a292c51ecbd6f3372f9538393d1 100644
--- a/var/spack/repos/builtin/packages/libgridxc/package.py
+++ b/var/spack/repos/builtin/packages/libgridxc/package.py
@@ -22,9 +22,7 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-
 from spack import *
-import shutil
 
 
 class Libgridxc(Package):
@@ -42,7 +40,7 @@ def configure(self, spec, prefix):
         sh = which('sh')
         with working_dir('build', create=True):
             sh('../src/config.sh')
-            shutil.copyfile('../extra/fortran.mk', 'fortran.mk')
+            copy('../extra/fortran.mk', 'fortran.mk')
 
     def install(self, spec, prefix):
         with working_dir('build'):
diff --git a/var/spack/repos/builtin/packages/libiconv/package.py b/var/spack/repos/builtin/packages/libiconv/package.py
index df57201d7e12b935cac137c80999678480858f56..d9ff4a251ad125197835fdfc5ea3bd63d82af049 100644
--- a/var/spack/repos/builtin/packages/libiconv/package.py
+++ b/var/spack/repos/builtin/packages/libiconv/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import shutil
 
 
 class Libiconv(AutotoolsPackage):
@@ -46,6 +45,6 @@ def configure_args(self):
         args = ['--enable-extra-encodings']
 
         # A hack to patch config.guess in the libcharset sub directory
-        shutil.copyfile('./build-aux/config.guess',
-                        'libcharset/build-aux/config.guess')
+        copy('./build-aux/config.guess',
+             'libcharset/build-aux/config.guess')
         return args
diff --git a/var/spack/repos/builtin/packages/llvm/package.py b/var/spack/repos/builtin/packages/llvm/package.py
index 2ecd61d75a1ab0c8642eaba0b5b1a99fceb43ce6..3be612fecc8f27aa65ed4c7fa5590b3cd809c34d 100644
--- a/var/spack/repos/builtin/packages/llvm/package.py
+++ b/var/spack/repos/builtin/packages/llvm/package.py
@@ -504,10 +504,9 @@ def check_darwin_lldb_codesign_requirement(self):
         if not self.spec.satisfies('+lldb platform=darwin'):
             return
         codesign = which('codesign')
-        cp = which('cp')
         mkdir('tmp')
         llvm_check_file = join_path('tmp', 'llvm_check')
-        cp('/usr/bin/false', llvm_check_file)
+        copy('/usr/bin/false', llvm_check_file)
 
         try:
             codesign('-f', '-s', 'lldb_codesign', '--dryrun',
diff --git a/var/spack/repos/builtin/packages/masurca/package.py b/var/spack/repos/builtin/packages/masurca/package.py
index 9c35f4565799f90e761f137318cc18b49a9752bc..a1786cd7f3604cb51380a9409bd8cb08f4ff096e 100644
--- a/var/spack/repos/builtin/packages/masurca/package.py
+++ b/var/spack/repos/builtin/packages/masurca/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Masurca(Package):
@@ -44,4 +43,4 @@ class Masurca(Package):
     def install(self, spec, prefix):
         installer = Executable('./install.sh')
         installer()
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/maven/package.py b/var/spack/repos/builtin/packages/maven/package.py
index aef6ddeaee2ee6f121cdf69730e462cb11178f86..abd4cca16cfbcdbef3e43f01f4dc7bb0ed173331 100644
--- a/var/spack/repos/builtin/packages/maven/package.py
+++ b/var/spack/repos/builtin/packages/maven/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Maven(Package):
@@ -39,4 +38,4 @@ class Maven(Package):
 
     def install(self, spec, prefix):
         # install pre-built distribution
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/mefit/package.py b/var/spack/repos/builtin/packages/mefit/package.py
index cbd05eb656f68771c6f0f344751bfad602c93457..61e74dfbbecf5e44b183868266af6a5741d4311c 100644
--- a/var/spack/repos/builtin/packages/mefit/package.py
+++ b/var/spack/repos/builtin/packages/mefit/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Mefit(Package):
@@ -41,7 +40,7 @@ class Mefit(Package):
     depends_on('casper %gcc@4.8.5')
 
     def install(self, spec, prefix):
-        distutils.dir_util.copy_tree(".", prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.prepend_path('PATH', self.prefix)
diff --git a/var/spack/repos/builtin/packages/mfem/package.py b/var/spack/repos/builtin/packages/mfem/package.py
index 9e26473f212e924659539a57213d2d5b31bf8b51..7d76ee8db939c1cb08d1d26e72889a19eb3c099b 100644
--- a/var/spack/repos/builtin/packages/mfem/package.py
+++ b/var/spack/repos/builtin/packages/mfem/package.py
@@ -440,7 +440,7 @@ def install(self, spec, prefix):
             # installed shared mfem library:
             with working_dir('config'):
                 os.rename('config.mk', 'config.mk.orig')
-                shutil.copyfile(str(self.config_mk), 'config.mk')
+                copy(str(self.config_mk), 'config.mk')
                 shutil.copystat('config.mk.orig', 'config.mk')
 
         if '+examples' in spec:
diff --git a/var/spack/repos/builtin/packages/mpix-launch-swift/package.py b/var/spack/repos/builtin/packages/mpix-launch-swift/package.py
index f72b0fff4fa5dde3c8c2776f098c4a8aec748207..57cb59eb20df51f6d8cf5c661ed098862ab80a68 100644
--- a/var/spack/repos/builtin/packages/mpix-launch-swift/package.py
+++ b/var/spack/repos/builtin/packages/mpix-launch-swift/package.py
@@ -23,10 +23,9 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
-class MpixLaunchSwift(Package):
+class MpixLaunchSwift(MakefilePackage):
     """Library that allows a child MPI application to be launched
     inside a subset of processes in a parent MPI application.
     """
@@ -42,5 +41,4 @@ class MpixLaunchSwift(Package):
     depends_on('swig', type='build')
 
     def install(self, spec, prefix):
-        make()
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/mrtrix3/package.py b/var/spack/repos/builtin/packages/mrtrix3/package.py
index a61a19cc4c547ba650f34e2728f17c9fb8bd36fe..26b083daf516b5a2f0bf3e1d2da1952fec811482 100644
--- a/var/spack/repos/builtin/packages/mrtrix3/package.py
+++ b/var/spack/repos/builtin/packages/mrtrix3/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Mrtrix3(Package):
@@ -53,9 +52,7 @@ def install(self, spec, prefix):
         build = Executable('./build')
         configure()
         build()
-        # install_tree('.', prefix) does not work since the prefix
-        # directory already exists by this point
-        distutils.dir_util.copy_tree('.', prefix)
+        install_tree('.', prefix)
 
     def setup_environment(self, spac_env, run_env):
         run_env.prepend_path('PATH', self.prefix)
diff --git a/var/spack/repos/builtin/packages/namd/package.py b/var/spack/repos/builtin/packages/namd/package.py
index 837ae1a5c8f473106996b44daff85ff38a21d96a..6179cacd84fcb7af9487ad52058686e731ac7356 100644
--- a/var/spack/repos/builtin/packages/namd/package.py
+++ b/var/spack/repos/builtin/packages/namd/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import platform
-import shutil
 import sys
 import os
 from spack import *
@@ -58,8 +57,8 @@ class Namd(MakefilePackage):
 
     def _copy_arch_file(self, lib):
         config_filename = 'arch/{0}.{1}'.format(self.arch, lib)
-        shutil.copy('arch/Linux-x86_64.{0}'.format(lib),
-                    config_filename)
+        copy('arch/Linux-x86_64.{0}'.format(lib),
+             config_filename)
         if lib == 'tcl':
             filter_file(r'-ltcl8\.5',
                         '-ltcl{0}'.format(self.spec['tcl'].version.up_to(2)),
diff --git a/var/spack/repos/builtin/packages/ncl/package.py b/var/spack/repos/builtin/packages/ncl/package.py
index 573acb664c022592bec67f0c5e76e819f5936766..218fc31eb9ffeb24fa2f400b040cb471e3c770fe 100644
--- a/var/spack/repos/builtin/packages/ncl/package.py
+++ b/var/spack/repos/builtin/packages/ncl/package.py
@@ -25,7 +25,6 @@
 from spack import *
 import glob
 import os
-import shutil
 import tempfile
 
 
@@ -263,8 +262,8 @@ def prepare_src_tree(self):
             triangle_src = join_path(self.stage.source_path, 'triangle_src')
             triangle_dst = join_path(self.stage.source_path, 'ni', 'src',
                                      'lib', 'hlu')
-            shutil.copy(join_path(triangle_src, 'triangle.h'), triangle_dst)
-            shutil.copy(join_path(triangle_src, 'triangle.c'), triangle_dst)
+            copy(join_path(triangle_src, 'triangle.h'), triangle_dst)
+            copy(join_path(triangle_src, 'triangle.c'), triangle_dst)
 
     @staticmethod
     def delete_files(*filenames):
diff --git a/var/spack/repos/builtin/packages/ncurses/package.py b/var/spack/repos/builtin/packages/ncurses/package.py
index c54cbcd71ff35394ab2b9fa0383b0319ae207b44..cc1b6a7287efcb26672ba90ff35244fd548be4d6 100644
--- a/var/spack/repos/builtin/packages/ncurses/package.py
+++ b/var/spack/repos/builtin/packages/ncurses/package.py
@@ -26,7 +26,6 @@
 from glob import glob
 from os.path import exists, join
 from os import makedirs
-from shutil import copy
 
 
 class Ncurses(AutotoolsPackage):
@@ -109,7 +108,7 @@ def install(self, spec, prefix):
             if not exists(path):
                 makedirs(path)
             for header in headers:
-                copy(header, path)
+                install(header, path)
 
     @property
     def libs(self):
diff --git a/var/spack/repos/builtin/packages/occa/package.py b/var/spack/repos/builtin/packages/occa/package.py
index a27d3c6b34bf98f1904673692341f24f4b12bd32..ff9285518e31e2e88f6f2c071213baed014cf7af 100644
--- a/var/spack/repos/builtin/packages/occa/package.py
+++ b/var/spack/repos/builtin/packages/occa/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import os
-import shutil
 
 
 class Occa(Package):
@@ -63,12 +61,7 @@ class Occa(Package):
     def install(self, spec, prefix):
         # The build environment is set by the 'setup_environment' method.
         # Copy the source to the installation directory and build OCCA there.
-        for file in os.listdir('.'):
-            dest = join_path(prefix, os.path.basename(file))
-            if os.path.isdir(file):
-                shutil.copytree(file, dest)
-            else:
-                shutil.copy2(file, dest)
+        install_tree('.', prefix)
         make('-C', prefix)
 
         if self.run_tests:
diff --git a/var/spack/repos/builtin/packages/pexsi/package.py b/var/spack/repos/builtin/packages/pexsi/package.py
index c730d3475665b6ea468ed1b6e409983303b22b97..931f951a09b31c87185324f652dfed1d25040673 100644
--- a/var/spack/repos/builtin/packages/pexsi/package.py
+++ b/var/spack/repos/builtin/packages/pexsi/package.py
@@ -25,7 +25,6 @@
 
 import inspect
 import os.path
-import shutil
 
 from spack import *
 
@@ -99,7 +98,7 @@ def edit(self, spec, prefix):
             self.stage.source_path,
             'make.inc'
         )
-        shutil.copy(template, makefile)
+        copy(template, makefile)
         for key, value in substitutions:
             filter_file(key, value, makefile)
 
diff --git a/var/spack/repos/builtin/packages/picard/package.py b/var/spack/repos/builtin/packages/picard/package.py
index cca0ae2f7bc6bc31dba5e8097a0575bdbcf282de..6cab04e59228d9a7980ba00abc1c98efc03ce856 100644
--- a/var/spack/repos/builtin/packages/picard/package.py
+++ b/var/spack/repos/builtin/packages/picard/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import glob
 import os.path
 import re
@@ -69,13 +68,13 @@ def install(self, spec, prefix):
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "picard.sh")
-        script = join_path(prefix.bin, "picard")
-        copyfile(script_sh, script)
+        script = prefix.bin.picard
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['java'].prefix, 'bin', 'java')
+        java = self.spec['java'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file('picard.jar', join_path(prefix.bin, 'picard.jar'),
diff --git a/var/spack/repos/builtin/packages/pilon/package.py b/var/spack/repos/builtin/packages/pilon/package.py
index 8fba2c2376b39dbc40cb48c00578aa9e0cc08cd1..0fec636fbaff37ef1dc96ef2181c63b7e8e11520 100644
--- a/var/spack/repos/builtin/packages/pilon/package.py
+++ b/var/spack/repos/builtin/packages/pilon/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import os.path
 
 
@@ -47,13 +46,13 @@ def install(self, spec, prefix):
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "pilon.sh")
-        script = join_path(prefix.bin, "pilon")
-        copyfile(script_sh, script)
+        script = prefix.bin.pilon
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['java'].prefix, 'bin', 'java')
+        java = self.spec['java'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file('pilon-{0}.jar', join_path(prefix.bin, jar_file),
diff --git a/var/spack/repos/builtin/packages/pindel/package.py b/var/spack/repos/builtin/packages/pindel/package.py
index 479128707be52316f4b7484ae79575020148359e..d0acc28472588e790b9985cbd974d3f609a6973c 100644
--- a/var/spack/repos/builtin/packages/pindel/package.py
+++ b/var/spack/repos/builtin/packages/pindel/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copytree, copyfile
 
 
 class Pindel(MakefilePackage):
@@ -51,9 +50,8 @@ class Pindel(MakefilePackage):
     #
 
     def edit(self, spec, prefix):
-        makefile2 = join_path(self.build_directory, 'Makefile2')
-        copyfile(join_path(self.build_directory, 'Makefile'), makefile2)
-        myedit = FileFilter(makefile2)
+        copy('Makefile', 'Makefile2')
+        myedit = FileFilter('Makefile2')
         myedit.filter('-include Makefile.local', '#removed include')
         myedit.filter('@false', '#removed autofailure')
 
@@ -69,6 +67,4 @@ def install(self, spec, prefix):
         install('src/pindel2vcf', prefix.bin)
         install('src/sam2pindel', prefix.bin)
         install('src/pindel2vcf4tcga', prefix.bin)
-        copytree(join_path(self.build_directory, 'demo'),
-                 prefix.doc,
-                 symlinks=True)
+        install_tree('demo', prefix.doc)
diff --git a/var/spack/repos/builtin/packages/python/package.py b/var/spack/repos/builtin/packages/python/package.py
index 94e6b61bd4e9583f18a0b2aa4084781591516616..5b8c7e94e305879bd91d445b36effa4177e9c916 100644
--- a/var/spack/repos/builtin/packages/python/package.py
+++ b/var/spack/repos/builtin/packages/python/package.py
@@ -27,7 +27,6 @@
 import platform
 import re
 import sys
-import shutil
 
 import llnl.util.tty as tty
 from llnl.util.lang import match_predicate
@@ -709,7 +708,7 @@ def add_files_to_view(self, view, merge_map):
             if not path_contains_subdirectory(src, bin_dir):
                 view.link(src, dst)
             elif not os.path.islink(src):
-                shutil.copy2(src, dst)
+                copy(src, dst)
                 if 'script' in get_filetype(src):
                     filter_file(
                         self.spec.prefix, os.path.abspath(view.root), dst)
diff --git a/var/spack/repos/builtin/packages/qbox/package.py b/var/spack/repos/builtin/packages/qbox/package.py
index 19d83773a8c04f83f2ebffca8d3de7cd48bd87df..805a567e552ce442818dd6da54d89db5b77ea3bf 100644
--- a/var/spack/repos/builtin/packages/qbox/package.py
+++ b/var/spack/repos/builtin/packages/qbox/package.py
@@ -22,8 +22,6 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-
-import shutil
 from spack import *
 
 
@@ -88,6 +86,6 @@ def edit(self, spec, prefix):
     def install(self, spec, prefix):
         mkdir(prefix.src)
         install('src/qb', prefix.src)
-        shutil.move('test', prefix)
-        shutil.move('xml', prefix)
-        shutil.move('util', prefix)
+        install_tree('test', prefix)
+        install_tree('xml', prefix)
+        install_tree('util', prefix)
diff --git a/var/spack/repos/builtin/packages/qorts/package.py b/var/spack/repos/builtin/packages/qorts/package.py
index bb71f15b8f9f76e41baf9ead75bbd3efe0dcfbad..7e745dc3046c633bf819d8e9fb68064640a916be 100644
--- a/var/spack/repos/builtin/packages/qorts/package.py
+++ b/var/spack/repos/builtin/packages/qorts/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import os.path
-from shutil import copyfile
 
 
 class Qorts(RPackage):
@@ -59,7 +58,7 @@ def install_jar(self):
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "QoRTs.sh")
         script = self.prefix.bin.QoRTs
-        copyfile(script_sh, script)
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
diff --git a/var/spack/repos/builtin/packages/r/package.py b/var/spack/repos/builtin/packages/r/package.py
index 6ae13af9f58872a20bdb1a26c9d6c3339e8f06eb..52d11f5bbb4f54544b33e5689a686da5f1eb5cb9 100644
--- a/var/spack/repos/builtin/packages/r/package.py
+++ b/var/spack/repos/builtin/packages/r/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import os
-import shutil
 
 from spack import *
 
@@ -142,7 +141,7 @@ def copy_makeconf(self):
         # dependencies in Spack.
         src_makeconf = join_path(self.etcdir, 'Makeconf')
         dst_makeconf = join_path(self.etcdir, 'Makeconf.spack')
-        shutil.copy(src_makeconf, dst_makeconf)
+        install(src_makeconf, dst_makeconf)
 
     # ========================================================================
     # Set up environment to make install easy for R extensions.
diff --git a/var/spack/repos/builtin/packages/repeatmasker/package.py b/var/spack/repos/builtin/packages/repeatmasker/package.py
index 72aa492f3d90a04664bdca741fd592743feb7f47..6177bb5710594112b539795cb3faa27a097b0114 100644
--- a/var/spack/repos/builtin/packages/repeatmasker/package.py
+++ b/var/spack/repos/builtin/packages/repeatmasker/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import inspect
-import distutils.dir_util
 
 
 class Repeatmasker(Package):
@@ -78,4 +77,4 @@ def install(self, spec, prefix):
         with open(config_answers_filename, 'r') as f:
             inspect.getmodule(self).perl('configure', input=f)
 
-        distutils.dir_util.copy_tree(".", prefix.bin)
+        install_tree('.', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/rna-seqc/package.py b/var/spack/repos/builtin/packages/rna-seqc/package.py
index 9fe5bcc0964a22c2df2d3f59878a6e0377e475e4..cc58cb7e0e7bb6ef64d62469052153ba7b6b027f 100644
--- a/var/spack/repos/builtin/packages/rna-seqc/package.py
+++ b/var/spack/repos/builtin/packages/rna-seqc/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import os.path
 
 
@@ -51,12 +50,12 @@ def install(self, spec, prefix):
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "rna-seqc.sh")
         script = join_path(prefix.bin, "rna-seqc")
-        copyfile(script_sh, script)
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['jdk'].prefix, 'bin', 'java')
+        java = self.spec['jdk'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file('RNA-SeQC_v{0}.jar', join_path(prefix.bin, jar_file),
diff --git a/var/spack/repos/builtin/packages/rockstar/package.py b/var/spack/repos/builtin/packages/rockstar/package.py
index f77403495fd8b21cb3ca10d495f023852011b235..ba4134f7312b3f4c20d0ce01eec7bee2d5bda1e1 100644
--- a/var/spack/repos/builtin/packages/rockstar/package.py
+++ b/var/spack/repos/builtin/packages/rockstar/package.py
@@ -22,10 +22,8 @@
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
-
 import os
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Rockstar(MakefilePackage):
@@ -59,7 +57,7 @@ def build(self, spec, prefix):
 
     def install(self, spec, prefix):
         # Install all files and directories
-        copy_tree(".", prefix)
+        install_tree('.', prefix)
 
         mkdir(prefix.bin)
         mkdir(prefix.lib)
diff --git a/var/spack/repos/builtin/packages/savanna/package.py b/var/spack/repos/builtin/packages/savanna/package.py
index 1e5ea83f5b8d5e24be7210219ad7f8d265a805d9..126c79a5ba5784a14c78fc6a17db80e5e3a9f738 100644
--- a/var/spack/repos/builtin/packages/savanna/package.py
+++ b/var/spack/repos/builtin/packages/savanna/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Savanna(MakefilePackage):
@@ -46,4 +45,4 @@ class Savanna(MakefilePackage):
     depends_on('tau', when='+tau')
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/sbt/package.py b/var/spack/repos/builtin/packages/sbt/package.py
index d5eecc145c72d55a0c31865bd1ac3df84438719f..5ad2bd2745c54b07b31d8166f8984359217ebbce 100644
--- a/var/spack/repos/builtin/packages/sbt/package.py
+++ b/var/spack/repos/builtin/packages/sbt/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import shutil
 
 
 class Sbt(Package):
@@ -40,5 +39,5 @@ class Sbt(Package):
     depends_on('java')
 
     def install(self, spec, prefix):
-        shutil.copytree('bin', join_path(prefix, 'bin'), symlinks=True)
-        shutil.copytree('conf', join_path(prefix, 'conf'), symlinks=True)
+        install_tree('bin',  prefix.bin)
+        install_tree('conf', prefix.conf)
diff --git a/var/spack/repos/builtin/packages/scr/package.py b/var/spack/repos/builtin/packages/scr/package.py
index 7ec0a5351eb9c289803d9f2ea2c65b4f91d52c0d..8fc0ecd4895517020713dbe6c152fe7fa4b0593c 100644
--- a/var/spack/repos/builtin/packages/scr/package.py
+++ b/var/spack/repos/builtin/packages/scr/package.py
@@ -25,7 +25,6 @@
 from spack import *
 
 import os
-import shutil
 
 
 class Scr(CMakePackage):
@@ -151,4 +150,4 @@ def copy_config(self):
         if spec.variants['copy_config'].value:
             dest_path = self.get_abs_path_rel_prefix(
                 spec.variants['scr_config'].value)
-            shutil.copyfile(spec.variants['copy_config'].value, dest_path)
+            install(spec.variants['copy_config'].value, dest_path)
diff --git a/var/spack/repos/builtin/packages/sctk/package.py b/var/spack/repos/builtin/packages/sctk/package.py
index 089b8c04fc82323ca1a3e0425faf61e8c5b9ad01..97326572ff8f48ba444b72cb7294db4dcf1c3a5e 100644
--- a/var/spack/repos/builtin/packages/sctk/package.py
+++ b/var/spack/repos/builtin/packages/sctk/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Sctk(Package):
@@ -49,5 +48,4 @@ def install(self, spec, prefix):
         make('config')
         make('all')
         make('install')
-        mkdirp(prefix.bin)
-        copy_tree('bin', prefix.bin)
+        install_tree('bin', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/snpeff/package.py b/var/spack/repos/builtin/packages/snpeff/package.py
index 44652ccee0758f4d962ca6f94358ef0f673a37c0..2d8c7900cec180e1c8ec258996f2208d457f99be 100644
--- a/var/spack/repos/builtin/packages/snpeff/package.py
+++ b/var/spack/repos/builtin/packages/snpeff/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 from spack import *
 import os.path
-from shutil import copyfile
 
 
 class Snpeff(Package):
@@ -45,13 +44,13 @@ def install(self, spec, prefix):
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "snpEff.sh")
-        script = join_path(prefix.bin, "snpEff")
-        copyfile(script_sh, script)
+        script = prefix.bin.snpEff
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['java'].prefix.bin, 'java')
+        java = self.spec['java'].prefix.bin.java
         kwargs = {'backup': False}
         filter_file('^java', java, script, **kwargs)
         filter_file('snpEff.jar', join_path(prefix.bin, 'snpEff.jar'),
diff --git a/var/spack/repos/builtin/packages/snphylo/package.py b/var/spack/repos/builtin/packages/snphylo/package.py
index 2add84ad2636524756bc6ab27853ab0981a63302..5066b41e2895fd1cf83057bc5787269d8a7686b0 100644
--- a/var/spack/repos/builtin/packages/snphylo/package.py
+++ b/var/spack/repos/builtin/packages/snphylo/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import distutils.dir_util
 
 
 class Snphylo(Package):
@@ -51,7 +50,7 @@ def install(self, spec, prefix):
         with open(install_answer_input, 'r') as f:
             bash = which('bash')
             bash('./setup.sh', input=f)
-            distutils.dir_util.copy_tree(".", prefix)
+            install_tree('.', prefix)
 
     def setup_environment(self, spack_env, run_env):
         run_env.prepend_path('PATH', self.spec.prefix)
diff --git a/var/spack/repos/builtin/packages/spark/package.py b/var/spack/repos/builtin/packages/spark/package.py
index 7cdd6b175f9bfcb05782aa506ef04c50b2f6f2de..1b318e8c783021a7cbb01180e5ec7c0a0fa95185 100644
--- a/var/spack/repos/builtin/packages/spark/package.py
+++ b/var/spack/repos/builtin/packages/spark/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 import re
-import shutil
 
 from spack import *
 
@@ -64,7 +63,7 @@ def install_dir(dirname):
         install_dir('yarn')
 
         # required for spark to recognize binary distribution
-        shutil.copy('RELEASE', prefix)
+        install('RELEASE', prefix)
 
     @when('+hadoop')
     def setup_environment(self, spack_env, run_env):
diff --git a/var/spack/repos/builtin/packages/sublime-text/package.py b/var/spack/repos/builtin/packages/sublime-text/package.py
index dad8ca0db4a5a08c1d0c31c5dacb3a012488a515..83dd2f380bb7580cf08be76de12d02d0ef1e0b88 100644
--- a/var/spack/repos/builtin/packages/sublime-text/package.py
+++ b/var/spack/repos/builtin/packages/sublime-text/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class SublimeText(Package):
@@ -57,4 +56,4 @@ def url_for_version(self, version):
 
     def install(self, spec, prefix):
         # Sublime text comes as a pre-compiled binary.
-        copy_tree('.', prefix)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/supernova/package.py b/var/spack/repos/builtin/packages/supernova/package.py
index 3e6ac97bc2c73fc516eed8a1a2a86be8af0df7e0..f358dd4939958151e92bd5a4e2ef16e514371a02 100644
--- a/var/spack/repos/builtin/packages/supernova/package.py
+++ b/var/spack/repos/builtin/packages/supernova/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 import os
 
 
@@ -62,4 +61,4 @@ def install(self, spec, prefix):
         # remove the broken symlinks
         rm('anaconda-cs/2.2.0-anaconda-cs-c7/lib/libtcl.so',
             'anaconda-cs/2.2.0-anaconda-cs-c7/lib/libtk.so')
-        copy_tree('.', prefix, preserve_symlinks=1)
+        install_tree('.', prefix)
diff --git a/var/spack/repos/builtin/packages/the-platinum-searcher/package.py b/var/spack/repos/builtin/packages/the-platinum-searcher/package.py
index e3d7629e1aa952bca195c81640accfd2a595d96a..858a0d5eba82d8fc2b48a60a29efdab4efac64d6 100644
--- a/var/spack/repos/builtin/packages/the-platinum-searcher/package.py
+++ b/var/spack/repos/builtin/packages/the-platinum-searcher/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-import os
-import shutil
 
 
 class ThePlatinumSearcher(Package):
@@ -38,7 +36,6 @@ class ThePlatinumSearcher(Package):
     extends("go", deptypes='build')
 
     def install(self, spec, prefix):
-        env = os.environ
         env['GOPATH'] = self.stage.source_path + ':' + env['GOPATH']
         go('install', self.package, env=env)
-        shutil.copytree('bin', os.path.join(prefix, 'bin'))
+        install_tree('bin', prefix.bin)
diff --git a/var/spack/repos/builtin/packages/tinyxml/package.py b/var/spack/repos/builtin/packages/tinyxml/package.py
index e34315882f531f5a77cc19a0440fa791e5f7f511..afd3c7f6b59f60cadedaf4b8f873c7e88e8cb2a8 100644
--- a/var/spack/repos/builtin/packages/tinyxml/package.py
+++ b/var/spack/repos/builtin/packages/tinyxml/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 import os.path
 
 
@@ -42,8 +41,8 @@ def url_for_version(self, version):
         return url.format(version.dotted, version.underscored)
 
     def patch(self):
-        copyfile(join_path(os.path.dirname(__file__),
-                           "CMakeLists.txt"), "CMakeLists.txt")
+        copy(join_path(os.path.dirname(__file__),
+             "CMakeLists.txt"), "CMakeLists.txt")
 
     def cmake_args(self):
         spec = self.spec
diff --git a/var/spack/repos/builtin/packages/trimmomatic/package.py b/var/spack/repos/builtin/packages/trimmomatic/package.py
index 470ba69defb93520c231a139f65cd84121bb3ff3..41459502ae036c29881f17717f8da7555c68b426 100644
--- a/var/spack/repos/builtin/packages/trimmomatic/package.py
+++ b/var/spack/repos/builtin/packages/trimmomatic/package.py
@@ -23,8 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
-from shutil import copyfile
 import os.path
 
 
@@ -47,18 +45,18 @@ def install(self, spec, prefix):
         install(jar_file, prefix.bin)
 
         # Put the adapter files someplace sensible
-        copy_tree('adapters', join_path(self.prefix.share, 'adapters'))
+        install_tree('adapters', prefix.share.adapters)
 
         # Set up a helper script to call java on the jar file,
         # explicitly codes the path for java and the jar file.
         script_sh = join_path(os.path.dirname(__file__), "trimmomatic.sh")
-        script = join_path(prefix.bin, "trimmomatic")
-        copyfile(script_sh, script)
+        script = prefix.bin.trimmomatic
+        install(script_sh, script)
         set_executable(script)
 
         # Munge the helper script to explicitly point to java and the
         # jar file.
-        java = join_path(self.spec['java'].prefix, 'bin', 'java')
+        java = self.spec['java'].prefix.bin.java
         kwargs = {'ignore_absent': False, 'backup': False, 'string': False}
         filter_file('^java', java, script, **kwargs)
         filter_file('trimmomatic.jar', join_path(prefix.bin, jar_file),
diff --git a/var/spack/repos/builtin/packages/trinity/package.py b/var/spack/repos/builtin/packages/trinity/package.py
index eab36f9ae4531df673e91c0988d1eac9b17f9604..5daad5e02f586561061877a59f8d5a3f95307041 100644
--- a/var/spack/repos/builtin/packages/trinity/package.py
+++ b/var/spack/repos/builtin/packages/trinity/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from distutils.dir_util import copy_tree
 
 
 class Trinity(MakefilePackage):
@@ -59,7 +58,7 @@ def build(self, spec, prefix):
         make("plugins")
 
     def install(self, spec, prefix):
-        copy_tree('.', prefix.bin, preserve_symlinks=1)
+        install_tree('.', prefix.bin)
         force_remove(join_path(prefix.bin, '.gitmodules'))
         force_remove(join_path(prefix.bin, 'Butterfly', '.err'))
         force_remove(join_path(prefix.bin, 'Butterfly', 'src', '.classpath'))
diff --git a/var/spack/repos/builtin/packages/wannier90/package.py b/var/spack/repos/builtin/packages/wannier90/package.py
index 60dcd21fffb60a3d25a19dccb944e2d3b33434d0..f8b7b9adfc82c965789b998034b001135502435f 100644
--- a/var/spack/repos/builtin/packages/wannier90/package.py
+++ b/var/spack/repos/builtin/packages/wannier90/package.py
@@ -24,7 +24,6 @@
 ##############################################################################
 import inspect
 import os.path
-import shutil
 
 from spack import *
 
@@ -77,7 +76,7 @@ def edit(self, spec, prefix):
             'make.sys'
         )
 
-        shutil.copy(template, self.makefile_name)
+        copy(template, self.makefile_name)
         for key, value in substitutions.items():
             filter_file(key, value, self.makefile_name)
 
diff --git a/var/spack/repos/builtin/packages/workrave/package.py b/var/spack/repos/builtin/packages/workrave/package.py
index 76434acad3dc11fd9a674d6f9b1eb5c77664a18f..a11fd9523e1e8b9685115b5b2954719c8084fdfa 100644
--- a/var/spack/repos/builtin/packages/workrave/package.py
+++ b/var/spack/repos/builtin/packages/workrave/package.py
@@ -23,7 +23,6 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 ##############################################################################
 from spack import *
-from shutil import copyfile
 
 
 class Workrave(AutotoolsPackage):
@@ -102,4 +101,4 @@ def extra_m4(self):
         for fname in self.m4files:
             src = '%s/%s/%s.m4' % (self.stage.source_path, fname, fname)
             dest = '%s/m4/%s.m4' % (self.stage.source_path, fname)
-            copyfile(src, dest)
+            copy(src, dest)
diff --git a/var/spack/repos/builtin/packages/yorick/package.py b/var/spack/repos/builtin/packages/yorick/package.py
index 2f4a3a349e45c39748f8964cc65f5de8bd3a5e01..63ba54761edce0c56005fc57d8e7e58a70dceead 100644
--- a/var/spack/repos/builtin/packages/yorick/package.py
+++ b/var/spack/repos/builtin/packages/yorick/package.py
@@ -24,8 +24,6 @@
 ##############################################################################
 from spack import *
 import os
-import shutil
-import glob
 
 
 class Yorick(Package):
@@ -74,13 +72,4 @@ def install(self, spec, prefix):
         make()
         make("install")
 
-        try:
-            os.makedirs(prefix)
-        except OSError:
-            pass
-        os.chdir("relocate")
-        for f in glob.glob('*'):
-            if os.path.isdir(f):
-                shutil.copytree(f, os.path.join(prefix, f))
-            else:
-                shutil.copy2(f, os.path.join(prefix, f))
+        install_tree('relocate', prefix)