summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Makefile.am4
-rw-r--r--config-daemon.ac4
-rw-r--r--configure.ac5
-rw-r--r--daemon.am2
-rw-r--r--doc/guix.texi52
-rw-r--r--gnu-system.am3
-rw-r--r--gnu/packages/algebra.scm17
-rw-r--r--gnu/packages/audio.scm2
-rw-r--r--gnu/packages/bioinformatics.scm119
-rw-r--r--gnu/packages/code.scm57
-rw-r--r--gnu/packages/databases.scm29
-rw-r--r--gnu/packages/dictionaries.scm47
-rw-r--r--gnu/packages/ebook.scm7
-rw-r--r--gnu/packages/emacs.scm64
-rw-r--r--gnu/packages/ghostscript.scm3
-rw-r--r--gnu/packages/gl.scm144
-rw-r--r--gnu/packages/glib.scm12
-rw-r--r--gnu/packages/gtk.scm4
-rw-r--r--gnu/packages/idutils.scm4
-rw-r--r--gnu/packages/java.scm172
-rw-r--r--gnu/packages/julia.scm172
-rw-r--r--gnu/packages/linux.scm2
-rw-r--r--gnu/packages/mail.scm9
-rw-r--r--gnu/packages/maths.scm118
-rw-r--r--gnu/packages/openssl.scm4
-rw-r--r--gnu/packages/package-management.scm6
-rw-r--r--gnu/packages/patches/agg-am_c_prototype.patch14
-rw-r--r--gnu/packages/patches/calibre-no-updates-dialog.patch18
-rw-r--r--gnu/packages/patches/mplayer2-theora-fix.patch286
-rw-r--r--gnu/packages/patchutils.scm32
-rw-r--r--gnu/packages/perl.scm701
-rw-r--r--gnu/packages/python.scm106
-rw-r--r--gnu/packages/scheme.scm2
-rw-r--r--gnu/packages/sdl.scm12
-rw-r--r--gnu/packages/ssh.scm1
-rw-r--r--gnu/packages/textutils.scm39
-rw-r--r--gnu/packages/version-control.scm2
-rw-r--r--gnu/packages/video.scm131
-rw-r--r--gnu/packages/web.scm595
-rw-r--r--gnu/packages/wxwidgets.scm4
-rw-r--r--gnu/packages/xorg.scm12
-rw-r--r--gnu/services/base.scm13
-rw-r--r--guix/derivations.scm48
-rw-r--r--guix/ftp-client.scm7
-rw-r--r--guix/gexp.scm66
-rw-r--r--guix/scripts/lint.scm27
-rw-r--r--guix/scripts/package.scm43
-rwxr-xr-xguix/scripts/substitute.scm (renamed from guix/scripts/substitute-binary.scm)317
-rw-r--r--guix/store.scm11
-rw-r--r--guix/tests.scm4
-rw-r--r--guix/ui.scm2
-rw-r--r--nix/scripts/substitute-binary.in11
-rw-r--r--nix/scripts/substitute.in11
-rw-r--r--pre-inst-env.in2
-rw-r--r--tests/derivations.scm14
-rw-r--r--tests/gexp.scm23
-rw-r--r--tests/store.scm12
-rw-r--r--tests/substitute.scm (renamed from tests/substitute-binary.scm)58
59 files changed, 3143 insertions, 545 deletions
diff --git a/.gitignore b/.gitignore
index 3ec36366e3..eaa7dbd51a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -96,7 +96,7 @@ stamp-h[0-9]
 /doc/guix.tp
 /doc/guix.vr
 /doc/guix.vrs
-/nix/scripts/substitute-binary
+/nix/scripts/substitute
 /doc/images/bootstrap-graph.png
 /doc/images/bootstrap-graph.eps
 /guix-register
diff --git a/Makefile.am b/Makefile.am
index 882ab8e27b..4a1f8d0a88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -96,7 +96,7 @@ MODULES =					\
   guix/scripts/gc.scm				\
   guix/scripts/hash.scm				\
   guix/scripts/pull.scm				\
-  guix/scripts/substitute-binary.scm		\
+  guix/scripts/substitute.scm			\
   guix/scripts/authenticate.scm			\
   guix/scripts/refresh.scm			\
   guix/scripts/system.scm			\
@@ -162,7 +162,7 @@ SCM_TESTS =					\
   tests/pk-crypto.scm				\
   tests/pki.scm					\
   tests/sets.scm				\
-  tests/substitute-binary.scm			\
+  tests/substitute.scm				\
   tests/builders.scm				\
   tests/derivations.scm				\
   tests/ui.scm					\
diff --git a/config-daemon.ac b/config-daemon.ac
index 5f83d45a4c..fb80c754c9 100644
--- a/config-daemon.ac
+++ b/config-daemon.ac
@@ -133,8 +133,8 @@ if test "x$guix_build_daemon" = "xyes"; then
 
   AC_CONFIG_FILES([nix/scripts/list-runtime-roots],
     [chmod +x nix/scripts/list-runtime-roots])
-  AC_CONFIG_FILES([nix/scripts/substitute-binary],
-    [chmod +x nix/scripts/substitute-binary])
+  AC_CONFIG_FILES([nix/scripts/substitute],
+    [chmod +x nix/scripts/substitute])
   AC_CONFIG_FILES([nix/scripts/guix-authenticate],
     [chmod +x nix/scripts/guix-authenticate])
   AC_CONFIG_FILES([nix/scripts/offload],
diff --git a/configure.ac b/configure.ac
index 8291b0c5d0..f2f803a2cd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -52,9 +52,10 @@ AC_SUBST([guix_sbindir])
 
 GUIX_CHECK_FILE_NAME_LIMITS
 
-dnl We require the pkg.m4 set of macros from pkg-config.
-dnl Make sure it's available.
+dnl We require pkg.m4 (from pkg-config) and guile.m4 (from Guile.)
+dnl Make sure they are available.
 m4_pattern_forbid([PKG_CHECK_MODULES])
+m4_pattern_forbid([GUILE_MODULE_AVAILABLE])
 
 PKG_CHECK_MODULES([GUILE], [guile-2.0 >= 2.0.5])
 AC_PATH_PROG([GUILE], [guile])
diff --git a/daemon.am b/daemon.am
index 5963606861..9d6516ae6c 100644
--- a/daemon.am
+++ b/daemon.am
@@ -165,7 +165,7 @@ nix/libstore/schema.sql.hh: nix/libstore/schema.sql
 
 nodist_pkglibexec_SCRIPTS =			\
   nix/scripts/list-runtime-roots		\
-  nix/scripts/substitute-binary
+  nix/scripts/substitute
 
 if BUILD_DAEMON_OFFLOAD
 
diff --git a/doc/guix.texi b/doc/guix.texi
index ae2f786111..17365036e8 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -83,6 +83,7 @@ package management tool written for the GNU system.
 Installation
 
 * Requirements::                Software needed to build and run Guix.
+* Running the Test Suite::      Testing Guix.
 * Setting Up the Daemon::       Preparing the build daemon's environment.
 * Invoking guix-daemon::        Running the build daemon.
 
@@ -156,12 +157,12 @@ Services
 
 Packaging Guidelines
 
-* Software Freedom::     What may go into the distribution.
-* Package Naming::       What's in a name?
-* Version Numbers::      When the name is not enough.
-* Python Modules::       Taming the snake.
-* Perl Modules::         Little pearls.
-* Fonts::                Fond of fonts.
+* Software Freedom::            What may go into the distribution.
+* Package Naming::              What's in a name?
+* Version Numbers::             When the name is not enough.
+* Python Modules::              Taming the snake.
+* Perl Modules::                Little pearls.
+* Fonts::                       Fond of fonts.
 
 @end detailmenu
 @end menu
@@ -239,6 +240,7 @@ is not covered here.  Please see the files @file{README} and
 
 @menu
 * Requirements::                Software needed to build and run Guix.
+* Running the Test Suite::      Testing Guix.
 * Setting Up the Daemon::       Preparing the build daemon's environment.
 * Invoking guix-daemon::        Running the build daemon.
 @end menu
@@ -295,6 +297,32 @@ located, among other things.  The default values for Nix are
 Note that @code{--disable-daemon} is not required if
 your goal is to share the store with Nix.
 
+@node Running the Test Suite
+@section Running the Test Suite
+
+After a successful @command{configure} and @code{make} run, it is a good
+idea to run the test suite.  It can help catch issues with the setup or
+environment, or bugs in Guix itself---and really, reporting test
+failures is a good way to help improve the software.  To run the test
+suite, type:
+
+@example
+make check
+@end example
+
+Test cases can run in parallel: you can use the @code{-j} option of
+GNU@tie{}make to speed things up.  The first run may take a few minutes
+on a recent machine; subsequent runs will be faster because the store
+that is created for test purposes will already have various things in
+cache.
+
+Upon failure, please email @email{bug-guix@@gnu.org} and attach the
+@file{test-suite.log} file.  When @file{tests/@var{something}.scm}
+fails, please also attach the @file{@var{something}.log} file available
+in the top-level build directory.  Please specify the Guix version being
+used as well as version numbers of the dependencies
+(@pxref{Requirements}) in your message.
+
 @node Setting Up the Daemon
 @section Setting Up the Daemon
 
@@ -5398,12 +5426,12 @@ needed is to review and apply the patch.
 
 
 @menu
-* Software Freedom::     What may go into the distribution.
-* Package Naming::       What's in a name?
-* Version Numbers::      When the name is not enough.
-* Python Modules::       Taming the snake.
-* Perl Modules::         Little pearls.
-* Fonts::                Fond of fonts.
+* Software Freedom::            What may go into the distribution.
+* Package Naming::              What's in a name?
+* Version Numbers::             When the name is not enough.
+* Python Modules::              Taming the snake.
+* Perl Modules::                Little pearls.
+* Fonts::                       Fond of fonts.
 @end menu
 
 @node Software Freedom
diff --git a/gnu-system.am b/gnu-system.am
index 2bed50fc40..153d395b57 100644
--- a/gnu-system.am
+++ b/gnu-system.am
@@ -156,6 +156,7 @@ GNU_SYSTEM_MODULES =				\
   gnu/packages/iso-codes.scm			\
   gnu/packages/java.scm				\
   gnu/packages/jrnl.scm				\
+  gnu/packages/julia.scm			\
   gnu/packages/kde.scm				\
   gnu/packages/key-mon.scm			\
   gnu/packages/language.scm			\
@@ -374,6 +375,7 @@ dist_patch_DATA =						\
   gnu/packages/patches/binutils-ld-new-dtags.patch		\
   gnu/packages/patches/binutils-loongson-workaround.patch	\
   gnu/packages/patches/calibre-drop-unrar.patch			\
+  gnu/packages/patches/calibre-no-updates-dialog.patch		\
   gnu/packages/patches/cdparanoia-fpic.patch			\
   gnu/packages/patches/chmlib-inttypes.patch			\
   gnu/packages/patches/clucene-pkgconfig.patch			\
@@ -461,6 +463,7 @@ dist_patch_DATA =						\
   gnu/packages/patches/mhash-keygen-test-segfault.patch		\
   gnu/packages/patches/mit-krb5-init-fix.patch			\
   gnu/packages/patches/mpc123-initialize-ao.patch		\
+  gnu/packages/patches/mplayer2-theora-fix.patch		\
   gnu/packages/patches/module-init-tools-moduledir.patch	\
   gnu/packages/patches/mupdf-buildsystem-fix.patch		\
   gnu/packages/patches/mutt-CVE-2014-9116.patch			\
diff --git a/gnu/packages/algebra.scm b/gnu/packages/algebra.scm
index da8dab9318..781e2a731f 100644
--- a/gnu/packages/algebra.scm
+++ b/gnu/packages/algebra.scm
@@ -158,18 +158,18 @@ GP2C, the GP to C compiler, translates GP scripts to PARI programs.")
 (define-public flint
   (package
    (name "flint")
-   (version "2.4.4")
+   (version "2.4.5")
    (source (origin
             (method url-fetch)
             (uri (string-append
                   "http://flintlib.org/flint-"
                   version ".tar.gz"))
             (sha256 (base32
-                     "1isv1sfv8sg3qvf0d99apdfi3jnql95xfzszcawdf1pgjj9rwyf4"))))
+                     "1qq11sxliy499a9g656dgk47ffb951q4gl6ddjbq838gy16kb2g4"))))
    (build-system gnu-build-system)
-   (inputs
+   (propagated-inputs
     `(("gmp" ,gmp)
-      ("mpfr" ,mpfr)))
+      ("mpfr" ,mpfr))) ; header files from both are included by flint/arith.h
    (arguments
     `(#:phases
         (alist-replace
@@ -209,7 +209,7 @@ fast arithmetic.")
 (define-public arb
   (package
    (name "arb")
-   (version "2.2.0")
+   (version "2.3.0")
    (source (origin
             (method url-fetch)
             (uri (string-append
@@ -217,11 +217,12 @@ fast arithmetic.")
                   version ".tar.gz"))
             (file-name (string-append name "-" version ".tar.gz"))
             (sha256 (base32
-                     "0a8cgzznkmr59ngj4di9a37b5h4i00gbnixnxlwd34bcbflvjzyr"))))
+                     "0yvabxyyj1g0d8b5mfgzrxq6qya8cmq97vz60ss6aajzm3nwrabk"))))
    (build-system gnu-build-system)
+   (propagated-inputs
+    `(("flint" ,flint))) ; flint.h is included by arf.h
    (inputs
-    `(("flint" ,flint)
-      ("gmp" ,gmp)
+    `(("gmp" ,gmp)
       ("mpfr" ,mpfr)))
    (arguments
     `(#:phases
diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index 58e2b8d76d..dec167f917 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -640,7 +640,7 @@ software.")
     (source (origin
               (method git-fetch)
               (uri (git-reference
-                    (url "https://gitorious.org/lv2-synths/lv2-mdametapiano.git")
+                    (url "http://git.elephly.net/software/lv2-mdametapiano.git")
                     (commit version)))
               (sha256
                (base32
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index 1214a0b708..ca8dcb761a 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -20,6 +20,7 @@
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix packages)
   #:use-module (guix download)
+  #:use-module (guix git-download)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system python)
@@ -285,6 +286,41 @@ and more accurate.  BWA-MEM also has better performance than BWA-backtrack for
 70-100bp Illumina reads.")
     (license license:gpl3+)))
 
+(define-public python2-bx-python
+  (package
+    (name "python2-bx-python")
+    (version "0.7.2")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://pypi.python.org/packages/source/b/bx-python/bx-python-"
+                    version ".tar.gz"))
+              (sha256
+               (base32
+                "0ld49idhc5zjdvbhvjq1a2qmpjj7h5v58rqr25dzmfq7g34b50xh"))
+              (modules '((guix build utils)))
+              (snippet
+               '(substitute* "setup.py"
+                  ;; remove dependency on outdated "distribute" module
+                  (("^from distribute_setup import use_setuptools") "")
+                  (("^use_setuptools\\(\\)") "")))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f ;tests fail because test data are not included
+       #:python ,python-2))
+    (inputs
+     `(("python-numpy" ,python2-numpy)
+       ("zlib" ,zlib)))
+    (native-inputs
+     `(("python-nose" ,python2-nose)
+       ("python-setuptools" ,python2-setuptools)))
+    (home-page "http://bitbucket.org/james_taylor/bx-python/")
+    (synopsis "Tools for manipulating biological data")
+    (description
+     "bx-python provides tools for manipulating biological data, particularly
+multiple sequence alignments.")
+    (license license:expat)))
+
 (define-public clipper
   (package
     (name "clipper")
@@ -615,6 +651,89 @@ RNA-Seq, the MISO model uses Bayesian inference to compute the probability
 that a read originated from a particular isoform.")
     (license license:gpl2)))
 
+(define-public python2-pbcore
+  (package
+    (name "python2-pbcore")
+    (version "0.9.3")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/PacificBiosciences/pbcore/archive/"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1z46rwjac93jm87cbj2zgjg6qvsgs65140wkbbxsvxps7ai4pm09"))))
+    (build-system python-build-system)
+    (arguments `(#:python ,python-2)) ; pbcore requires Python 2.7
+    (inputs
+     `(("python-cython" ,python2-cython)
+       ("python-numpy" ,python2-numpy)
+       ("python-pysam" ,python2-pysam)
+       ("python-h5py" ,python2-h5py)))
+    (native-inputs
+     `(("python-setuptools" ,python2-setuptools)))
+    (home-page "http://pacificbiosciences.github.io/pbcore/")
+    (synopsis "Library for reading and writing PacBio data files")
+    (description
+     "The pbcore package provides Python APIs for interacting with PacBio data
+files and writing bioinformatics applications.")
+    (license license:bsd-3)))
+
+(define-public pbtranscript-tofu
+  (let ((commit "c7bbd5472"))
+    (package
+      (name "pbtranscript-tofu")
+      (version (string-append "0.4.1." commit))
+      (source (origin
+                (method git-fetch)
+                (uri (git-reference
+                      (url "https://github.com/PacificBiosciences/cDNA_primer.git")
+                      (commit commit)))
+                (file-name (string-append name "-" version ".tar.gz"))
+                (sha256
+                 (base32
+                  "148xkzi689c49g6fdhckp6mnmj2qhjdf1j4wifm6ja7ij95d7fxx"))))
+      (build-system python-build-system)
+      (arguments
+       `(#:python ,python-2
+         ;; With standard flags, the install phase attempts to create a zip'd
+         ;; egg file, and fails with an error: 'ZIP does not support timestamps
+         ;; before 1980'
+         #:configure-flags '("--single-version-externally-managed"
+                             "--record=pbtranscript-tofu.txt")
+         #:phases
+         (alist-cons-after
+          'unpack 'enter-directory-and-clean-up
+          (lambda _
+            (chdir "pbtranscript-tofu/pbtranscript/")
+            ;; Delete clutter
+            (delete-file-recursively "dist/")
+            (delete-file-recursively "setuptools_cython-0.2.1-py2.6.egg/")
+            (delete-file-recursively "pbtools.pbtranscript.egg-info")
+            (delete-file "Cython-0.20.1.tar.gz")
+            (delete-file "setuptools_cython-0.2.1-py2.7.egg")
+            (delete-file "setuptools_cython-0.2.1.tar.gz")
+            (delete-file "setup.cfg")
+            ;; files should be writable for install phase
+            (for-each (lambda (f) (chmod f #o755))
+                      (find-files "." "\\.py")))
+          %standard-phases)))
+      (inputs
+       `(("python-cython" ,python2-cython)
+         ("python-numpy" ,python2-numpy)
+         ("python-bx-python" ,python2-bx-python)
+         ("python-pbcore" ,python2-pbcore)))
+      (native-inputs
+       `(("python-nose" ,python2-nose)
+         ("python-setuptools" ,python2-setuptools)))
+      (home-page "https://github.com/PacificBiosciences/cDNA_primer")
+      (synopsis "Analyze transcriptome data generated with the Iso-Seq protocol")
+      (description
+       "pbtranscript-tofu contains scripts to analyze transcriptome data
+generated using the PacBio Iso-Seq protocol.")
+      (license license:bsd-3))))
+
 (define-public rseqc
   (package
     (name "rseqc")
diff --git a/gnu/packages/code.scm b/gnu/packages/code.scm
index 544681212b..ad61b85afc 100644
--- a/gnu/packages/code.scm
+++ b/gnu/packages/code.scm
@@ -20,9 +20,12 @@
 (define-module (gnu packages code)
   #:use-module (guix packages)
   #:use-module (guix download)
-  #:use-module (guix licenses)
+  #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix build-system gnu)
+  #:use-module (gnu packages compression)
   #:use-module (gnu packages emacs)
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages perl)
   #:use-module (gnu packages texinfo)
   #:use-module (gnu packages autogen)
@@ -45,7 +48,7 @@
     (build-system gnu-build-system)
 
     ;; Needed to have cflow-mode.el installed.
-    (native-inputs `(("emacs" ,emacs)))
+    (native-inputs `(("emacs" ,emacs-no-x)))
 
     (home-page "http://www.gnu.org/software/cflow/")
     (synopsis "Create a graph of control flow within a program")
@@ -54,7 +57,7 @@
 control flow of the program.  It can output the graph in several styles and
 in either the POSIX format or in an extended GNU format. cflow also includes
 a major mode for Emacs for examining the flowcharts that it produces.")
-    (license gpl3+)))
+    (license license:gpl3+)))
 
 (define-public complexity
   (package
@@ -78,7 +81,7 @@ a major mode for Emacs for examining the flowcharts that it produces.")
 convoluted, overly long or otherwise difficult to understand.  This
 may help in learning or reviewing unfamiliar code or perhaps
 highlighting your own code that seemed comprehensible when you wrote it.")
-    (license gpl3+)))
+    (license license:gpl3+)))
 
 (define-public global                             ; a global variable
   (package
@@ -119,7 +122,7 @@ highlighting your own code that seemed comprehensible when you wrote it.")
 across a wide array of environments, such as different text editors, shells
 and web browsers.  The resulting tags are useful for quickly moving around in
 a large, deeply nested project.")
-    (license gpl3+)))
+    (license license:gpl3+)))
 
 (define-public sloccount
   (package
@@ -175,4 +178,46 @@ code (SLOC) in large software systems.  It can automatically identify and
 measure a wide range of programming languages.  It automatically estimates the
 effort, time, and money it would take to develop the software, using the
 COCOMO model or user-provided parameters.")
-    (license gpl2+)))
+    (license license:gpl2+)))
+
+(define-public the-silver-searcher
+  (package
+    (name "the-silver-searcher")
+    (version "0.29.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/ggreer/the_silver_searcher/archive/"
+                    version ".tar.gz"))
+              (sha256
+               (base32
+                "0ah7vcqprl9hhafi68bvzaiywy7dfm28zf7kpw3xrlqzfn0vg7kp"))
+              (file-name (string-append name "-" version ".tar.gz"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("autoconf" ,autoconf)
+       ("automake" ,automake)
+       ("libtool" ,libtool)
+       ("pkg-config" ,pkg-config)))
+    (inputs
+     `(("pcre" ,pcre)
+       ("xz" ,xz)
+       ("zlib" ,zlib)))
+    (arguments
+     `(#:phases
+       ;; There is no configure yet, so let's create it, but let configure and
+       ;; make do the work in later phases.
+       (alist-cons-before 'configure 'autoconf
+                          (lambda _
+                            (substitute* "build.sh"
+                              (("./configure") "true")
+                              (("make -j4") "true"))
+                            (zero? (system* "sh" "build.sh")))
+                          %standard-phases)))
+    (home-page "http://geoff.greer.fm/ag/")
+    (synopsis "Fast code searching tool")
+    (description
+     "The silver searcher, or 'ag', is tool for quickly searching through
+files, but compared to grep is much faster and respects files like .gitignore,
+.hgignore, etc.")
+    (license license:asl2.0)))
diff --git a/gnu/packages/databases.scm b/gnu/packages/databases.scm
index 1e2bece227..5d6be59fe5 100644
--- a/gnu/packages/databases.scm
+++ b/gnu/packages/databases.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2012, 2014 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2013 Cyril Roelandt <tipecaml@gmail.com>
 ;;; Copyright © 2014 David Thompson <davet@gnu.org>
@@ -192,7 +192,7 @@ pictures, sounds, or video.")
     ;; torture/utils.
     (arguments '(#:parallel-tests? #f))
 
-    (native-inputs `(("emacs" ,emacs)
+    (native-inputs `(("emacs" ,emacs-no-x)
                      ("bc" ,bc)))
 
     ;; TODO: Add more optional inputs.
@@ -362,6 +362,31 @@ single query, \"JOIN\", \"LEFT JOIN\", \"COUNT\", \"DISTINCT\", \"GROUP BY\",
 \"ORDER BY\" and \"HAVING\" support.")
     (license (package-license perl))))
 
+(define-public perl-dbix-class-cursor-cached
+  (package
+    (name "perl-dbix-class-cursor-cached")
+    (version "1.001002")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/A/AR/ARCANEZ/"
+                           "DBIx-Class-Cursor-Cached-" version ".tar.gz"))
+       (sha256
+        (base32
+         "19r7jr6pknxiirrybq0cd0lnr76xiw05arnfqgk9nrhp6c7vvil0"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-cache-cache" ,perl-cache-cache)
+       ("perl-dbd-sqlite" ,perl-dbd-sqlite)))
+    (propagated-inputs
+     `(("perl-carp-clan" ,perl-carp-clan)
+       ("perl-dbix-class" ,perl-dbix-class)))
+    (home-page "http://search.cpan.org/dist/DBIx-Class-Cursor-Cached")
+    (synopsis "Cursor with built-in caching support")
+    (description "DBIx::Class::Cursor::Cached provides a cursor class with
+built-in caching support.")
+    (license (package-license perl))))
+
 (define-public perl-dbix-class-introspectablem2m
   (package
     (name "perl-dbix-class-introspectablem2m")
diff --git a/gnu/packages/dictionaries.scm b/gnu/packages/dictionaries.scm
index b18e02a77e..345d0a26c1 100644
--- a/gnu/packages/dictionaries.scm
+++ b/gnu/packages/dictionaries.scm
@@ -17,18 +17,14 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu packages dictionaries)
-  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix licenses)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build-system trivial)
-  #:use-module (guix build-system cmake)
   #:use-module (gnu packages base)
-  #:use-module (gnu packages compression)
-  #:use-module (gnu packages gettext)
-  #:use-module (gnu packages glib)
-  #:use-module (gnu packages pkg-config)
-  #:use-module (gnu packages readline)
-  #:use-module (gnu packages texinfo))
+  #:use-module (gnu packages texinfo)
+  #:use-module ((gnu packages compression)
+                #:select (gzip)))
 
 (define-public vera
   (package
@@ -79,37 +75,4 @@
     (description
      "V.E.R.A. (Virtual Entity of Relevant Acronyms) is a list of computing
 acronyms distributed as an info document.")
-    (license license:fdl1.3+)))
-
-(define-public sdcv
-  (package
-    (name "sdcv")
-    (version "0.5.0-beta4")
-    (source
-     (origin
-       (method url-fetch)
-       (uri (string-append "mirror://sourceforge/project/sdcv/sdcv/sdcv-"
-                           version "-Source.tar.bz2"))
-       (sha256
-        (base32 "1b9v91al2c1499q6yx6q8jggid0714444mfj6myqgz3nvqjyrrqr"))))
-    (build-system cmake-build-system)
-    (native-inputs
-     `(("pkg-config" ,pkg-config)))
-    (inputs
-     `(("glib" ,glib)
-       ("gettext" ,gnu-gettext)
-       ("readline" ,readline)
-       ("zlib" ,zlib)))
-    (arguments
-     `(#:tests? #f ; no tests implemented
-       #:phases
-       ;; this is known workaround for missing lang files
-       (alist-cons-after 'build 'build-lang
-                         (lambda _ (zero? (system* "make" "lang")))
-                         %standard-phases)))
-    (home-page "http://sdcv.sourceforge.net/")
-    (synopsis "Command line variant of StarDict")
-    (description
-     "Sdcv is command line dictionary utility, which supports StarDict dictinary
-format.")
-    (license license:gpl2+)))
+    (license fdl1.3+)))
diff --git a/gnu/packages/ebook.scm b/gnu/packages/ebook.scm
index 196cbaeea3..05165774d7 100644
--- a/gnu/packages/ebook.scm
+++ b/gnu/packages/ebook.scm
@@ -60,7 +60,7 @@
 (define-public calibre
   (package
     (name "calibre")
-    (version "2.21.0")
+    (version "2.22.0")
     (source
       (origin
         (method url-fetch)
@@ -69,7 +69,7 @@
                             version ".tar.xz"))
         (sha256
           (base32
-           "1adig2jxwbmsxcs36jaybhc8zdb8mnkc23kabw0c72izrsg4c5gb"))
+           "19hpm5xzhjr0nfjm6xyqxjx2iwm3iw7y6bbs11337arfrxn16ly0"))
         ;; Remove non-free or doubtful code, see
         ;; https://lists.gnu.org/archive/html/guix-devel/2015-02/msg00478.html
         (modules '((guix build utils)))
@@ -77,7 +77,8 @@
           '(begin
             (delete-file-recursively "src/unrar")
             (delete-file "src/odf/thumbnail.py")))
-        (patches (list (search-patch "calibre-drop-unrar.patch")))))
+        (patches (list (search-patch "calibre-drop-unrar.patch")
+                       (search-patch "calibre-no-updates-dialog.patch")))))
     (build-system python-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index 0a6b15383f..b844661fa1 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -79,9 +79,9 @@
        ("ncurses" ,ncurses)
 
        ;; TODO: Add the optional dependencies.
-       ("xlibs" ,libx11)
+       ("libx11" ,libx11)
        ("gtk+" ,gtk+)
-       ("libXft" ,libxft)
+       ("libxft" ,libxft)
        ("libtiff" ,libtiff)
        ("giflib" ,giflib)
        ("libjpeg" ,libjpeg-8)
@@ -92,7 +92,7 @@
        ("libpng" ,libpng)
        ("zlib" ,zlib)
 
-       ("libXpm" ,libxpm)
+       ("libxpm" ,libxpm)
        ("libxml2" ,libxml2)
        ("libice" ,libice)
        ("libsm" ,libsm)
@@ -114,6 +114,23 @@ large Lisp programs.  It has full Unicode support for nearly all human
 languages.")
     (license license:gpl3+)))
 
+(define-public emacs-no-x
+  ;; This is the version that you should use as an input to packages that just
+  ;; need to byte-compile .el files.
+  (package (inherit emacs)
+    (location (source-properties->location (current-source-location)))
+    (name "emacs-no-x")
+    (synopsis "The extensible, customizable, self-documenting text
+editor (console only)")
+    (build-system gnu-build-system)
+    (inputs (fold alist-delete
+                  (package-inputs emacs)
+                  '("libx11" "gtk+" "libxft" "libtiff" "giflib" "libjpeg"
+                    "libpng" "libxpm" "libice" "libsm"
+
+                    ;; D-Bus depends on libx11, so remove it as well.
+                    "dbus")))))
+
 (define-public emacs-no-x-toolkit
   (package (inherit emacs)
     (location (source-properties->location (current-source-location)))
@@ -134,13 +151,14 @@ editor (without an X toolkit)" )
 (define-public geiser
   (package
     (name "geiser")
-    (version "0.6")
+    (version "0.7")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://savannah/geiser/" version
                                  "/geiser-" version ".tar.gz"))
              (sha256
-              (base32 "1mrk0bzqcpfhsw6635qznn47nzfy9ps7wrhkpymswdfpw5mdsry5"))))
+              (base32
+               "0cp7r91ibw45yw9k3fz1s13y7ryfsxjgpk57qv37qsznb9lmqylx"))))
     (build-system gnu-build-system)
     (arguments
      '(#:phases (alist-cons-after
@@ -152,24 +170,16 @@ editor (without an X toolkit)" )
                                            "geiser-autoloads.el")))
                  %standard-phases)))
     (inputs `(("guile" ,guile-2.0)
-              ("emacs" ,emacs)))
+              ("emacs" ,emacs-no-x)))
     (home-page "http://nongnu.org/geiser/")
     (synopsis "Collection of Emacs modes for Guile and Racket hacking")
     (description
-     "Geiser is a collection of Emacs major and minor modes that
-conspire with one or more Scheme interpreters to keep the Lisp Machine
-Spirit alive.  It draws inspiration (and a bit more) from environments
-such as Common Lisp’s Slime, Factor’s FUEL, Squeak or Emacs itself, and
-does its best to make Scheme hacking inside Emacs (even more) fun.
-
-Or, to be precise, what i consider fun.  Geiser is thus my humble
-contribution to the dynamic school of expression, and a reaction against
-what i perceive as a derailment, in modern times, of standard Scheme
-towards the static camp.  Because i prefer growing and healing to poking
-at corpses, the continuously running Scheme interpreter takes the center
-of the stage in Geiser.  A bundle of Elisp shims orchestrates the dialog
-between the Scheme interpreter, Emacs and, ultimately, the schemer,
-giving her access to live metadata.")
+     "Geiser is a collection of Emacs major and minor modes that conspire with
+one or more Scheme implementations to keep the Lisp Machine Spirit alive.  The
+continuously running Scheme interpreter takes the center of the stage in
+Geiser.  A bundle of Elisp shims orchestrates the dialog between the Scheme
+implementation, Emacs and, ultimately, the schemer, giving them access to live
+metadata.")
     (license license:bsd-3)))
 
 (define-public paredit
@@ -183,7 +193,7 @@ giving her access to live metadata.")
              (sha256
               (base32 "1np882jzvxckljx3cjz4absyzmc5hw65cs21sjmbic82163m9lf8"))))
     (build-system trivial-build-system)
-    (inputs `(("emacs" ,emacs)))
+    (inputs `(("emacs" ,emacs-no-x)))
     (arguments
      `(#:modules ((guix build utils)
                   (guix build emacs-utils))
@@ -230,7 +240,7 @@ when typing parentheses directly or commenting out code line by line.")
               (base32 "1in48g5l5xdc9cf2apnpgx73mqlz2njrpi1w52dgql4qxv3kg6gr"))))
     (build-system gnu-build-system)
     (native-inputs `(("texinfo" ,texinfo)))
-    (inputs `(("emacs" ,emacs)
+    (inputs `(("emacs" ,emacs-no-x)
               ("git" ,git)
               ("git:gui" ,git "gui")))
     (arguments
@@ -293,7 +303,7 @@ operations.")
     (native-inputs `(("autoconf" ,autoconf)))
     (inputs `(("w3m" ,w3m)
               ("imagemagick" ,imagemagick)
-              ("emacs" ,emacs)))
+              ("emacs" ,emacs-no-x)))
     (arguments
      '(#:modules ((guix build gnu-build-system)
                   (guix build utils)
@@ -361,7 +371,7 @@ operations.")
               (base32 "10byvyv9dk0ib55gfqm7bcpxmx2qbih1jd03gmihrppr2mn52nff"))))
     (build-system gnu-build-system)
     (inputs `(("wget" ,wget)
-              ("emacs" ,emacs)))
+              ("emacs" ,emacs-no-x)))
     (arguments
      '(#:modules ((guix build gnu-build-system)
                   (guix build utils)
@@ -478,7 +488,7 @@ operations.")
                           (string-append "\"" alsa "/bin/amixer\"")))
                        (substitute* "emms-tag-editor.el"
                          (("\"mp3info\"")
-                          (string-append mp3info "/bin/mp3info"))))))
+                          (string-append "\"" mp3info "/bin/mp3info\""))))))
                  (alist-cons-before
                   'install 'pre-install
                   (lambda* (#:key outputs #:allow-other-keys)
@@ -502,7 +512,7 @@ operations.")
                        (chmod target #o555)))
                    %standard-phases)))
        #:tests? #f))
-    (native-inputs `(("emacs" ,emacs)            ;for (guix build emacs-utils)
+    (native-inputs `(("emacs" ,emacs-no-x)       ;for (guix build emacs-utils)
                      ("texinfo" ,texinfo)))
     (inputs `(("alsa-utils" ,alsa-utils)
               ("vorbis-tools" ,vorbis-tools)
@@ -552,7 +562,7 @@ light user interface.")
                      (with-directory-excursion site
                        (symlink "bbdb-loaddefs.el" "bbdb-autoloads.el"))))
                  %standard-phases)))
-    (native-inputs `(("emacs" ,emacs)))
+    (native-inputs `(("emacs" ,emacs-no-x)))
     (home-page "http://savannah.nongnu.org/projects/bbdb/")
     (synopsis "Contact management utility for Emacs")
     (description
diff --git a/gnu/packages/ghostscript.scm b/gnu/packages/ghostscript.scm
index 08d1c69a57..c63e0415b4 100644
--- a/gnu/packages/ghostscript.scm
+++ b/gnu/packages/ghostscript.scm
@@ -40,8 +40,7 @@
    (source (origin
             (method url-fetch)
             (uri (string-append
-                   "http://downloads.sourceforge.net/project/lcms/lcms/"
-                   version "/lcms2-" version ".tar.gz"))
+                  "mirror://sourceforge/lcms/lcms2-" version ".tar.gz"))
             (sha256 (base32
                      "1c8lgq8gfs3nyplvbx9k8wzfj6r2bqi3f611vb1m8z3476454wji"))))
    (build-system gnu-build-system)
diff --git a/gnu/packages/gl.scm b/gnu/packages/gl.scm
index 7d549d38e5..e9b2c535a8 100644
--- a/gnu/packages/gl.scm
+++ b/gnu/packages/gl.scm
@@ -26,6 +26,7 @@
   #:use-module (guix download)
   #:use-module (guix build-system gnu)
   #:use-module (guix packages)
+  #:use-module (gnu packages autotools)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages flex)
   #:use-module (gnu packages pkg-config)
@@ -123,6 +124,38 @@ rendering modes are: Bitmaps, Anti-aliased pixmaps, Texture maps, Outlines,
 Polygon meshes, and Extruded polygon meshes")
     (license l:x11)))
 
+(define-public s2tc
+  (package
+    (name "s2tc")
+    (version "1.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/divVerent/s2tc/archive/v" version ".tar.gz"))
+       (sha256
+        (base32 "0ibfdib277fhbqvxzan0bmglwnsl1y1rw2g8skvz82l1sfmmn752"))
+       (file-name (string-append name "-" version ".tar.gz"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("autoconf" ,autoconf)
+       ("automake" ,automake)
+       ("libtool" ,libtool)))
+    (inputs
+     `(("mesa-headers" ,mesa-headers)))
+    (arguments
+     '(#:phases
+       (modify-phases %standard-phases
+         (add-after unpack autogen
+          (lambda _
+            (zero? (system* "sh" "autogen.sh")))))))
+    (home-page "https://github.com/divVerent/s2tc")
+    (synopsis "S3 Texture Compression implementation")
+    (description
+     "S2TC is a patent-free implementation of S3 Texture Compression (S3TC,
+also known as DXTn or DXTC) for Mesa.")
+    (license l:expat)))
+
 (define-public mesa
   (package
     (name "mesa")
@@ -138,22 +171,24 @@ Polygon meshes, and Extruded polygon meshes")
     (build-system gnu-build-system)
     (propagated-inputs
       `(("glproto" ,glproto)
+        ;; The following are in the Requires.private field of gl.pc.
         ("libdrm" ,libdrm)
         ("libx11" ,libx11)
         ("libxdamage" ,libxdamage)
+        ("libxfixes" ,libxfixes)
+        ("libxshmfence" ,libxshmfence)
         ("libxxf86vm" ,libxxf86vm)))
     (inputs
       `(("udev" ,eudev)
         ("dri2proto" ,dri2proto)
         ("dri3proto" ,dri3proto)
         ("presentproto" ,presentproto)
-        ("libxshmfence" ,libxshmfence)
         ("expat" ,expat)
-        ("libxfixes" ,libxfixes)
         ("libxml2" ,libxml2)
         ;; TODO: Add 'libva'
         ;; TODO: Add 'libxml2-python' for OpenGL ES 1.1 and 2.0 support
-        ("makedepend" ,makedepend)))
+        ("makedepend" ,makedepend)
+        ("s2tc" ,s2tc)))
     (native-inputs
       `(("pkg-config" ,pkg-config)
         ("gettext" ,gnu-gettext)
@@ -164,6 +199,13 @@ Polygon meshes, and Extruded polygon meshes")
      `(#:configure-flags
        '(;; drop r300 from default gallium drivers, as it requires llvm
          "--with-gallium-drivers=r600,svga,swrast"
+         ;; Enable various optional features.  TODO: opencl requires libclc,
+         ;; omx requires libomxil-bellagio
+         "--with-egl-platforms=x11,drm"
+         "--enable-glx-tls"        ;Thread Local Storage, improves performance
+         ;; "--enable-opencl"
+         ;; "--enable-omx"
+         "--enable-osmesa"
          "--enable-xa"
 
          ;; on non-intel systems, drop i915 and i965
@@ -187,7 +229,38 @@ Polygon meshes, and Extruded polygon meshes")
                   (lambda _
                     (substitute* "src/glsl/tests/lower_jumps/create_test_cases.py"
                       (("/usr/bin/env bash") (which "bash"))))
-                  %standard-phases))))
+                  (alist-cons-before
+                   'build 'fix-dlopen-libnames
+                   (lambda* (#:key inputs outputs #:allow-other-keys)
+                     (let ((s2tc (assoc-ref inputs "s2tc"))
+                           (udev (assoc-ref inputs "udev"))
+                           (out (assoc-ref outputs "out")))
+                       ;; Remain agnostic to .so.X.Y.Z versions while doing
+                       ;; the substitutions so we're future-safe.
+                       (substitute*
+                           '("src/gallium/auxiliary/util/u_format_s3tc.c"
+                             "src/mesa/main/texcompress_s3tc.c")
+                         (("\"libtxc_dxtn\\.so")
+                          (string-append "\"" s2tc "/lib/libtxc_dxtn.so")))
+                       (substitute* "src/gallium/targets/egl-static/egl_st.c"
+                         (("\"libglapi\"")
+                          (string-append "\"" out "/lib/libglapi\"")))
+                       (substitute* "src/loader/loader.c"
+                         (("dlopen\\(\"libudev\\.so")
+                          (string-append "dlopen(\"" udev "/lib/libudev.so")))
+                       (substitute* "src/glx/dri_common.c"
+                         (("dlopen\\(\"libGL\\.so")
+                          (string-append "dlopen(\"" out "/lib/libGL.so")))
+                       (substitute* "src/egl/drivers/dri2/egl_dri2.c"
+                         (("\"libglapi\\.so")
+                          (string-append "\"" out "/lib/libglapi.so")))
+                       (substitute* "src/gbm/main/backend.c"
+                         ;; No need to patch the gbm_gallium_drm.so reference;
+                         ;; it's never installed since Mesa removed its
+                         ;; egl_gallium support.
+                         (("\"gbm_dri\\.so")
+                          (string-append "\"" out "/lib/dri/gbm_dri.so")))))
+                   %standard-phases)))))
     (home-page "http://mesa3d.org/")
     (synopsis "OpenGL implementation")
     (description "Mesa is a free implementation of the OpenGL specification -
@@ -196,6 +269,69 @@ allows Mesa to be used in many different environments ranging from software
 emulation to complete hardware acceleration for modern GPUs.")
     (license l:x11)))
 
+(define-public mesa-headers
+  (package
+    (inherit mesa)
+    (name "mesa-headers")
+    (propagated-inputs '())
+    (inputs '())
+    (native-inputs '())
+    (arguments
+     '(#:phases
+       (modify-phases %standard-phases
+         (delete configure)
+         (delete build)
+         (delete check)
+         (replace install
+                  (lambda* (#:key outputs #:allow-other-keys)
+                    (copy-recursively "include" (string-append
+                                                 (assoc-ref outputs "out")
+                                                 "/include")))))))))
+
+;;; The mesa-demos distribution contains non-free files, many files with no
+;;; clear license information, and many demos that aren't useful for most
+;;; people, so we just use this for the mesa-utils package below, and possibly
+;;; other packages in the future.  This is modeled after Debian's solution.
+(define (mesa-demos-source version)
+  (origin
+    (method url-fetch)
+    (uri (string-append "ftp://ftp.freedesktop.org/pub/mesa/demos/" version
+                        "/mesa-demos-" version ".tar.bz2"))
+    (sha256 (base32 "14msj0prbl3ljwd24yaqv9pz1xzicdmqgg616xxlppbdh6syrgz4"))))
+
+(define-public mesa-utils
+  (package
+    (name "mesa-utils")
+    (version "8.2.0")
+    (source (mesa-demos-source version))
+    (build-system gnu-build-system)
+    (inputs
+     `(("mesa" ,mesa)
+       ("glut" ,freeglut)
+       ("glew" ,glew)))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)))
+    (arguments
+     '(#:phases
+       (modify-phases %standard-phases
+         (replace
+          install
+          (lambda* (#:key outputs #:allow-other-keys)
+            (let ((out (assoc-ref outputs "out")))
+              (mkdir-p (string-append out "/bin"))
+              (for-each
+               (lambda (file)
+                 (copy-file file (string-append out "/bin/" (basename file))))
+               '("src/xdemos/glxdemo" "src/xdemos/glxgears"
+                 "src/xdemos/glxinfo" "src/xdemos/glxheads"))))))))
+    (home-page "http://mesa3d.org/")
+    (synopsis "Utility tools for Mesa")
+    (description
+     "The mesa-utils package contains several utility tools for Mesa: glxdemo,
+glxgears, glxheads, and glxinfo.")
+    ;; glxdemo is public domain; others expat.
+    (license (list l:expat l:public-domain))))
+
 (define-public glew
   (package
     (name "glew")
diff --git a/gnu/packages/glib.scm b/gnu/packages/glib.scm
index a2f3cbca9d..3c68d86c96 100644
--- a/gnu/packages/glib.scm
+++ b/gnu/packages/glib.scm
@@ -514,12 +514,22 @@ useful for C++.")
      ;; test_callback_user_data_middle_single
      ;; test_callback_user_data_middle_tuple
      '(#:tests? #f))
-    (home-page "https://pypi.python.org/pypi/PyGObject")
+    (home-page "https://live.gnome.org/PyGObject")
     (synopsis "Python bindings for GObject")
     (description
      "Python bindings for GLib, GObject, and GIO.")
     (license license:lgpl2.1+)))
 
+(define-public python2-pygobject
+  (package (inherit python-pygobject)
+    (name "python2-pygobject")
+    (inputs
+     `(("python" ,python-2)
+       ("glib" ,glib)
+       ("python-pycairo" ,python2-pycairo)
+       ("gobject-introspection" ,gobject-introspection)
+       ("libffi" ,libffi)))))
+
 (define telepathy-glib
   (package
     (name "telepathy-glib")
diff --git a/gnu/packages/gtk.scm b/gnu/packages/gtk.scm
index fef5a814db..b3688d5ec1 100644
--- a/gnu/packages/gtk.scm
+++ b/gnu/packages/gtk.scm
@@ -408,10 +408,12 @@ is part of the GNOME accessibility project.")
    (native-inputs
     `(("perl" ,perl)
       ("glib" ,glib "bin")
+      ("gobject-introspection" ,gobject-introspection)
       ("pkg-config" ,pkg-config)
       ("python-wrapper" ,python-wrapper)))
    (arguments
-    `(#:phases
+    `(#:make-flags '("CC=gcc")
+      #:phases
       (alist-cons-before
        'configure 'disable-tests
        (lambda _
diff --git a/gnu/packages/idutils.scm b/gnu/packages/idutils.scm
index d71f1271bc..3dc322f568 100644
--- a/gnu/packages/idutils.scm
+++ b/gnu/packages/idutils.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -38,7 +38,7 @@
              (patches (list
                        (search-patch "diffutils-gets-undeclared.patch")))))
     (build-system gnu-build-system)
-    (native-inputs `(("emacs" ,emacs)))
+    (native-inputs `(("emacs" ,emacs-no-x)))
     (home-page "http://www.gnu.org/software/idutils/")
     (synopsis "Identifier database utilities")
     (description
diff --git a/gnu/packages/java.scm b/gnu/packages/java.scm
index 29f628ca38..d50281839f 100644
--- a/gnu/packages/java.scm
+++ b/gnu/packages/java.scm
@@ -184,6 +184,7 @@ build process and its dependencies, whereas Make uses Makefile format.")
                (zero? (system* "tar" "xvjf"
                                (assoc-ref inputs "ant-bootstrap")))
                (begin
+                 (patch-shebang "apache-ant-1.9.4/bin/ant")
                  (chdir (string-append ,name "-" ,version))
                  (mkdir "openjdk")
                  (with-directory-excursion "openjdk"
@@ -191,10 +192,8 @@ build process and its dependencies, whereas Make uses Makefile format.")
                               "openjdk6-src.tar.xz")
                    (zero? (system* "tar" "xvf" "openjdk6-src.tar.xz"))))))
         (alist-cons-after
-         'unpack 'patch-paths
+         'unpack 'patch-patches
          (lambda _
-           (patch-shebang "../apache-ant-1.9.4/bin/ant")
-
            ;; shebang in patches so that they apply cleanly
            (substitute* '("patches/jtreg-jrunscript.patch"
                           "patches/hotspot/hs23/drop_unlicensed_test.patch")
@@ -205,90 +204,91 @@ build process and its dependencies, whereas Make uses Makefile format.")
              (("ALSA_INCLUDE=/usr/include/alsa/version.h")
               (string-append "ALSA_INCLUDE="
                              (assoc-ref %build-inputs "alsa-lib")
-                             "/include/alsa/version.h")))
-
-           ;; buildtree.make generates shell scripts, so we need to replace
-           ;; the generated shebang
-           (substitute* '("openjdk/hotspot/make/linux/makefiles/buildtree.make")
-             (("/bin/sh") (which "bash")))
+                             "/include/alsa/version.h"))))
+         (alist-cons-after
+          'unpack 'patch-paths
+          (lambda _
+            ;; buildtree.make generates shell scripts, so we need to replace
+            ;; the generated shebang
+            (substitute* '("openjdk/hotspot/make/linux/makefiles/buildtree.make")
+              (("/bin/sh") (which "bash")))
 
-           (let ((corebin (string-append
-                           (assoc-ref %build-inputs "coreutils") "/bin/"))
-                 (binbin  (string-append
-                           (assoc-ref %build-inputs "binutils") "/bin/"))
-                 (grepbin (string-append
-                           (assoc-ref %build-inputs "grep") "/bin/")))
-             (substitute* '("openjdk/jdk/make/common/shared/Defs-linux.gmk"
-                            "openjdk/corba/make/common/shared/Defs-linux.gmk")
-               (("UNIXCOMMAND_PATH  = /bin/")
-                (string-append "UNIXCOMMAND_PATH = " corebin))
-               (("USRBIN_PATH  = /usr/bin/")
-                (string-append "USRBIN_PATH = " corebin))
-               (("DEVTOOLS_PATH *= */usr/bin/")
-                (string-append "DEVTOOLS_PATH = " corebin))
-               (("COMPILER_PATH *= */usr/bin/")
-                (string-append "COMPILER_PATH = "
-                               (assoc-ref %build-inputs "gcc") "/bin/")))
+            (let ((corebin (string-append
+                            (assoc-ref %build-inputs "coreutils") "/bin/"))
+                  (binbin  (string-append
+                            (assoc-ref %build-inputs "binutils") "/bin/"))
+                  (grepbin (string-append
+                            (assoc-ref %build-inputs "grep") "/bin/")))
+              (substitute* '("openjdk/jdk/make/common/shared/Defs-linux.gmk"
+                             "openjdk/corba/make/common/shared/Defs-linux.gmk")
+                (("UNIXCOMMAND_PATH  = /bin/")
+                 (string-append "UNIXCOMMAND_PATH = " corebin))
+                (("USRBIN_PATH  = /usr/bin/")
+                 (string-append "USRBIN_PATH = " corebin))
+                (("DEVTOOLS_PATH *= */usr/bin/")
+                 (string-append "DEVTOOLS_PATH = " corebin))
+                (("COMPILER_PATH *= */usr/bin/")
+                 (string-append "COMPILER_PATH = "
+                                (assoc-ref %build-inputs "gcc") "/bin/"))
+                (("DEF_OBJCOPY *=.*objcopy")
+                 (string-append "DEF_OBJCOPY = " (which "objcopy"))))
 
-             ;; fix hard-coded utility paths
-             (substitute* '("openjdk/jdk/make/common/shared/Defs-utils.gmk"
-                            "openjdk/corba/make/common/shared/Defs-utils.gmk")
-               (("ECHO *=.*echo")
-                (string-append "ECHO = " (which "echo")))
-               (("^GREP *=.*grep")
-                (string-append "GREP = " (which "grep")))
-               (("EGREP *=.*egrep")
-                (string-append "EGREP = " (which "egrep")))
-               (("CPIO *=.*cpio")
-                (string-append "CPIO = " (which "cpio")))
-               (("READELF *=.*readelf")
-                (string-append "READELF = " (which "readelf")))
-               (("^ *AR *=.*ar")
-                (string-append "AR = " (which "ar")))
-               (("^ *TAR *=.*tar")
-                (string-append "TAR = " (which "tar")))
-               (("AS *=.*as")
-                (string-append "AS = " (which "as")))
-               (("LD *=.*ld")
-                (string-append "LD = " (which "ld")))
-               (("STRIP *=.*strip")
-                (string-append "STRIP = " (which "strip")))
-               (("NM *=.*nm")
-                (string-append "NM = " (which "nm")))
-               (("^SH *=.*sh")
-                (string-append "SH = " (which "bash")))
-               (("^FIND *=.*find")
-                (string-append "FIND = " (which "find")))
-               (("LDD *=.*ldd")
-                (string-append "LDD = " (which "ldd")))
-               (("NAWK *=.*(n|g)awk")
-                (string-append "NAWK = " (which "gawk")))
-               ;; (("NAWK *=.*gawk")
-               ;;  (string-append "NAWK = " (which "gawk")))
-               (("XARGS *=.*xargs")
-                (string-append "XARGS = " (which "xargs")))
-               (("UNZIP *=.*unzip")
-                (string-append "UNZIP = " (which "unzip")))
-               (("ZIPEXE *=.*zip")
-                (string-append "ZIPEXE = " (which "zip")))
-               (("SED *=.*sed")
-                (string-append "SED = " (which "sed"))))
+              ;; fix hard-coded utility paths
+              (substitute* '("openjdk/jdk/make/common/shared/Defs-utils.gmk"
+                             "openjdk/corba/make/common/shared/Defs-utils.gmk")
+                (("ECHO *=.*echo")
+                 (string-append "ECHO = " (which "echo")))
+                (("^GREP *=.*grep")
+                 (string-append "GREP = " (which "grep")))
+                (("EGREP *=.*egrep")
+                 (string-append "EGREP = " (which "egrep")))
+                (("CPIO *=.*cpio")
+                 (string-append "CPIO = " (which "cpio")))
+                (("READELF *=.*readelf")
+                 (string-append "READELF = " (which "readelf")))
+                (("^ *AR *=.*ar")
+                 (string-append "AR = " (which "ar")))
+                (("^ *TAR *=.*tar")
+                 (string-append "TAR = " (which "tar")))
+                (("AS *=.*as")
+                 (string-append "AS = " (which "as")))
+                (("LD *=.*ld")
+                 (string-append "LD = " (which "ld")))
+                (("STRIP *=.*strip")
+                 (string-append "STRIP = " (which "strip")))
+                (("NM *=.*nm")
+                 (string-append "NM = " (which "nm")))
+                (("^SH *=.*sh")
+                 (string-append "SH = " (which "bash")))
+                (("^FIND *=.*find")
+                 (string-append "FIND = " (which "find")))
+                (("LDD *=.*ldd")
+                 (string-append "LDD = " (which "ldd")))
+                (("NAWK *=.*(n|g)awk")
+                 (string-append "NAWK = " (which "gawk")))
+                (("XARGS *=.*xargs")
+                 (string-append "XARGS = " (which "xargs")))
+                (("UNZIP *=.*unzip")
+                 (string-append "UNZIP = " (which "unzip")))
+                (("ZIPEXE *=.*zip")
+                 (string-append "ZIPEXE = " (which "zip")))
+                (("SED *=.*sed")
+                 (string-append "SED = " (which "sed"))))
 
-             ;; Some of these timestamps cause problems as they are more than
-             ;; 10 years ago, failing the build process.
-             (substitute*
-                 "openjdk/jdk/src/share/classes/java/util/CurrencyData.properties"
-               (("AZ=AZM;2005-12-31-20-00-00;AZN") "AZ=AZN")
-               (("MZ=MZM;2006-06-30-22-00-00;MZN") "MZ=MZN")
-               (("RO=ROL;2005-06-30-21-00-00;RON") "RO=RON")
-               (("TR=TRL;2004-12-31-22-00-00;TRY") "TR=TRY"))))
+              ;; Some of these timestamps cause problems as they are more than
+              ;; 10 years ago, failing the build process.
+              (substitute*
+                  "openjdk/jdk/src/share/classes/java/util/CurrencyData.properties"
+                (("AZ=AZM;2005-12-31-20-00-00;AZN") "AZ=AZN")
+                (("MZ=MZM;2006-06-30-22-00-00;MZN") "MZ=MZN")
+                (("RO=ROL;2005-06-30-21-00-00;RON") "RO=RON")
+                (("TR=TRL;2004-12-31-22-00-00;TRY") "TR=TRY"))))
           (alist-cons-before
-           'configure 'set-paths
+           'configure 'set-additional-paths
            (lambda* (#:key inputs #:allow-other-keys)
              (let* ((gcjdir  (assoc-ref %build-inputs "gcj"))
                     (gcjlib  (string-append gcjdir "/lib"))
                     (antpath (string-append (getcwd) "/../apache-ant-1.9.4")))
-               (setenv "CC" (which "gcc"))
                (setenv "CPATH"
                        (string-append (assoc-ref %build-inputs "libxrender")
                                       "/include/X11/extensions" ":"
@@ -306,8 +306,6 @@ build process and its dependencies, whereas Make uses Makefile format.")
                (setenv "ALT_FREETYPE_LIB_PATH"
                        (string-append (assoc-ref %build-inputs "freetype")
                                       "/lib"))
-               (setenv "LD_LIBRARY_PATH"
-                       (string-append antpath "/lib" ":" gcjlib))
                (setenv "PATH" (string-append antpath "/bin:"
                                              (getenv "PATH")))))
            (alist-cons-before
@@ -398,11 +396,11 @@ build process and its dependencies, whereas Make uses Makefile format.")
                (let* ((error-pattern (make-regexp "^(Error|FAILED):.*"))
                       (checker (lambda (port)
                                  (let loop ()
-                                  (let ((line (read-line port)))
-                                    (cond
-                                     ((eof-object? line) #t)
-                                     ((regexp-exec error-pattern line) #f)
-                                     (else (loop)))))))
+                                   (let ((line (read-line port)))
+                                     (cond
+                                      ((eof-object? line) #t)
+                                      ((regexp-exec error-pattern line) #f)
+                                      (else (loop)))))))
                       (run-test (lambda (test)
                                   (system* "make" test)
                                   (call-with-input-file
@@ -421,7 +419,7 @@ build process and its dependencies, whereas Make uses Makefile format.")
                   (copy-recursively "openjdk.build/docs" doc)
                   (copy-recursively "openjdk.build/j2re-image" jre)
                   (copy-recursively "openjdk.build/j2sdk-image" jdk)))
-              %standard-phases))))))))
+              %standard-phases)))))))))
     (native-inputs
      `(("ant-bootstrap"
         ,(origin
diff --git a/gnu/packages/julia.scm b/gnu/packages/julia.scm
new file mode 100644
index 0000000000..844f1b2a19
--- /dev/null
+++ b/gnu/packages/julia.scm
@@ -0,0 +1,172 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;;
+;;; This file is part of GNU Guix.
+;;;
+;;; GNU Guix is free software; you can redistribute it and/or modify it
+;;; under the terms of the GNU General Public License as published by
+;;; the Free Software Foundation; either version 3 of the License, or (at
+;;; your option) any later version.
+;;;
+;;; GNU Guix 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
+;;; GNU General Public License for more details.
+;;;
+;;; You should have received a copy of the GNU General Public License
+;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
+
+(define-module (gnu packages julia)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix build-system gnu)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages algebra)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages elf)
+  #:use-module (gnu packages gcc)
+  #:use-module (gnu packages llvm)
+  #:use-module (gnu packages libunwind)
+  #:use-module (gnu packages maths)
+  #:use-module (gnu packages multiprecision) ; mpfr
+  #:use-module (gnu packages pcre)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages python)
+  #:use-module (gnu packages textutils)
+  #:use-module (gnu packages version-control))
+
+(define-public julia
+  (package
+    (name "julia")
+    (version "0.3.6")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/JuliaLang/julia/releases/download/v"
+                    version "/julia-" version "_0c24dca65c.tar.gz"))
+              (sha256
+               (base32
+                "1hnbc2blzr9bc27m3vsr127fhg0h5imgqlrx00jakf0my0ccw8gr"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:test-target "test"
+       #:modules ((ice-9 match)
+                  (guix build gnu-build-system)
+                  (guix build utils))
+       #:phases
+       (alist-cons-after
+        'unpack 'hardcode-soname-map
+        ;; ./src/ccall.cpp creates a map from library names to paths using the
+        ;; output of "/sbin/ldconfig -p".  Since ldconfig is not used in Guix,
+        ;; we patch ccall.cpp to contain a static map.
+        (lambda* (#:key inputs #:allow-other-keys)
+          (use-modules (ice-9 match))
+          (substitute* "src/ccall.cpp"
+            (("jl_read_sonames.*;")
+             (string-join
+              (map (match-lambda
+                    ((input libname soname)
+                     (string-append
+                      "sonameMap[\"" libname "\"] = "
+                      "\"" (assoc-ref inputs input) "/lib/" soname "\";")))
+                   '(("libc"        "libc"           "libc.so.6")
+                     ("pcre"        "libpcre"        "libpcre.so")
+                     ("mpfr"        "libmpfr"        "libmpfr.so")
+                     ("openblas"    "libblas"        "libopenblas.so")
+                     ("arpack-ng"   "libarpack"      "libarpack.so")
+                     ("lapack"      "liblapack"      "liblapack.so")
+                     ("gmp"         "libgmp"         "libgmp.so")
+                     ("openlibm"    "libopenlibm"    "libopenlibm.so")
+                     ("openspecfun" "libopenspecfun" "libopenspecfun.so")
+                     ("fftw"        "libfftw3"       "libfftw3.so")
+                     ("fftwf"       "libfftw3f"      "libfftw3f.so")))))))
+        (alist-cons-before
+         'build 'replace-default-shell
+         (lambda _
+           (substitute* "base/client.jl"
+             (("/bin/sh") (which "sh"))))
+         (alist-cons-before
+          'build 'patch-include-path
+          (lambda _
+            (substitute* "deps/Makefile"
+              (("/usr/include/double-conversion")
+               (string-append (assoc-ref %build-inputs "double-conversion")
+                              "/include/double-conversion"))))
+          (alist-cons-before
+           'check 'disable-broken-test
+           ;; One test fails because it produces slightly different output.
+           (lambda _
+             (substitute* "test/repl.jl"
+               (("@test output") "# @test output")))
+           ;; no configure script
+           (alist-delete 'configure %standard-phases)))))
+       #:make-flags
+       (list
+        (string-append "prefix=" (assoc-ref %outputs "out"))
+        "CONFIG_SHELL=bash"     ;needed to build bundled libraries
+        "USE_SYSTEM_LIBUV=0"    ;Julia expects a modified libuv
+        "USE_SYSTEM_DSFMT=0"    ;not packaged for Guix and upstream has no
+                                ;build system for a shared library.
+        "USE_SYSTEM_RMATH=0"    ;Julia uses a bundled version of R's math
+                                ;library, patched to use the DSFMT RNG.
+
+        "USE_SYSTEM_LAPACK=1"
+        "USE_SYSTEM_BLAS=1"
+        "USE_BLAS64=0"          ;needed when USE_SYSTEM_BLAS=1
+
+        "USE_SYSTEM_FFTW=1"
+        "LIBFFTWNAME=libfftw3"
+        "LIBFFTWFNAME=libfftw3f"
+
+        ;; TODO: Suitesparse does not install shared libraries, so we cannot
+        ;; use the suitesparse package.
+        ;; "USE_SYSTEM_SUITESPARSE=1"
+        ;; (string-append "SUITESPARSE_INC=-I "
+        ;;                (assoc-ref %build-inputs "suitesparse")
+        ;;                "/include")
+
+        "USE_SYSTEM_GRISU=1"    ;for double-conversion
+        "USE_SYSTEM_UTF8PROC=1"
+        "USE_SYSTEM_LLVM=1"
+        "USE_SYSTEM_LIBUNWIND=1"
+        "USE_SYSTEM_PCRE=1"
+        "USE_SYSTEM_OPENLIBM=1"
+        "USE_SYSTEM_GMP=1"
+        "USE_SYSTEM_MPFR=1"
+        "USE_SYSTEM_ARPACK=1"
+        "USE_SYSTEM_LIBGIT2=1"
+        "USE_SYSTEM_OPENSPECFUN=1")))
+    (inputs
+     `(("llvm" ,llvm-3.5)
+       ("arpack-ng" ,arpack-ng)
+       ("lapack" ,lapack)
+       ("openblas" ,openblas) ;Julia does not build with Atlas
+       ("libunwind" ,libunwind)
+       ("openlibm" ,openlibm)
+       ("openspecfun" ,openspecfun)
+       ("double-conversion" ,double-conversion)
+       ("fftw" ,fftw)
+       ("fftwf" ,fftwf)
+       ("fortran" ,gfortran-4.8)
+       ("pcre" ,pcre)
+       ("utf8proc" ,utf8proc)
+       ("git" ,git)
+       ("mpfr" ,mpfr)
+       ("gmp" ,gmp)))
+    (native-inputs
+     `(("perl" ,perl)
+       ("patchelf" ,patchelf)
+       ("pkg-config" ,pkg-config)
+       ("python" ,python-2)
+       ("which" ,which)))
+    (home-page "http://julialang.org/")
+    (synopsis "High-performance dynamic language for technical computing")
+    (description
+     "Julia is a high-level, high-performance dynamic programming language for
+technical computing, with syntax that is familiar to users of other technical
+computing environments.  It provides a sophisticated compiler, distributed
+parallel execution, numerical accuracy, and an extensive mathematical function
+library.")
+    (license license:expat)))
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index c95c61692c..bd9ae0e08d 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -437,6 +437,8 @@ providing the system administrator with some help in common tasks.")
     (version "3.2.8")
     (source (origin
              (method url-fetch)
+             ;; A mirror://sourceforge URI doesn't work, presumably becuase
+             ;; the SourceForge project is misconfigured.
              (uri (string-append "http://procps.sourceforge.net/procps-"
                                  version ".tar.gz"))
              (sha256
diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index f7bb1ee896..6d20b182cd 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -329,7 +329,7 @@ repository and Maildir/IMAP as LOCAL repository.")
     ;; TODO: Add webkit and gtk to build the mug GUI.
     (inputs
      `(("xapian" ,xapian)
-       ("emacs" ,emacs)
+       ("emacs" ,emacs-no-x)
        ("guile" ,guile-2.0)
        ("glib" ,glib)
        ("gmime" ,gmime)
@@ -470,8 +470,8 @@ MailCore 2.")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "http://downloads.sourceforge.net/project/claws-mail/"
-                    "Claws Mail/" version "/" name "-" version ".tar.xz"))
+                    "mirror://sourceforge/claws-mail/claws-mail-" version
+                    ".tar.xz"))
               (sha256
                (base32 "0cyixz1jgfpi8abh9fbb8ylx9mcvw4jqj81cms666wpqr6v828yp"))))
     (build-system gnu-build-system)
@@ -517,8 +517,7 @@ which can add many functionalities to the base client.")
      (origin
        (method url-fetch)
        (uri (string-append
-             "http://downloads.sourceforge.net/project/msmtp/msmtp/" version
-             "/msmtp-" version ".tar.bz2"))
+             "mirror://sourceforge/msmtp/msmtp-" version ".tar.bz2"))
        (sha256 (base32
                 "122z38pv4q03w3mbnhrhg4w85a51258sfdg2ips0b6cgwz3wbw1b"))))
     (build-system gnu-build-system)
diff --git a/gnu/packages/maths.scm b/gnu/packages/maths.scm
index b6d3ed3680..49667cc71b 100644
--- a/gnu/packages/maths.scm
+++ b/gnu/packages/maths.scm
@@ -35,6 +35,7 @@
   #:use-module (guix build-system gnu)
   #:use-module (gnu packages algebra)
   #:use-module (gnu packages bison)
+  #:use-module (gnu packages check)
   #:use-module (gnu packages cmake)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages curl)
@@ -62,6 +63,7 @@
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
   #:use-module (gnu packages readline)
+  #:use-module (gnu packages tbb)
   #:use-module (gnu packages tcsh)
   #:use-module (gnu packages tcl)
   #:use-module (gnu packages texinfo)
@@ -90,6 +92,32 @@ effectively as a scientific calculator.")
    (license license:gpl3+)
    (home-page "http://www.gnu.org/software/units/")))
 
+(define-public double-conversion
+  (package
+    (name "double-conversion")
+    (version "1.1.5")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/floitsch/double-conversion/archive/v"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0cnr8xhyjfxijay8ymkqcph3672wp2lj23qhdmr3m4kia5kpdf83"))))
+    (build-system cmake-build-system)
+    (arguments
+     '(#:test-target "test"
+       #:configure-flags '("-DBUILD_SHARED_LIBS=ON"
+                           "-DBUILD_TESTING=ON")))
+    (home-page "https://github.com/floitsch/double-conversion")
+    (synopsis "Conversion routines for IEEE doubles")
+    (description
+     "The double-conversion library provides binary-decimal and decimal-binary
+routines for IEEE doubles.  The library consists of efficient conversion
+routines that have been extracted from the V8 JavaScript engine.")
+    (license license:bsd-3)))
+
 (define-public dionysus
   (package
     (name "dionysus")
@@ -255,7 +283,6 @@ large scale eigenvalue problems.")
         "0lk3f97i9imqascnlf6wr5mjpyxqcdj73pgj97dj2mgvyg9z1n4s"))))
     (build-system cmake-build-system)
     (home-page "http://www.netlib.org/lapack/")
-    (native-inputs `(("patchelf" ,patchelf))) ;for augment-rpath
     (inputs `(("fortran" ,gfortran-4.8)
               ("python" ,python-2)))
     (arguments
@@ -407,7 +434,6 @@ files.")
        ;; Remove non-free METIS code
        '(delete-file-recursively "contrib/Metis"))))
     (build-system cmake-build-system)
-    (native-inputs `(("patchelf" ,patchelf))) ;for augment-rpath
     (propagated-inputs
      `(("fltk" ,fltk)
        ("gfortran" ,gfortran-4.8)
@@ -991,6 +1017,40 @@ based on transforming an expression into a bytecode and precalculating
 constant parts of it.")
     (license license:expat)))
 
+(define-public openblas
+  (package
+    (name "openblas")
+    (version "0.2.13")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "https://github.com/xianyi/OpenBLAS/tarball/v"
+                           version))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1asg5mix13ipxgj5h2yj2p0r8km1di5jbcjkn5gmhb37nx7qfv6k"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:tests? #f  ;no "check" target
+       #:substitutable? #f ;force local build because of CPU detection
+       #:make-flags
+       (list (string-append "PREFIX=" (assoc-ref %outputs "out"))
+             "SHELL=bash"
+             "NO_LAPACK=1")
+       ;; no configure script
+       #:phases (alist-delete 'configure %standard-phases)))
+    (inputs
+     `(("fortran" ,gfortran-4.8)))
+    (native-inputs
+     `(("cunit" ,cunit)
+       ("perl" ,perl)))
+    (home-page "http://www.openblas.net/")
+    (synopsis "Optimized BLAS library based on GotoBLAS")
+    (description
+     "OpenBLAS is a BLAS library forked from the GotoBLAS2-1.13 BSD version.")
+    (license license:bsd-3)))
+
 (define-public openlibm
   (package
     (name "openlibm")
@@ -1065,6 +1125,60 @@ Fresnel integrals, and similar related functions as well.")
     ;; public domain software.
     (license (list license:expat license:public-domain))))
 
+(define-public suitesparse
+  (package
+    (name "suitesparse")
+    (version "4.4.3")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "http://faculty.cse.tamu.edu/davis/SuiteSparse/SuiteSparse-"
+             version ".tar.gz"))
+       (sha256
+        (base32
+         "100hdzr0mf4mzlwnqpmwpfw4pymgsf9n3g0ywb1yps2nk1zbkdy5"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:parallel-build? #f ;cholmod build fails otherwise
+       #:tests? #f  ;no "check" target
+       #:make-flags
+       (list "CC=gcc"
+             "BLAS=-lblas"
+             "TBB=-ltbb"
+             "CHOLMOD_CONFIG=-DNPARTITION" ;required when METIS is not used
+             (string-append "INSTALL_LIB="
+                            (assoc-ref %outputs "out") "/lib")
+             (string-append "INSTALL_INCLUDE="
+                            (assoc-ref %outputs "out") "/include"))
+       #:phases
+       (alist-cons-before
+        'install 'prepare-out
+        ;; README.txt states that the target directories must exist prior to
+        ;; running "make install".
+        (lambda _
+          (mkdir-p (string-append (assoc-ref %outputs "out") "/lib"))
+          (mkdir-p (string-append (assoc-ref %outputs "out") "/include")))
+        ;; no configure script
+        (alist-delete 'configure %standard-phases))))
+    (inputs
+     `(("tbb" ,tbb)
+       ("lapack" ,lapack)))
+    (home-page "http://faculty.cse.tamu.edu/davis/suitesparse.html")
+    (synopsis "Suite of sparse matrix software")
+    (description
+     "SuiteSparse is a suite of sparse matrix algorithms, including: UMFPACK,
+multifrontal LU factorization; CHOLMOD, supernodal Cholesky; SPQR,
+multifrontal QR; KLU and BTF, sparse LU factorization, well-suited for circuit
+simulation; ordering methods (AMD, CAMD, COLAMD, and CCOLAMD); CSparse and
+CXSparse, a concise sparse Cholesky factorization package; and many other
+packages.")
+    ;; LGPLv2.1+:
+    ;;   AMD, CAMD, BTF, COLAMD, CCOLAMD, CSparse, CXSparse, KLU, LDL
+    ;; GPLv2+:
+    ;;  GPUQREngine, RBio, SuiteSparse_GPURuntime, SuiteSparseQR, UMFPACK
+    (license (list license:gpl2+ license:lgpl2.1+))))
+
 (define-public atlas
   (package
     (name "atlas")
diff --git a/gnu/packages/openssl.scm b/gnu/packages/openssl.scm
index 26a1bbb811..6acbb12737 100644
--- a/gnu/packages/openssl.scm
+++ b/gnu/packages/openssl.scm
@@ -29,14 +29,14 @@
 (define-public openssl
   (package
    (name "openssl")
-   (version "1.0.2")
+   (version "1.0.2a")
    (source (origin
             (method url-fetch)
             (uri (string-append "ftp://ftp.openssl.org/source/openssl-" version
                                 ".tar.gz"))
             (sha256
              (base32
-              "1s988w1h1yxh7lhrhh164hv6vil94lkwzh6g2rfm03dypbrvlj4c"))))
+              "0jijgzf72659pikms2bc5w31h78xrd1h5zp2r01an2h340y3kdhm"))))
    (build-system gnu-build-system)
    (native-inputs `(("perl" ,perl)))
    (arguments
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index b20e7d3566..f31f872602 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -96,7 +96,7 @@
                    #t)
                  %standard-phases)))
     (native-inputs `(("pkg-config" ,pkg-config)
-                     ("emacs" ,emacs)))           ;for guix.el
+                     ("emacs" ,emacs-no-x)))      ;for guix.el
     (inputs
      (let ((boot-guile (lambda (arch hash)
                          (origin
@@ -142,7 +142,7 @@ the Nix package manager.")
 
 (define guix-devel
   ;; Development version of Guix.
-  (let ((commit "07157e8"))
+  (let ((commit "9586011"))
     (package (inherit guix-0.8.1)
       (version (string-append "0.8.1." commit))
       (source (origin
@@ -152,7 +152,7 @@ the Nix package manager.")
                       (commit commit)))
                 (sha256
                  (base32
-                  "0ksfvkkgzsz58h60a8kypg9x24sabl5007hr3a2ddgh05rjckbci"))))
+                  "0dcmw8gz2qxknjnh9k8rdwmgysnxnvawdmlg1pyzngakwlsy1c3z"))))
       (arguments
        (substitute-keyword-arguments (package-arguments guix-0.8.1)
          ((#:phases phases)
diff --git a/gnu/packages/patches/agg-am_c_prototype.patch b/gnu/packages/patches/agg-am_c_prototype.patch
index 3a09dc7be6..b31e86cc2d 100644
--- a/gnu/packages/patches/agg-am_c_prototype.patch
+++ b/gnu/packages/patches/agg-am_c_prototype.patch
@@ -1,3 +1,17 @@
+AM_C_PROTOTYPES is no longer supported.
+
+https://lists.gnu.org/archive/html/automake-patches/2011-06/msg00082.html
+
+Failure without patch:
+
+starting phase `autoreconf'
+aclocal: warning: autoconf input should be named 'configure.ac', not 'configure.in'
+configure.in:11: error: automatic de-ANSI-fication support has been removed
+/gnu/store/…-automake-1.15/share/aclocal-1.15/obsolete.m4:26: AM_C_PROTOTYPES is expanded from...
+configure.in:11: the top level
+
+
+Upstream is dead.
 --- a/configure.in	2015-03-15 18:59:12.557417149 +0100
 +++ b/configure.in	2015-03-15 18:59:29.273416518 +0100
 @@ -8,7 +8,6 @@
diff --git a/gnu/packages/patches/calibre-no-updates-dialog.patch b/gnu/packages/patches/calibre-no-updates-dialog.patch
new file mode 100644
index 0000000000..1d8d79660e
--- /dev/null
+++ b/gnu/packages/patches/calibre-no-updates-dialog.patch
@@ -0,0 +1,18 @@
+Taken from debian.
+
+# Description: Disable update check by default.
+Index: calibre/src/calibre/gui2/main.py
+===================================================================
+--- calibre.orig/src/calibre/gui2/main.py	2014-02-02 10:41:28.470954623 +0100
++++ calibre/src/calibre/gui2/main.py	2014-02-02 10:41:56.546954247 +0100
+@@ -37,8 +37,8 @@
+                       help=_('Start minimized to system tray.'))
+     parser.add_option('-v', '--verbose', default=0, action='count',
+                       help=_('Ignored, do not use. Present only for legacy reasons'))
+-    parser.add_option('--no-update-check', default=False, action='store_true',
+-            help=_('Do not check for updates'))
++    parser.add_option('--update-check', dest='no_update_check', default=True, action='store_false',
++            help=_('Check for updates'))
+     parser.add_option('--ignore-plugins', default=False, action='store_true',
+             help=_('Ignore custom plugins, useful if you installed a plugin'
+                 ' that is preventing calibre from starting'))
diff --git a/gnu/packages/patches/mplayer2-theora-fix.patch b/gnu/packages/patches/mplayer2-theora-fix.patch
new file mode 100644
index 0000000000..982db5f57c
--- /dev/null
+++ b/gnu/packages/patches/mplayer2-theora-fix.patch
@@ -0,0 +1,286 @@
+Fix libtheora linking issue with modern theora versions.
+
+Adapted from:
+http://git.buildroot.net/buildroot/commit/?id=46b71cb0be27c0e6b7c93afb49fc80779bf310e3
+
+--- a/libmpcodecs/vd_theora.c
++++ b/libmpcodecs/vd_theora.c
+@@ -39,22 +39,23 @@
+ 
+ LIBVD_EXTERN(theora)
+ 
+-#include <theora/theora.h>
++#include <theora/theoradec.h>
+ 
+ #define THEORA_NUM_HEADER_PACKETS 3
+ 
+ typedef struct theora_struct_st {
+-    theora_state st;
+-    theora_comment cc;
+-    theora_info inf;
++    th_setup_info *tsi;
++    th_dec_ctx    *tctx;
++    th_comment     tc;
++    th_info        ti;
+ } theora_struct_t;
+ 
+ /** Convert Theora pixelformat to the corresponding IMGFMT_ */
+-static uint32_t theora_pixelformat2imgfmt(theora_pixelformat fmt){
++static uint32_t theora_pixelformat2imgfmt(th_pixel_fmt fmt){
+     switch(fmt) {
+-       case OC_PF_420: return IMGFMT_YV12;
+-       case OC_PF_422: return IMGFMT_422P;
+-       case OC_PF_444: return IMGFMT_444P;
++       case TH_PF_420: return IMGFMT_YV12;
++       case TH_PF_422: return IMGFMT_422P;
++       case TH_PF_444: return IMGFMT_444P;
+     }
+     return 0;
+ }
+@@ -64,7 +65,7 @@
+     theora_struct_t *context = sh->context;
+     switch(cmd) {
+     case VDCTRL_QUERY_FORMAT:
+-        if (*(int*)arg == theora_pixelformat2imgfmt(context->inf.pixelformat))
++        if (*(int*)arg == theora_pixelformat2imgfmt(context->ti.pixel_fmt))
+ 	    return CONTROL_TRUE;
+ 	return CONTROL_FALSE;
+     }
+@@ -88,8 +89,9 @@
+     if (!context)
+         goto err_out;
+ 
+-    theora_info_init(&context->inf);
+-    theora_comment_init(&context->cc);
++    th_info_init(&context->ti);
++    th_comment_init(&context->tc);
++    context->tsi = NULL;
+ 
+     /* Read all header packets, pass them to theora_decode_header. */
+     for (i = 0; i < THEORA_NUM_HEADER_PACKETS; i++)
+@@ -109,7 +111,7 @@
+             op.b_o_s = 1;
+         }
+ 
+-        if ( (errorCode = theora_decode_header (&context->inf, &context->cc, &op)) )
++        if ( (errorCode = th_decode_headerin (&context->ti, &context->tc, &context->tsi, &op)) < 0)
+         {
+             mp_msg(MSGT_DECVIDEO, MSGL_ERR, "Broken Theora header; errorCode=%i!\n", errorCode);
+             goto err_out;
+@@ -117,23 +119,25 @@
+     }
+ 
+     /* now init codec */
+-    errorCode = theora_decode_init (&context->st, &context->inf);
+-    if (errorCode)
++    context->tctx = th_decode_alloc (&context->ti, context->tsi);
++    if (!context->tctx)
+     {
+-        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed: %i \n", errorCode);
++        mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode init failed\n");
+         goto err_out;
+     }
++    /* free memory used for decoder setup information */
++    th_setup_free(context->tsi);
+ 
+-    if(sh->aspect==0.0 && context->inf.aspect_denominator!=0)
++    if(sh->aspect==0.0 && context->ti.aspect_denominator!=0)
+     {
+-       sh->aspect = ((double)context->inf.aspect_numerator * context->inf.width)/
+-          ((double)context->inf.aspect_denominator * context->inf.height);
++       sh->aspect = ((double)context->ti.aspect_numerator * context->ti.frame_width)/
++          ((double)context->ti.aspect_denominator * context->ti.frame_height);
+     }
+ 
+     mp_msg(MSGT_DECVIDEO,MSGL_V,"INFO: Theora video init ok!\n");
+-    mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Frame: %dx%d, Picture %dx%d, Offset [%d,%d]\n", context->inf.width, context->inf.height, context->inf.frame_width, context->inf.frame_height, context->inf.offset_x, context->inf.offset_y);
++    mp_msg(MSGT_DECVIDEO,MSGL_INFO,"Frame: %dx%d, Picture %dx%d, Offset [%d,%d]\n", context->ti.frame_width, context->ti.frame_height, context->ti.pic_width, context->ti.pic_height, context->ti.pic_x, context->ti.pic_y);
+ 
+-    return mpcodecs_config_vo (sh,context->inf.width,context->inf.height,theora_pixelformat2imgfmt(context->inf.pixelformat));
++    return mpcodecs_config_vo (sh,context->ti.frame_width,context->ti.frame_height,theora_pixelformat2imgfmt(context->ti.pixel_fmt));
+ 
+ err_out:
+     free(context);
+@@ -150,9 +154,9 @@
+ 
+    if (context)
+    {
+-      theora_info_clear(&context->inf);
+-      theora_comment_clear(&context->cc);
+-      theora_clear (&context->st);
++      th_info_clear(&context->ti);
++      th_comment_clear(&context->tc);
++      th_decode_free (context->tctx);
+       free (context);
+    }
+ }
+@@ -165,7 +169,7 @@
+    theora_struct_t *context = sh->context;
+    int errorCode = 0;
+    ogg_packet op;
+-   yuv_buffer yuv;
++   th_ycbcr_buffer ycbcrbuf;
+    mp_image_t* mpi;
+ 
+    // no delayed frames
+@@ -177,31 +181,31 @@
+    op.packet = data;
+    op.granulepos = -1;
+ 
+-   errorCode = theora_decode_packetin (&context->st, &op);
+-   if (errorCode)
++   errorCode = th_decode_packetin (context->tctx, &op, NULL);
++   if (errorCode < 0)
+    {
+       mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode packetin failed: %i \n",
+ 	     errorCode);
+       return NULL;
+    }
+ 
+-   errorCode = theora_decode_YUVout (&context->st, &yuv);
+-   if (errorCode)
++   errorCode = th_decode_ycbcr_out (context->tctx, ycbcrbuf);
++   if (errorCode < 0)
+    {
+       mp_msg(MSGT_DECVIDEO,MSGL_ERR,"Theora decode YUVout failed: %i \n",
+ 	     errorCode);
+       return NULL;
+    }
+ 
+-    mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, yuv.y_width, yuv.y_height);
++    mpi = mpcodecs_get_image(sh, MP_IMGTYPE_EXPORT, 0, ycbcrbuf[0].width, ycbcrbuf[0].height);
+     if(!mpi) return NULL;
+ 
+-    mpi->planes[0]=yuv.y;
+-    mpi->stride[0]=yuv.y_stride;
+-    mpi->planes[1]=yuv.u;
+-    mpi->stride[1]=yuv.uv_stride;
+-    mpi->planes[2]=yuv.v;
+-    mpi->stride[2]=yuv.uv_stride;
++    mpi->planes[0]=ycbcrbuf[0].data;
++    mpi->stride[0]=ycbcrbuf[0].stride;
++    mpi->planes[1]=ycbcrbuf[1].data;
++    mpi->stride[1]=ycbcrbuf[1].stride;
++    mpi->planes[2]=ycbcrbuf[2].data;
++    mpi->stride[2]=ycbcrbuf[2].stride;
+ 
+     return mpi;
+ }
+--- a/libmpdemux/demux_ogg.c
++++ b/libmpdemux/demux_ogg.c
+@@ -49,21 +49,21 @@
+ #endif
+ 
+ #ifdef CONFIG_OGGTHEORA
+-#include <theora/theora.h>
+-int _ilog (unsigned int); /* defined in many places in theora/lib/ */
++#include <theora/theoradec.h>
+ #endif
+ 
+ #define BLOCK_SIZE 4096
+ 
+ /* Theora decoder context : we won't be able to interpret granule positions
+- * without using theora_granule_time with the theora_state of the stream.
++ * without using th_granule_time with the th_dec_ctx of the stream.
+  * This is duplicated in `vd_theora.c'; put this in a common header?
+  */
+ #ifdef CONFIG_OGGTHEORA
+ typedef struct theora_struct_st {
+-    theora_state   st;
+-    theora_comment cc;
+-    theora_info    inf;
++    th_setup_info *tsi;
++    th_dec_ctx    *tctx;
++    th_comment     tc;
++    th_info        ti;
+ } theora_struct_t;
+ #endif
+ 
+@@ -116,7 +116,7 @@
+     float   samplerate; /// granulpos 2 time
+     int64_t lastpos;
+     int32_t lastsize;
+-    int     keyframe_frequency_force;
++    int     keyframe_granule_shift;
+ 
+     // Logical stream state
+     ogg_stream_state stream;
+@@ -299,11 +299,10 @@
+            have theora_state st, until all header packets were passed to the
+            decoder. */
+         if (!pack->bytes || !(*data&0x80)) {
+-            int keyframe_granule_shift = _ilog(os->keyframe_frequency_force - 1);
+-            int64_t iframemask = (1 << keyframe_granule_shift) - 1;
++            int64_t iframemask = (1 << os->keyframe_granule_shift) - 1;
+ 
+             if (pack->granulepos >= 0) {
+-                os->lastpos  = pack->granulepos >> keyframe_granule_shift;
++                os->lastpos  = pack->granulepos >> os->keyframe_granule_shift;
+                 os->lastpos += pack->granulepos & iframemask;
+                 *flags = (pack->granulepos & iframemask) == 0;
+             } else {
+@@ -892,14 +891,15 @@
+ #ifdef CONFIG_OGGTHEORA
+         } else if (pack.bytes >= 7 && !strncmp (&pack.packet[1], "theora", 6)) {
+             int errorCode = 0;
+-            theora_info inf;
+-            theora_comment cc;
++            th_info ti;
++            th_comment tc;
++            th_setup_info *tsi = NULL;
+ 
+-            theora_info_init (&inf);
+-            theora_comment_init (&cc);
++            th_info_init (&ti);
++            th_comment_init (&tc);
+ 
+-            errorCode = theora_decode_header (&inf, &cc, &pack);
+-            if (errorCode) {
++            errorCode = th_decode_headerin(&ti, &tc, &tsi, &pack);
++            if (errorCode < 0) {
+                 mp_msg(MSGT_DEMUX, MSGL_ERR,
+                        "Theora header parsing failed: %i \n", errorCode);
+             } else {
+@@ -908,30 +908,32 @@
+                 sh_v->bih = calloc(1, sizeof(*sh_v->bih));
+                 sh_v->bih->biSize        = sizeof(*sh_v->bih);
+                 sh_v->bih->biCompression = sh_v->format = FOURCC_THEORA;
+-                sh_v->fps = ((double)inf.fps_numerator) / (double)inf.fps_denominator;
+-                sh_v->frametime = ((double)inf.fps_denominator) / (double)inf.fps_numerator;
+-                sh_v->disp_w = sh_v->bih->biWidth  = inf.frame_width;
+-                sh_v->disp_h = sh_v->bih->biHeight = inf.frame_height;
++                sh_v->fps = ((double)ti.fps_numerator) / (double)ti.fps_denominator;
++                sh_v->frametime = ((double)ti.fps_denominator) / (double)ti.fps_numerator;
++                sh_v->i_bps  = ti.target_bitrate / 8;
++                sh_v->disp_w = sh_v->bih->biWidth  = ti.frame_width;
++                sh_v->disp_h = sh_v->bih->biHeight = ti.frame_height;
+                 sh_v->bih->biBitCount  = 24;
+                 sh_v->bih->biPlanes    = 3;
+                 sh_v->bih->biSizeImage = ((sh_v->bih->biBitCount / 8) * sh_v->bih->biWidth * sh_v->bih->biHeight);
+                 ogg_d->subs[ogg_d->num_sub].samplerate               = sh_v->fps;
+                 ogg_d->subs[ogg_d->num_sub].theora                   = 1;
+-                ogg_d->subs[ogg_d->num_sub].keyframe_frequency_force = inf.keyframe_frequency_force;
++                ogg_d->subs[ogg_d->num_sub].keyframe_granule_shift   = ti.keyframe_granule_shift;
+                 ogg_d->subs[ogg_d->num_sub].id                       = n_video;
+                 n_video++;
+                 mp_msg(MSGT_DEMUX, MSGL_INFO,
+                        "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
+                        ogg_d->num_sub,
+-                       (int)inf.version_major,
+-                       (int)inf.version_minor,
+-                       (int)inf.version_subminor,
++                       (int)ti.version_major,
++                       (int)ti.version_minor,
++                       (int)ti.version_subminor,
+                        n_video - 1);
+                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
+                     print_video_header(sh_v->bih, MSGL_V);
+             }
+-            theora_comment_clear(&cc);
+-            theora_info_clear(&inf);
++            th_comment_clear(&tc);
++            th_info_clear(&ti);
++            th_setup_free(tsi);
+ #endif /* CONFIG_OGGTHEORA */
+         } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) {
+             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
diff --git a/gnu/packages/patchutils.scm b/gnu/packages/patchutils.scm
index 48f4d29584..cf8a6e494b 100644
--- a/gnu/packages/patchutils.scm
+++ b/gnu/packages/patchutils.scm
@@ -28,7 +28,8 @@
   #:use-module (gnu packages file)
   #:use-module (gnu packages gawk)
   #:use-module (gnu packages less)
-  #:use-module (gnu packages perl))
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages xml))
 
 (define-public patchutils
   (package
@@ -140,3 +141,32 @@ listing the files modified by a patch.")
 track of the changes each patch makes.  Patches can be applied, un-applied,
 refreshed, and more.")
     (license gpl2)))
+
+(define-public colordiff
+  (package
+    (name "colordiff")
+    (version "1.0.13")
+    (source
+     (origin
+      (method url-fetch)
+      (uri (string-append "http://www.colordiff.org/colordiff-"
+                          version ".tar.gz"))
+      (sha256
+       (base32 "0akcz1p3klsjnhwcqdfq4grs6paljc5c0jzr3mqla5f862hhaa6f"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f
+       #:make-flags (list (string-append "DESTDIR=" (assoc-ref %outputs "out"))
+                          "INSTALL_DIR=/bin" "MAN_DIR=/share/man/man1")
+       #:phases
+       (alist-delete 'configure
+                     (alist-delete 'build %standard-phases))))
+    (inputs
+     `(("perl" ,perl)
+       ("xmlto" ,xmlto)))
+    (home-page "http://www.colordiff.org")
+    (synopsis "Display diff output with colors")
+    (description
+     "Colordiff is Perl script wrapper on top of diff command which provides
+'syntax highlighting' for various patch formats.")
+    (license gpl2+)))
diff --git a/gnu/packages/perl.scm b/gnu/packages/perl.scm
index 0b3666107e..9d41d88d26 100644
--- a/gnu/packages/perl.scm
+++ b/gnu/packages/perl.scm
@@ -143,6 +143,27 @@ explicitly alias the class to another name or, if you prefer, you can do so
 implicitly.")
     (license (package-license perl))))
 
+(define-public perl-appconfig
+  (package
+    (name "perl-appconfig")
+    (version "1.71")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/N/NE/NEILB/"
+                           "AppConfig-" version ".tar.gz"))
+       (sha256
+        (base32
+         "03vvi3mk4833mx2c6dkm9zhvakf02mb2b7wz9pk9xc7c4mq04xqi"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-pod" ,perl-test-pod)))
+    (home-page "http://search.cpan.org/dist/AppConfig")
+    (synopsis "Configuration files and command line parsing")
+    (description "AppConfig is a bundle of Perl5 modules for reading
+configuration files and parsing command line arguments.")
+    (license (package-license perl))))
+
 (define-public perl-archive-zip
   (package
     (name "perl-archive-zip")
@@ -233,6 +254,33 @@ but don't want to go all out and profile your code.")
                               "Benchmark-Timer-" version))
     (license gpl2)))
 
+(define-public perl-cache-cache
+  (package
+    (name "perl-cache-cache")
+    (version "1.08")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://cpan/authors/id/R/RJ/RJBS/"
+                                  "Cache-Cache-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1s6i670dc3yb6ngvdk48y6szdk5n1f4icdcjv2vi1l2xp9fzviyj"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-digest-sha1" ,perl-digest-sha1)
+       ("perl-error" ,perl-error)
+       ("perl-ipc-sharelite" ,perl-ipc-sharelite)))
+    (home-page "http://search.cpan.org/dist/Cache-Cache")
+    (synopsis "Cache interface for Perl")
+    (description "The Cache modules are designed to assist a developer in
+persisting data for a specified period of time.  Often these modules are used
+in web applications to store data locally to save repeated and redundant
+expensive calls to remote machines or databases.  People have also been known
+to use Cache::Cache for its straightforward interface in sharing data between
+runs of an application or invocations of a CGI-style script or simply as an
+easy to use abstraction of the filesystem or shared memory.")
+    (license (package-license perl))))
+
 (define-public perl-capture-tiny
   (package
     (name "perl-capture-tiny")
@@ -256,6 +304,48 @@ code or from an external program.  Optionally, output can be teed so that it
 is captured while being passed through to the original file handles.")
     (license asl2.0)))
 
+(define-public perl-carp-assert
+  (package
+    (name "perl-carp-assert")
+    (version "0.21")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/N/NE/NEILB/"
+                           "Carp-Assert-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0km5fc6r6whxh6h5yd7g1j0bi96sgk0gkda6cardicrw9qmqwkwj"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/Carp-Assert")
+    (synopsis "Executable comments for Perl")
+    (description "Carp::Assert is intended for a purpose like the ANSI C
+library assert.h.")
+    (license (package-license perl))))
+
+(define-public perl-carp-assert-more
+  (package
+    (name "perl-carp-assert-more")
+    (version "1.14")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/P/PE/PETDANCE/"
+                           "Carp-Assert-More-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0cq7qk4qbhqppm4raby5k24b5mx5qjgy1884nrddhxillnzlq01z"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-exception" ,perl-test-exception)))
+    (propagated-inputs
+     `(("perl-carp-assert" ,perl-carp-assert)))
+    (home-page "http://search.cpan.org/dist/Carp-Assert-More")
+    (synopsis "Convenience wrappers around Carp::Assert")
+    (description "Carp::Assert::More is a set of handy assertion functions for
+Perl.")
+    (license artistic2.0)))
+
 (define-public perl-carp-clan
   (package
     (name "perl-carp-clan")
@@ -771,6 +861,27 @@ the caller.")
 CPAN::Meta object are present.")
     (license (package-license perl))))
 
+(define-public perl-cpanel-json-xs
+  (package
+    (name "perl-cpanel-json-xs")
+    (version "3.0114")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RU/RURBAN/"
+                           "Cpanel-JSON-XS-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0jhi1v0631x4d14a7cpfnpjqhs34zkygxjn1nwvvr927awx5jx71"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-common-sense" ,perl-common-sense)))
+    (home-page "http://search.cpan.org/dist/Cpanel-JSON-XS")
+    (synopsis "JSON::XS for Cpanel")
+    (description "This module converts Perl data structures to JSON and vice
+versa.")
+    (license (package-license perl))))
+
 (define-public perl-data-dump
   (package
     (name "perl-data-dump")
@@ -881,6 +992,37 @@ The maths behind this is unfortunately fiddly, hence this module.")
 variants")
     (license (package-license perl))))
 
+(define-public perl-data-visitor
+  (package
+    (name "perl-data-visitor")
+    (version "0.30")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/D/DO/DOY/"
+                           "Data-Visitor-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0m7d1505af9z2hj5aw020grcmjjlvnkjpvjam457d7k5qfy4m8lf"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-requires" ,perl-test-requires)))
+    (propagated-inputs
+     `(("perl-class-load" ,perl-class-load)
+       ("perl-moose" ,perl-moose)
+       ("perl-namespace-clean" ,perl-namespace-clean)
+       ("perl-task-weaken" ,perl-task-weaken)
+       ("perl-tie-toobject" ,perl-tie-toobject)))
+    (home-page "http://search.cpan.org/dist/Data-Visitor")
+    (synopsis "Visitor style traversal of Perl data structures")
+    (description "This module is a simple visitor implementation for Perl
+values.  It has a main dispatcher method, visit, which takes a single perl
+value and then calls the methods appropriate for that value.  It can
+recursively map (cloning as necessary) or just traverse most structures, with
+support for per-object behavior, circular structures, visiting tied
+structures, and all ref types (hashes, arrays, scalars, code, globs).")
+    (license (package-license perl))))
+
 (define-public perl-devel-caller
   (package
     (name "perl-devel-caller")
@@ -1099,6 +1241,26 @@ SHA-1 message digest algorithm for use by Perl programs.")
 modules separately and deal with them after the module is done installing.")
     (license (package-license perl))))
 
+(define-public perl-error
+  (package
+    (name "perl-error")
+    (version "0.17023")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://cpan/authors/id/S/SH/SHLOMIF/"
+                                  "Error-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0dsxic78mxy30qvbbdzfyp501hbkwhnbmafqfxipr0yqfy8f2j5g"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/Error")
+    (synopsis "OO-ish Error/Exception handling for Perl")
+    (description "The Error package provides two interfaces. Firstly Error
+provides a procedural interface to exception handling. Secondly Error is a
+base class for errors/exceptions that can either be thrown, for subsequent
+catch, or can simply be recorded.")
+    (license (package-license perl))))
+
 (define-public perl-eval-closure
   (package
     (name "perl-eval-closure")
@@ -1256,6 +1418,55 @@ it ties together a family of modern toolchain modules.")
 module building modules.")
     (license (package-license perl))))
 
+(define-public perl-file-changenotify
+  (package
+    (name "perl-file-changenotify")
+    (version "0.24")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/D/DR/DROLSKY/"
+                           "File-ChangeNotify-" version ".tar.gz"))
+       (sha256
+        (base32
+         "090i265f73jlcl5rv250791vw32j9vvl4nd5abc7myg0klb8109w"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-exception" ,perl-test-exception)))
+    (propagated-inputs
+     `(("perl-class-load" ,perl-class-load)
+       ("perl-list-moreutils" ,perl-list-moreutils)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-params-validate" ,perl-moosex-params-validate)
+       ("perl-moosex-semiaffordanceaccessor"
+        ,perl-moosex-semiaffordanceaccessor)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)))
+    (home-page "http://search.cpan.org/dist/File-ChangeNotify")
+    (synopsis "Watch for changes to files")
+    (description "This module provides a class to monitor a directory for
+changes made to any file.")
+    (license artistic2.0)))
+
+(define-public perl-file-copy-recursive
+  (package
+    (name "perl-file-copy-recursive")
+    (version "0.38")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/D/DM/DMUEY/"
+                           "File-Copy-Recursive-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1syyyvylr51iicialdmv0dw06q49xzv8zrkb5cn8ma4l73gvvk44"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/File-Copy-Recursive")
+    (synopsis "Recursively copy files and directories")
+    (description "This module has 3 functions: one to copy files only, one to
+copy directories only, and one to do either depending on the argument's
+type.")
+    (license (package-license perl))))
+
 (define-public perl-file-find-rule
   (package
     (name "perl-file-find-rule")
@@ -1357,6 +1568,27 @@ provided base directory and can return files (and/or directories if desired)
 matching a regular expression.")
     (home-page "http://search.cpan.org/~dopacki/File-List/")))
 
+(define-public perl-file-remove
+  (package
+    (name "perl-file-remove")
+    (version "1.52")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/A/AD/ADAMK/"
+                           "File-Remove-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1p8bal9qhwkjbghivxn1d5m3qdj2qwm1agrjbmakm6la9dbxqm21"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/File-Remove")
+    (synopsis "Remove files and directories in Perl")
+    (description "File::Remove::remove removes files and directories.  It acts
+like /bin/rm, for the most part.  Although \"unlink\" can be given a list of
+files, it will not remove directories; this module remedies that.  It also
+accepts wildcards, * and ?, as arguments for filenames.")
+    (license (package-license perl))))
+
 (define-public perl-file-sharedir
   (package
     (name "perl-file-sharedir")
@@ -1644,6 +1876,93 @@ Perlish API and none of the bloat and rarely used features of IPC::Run.")
     ;; licenses, any version."
     (license (list bsd-3 gpl3+))))
 
+(define-public perl-ipc-sharelite
+  (package
+    (name "perl-ipc-sharelite")
+    (version "0.17")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/A/AN/ANDYA/"
+                           "IPC-ShareLite-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1gz7dbwxrzbzdsjv11kb49jlf9q6lci2va6is0hnavd93nwhdm0l"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/IPC-ShareLite")
+    (synopsis "Lightweight interface to shared memory")
+    (description "IPC::ShareLite provides a simple interface to shared memory,
+allowing data to be efficiently communicated between processes.")
+    (license (package-license perl))))
+
+(define-public perl-json
+  (package
+    (name "perl-json")
+    (version "2.90")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/M/MA/MAKAMAKA/"
+                           "JSON-" version ".tar.gz"))
+       (sha256
+        (base32
+         "127yppvr17qik9pkd1vy901hs4l13kg6rhp76jdgcyask35v7nsd"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-json-xs" ,perl-json-xs))) ;recommended
+    (home-page "http://search.cpan.org/dist/JSON")
+    (synopsis "JSON encoder/decoder for Perl")
+    (description "This module converts Perl data structures to JSON and vice
+versa using either JSON::XS or JSON::PP.")
+    (license (package-license perl))))
+
+(define-public perl-json-maybexs
+  (package
+    (name "perl-json-maybexs")
+    (version "1.003003")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/E/ET/ETHER/"
+                           "JSON-MaybeXS-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0q21wzz87drrvblxcm2py8fcvkzwx1hxzfybynz8ln7wv66vbx3f"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-without-module" ,perl-test-without-module)))
+    (inputs
+     `(("perl-cpanel-json-xs" ,perl-cpanel-json-xs)))
+    (home-page "http://search.cpan.org/dist/JSON-MaybeXS")
+    (synopsis "Cpanel::JSON::XS with fallback")
+    (description "This module first checks to see if either Cpanel::JSON::XS
+or JSON::XS is already loaded, in which case it uses that module.  Otherwise
+it tries to load Cpanel::JSON::XS, then JSON::XS, then JSON::PP in order, and
+either uses the first module it finds or throws an error.")
+    (license (package-license perl))))
+
+(define-public perl-json-xs
+  (package
+    (name "perl-json-xs")
+    (version "3.01")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/M/ML/MLEHMANN/"
+                           "JSON-XS-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1aviik480m61ykwvyix83grywzbk828wvfz19hqfvaasd8jz73af"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-common-sense" ,perl-common-sense)
+       ("perl-types-serialiser" ,perl-types-serialiser)))
+    (home-page "http://search.cpan.org/dist/JSON-XS")
+    (synopsis "JSON serialising/deserialising for Perl")
+    (description "This module converts Perl data structures to JSON and vice
+versa.")
+    (license (package-license perl))))
+
 (define-public perl-list-moreutils
   (package
     (name "perl-list-moreutils")
@@ -1771,6 +2090,44 @@ implementation for a given OS or any other case of needing to provide multiple
 implementations.")
     (license artistic2.0)))
 
+(define-public perl-module-install
+  (package
+    (name "perl-module-install")
+    (version "1.14")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/B/BI/BINGOS/"
+                           "Module-Install-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0j8dz87k60i1khd9xadd8kl6bgm9s5s5zl86rzsz5bq36siz00iz"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-yaml-tiny" ,perl-yaml-tiny)))
+    (propagated-inputs
+     `(("perl-archive-zip" ,perl-archive-zip)
+       ("perl-file-homedir" ,perl-file-homedir)
+       ("perl-file-remove" ,perl-file-remove)
+       ("perl-json" ,perl-json)
+       ;; The LWP::Simple and LWP::UserAgent modules are recommended, but
+       ;; would cause a circular dependency with (gnu packages web), so we
+       ;; leave it out.  It may be resolved at runtime, however.
+       ;("perl-libwww-perl" ,perl-libwww-perl)
+       ("perl-module-scandeps" ,perl-module-scandeps)
+       ("perl-par-dist" ,perl-par-dist)
+       ("perl-yaml-tiny" ,perl-yaml-tiny)))
+    ;; TODO: One test requires Test::More >= 0.99, another fails with unicode
+    ;; character handling.
+    (arguments `(#:tests? #f))
+    (home-page "http://search.cpan.org/dist/Module-Install")
+    (synopsis "Standalone, extensible Perl module installer")
+    (description "Module::Install is a package for writing installers for
+CPAN (or CPAN-like) distributions that are clean, simple, minimalist, act in a
+strictly correct manner with ExtUtils::MakeMaker, and will run on any Perl
+installation version 5.005 or newer.")
+    (license (package-license perl))))
+
 (define-public perl-module-runtime
   (package
     (name "perl-module-runtime")
@@ -1813,6 +2170,27 @@ which had a recent release that broke some versions of Moose.  It is called
 from Moose::Conflicts and moose-outdated.")
     (license (package-license perl))))
 
+(define-public perl-module-scandeps
+  (package
+    (name "perl-module-scandeps")
+    (version "1.18")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RS/RSCHUPP/"
+                           "Module-ScanDeps-" version ".tar.gz"))
+       (sha256
+        (base32
+         "17mbyqwd8c20nqw01hjshl524vkw8pq6y2lwndmw36xkqr945npz"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-requires" ,perl-test-requires)))
+    (home-page "http://search.cpan.org/dist/Module-ScanDeps")
+    (synopsis "Recursively scan Perl code for dependencies")
+    (description "Module::ScanDeps is a module to recursively scan Perl
+programs for dependencies.")
+    (license (package-license perl))))
+
 (define-public perl-moo
   (package
     (name "perl-moo")
@@ -2064,6 +2442,33 @@ inlining, at make_immutable time) a constructor that makes sure things like
 BUILD methods are called.  It tries to be as non-intrusive as possible.")
   (license (package-license perl))))
 
+(define-public perl-moosex-params-validate
+  (package
+    (name "perl-moosex-params-validate")
+    (version "0.19")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/D/DR/DROLSKY/"
+                           "MooseX-Params-Validate-" version ".tar.gz"))
+       (sha256
+        (base32
+         "16isvyfsnzp63qr9cwsn094hasb6m7rzldmzav6spk7rih4mxdwk"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-moose" ,perl-moose)
+       ("perl-test-fatal" ,perl-test-fatal)))
+    (propagated-inputs
+     `(("perl-devel-caller" ,perl-devel-caller)
+       ("perl-moose" ,perl-moose)
+       ("perl-params-validate" ,perl-params-validate)
+       ("perl-sub-exporter" ,perl-sub-exporter)))
+    (home-page "http://search.cpan.org/dist/MooseX-Params-Validate")
+    (synopsis "Extension of Params::Validate using Moose's types")
+    (description "This module fills a gap in Moose by adding method parameter
+validation to Moose.")
+    (license (package-license perl))))
+
 (define-public perl-moosex-role-parameterized
   (package
     (name "perl-moosex-role-parameterized")
@@ -2120,6 +2525,57 @@ methods to be composed into the classes/roles/instances it's compiled to,
 where plain Moose::Roles would lose the overloading.")
     (license (package-license perl))))
 
+(define-public perl-moosex-semiaffordanceaccessor
+  (package
+    (name "perl-moosex-semiaffordanceaccessor")
+    (version "0.10")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/D/DR/DROLSKY/"
+                           "MooseX-SemiAffordanceAccessor-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1mdil9ckgmgr78z59p8wfa35ixn5855ndzx14y01dvfxpiv5gf55"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-moose" ,perl-moose)))
+    (home-page "http://search.cpan.org/dist/MooseX-SemiAffordanceAccessor")
+    (synopsis "Name your accessors foo() and set_foo()")
+    (description "This module does not provide any methods.  Simply loading it
+changes the default naming policy for the loading class so that accessors are
+separated into get and set methods.  The get methods have the same name as the
+accessor, while set methods are prefixed with \"_set_\".")
+    (license artistic2.0)))
+
+(define-public perl-moosex-traits-pluggable
+  (package
+    (name "perl-moosex-traits-pluggable")
+    (version "0.12")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RK/RKITOVER/"
+                           "MooseX-Traits-Pluggable-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1jjqmcidy4kdgp5yffqqwxrsab62mbhbpvnzdy1rpwnb1savg5mb"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-moose" ,perl-moose)
+       ("perl-test-exception" ,perl-test-exception)))
+    (propagated-inputs
+     `(("perl-class-load" ,perl-class-load)
+       ("perl-list-moreutils" ,perl-list-moreutils)
+       ("perl-moose" ,perl-moose)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)))
+    (home-page
+     "http://search.cpan.org/dist/MooseX-Traits-Pluggable")
+    (synopsis "Trait loading and resolution for Moose")
+    (description "Adds support on top of MooseX::Traits for class precedence
+search for traits and some extra attributes")
+    (license (package-license perl))))
+
 (define-public perl-moosex-types
   (package
     (name "perl-moosex-types")
@@ -2147,6 +2603,35 @@ behind the scenes it namespaces all your type declarations, effectively
 prevent name clashes between packages.")
     (license (package-license perl))))
 
+(define-public perl-moosex-types-loadableclass
+  (package
+    (name "perl-moosex-types-loadableclass")
+    (version "0.013")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/E/ET/ETHER/"
+                           "MooseX-Types-LoadableClass-" version ".tar.gz"))
+       (sha256
+        (base32
+         "13v2hn3xr6adx15qik8b6966fbbw77ik1v4sxx24f766la10w2mq"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-module-build-tiny" ,perl-module-build-tiny)
+       ("perl-namespace-clean" ,perl-namespace-clean)
+       ("perl-moose" ,perl-moose)
+       ("perl-test-fatal" ,perl-test-fatal)
+       ("perl-class-load" ,perl-class-load)))
+    (propagated-inputs
+     `(("perl-module-runtime" ,perl-module-runtime)
+       ("perl-moosex-types" ,perl-moosex-types)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)))
+    (home-page "http://search.cpan.org/dist/MooseX-Types-LoadableClass")
+    (synopsis "ClassName type constraints for Moose")
+    (description "MooseX::Types::LoadableClass provides a ClassName type
+constraint with coercion to load the class.")
+    (license (package-license perl))))
+
 (define-public perl-mro-compat
   (package
     (name "perl-mro-compat")
@@ -2241,6 +2726,26 @@ name, but they won't show up as methods on your class or instances.")
 subroutine, which you can call with a value to be tested against.")
     (license (package-license perl))))
 
+(define-public perl-object-signature
+  (package
+    (name "perl-object-signature")
+    (version "1.07")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/A/AD/ADAMK/"
+                           "Object-Signature-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0c8l7195bjvx0v6zmkgdnxvwg7yj2zq8hi7xd25a3iikd12dc4f6"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/Object-Signature")
+    (synopsis "Generate cryptographic signatures for objects")
+    (description "Object::Signature is an abstract base class that you can
+inherit from in order to allow your objects to generate unique cryptographic
+signatures.")
+    (license (package-license perl))))
+
 (define-public perl-package-anon
   (package
     (name "perl-package-anon")
@@ -2412,6 +2917,25 @@ checking parameters easier.")
 function call parameters to an arbitrary level of specificity.")
     (license artistic2.0)))
 
+(define-public perl-par-dist
+  (package
+    (name "perl-par-dist")
+    (version "0.49")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RS/RSCHUPP/"
+                           "PAR-Dist-" version ".tar.gz"))
+       (sha256
+        (base32
+         "078ycyn8pw3rba4k3qwcqrqfcym5c1pivymwa0bvs9sab45j4iwy"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/PAR-Dist")
+    (synopsis "Create and manipulate PAR distributions")
+    (description "PAR::Dist is a toolkit to create and manipulate PAR
+distributions.")
+    (license (package-license perl))))
+
 (define-public perl-parent
   (package
     (name "perl-parent")
@@ -2795,6 +3319,28 @@ The idea is just to fool caller().  All the really naughty bits of Tcl's
 uplevel() are avoided.")
     (license (package-license perl))))
 
+(define-public perl-svg
+  (package
+    (name "perl-svg")
+    (version "2.63")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/S/SZ/SZABGAB/SVG-"
+                           version ".tar.gz"))
+       (sha256
+        (base32
+         "12cbncsfxbwg1w3p1qmymfbqdb22kmyajxzdnxnxbq5xjl6yncha"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/SVG")
+    (synopsis "Perl extension for generating SVG documents")
+    (description "SVG is a Perl module which generates a nested data structure
+containing the DOM representation of an SVG (Scalable Vector Graphics) image.
+Using SVG, you can generate SVG objects, embed other SVG instances into it,
+access the DOM object, create and access Javascript, and generate SMIL
+animation content.")
+    (license (package-license perl))))
+
 (define-public perl-sys-cpu
   (package
     (name "perl-sys-cpu")
@@ -2839,6 +3385,31 @@ module does not have weaken, the install will bail out altogether with a long
 error encouraging the user to seek support.")
     (license (package-license perl))))
 
+(define-public perl-template-toolkit
+  (package
+    (name "perl-template-toolkit")
+    (version "2.26")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/A/AB/ABW/"
+                           "Template-Toolkit-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1gknrm8hdci5ryg67p4y23lsy7lynczqmq9kh9nzj7kg08vczqg7"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-appconfig" ,perl-appconfig)
+       ("perl-test-leaktrace" ,perl-test-leaktrace)))
+    (home-page "http://search.cpan.org/dist/Template-Toolkit")
+    (synopsis "Template processing system for Perl")
+    (description "The Template Toolkit is a collection of modules which
+implement an extensible template processing system.  It was originally
+designed and remains primarily useful for generating dynamic web content, but
+it can be used equally well for processing any other kind of text based
+documents: HTML, XML, POD, PostScript, LaTeX, and so on.")
+    (license (package-license perl))))
+
 (define-public perl-test-cleannamespaces
   (package
     (name "perl-test-cleannamespaces")
@@ -3019,6 +3590,46 @@ testing exception-throwing code with about the same amount of typing.")
 automatically aggregated and output to STDOUT.")
     (license (package-license perl))))
 
+(define-public perl-test-leaktrace
+  (package
+    (name "perl-test-leaktrace")
+    (version "0.15")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/G/GF/GFUJI/"
+                           "Test-LeakTrace-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0pp6ip012c474ibw0mwd7jgig34gf98bb8xlqk4wdvw1d65vbf7g"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/Test-LeakTrace")
+    (synopsis "Traces memory leaks in Perl")
+    (description "Test::LeakTrace provides several functions that trace memory
+leaks. This module scans arenas, the memory allocation system, so it can
+detect any leaked SVs in given blocks.")
+    (license (package-license perl))))
+
+(define-public perl-test-longstring
+  (package
+    (name "perl-test-longstring")
+    (version "0.17")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RG/RGARCIA/"
+                           "Test-LongString-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0kwp7rfr1i2amz4ckigkv13ah7jr30q6l5k4wk0vxl84myg39i5b"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/Test-LongString")
+    (synopsis "Tests strings for equality, with more helpful failures")
+    (description "This module provides some drop-in replacements for the
+string comparison functions of Test::More, but which are more suitable when
+you test against long strings.")
+    (license (package-license perl))))
+
 (define-public perl-test-mocktime
   (package
     (name "perl-test-mocktime")
@@ -3456,6 +4067,50 @@ letters, the pronunciation expressed by the text in some other writing
 system.")
     (license (package-license perl))))
 
+(define-public perl-tie-ixhash
+  (package
+  (name "perl-tie-ixhash")
+  (version "1.23")
+  (source
+    (origin
+      (method url-fetch)
+      (uri (string-append "mirror://cpan/authors/id/C/CH/CHORNY/"
+                          "Tie-IxHash-" version ".tar.gz"))
+      (sha256
+        (base32
+          "0mmg9iyh42syal3z1p2pn9airq65yrkfs66cnqs9nz76jy60pfzs"))))
+  (build-system perl-build-system)
+  (home-page "http://search.cpan.org/dist/Tie-IxHash")
+  (synopsis "Ordered associative arrays for Perl")
+  (description "This Perl module implements Perl hashes that preserve the
+order in which the hash elements were added. The order is not affected when
+values corresponding to existing keys in the IxHash are changed. The elements
+can also be set to any arbitrary supplied order. The familiar perl array
+operations can also be performed on the IxHash.")
+  (license (package-license perl))))
+
+(define-public perl-tie-toobject
+  (package
+    (name "perl-tie-toobject")
+    (version "0.03")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/N/NU/NUFFIN/"
+                           "Tie-ToObject-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1x1smn1kw383xc5h9wajxk9dlx92bgrbf7gk4abga57y6120s6m3"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-test-simple" ,perl-test-simple)))
+    (home-page "http://search.cpan.org/dist/Tie-ToObject")
+    (synopsis "Tie to an existing Perl object")
+    (description "This class provides a tie constructor that returns the
+object it was given as it's first argument.  This way side effects of calling
+$object->TIEHASH are avoided.")
+    (license (package-license perl))))
+
 (define-public perl-time-local
   (package
     (name "perl-time-local")
@@ -3585,6 +4240,27 @@ that are designed to minimize common mistakes with eval blocks, and nothing
 else.")
     (license x11)))
 
+(define-public perl-types-serialiser
+  (package
+    (name "perl-types-serialiser")
+    (version "1.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/M/ML/MLEHMANN/"
+                           "Types-Serialiser-" version ".tar.gz"))
+       (sha256
+        (base32
+         "03bk0hm5ys8k7265dkap825ybn2zmzb1hl0kf1jdm8yq95w39lvs"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-common-sense" ,perl-common-sense)))
+    (home-page "http://search.cpan.org/dist/Types-Serialiser")
+    (synopsis "Data types for common serialisation formats")
+    (description "This module provides some extra datatypes that are used by
+common serialisation formats such as JSON or CBOR.")
+    (license (package-license perl))))
+
 (define-public perl-variable-magic
   (package
     (name "perl-variable-magic")
@@ -3607,6 +4283,31 @@ it.  With this module, you can add your own magic to any variable without
 having to write a single line of XS.")
     (license (package-license perl))))
 
+(define-public perl-yaml-tiny
+  (package
+    (name "perl-yaml-tiny")
+    (version "1.66")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/E/ET/ETHER/"
+                           "YAML-Tiny-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0c17l8pvpraznpb31ncmr4wxlyww8sg8dhvp3s3q02yqll3cnygv"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-json-maybexs" ,perl-json-maybexs)
+       ("perl-module-build-tiny" ,perl-module-build-tiny)))
+    (arguments
+     `(#:tests? #f))                    ;requires Test::More >= 0.99
+    (home-page "http://search.cpan.org/dist/YAML-Tiny")
+    (synopsis "Read/Write YAML files")
+    (description "YAML::Tiny is a perl class for reading and writing
+YAML-style files, written with as little code as possible, reducing load time
+and memory overhead.")
+    (license (package-license perl))))
+
 
 ;;; Some packaged modules need versions of core modules that are newer than
 ;;; those in our perl 5.16.1.
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 2fcdbcc211..23afec7950 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -33,7 +33,6 @@
   #:use-module (gnu packages)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages databases)
-  #:use-module (gnu packages elf)
   #:use-module (gnu packages fontutils)
   #:use-module (gnu packages gdbm)
   #:use-module (gnu packages gcc)
@@ -134,7 +133,8 @@
               (sqlite (assoc-ref %build-inputs "sqlite"))
               (openssl (assoc-ref %build-inputs "openssl"))
               (readline (assoc-ref %build-inputs "readline"))
-              (zlib (assoc-ref %build-inputs "zlib")))
+              (zlib (assoc-ref %build-inputs "zlib"))
+              (out (assoc-ref %outputs "out")))
          (list "--enable-shared"                  ; allow embedding
                "--with-system-ffi"                ; build ctypes
                (string-append "CPPFLAGS="
@@ -151,43 +151,27 @@
                 "-L" sqlite "/lib "
                 "-L" openssl "/lib "
                 "-L" readline "/lib "
-                "-L" zlib "/lib")))
-
-        #:modules ((guix build gnu-build-system)
-                   (guix build utils)
-                   (guix build rpath)
-                   (srfi srfi-26))
-        #:imported-modules ((guix build gnu-build-system)
-                            (guix build utils)
-                            (guix build rpath))
+                "-L" zlib "/lib "
+                "-Wl,-rpath=" out "/lib")))
 
         #:phases
-        (alist-cons-after
-         'strip 'add-lib-to-runpath
-         (lambda* (#:key outputs #:allow-other-keys)
-           (let* ((out (assoc-ref outputs "out"))
-                  (lib (string-append out "/lib")))
-             ;; Add LIB to the RUNPATH of all the executables.
-             (with-directory-excursion out
-               (for-each (cut augment-rpath <> lib)
-                         (find-files "bin" ".*")))))
+        (alist-cons-before
+         'configure 'patch-lib-shells
+         (lambda _
+           ;; Filter for existing files, since some may not exist in all
+           ;; versions of python that are built with this recipe.
+           (substitute* (filter file-exists?
+                                '("Lib/subprocess.py"
+                                  "Lib/popen2.py"
+                                  "Lib/distutils/tests/test_spawn.py"
+                                  "Lib/test/test_subprocess.py"))
+             (("/bin/sh") (which "sh"))))
          (alist-cons-before
-          'configure 'patch-lib-shells
+          'check 'pre-check
           (lambda _
-            ;; Filter for existing files, since some may not exist in all
-            ;; versions of python that are built with this recipe.
-            (substitute* (filter file-exists?
-                                 '("Lib/subprocess.py"
-                                   "Lib/popen2.py"
-                                   "Lib/distutils/tests/test_spawn.py"
-                                   "Lib/test/test_subprocess.py"))
-              (("/bin/sh") (which "sh"))))
-          (alist-cons-before
-           'check 'pre-check
-           (lambda _
-             ;; 'Lib/test/test_site.py' needs a valid $HOME
-             (setenv "HOME" (getcwd)))
-           %standard-phases)))))
+            ;; 'Lib/test/test_site.py' needs a valid $HOME
+            (setenv "HOME" (getcwd)))
+          %standard-phases))))
     (inputs
      `(("bzip2" ,bzip2)
        ("gdbm" ,gdbm)
@@ -195,8 +179,7 @@
        ("sqlite" ,sqlite)                         ; for sqlite extension
        ("openssl" ,openssl)
        ("readline" ,readline)
-       ("zlib" ,zlib)
-       ("patchelf" ,patchelf)))                   ; for (guix build rpath)
+       ("zlib" ,zlib)))
     (native-inputs
      `(("pkg-config" ,pkg-config)))
     (native-search-paths
@@ -230,14 +213,8 @@ data types.")
               (sha256
                (base32
                 "1rdncc7g8g6f3lfdg33rli1yffbiq8z283xy4f5ksl1l8i49psdb"))))
-    (arguments
-     (let ((args `(#:modules ((guix build gnu-build-system)
-                              (guix build utils)
-                             (srfi srfi-1)
-                              (srfi srfi-26))
-                   ,@(package-arguments python-2))))
-       (substitute-keyword-arguments args
-         ((#:tests? _) #t))))
+    (arguments (substitute-keyword-arguments (package-arguments python-2)
+                 ((#:tests? _) #t)))
     (native-search-paths
      (list (search-path-specification
             (variable "PYTHONPATH")
@@ -324,6 +301,45 @@ etc. ")
 (define-public python2-babel
   (package-with-python2 python-babel))
 
+(define-public python-h5py
+  (package
+    (name "python-h5py")
+    (version "2.4.0")
+    (source
+     (origin
+      (method url-fetch)
+      (uri (string-append "https://pypi.python.org/packages/source/h/h5py/h5py-"
+                          version ".tar.gz"))
+      (sha256
+       (base32
+        "0q4f9l8grf6pwp64xbv8bmyxx416s7h4522nnxac056ap3savbps"))))
+    (build-system python-build-system)
+    (inputs
+     `(("python-cython" ,python-cython)
+       ("python-numpy" ,python-numpy)
+       ("hdf5" ,hdf5)))
+    (native-inputs
+     `(("python-setuptools" ,python-setuptools)))
+    (arguments `(#:tests? #f)) ; no test target
+    (home-page "http://www.h5py.org/")
+    (synopsis "Read and write HDF5 files from Python")
+    (description
+     "The h5py package provides both a high- and low-level interface to the
+HDF5 library from Python.  The low-level interface is intended to be a
+complete wrapping of the HDF5 API, while the high-level component supports
+access to HDF5 files, datasets and groups using established Python and NumPy
+concepts.")
+    (license bsd-3)))
+
+(define-public python2-h5py
+  (let ((h5py (package-with-python2 python-h5py)))
+    (package (inherit h5py)
+      (inputs
+       `(("python2-numpy" ,python2-numpy)
+         ,@(alist-delete
+            "python-numpy"
+            (package-inputs h5py)))))))
+
 (define-public python-lockfile
   (package
     (name "python-lockfile")
diff --git a/gnu/packages/scheme.scm b/gnu/packages/scheme.scm
index e0eccf51ff..b450e33bbd 100644
--- a/gnu/packages/scheme.scm
+++ b/gnu/packages/scheme.scm
@@ -199,7 +199,7 @@ features an integrated Emacs-like editor and a large runtime library.")
                                       (string-append "EMACSDIR=" dir)))))
                   %standard-phases))))
     (inputs
-     `(("emacs" ,emacs)
+     `(("emacs" ,emacs)                      ;UDE needs the X version of Emacs
 
        ;; Optional APIs for which Bigloo has bindings.
        ("avahi" ,avahi)
diff --git a/gnu/packages/sdl.scm b/gnu/packages/sdl.scm
index 03aa56d118..9a3b3898d8 100644
--- a/gnu/packages/sdl.scm
+++ b/gnu/packages/sdl.scm
@@ -60,8 +60,15 @@
     (build-system gnu-build-system)
     (arguments
      '(;; Explicitly link against shared libraries instead of dlopening them.
-       ;; For X11, ALSA, PulseAudio, etc.
-       #:configure-flags '("--disable-sdl-dlopen")
+       ;; For X11, ALSA, and PulseAudio.
+       ;; OpenGL library is still dlopened at runtime.
+       #:configure-flags '("--disable-alsa-shared"
+                           "--disable-pulseaudio-shared"
+                           "--disable-x11-shared"
+                           ;; Explicitly link with mesa.
+                           ;; This add mesa to libsdl's RUNPATH, to make dlopen
+                           ;; finding the libGL from mesa at runtime.
+                           "LDFLAGS=-lGL")
 
        #:tests? #f)) ; no check target
     (propagated-inputs
@@ -71,6 +78,7 @@
     (native-inputs `(("pkg-config" ,pkg-config)))
     (inputs `(("libxrandr" ,libxrandr)
               ("mesa" ,mesa)
+              ("glu" ,glu)
               ("alsa-lib" ,alsa-lib)
               ("pulseaudio" ,pulseaudio)))
     (synopsis "Cross platform game development library")
diff --git a/gnu/packages/ssh.scm b/gnu/packages/ssh.scm
index 0148b25a16..10697850f4 100644
--- a/gnu/packages/ssh.scm
+++ b/gnu/packages/ssh.scm
@@ -72,7 +72,6 @@
                ;; fields of 'gcry_thread_cbs' that are now private:
                ;; src/threads.c:72:26: error: 'struct gcry_thread_cbs' has no member named 'mutex_init'
               ("libgcrypt", libgcrypt-1.5)))
-    (native-inputs `(("patchelf" ,patchelf)))
     (synopsis "SSH client library")
     (description
      "libssh is a C library implementing the SSHv2 and SSHv1 protocol for
diff --git a/gnu/packages/textutils.scm b/gnu/packages/textutils.scm
index 5a8f9f09ea..d6cc577e7d 100644
--- a/gnu/packages/textutils.scm
+++ b/gnu/packages/textutils.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
+;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -83,3 +84,41 @@ handy front-end to the library.")
 an encoding detection library, and enca, a command line frontend, integrating
 libenca and several charset conversion libraries and tools.")
     (license license:gpl2)))
+
+(define-public utf8proc
+  (package
+    (name "utf8proc")
+    (version "1.1.6")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "https://github.com/JuliaLang/utf8proc/archive/v"
+             version ".tar.gz"))
+       (file-name (string-append name "-" version ".tar.gz"))
+       (sha256
+        (base32 "0wmsi672knii0q70wh6a3ll0gv7qk33c50zbpzasrs3b16bqy659"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:tests? #f ;no "check" target
+       #:make-flags '("CC=gcc")
+       #:phases
+       (alist-replace
+        'install
+        (lambda* (#:key outputs #:allow-other-keys)
+          (let ((lib (string-append (assoc-ref outputs "out") "/lib/"))
+                (include (string-append (assoc-ref outputs "out") "/include/")))
+            (mkdir-p lib)
+            (mkdir-p include)
+            (copy-file "utf8proc.h" (string-append include "utf8proc.h"))
+            (for-each (lambda (file)
+                        (copy-file file (string-append lib (basename file))))
+                      '("libutf8proc.a" "libutf8proc.so"))))
+        ;; no configure script
+        (alist-delete 'configure %standard-phases))))
+    (home-page "http://julialang.org/utf8proc/")
+    (synopsis "C library for processing UTF-8 Unicode data")
+    (description "utf8proc is a small C library that provides Unicode
+normalization, case-folding, and other operations for data in the UTF-8
+encoding, supporting Unicode version 7.0.")
+    (license license:expat)))
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index 5af2905eaa..48e16a14be 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -619,7 +619,7 @@ RCS, PRCS, and Aegis packages.")
     (build-system gnu-build-system)
     (inputs `(("perl" ,perl)
               ("inetutils" ,inetutils)     ; for `hostname', used in the tests
-              ("emacs" ,emacs)))           ; for `ctags'
+              ("emacs" ,emacs-no-x)))      ; for `ctags'
     (home-page "http://www.gnu.org/software/vc-dwim/")
     (synopsis "Version-control-agnostic ChangeLog diff and commit tool")
     (description
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index b1c0c52ee4..a7f39b8249 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -26,6 +26,7 @@
                                fsf-free isc))
   #:use-module (guix packages)
   #:use-module (guix download)
+  #:use-module (guix git-download)
   #:use-module (guix build-system cmake)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system python)
@@ -34,6 +35,7 @@
   #:use-module (gnu packages audio)
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages avahi)
+  #:use-module (gnu packages base)
   #:use-module (gnu packages cdrom)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages databases)
@@ -42,6 +44,7 @@
   #:use-module (gnu packages fontutils)
   #:use-module (gnu packages fribidi)
   #:use-module (gnu packages gettext)
+  #:use-module (gnu packages ghostscript)
   #:use-module (gnu packages gl)
   #:use-module (gnu packages glib)
   #:use-module (gnu packages guile)
@@ -59,6 +62,7 @@
   #:use-module (gnu packages pulseaudio)
   #:use-module (gnu packages python)
   #:use-module (gnu packages qt)
+  #:use-module (gnu packages samba)
   #:use-module (gnu packages sdl)
   #:use-module (gnu packages ssh)
   #:use-module (gnu packages texlive)
@@ -77,8 +81,11 @@
     (version "0.7.4")
     (source (origin
               (method url-fetch)
-              (uri (string-append "mirror://sourceforge/liba52/a52dec-"
-                                  version ".tar.gz"))
+              (uri (string-append
+                    ;; A mirror://sourceforge URI doesn't work, presumably
+                    ;; because the SourceForge project is misconfigured.
+                    "http://liba52.sourceforge.net/files/a52dec-" version
+                    ".tar.gz"))
               (sha256
                (base32
                 "0czccp4fcpf2ykp16xcrzdfmnircz1ynhls334q374xknd5747d2"))))
@@ -509,6 +516,126 @@ NuppelVideo, FLI, YUV4MPEG, FILM, RoQ, PVA files.  One can watch VideoCD,
 SVCD, DVD, 3ivx, DivX 3/4/5, WMV and H.264 movies.")
     (license gpl2)))
 
+;;; This is not version 2; it's a fork literally named "mplayer2".
+(define-public mplayer2
+  (package
+    (name "mplayer2")
+    ;; There are no tarballs.  The 2.0 git tag, which is actually the first
+    ;; release is from 2011.  The latest commit is from 2013 October, so we
+    ;; use that commit.
+    (version "201310")
+    (source (origin
+              (method git-fetch)
+              (uri (git-reference
+                    ;; XXX Change this if mplayer2.org goes up again.
+                    (url "http://repo.or.cz/mplayer2.git")
+                    (commit "2c378c71a4d9b1df382db9aa787b646628b4e3f9")))
+              (sha256
+               (base32
+                "0s8554sanj6cvnf0h148nsmjgy5v0568nmcza7grpv6fnmddpfam"))
+              (file-name (string-append name "-" version "-checkout"))
+              ;; Warning: after using this patch, one must pass the -ltheora
+              ;; linker flag manually to configure; see below.
+              (patches (list (search-patch "mplayer2-theora-fix.patch")))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("perl" ,perl)
+       ("python" ,python)
+       ("python-2" ,python-2)
+       ("python-docutils" ,python-docutils)
+       ;; ./configure uses which(1) to find rst2man.py.
+       ("which" ,which)))
+    ;; Missing features: DirectFB, Xss screensaver extensions, VDPAU, MNG,
+    ;; libnut, DirectShow TV interface, Radio interfaces of all kinds, vstream
+    ;; client, XMSS inputplugin support, joystick, lirc/lircc, and openal.
+    ;; OpenAL support is experimental and causes compilation to fail with
+    ;; linker errors.
+    (inputs
+     `(("alsa-lib" ,alsa-lib)
+       ("faad2" ,faad2)
+       ("ffmpeg" ,ffmpeg)
+       ("gettext" ,gnu-gettext)
+       ("jack" ,jack-2)
+       ("ladspa" ,ladspa)
+       ("lcms" ,lcms)
+       ("liba52" ,liba52)
+       ("libass" ,libass)
+       ("libbluray" ,libbluray)
+       ("libbs2b" ,libbs2b)
+       ("libcaca" ,libcaca)
+       ("libcdio-paranoia" ,libcdio-paranoia)
+       ("libdca" ,libdca)
+       ("libdv" ,libdv)
+       ("libdvdread" ,libdvdread)
+       ("libdvdnav" ,libdvdnav-4)
+       ("libjpeg" ,libjpeg)
+       ("libmad" ,libmad)
+       ("libpng" ,libpng)
+       ("libquvi" ,libquvi)
+       ("libtheora" ,libtheora)
+       ("libungif" ,libungif)
+       ("libvorbis" ,libvorbis)
+       ("libx11" ,libx11)
+       ("libxinerama" ,libxinerama)
+       ("libxv" ,libxv)
+       ("mesa" ,mesa)
+       ("mpg123" ,mpg123)
+       ("ncurses" ,ncurses)
+       ("portaudio" ,portaudio)
+       ("pulseaudio" ,pulseaudio)
+       ("rsound" ,rsound)
+       ("samba" ,samba)
+       ("sdl" ,sdl)
+       ("speex" ,speex)
+       ("xvid" ,xvid)))
+    (arguments
+     '(#:phases
+       (alist-replace
+        'configure
+        ;; ./configure does not work followed by "SHELL=..." and
+        ;; "CONFIG_SHELL=..."; set environment variables instead.
+        (lambda* (#:key inputs outputs #:allow-other-keys)
+          (setenv "SHELL" (which "bash"))
+          (setenv "CONFIG_SHELL" (which "bash"))
+          (substitute* "configure"
+            (("/usr/X11") (assoc-ref inputs "libx11")))
+          (zero?
+           (system* "./configure"
+                    (string-append "--prefix=" (assoc-ref outputs "out"))
+                    "--enable-translation"
+                    "--enable-runtime-cpudetection"
+                    ;; This is needed in accordance with the theora patch.
+                    "--extra-libs=-ltheoradec")))
+        (alist-cons-before
+         'build 'fix-TOOLS-shebangs
+         (lambda _
+           (substitute* (find-files "TOOLS" "\\.(sh|pl|py)$")
+             (("/usr/bin/env") (which "env"))
+             (("/usr/bin/perl") (which "perl"))
+             (("/usr/bin/python3") (which "python3"))
+             (("/usr/bin/python") (which "python"))))
+         (alist-cons-before
+          'build 'fix-input-buffer-padding-size
+          (lambda _
+            (substitute* "libmpdemux/demuxer.h"
+              ;; This has to match with FFmpeg's FF_INPUT_BUFFER_PADDING_SIZE,
+              ;; which has changed at some point.
+              (("(#define MP_INPUT_BUFFER_PADDING_SIZE )[0-9]*" all)
+               (string-append all "32"))))
+          %standard-phases)))
+       ;; No 'check' target.
+       #:tests? #f))
+    ;; XXX Change this if mplayer2.org goes up again.
+    (home-page "http://repo.or.cz/w/mplayer2.git")
+    (synopsis "Audio and video player")
+    (description "mplayer2 is a general-purpose audio and video player.  It's
+a fork of the original MPlayer project, and contains further development in
+several areas.")
+    ;; See file Copyright.  Most files are gpl2+ or compatible, but talloc.c
+    ;; is under lgpl3+, thus the whole project becomes gpl3+.
+    (license gpl3+)))
+
 (define-public libvpx
   (package
     (name "libvpx")
diff --git a/gnu/packages/web.scm b/gnu/packages/web.scm
index 62adab3952..cbf3cb3465 100644
--- a/gnu/packages/web.scm
+++ b/gnu/packages/web.scm
@@ -38,6 +38,7 @@
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages cyrus-sasl)
+  #:use-module (gnu packages databases)
   #:use-module (gnu packages openssl)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages icu4c)
@@ -523,6 +524,297 @@ from streaming URLs.  It is a command-line wrapper for the libquvi library.")
 to perl-code, for faster generation of access_log lines.")
     (license (package-license perl))))
 
+(define-public perl-catalyst-action-renderview
+  (package
+    (name "perl-catalyst-action-renderview")
+    (version "0.16")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/B/BO/BOBTFISH/"
+                           "Catalyst-Action-RenderView-"
+                           version ".tar.gz"))
+       (sha256
+        (base32
+         "0j1rrld13cjk7ks92b5hv3xw4rfm2lvmksb4rlzd8mx0a0wj0rc5"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-http-request-ascgi" ,perl-http-request-ascgi)))
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-data-visitor" ,perl-data-visitor)
+       ("perl-mro-compat" ,perl-mro-compat)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Action-RenderView")
+    (synopsis "Sensible default Catalyst action")
+    (description "This Catalyst action implements a sensible default end
+action, which will forward to the first available view.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-action-rest
+  (package
+    (name "perl-catalyst-action-rest")
+    (version "1.17")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://cpan/authors/id/F/FR/FREW/"
+                                  "Catalyst-Action-REST-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1rnxmsd9dsqz4xc0g9ynafxi934jwp0nixbg92q3bc2h46xcccy8"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-requires" ,perl-test-requires)))
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-class-inspector" ,perl-class-inspector)
+       ("perl-libwww" ,perl-libwww)
+       ("perl-moose" ,perl-moose)
+       ("perl-mro-compat" ,perl-mro-compat)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)
+       ("perl-params-validate" ,perl-params-validate)
+       ("perl-uri-find" ,perl-uri-find)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Action-REST")
+    (synopsis "Automated REST Method Dispatching")
+    (description "This Action handles doing automatic method dispatching for
+REST requests.  It takes a normal Catalyst action, and changes the dispatch to
+append an underscore and method name.  First it will try dispatching to an
+action with the generated name, and failing that it will try to dispatch to a
+regular method.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-component-instancepercontext
+  (package
+    (name "perl-catalyst-component-instancepercontext")
+    (version "0.001001")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/G/GR/GRODITI/"
+                           "Catalyst-Component-InstancePerContext-"
+                           version ".tar.gz"))
+       (sha256
+        (base32
+         "0wfj4vnn2cvk6jh62amwlg050p37fcwdgrn9amcz24z6w4qgjqvz"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-moose" ,perl-moose)))
+    (home-page
+     "http://search.cpan.org/dist/Catalyst-Component-InstancePerContext")
+    (synopsis "Create only one instance of Moose component per context")
+    (description "Catalyst::Component::InstancePerContext returns a new
+instance of a component on each request.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-devel
+  (package
+    (name "perl-catalyst-devel")
+    (version "1.39")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/I/IL/ILMARI/"
+                           "Catalyst-Devel-" version ".tar.gz"))
+       (sha256
+        (base32
+         "12m50bbkggjmpxihv3wnvr0g2qng0zwhlzi5ygppjz8wh2x73qxw"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-fatal" ,perl-test-fatal)))
+    (propagated-inputs
+     `(("perl-catalyst-action-renderview" ,perl-catalyst-action-renderview)
+       ("perl-catalyst-plugin-configloader" ,perl-catalyst-plugin-configloader)
+       ("perl-catalyst-plugin-static-simple" ,perl-catalyst-plugin-static-simple)
+       ("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-config-general" ,perl-config-general)
+       ("perl-file-changenotify" ,perl-file-changenotify)
+       ("perl-file-copy-recursive" ,perl-file-copy-recursive)
+       ("perl-file-sharedir" ,perl-file-sharedir)
+       ("perl-module-install" ,perl-module-install)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-emulate-class-accessor-fast"
+        ,perl-moosex-emulate-class-accessor-fast)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)
+       ("perl-namespace-clean" ,perl-namespace-clean)
+       ("perl-path-class" ,perl-path-class)
+       ("perl-template-toolkit" ,perl-template-toolkit)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Devel")
+    (synopsis "Catalyst Development Tools")
+    (description "The Catalyst-Devel distribution includes a variety of
+modules useful for the development of Catalyst applications, but not required
+to run them.  Catalyst-Devel includes the Catalyst::Helper system, which
+autogenerates scripts and tests; Module::Install::Catalyst, a Module::Install
+extension for Catalyst; and requirements for a variety of development-related
+modules.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-model-dbic-schema
+  (package
+  (name "perl-catalyst-model-dbic-schema")
+  (version "0.65")
+  (source
+    (origin
+      (method url-fetch)
+      (uri (string-append "mirror://cpan/authors/id/G/GB/GBJK/"
+                          "Catalyst-Model-DBIC-Schema-"
+                          version ".tar.gz"))
+      (sha256
+        (base32
+          "1spfjcjc0b9dv3k2gbanqj1m1cqzyxb32p76dhdwizzpbvpi3a96"))))
+  (build-system perl-build-system)
+  (native-inputs
+   `(("perl-dbd-sqlite" ,perl-dbd-sqlite)
+     ("perl-test-exception" ,perl-test-exception)
+     ("perl-test-requires" ,perl-test-requires)))
+  (propagated-inputs
+   `(("perl-carp-clan" ,perl-carp-clan)
+     ("perl-catalyst-component-instancepercontext"
+      ,perl-catalyst-component-instancepercontext)
+     ("perl-catalyst-runtime" ,perl-catalyst-runtime)
+     ("perl-catalystx-component-traits" ,perl-catalystx-component-traits)
+     ("perl-dbix-class" ,perl-dbix-class)
+     ("perl-dbix-class-cursor-cached" ,perl-dbix-class-cursor-cached)
+     ("perl-dbix-class-schema-loader" ,perl-dbix-class-schema-loader)
+     ("perl-hash-merge" ,perl-hash-merge)
+     ("perl-list-moreutils" ,perl-list-moreutils)
+     ("perl-module-runtime" ,perl-module-runtime)
+     ("perl-moose" ,perl-moose)
+     ("perl-moosex-markasmethods" ,perl-moosex-markasmethods)
+     ("perl-moosex-nonmoose" ,perl-moosex-nonmoose)
+     ("perl-moosex-types" ,perl-moosex-types)
+     ("perl-moosex-types-loadableclass" ,perl-moosex-types-loadableclass)
+     ("perl-namespace-autoclean" ,perl-namespace-autoclean)
+     ("perl-namespace-clean" ,perl-namespace-clean)
+     ("perl-tie-ixhash" ,perl-tie-ixhash)
+     ("perl-try-tiny" ,perl-try-tiny)))
+  (home-page "http://search.cpan.org/dist/Catalyst-Model-DBIC-Schema")
+  (synopsis "DBIx::Class::Schema Model Class")
+  (description "This is a Catalyst Model for DBIx::Class::Schema-based
+Models.")
+  (license (package-license perl))))
+
+(define-public perl-catalyst-plugin-authentication
+  (package
+    (name "perl-catalyst-plugin-authentication")
+    (version "0.10023")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/B/BO/BOBTFISH/"
+                           "Catalyst-Plugin-Authentication-"
+                           version ".tar.gz"))
+       (sha256
+        (base32
+         "0v6hb4r1wv3djrnqvnjcn3xx1scgqzx8nyjdg9lfc1ybvamrl0rn"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-catalyst-plugin-session" ,perl-catalyst-plugin-session)
+       ("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-class-inspector" ,perl-class-inspector)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-emulate-class-accessor-fast"
+        ,perl-moosex-emulate-class-accessor-fast)
+       ("perl-mro-compat" ,perl-mro-compat)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)
+       ("perl-string-rewriteprefix" ,perl-string-rewriteprefix)
+       ("perl-test-exception" ,perl-test-exception)
+       ("perl-try-tiny" ,perl-try-tiny)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Plugin-Authentication")
+    (synopsis "Infrastructure plugin for the Catalyst authentication framework")
+    (description "The authentication plugin provides generic user support for
+Catalyst apps. It is the basis for both authentication (checking the user is
+who they claim to be), and authorization (allowing the user to do what the
+system authorises them to do).")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-plugin-configloader
+  (package
+    (name "perl-catalyst-plugin-configloader")
+    (version "0.34")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/B/BO/BOBTFISH/"
+                           "Catalyst-Plugin-ConfigLoader-"
+                           version ".tar.gz"))
+       (sha256
+        (base32
+         "19j7p4v7mbx6wrmpvmrnd974apx7hdl2s095ga3b9zcbdrl77h5q"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-path-class" ,perl-path-class)))
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-config-any" ,perl-config-any)
+       ("perl-data-visitor" ,perl-data-visitor)
+       ("perl-mro-compat" ,perl-mro-compat)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Plugin-ConfigLoader")
+    (synopsis "Load config files of various types")
+    (description "This module will attempt to load find and load configuration
+files of various types.  Currently it supports YAML, JSON, XML, INI and Perl
+formats.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-plugin-session
+  (package
+    (name "perl-catalyst-plugin-session")
+    (version "0.39")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/J/JJ/JJNAPIORK/"
+                           "Catalyst-Plugin-Session-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0m4a003qgz7848iyckwbigg2vw3kmfxggh1razrnzxrbz3n6x5gi"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-deep" ,perl-test-deep)
+       ("perl-test-exception" ,perl-test-exception)))
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-emulate-class-accessor-fast"
+        ,perl-moosex-emulate-class-accessor-fast)
+       ("perl-namespace-clean" ,perl-namespace-clean)
+       ("perl-object-signature" ,perl-object-signature)
+       ("perl-test-www-mechanize-psgi" ,perl-test-www-mechanize-psgi)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Plugin-Session")
+    (synopsis "Catalyst generic session plugin")
+    (description "This plugin links the two pieces required for session
+management in web applications together: the state, and the store.")
+    (license (package-license perl))))
+
+(define-public perl-catalyst-plugin-static-simple
+  (package
+    (name "perl-catalyst-plugin-static-simple")
+    (version "0.33")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/J/JJ/JJNAPIORK/"
+                           "Catalyst-Plugin-Static-Simple-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1h8f12bhzh0ssq9gs8r9g3hqn8zn2k0q944vc1vm8j81bns16msy"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-mime-types" ,perl-mime-types)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-types" ,perl-moosex-types)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)))
+    (home-page "http://search.cpan.org/dist/Catalyst-Plugin-Static-Simple")
+    (synopsis "Simple serving of static pages")
+    (description "The Static::Simple plugin is designed to make serving static
+content in your application during development quick and easy, without
+requiring a single line of code from you.  This plugin detects static files by
+looking at the file extension in the URL (such as .css or .png or .js).  The
+plugin uses the lightweight MIME::Types module to map file extensions to
+IANA-registered MIME types, and will serve your static files with the correct
+MIME type directly to the browser, without being processed through Catalyst.")
+    (license (package-license perl))))
+
 (define-public perl-catalyst-runtime
   (package
     (name "perl-catalyst-runtime")
@@ -587,6 +879,39 @@ run an application on the web, either by doing them itself, or by letting you
 \"plug in\" existing Perl modules that do what you need.")
     (license (package-license perl))))
 
+(define-public perl-catalystx-component-traits
+  (package
+    (name "perl-catalystx-component-traits")
+    (version "0.19")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/R/RK/RKITOVER/"
+                           "CatalystX-Component-Traits-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0iq4ci8m6g2c4g01fvdl568y7pjz28f3widk986v3pyhr7ll8j88"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-moose" ,perl-moose)
+       ("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-moosex-methodattributes" ,perl-moosex-methodattributes)))
+    (propagated-inputs
+     `(("perl-catalyst-runtime" ,perl-catalyst-runtime)
+       ("perl-class-load" ,perl-class-load)
+       ("perl-moose" ,perl-moose)
+       ("perl-moosex-traits-pluggable" ,perl-moosex-traits-pluggable)
+       ("perl-namespace-autoclean" ,perl-namespace-autoclean)
+       ("perl-list-moreutils" ,perl-list-moreutils)))
+    (home-page "http://search.cpan.org/dist/CatalystX-Component-Traits")
+    (synopsis "Trait Loading and Resolution for Catalyst Components")
+    (description "Adds a \"COMPONENT\" in Catalyst::Component method to your
+Catalyst component base class that reads the optional \"traits\" parameter
+from app and component config and instantiates the component subclass with
+those traits using \"new_with_traits\" in MooseX::Traits from
+MooseX::Traits::Pluggable.")
+    (license (package-license perl))))
+
 (define-public perl-cgi-simple
   (package
     (name "perl-cgi-simple")
@@ -630,27 +955,6 @@ parameter parsing, file upload, cookie handling and header generation.")
 inputs, in a manner reminiscent of how PHP does.")
     (license l:bsd-2)))
 
-(define-public perl-cpanel-json-xs
-  (package
-    (name "perl-cpanel-json-xs")
-    (version "3.0114")
-    (source
-     (origin
-       (method url-fetch)
-       (uri (string-append "mirror://cpan/authors/id/R/RU/RURBAN/"
-                           "Cpanel-JSON-XS-" version ".tar.gz"))
-       (sha256
-        (base32
-         "0jhi1v0631x4d14a7cpfnpjqhs34zkygxjn1nwvvr927awx5jx71"))))
-    (build-system perl-build-system)
-    (propagated-inputs
-     `(("perl-common-sense" ,perl-common-sense)))
-    (home-page "http://search.cpan.org/dist/Cpanel-JSON-XS")
-    (synopsis "JSON::XS for Cpanel")
-    (description "This module converts Perl data structures to JSON and vice
-versa.")
-    (license (package-license perl))))
-
 (define-public perl-encode-locale
   (package
     (name "perl-encode-locale")
@@ -699,6 +1003,79 @@ Encode::decode(locale => $string).")
 which can be used to parse directory listings.")
     (home-page "http://search.cpan.org/~gaas/File-Listing/")))
 
+(define-public perl-html-form
+  (package
+    (name "perl-html-form")
+    (version "6.03")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/G/GA/GAAS/"
+                           "HTML-Form-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0dpwr7yz6hjc3bcqgcbdzjjk9l58ycdjmbam9nfcmm85y2a1vh38"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-html-parser" ,perl-html-parser)
+       ("perl-html-tagset" ,perl-html-tagset)
+       ("perl-http-message" ,perl-http-message)
+       ("perl-lwp-mediatypes" ,perl-lwp-mediatypes)
+       ("perl-uri" ,perl-uri)))
+    (home-page "http://search.cpan.org/dist/HTML-Form")
+    (synopsis "Perl class representing an HTML form element")
+    (description "Objects of the HTML::Form class represents a single HTML
+<form> ... </form> instance.")
+    (license (package-license perl))))
+
+(define-public perl-html-lint
+  (package
+    (name "perl-html-lint")
+    (version "2.20")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/P/PE/PETDANCE/"
+                           "HTML-Lint-" version ".tar.gz"))
+       (sha256
+        (base32
+         "15vrqjnlb0f8rib1kqdf4islqy6i33h08wy7b1bkgd550p7lfjwk"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-html-parser" ,perl-html-parser)
+       ("perl-html-tagset" ,perl-html-tagset)
+       ("perl-libwww" ,perl-libwww)))
+    (home-page "http://search.cpan.org/dist/HTML-Lint")
+    (synopsis "Check for HTML errors in a string or file")
+    (description "HTML::Lint is a pure-Perl HTML parser and checker for
+syntactic legitmacy.")
+    (license l:artistic2.0)))
+
+(define-public perl-html-tree
+  (package
+    (name "perl-html-tree")
+    (version "5.03")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/C/CJ/CJM/"
+                           "HTML-Tree-" version ".tar.gz"))
+       (sha256
+        (base32
+         "13qlqbpixw470gnck0xgny8hyjj576m8y24bba2p9ai2lvy76vbx"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-fatal" ,perl-test-fatal)))
+    (propagated-inputs
+     `(("perl-html-parser" ,perl-html-parser)
+       ("perl-html-tagset" ,perl-html-tagset)
+       ("perl-libwww" ,perl-libwww)))
+    (home-page "http://search.cpan.org/dist/HTML-Tree")
+    (synopsis "Work with HTML in a DOM-like tree structure")
+    (description "This distribution contains a suite of modules for
+representing, creating, and extracting information from HTML syntax trees.")
+    (license (package-license perl))))
+
 (define-public perl-html-parser
   (package
     (name "perl-html-parser")
@@ -933,6 +1310,30 @@ fields in the request.")
 environment from an HTTP::Request.")
     (license (package-license perl))))
 
+(define-public perl-http-server-simple
+  (package
+    (name "perl-http-server-simple")
+    (version "0.44")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/J/JE/JESSE/"
+                           "HTTP-Server-Simple-" version ".tar.gz"))
+       (sha256
+        (base32
+         "05klpfkss2a6i5ihmvcm27fyar0f2v4ispg2f49agab3va1gix6g"))))
+    (build-system perl-build-system)
+    (arguments
+     ;; See the discussion of a related tests issue at
+     ;; https://lists.gnu.org/archive/html/guix-devel/2015-01/msg00346.html
+     `(#:tests? #f))
+    (home-page "http://search.cpan.org/dist/HTTP-Server-Simple")
+    (synopsis "Lightweight HTTP server")
+    (description "HTTP::Server::Simple is a simple standalone HTTP daemon with
+no non-core module dependencies.  It can be used for building a standalone
+http-based UI to your existing tools.")
+    (license (package-license perl))))
+
 (define-public perl-http-tiny
   (package
     (name "perl-http-tiny")
@@ -1021,31 +1422,6 @@ select or poll.")
     (license (package-license perl))
     (home-page "https://github.com/noxxi/p5-io-socket-ssl")))
 
-(define-public perl-json-maybexs
-  (package
-    (name "perl-json-maybexs")
-    (version "1.003003")
-    (source
-     (origin
-       (method url-fetch)
-       (uri (string-append "mirror://cpan/authors/id/E/ET/ETHER/"
-                           "JSON-MaybeXS-" version ".tar.gz"))
-       (sha256
-        (base32
-         "0q21wzz87drrvblxcm2py8fcvkzwx1hxzfybynz8ln7wv66vbx3f"))))
-    (build-system perl-build-system)
-    (native-inputs
-     `(("perl-test-without-module" ,perl-test-without-module)))
-    (inputs
-     `(("perl-cpanel-json-xs" ,perl-cpanel-json-xs)))
-    (home-page "http://search.cpan.org/dist/JSON-MaybeXS")
-    (synopsis "Cpanel::JSON::XS with fallback")
-    (description "This module first checks to see if either Cpanel::JSON::XS
-or JSON::XS is already loaded, in which case it uses that module.  Otherwise
-it tries to load Cpanel::JSON::XS, then JSON::XS, then JSON::PP in order, and
-either uses the first module it finds or throws an error.")
-    (license (package-license perl))))
-
 (define-public perl-libwww
   (package
     (name "perl-libwww")
@@ -1101,6 +1477,26 @@ media types is defined by the media.types file.  If the ~/.media.types file
 exists it is used instead.")
     (home-page "http://search.cpan.org/~gaas/LWP-MediaTypes/")))
 
+(define-public perl-mime-types
+  (package
+    (name "perl-mime-types")
+    (version "2.09")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/M/MA/MARKOV/"
+                           "MIME-Types-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0s7s2z9xc1nc2l59rk80iaa04r36k0y95231212kz5p3ln7szk1c"))))
+    (build-system perl-build-system)
+    (home-page "http://search.cpan.org/dist/MIME-Types")
+    (synopsis "Definition of MIME types")
+    (description "This module provides a list of known mime-types, combined
+from various sources.  For instance, it contains all IANA types and the
+knowledge of Apache.")
+    (license (package-license perl))))
+
 (define-public perl-net-http
   (package
     (name "perl-net-http")
@@ -1299,6 +1695,63 @@ either mocked HTTP or a locally spawned server.")
     (description "Test::TCP is test utilities for TCP/IP programs.")
     (license (package-license perl))))
 
+(define-public perl-test-www-mechanize
+  (package
+    (name "perl-test-www-mechanize")
+    (version "1.44")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/P/PE/PETDANCE/"
+                           "Test-WWW-Mechanize-" version ".tar.gz"))
+       (sha256
+        (base32
+         "062pj242vsc73bw11jqpap92ax9wzc9f2m4xhyp1wzrwkfchpl2q"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-exception" ,perl-test-exception)))
+    (propagated-inputs
+     `(("perl-carp-assert-more" ,perl-carp-assert-more)
+       ("perl-html-form" ,perl-html-form)
+       ("perl-html-lint" ,perl-html-lint)
+       ("perl-html-tree" ,perl-html-tree)
+       ("perl-http-server-simple" ,perl-http-server-simple)
+       ("perl-libwww" ,perl-libwww)
+       ("perl-test-longstring" ,perl-test-longstring)
+       ("perl-www-mechanize" ,perl-www-mechanize)))
+    (home-page "http://search.cpan.org/dist/Test-WWW-Mechanize")
+    (synopsis "Testing-specific WWW::Mechanize subclass")
+    (description "Test::WWW::Mechanize is a subclass of the Perl module
+WWW::Mechanize that incorporates features for web application testing.")
+    (license l:artistic2.0)))
+
+(define-public perl-test-www-mechanize-psgi
+  (package
+    (name "perl-test-www-mechanize-psgi")
+    (version "0.35")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/L/LB/LBROCARD/"
+                           "Test-WWW-Mechanize-PSGI-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1hih8s49zf38bisvhnhzrrj0zwyiivkrbs7nmmdqm1qqy27wv7pc"))))
+    (build-system perl-build-system)
+    (native-inputs
+     `(("perl-test-pod" ,perl-test-pod)))
+    (propagated-inputs
+     `(("perl-plack" ,perl-plack)
+       ("perl-test-www-mechanize" ,perl-test-www-mechanize)))
+    (home-page "http://search.cpan.org/dist/Test-WWW-Mechanize-PSGI")
+    (synopsis "Test PSGI programs using WWW::Mechanize")
+    (description "PSGI is a specification to decouple web server environments
+from web application framework code.  Test::WWW::Mechanize is a subclass of
+WWW::Mechanize that incorporates features for web application testing.  The
+Test::WWW::Mechanize::PSGI module meshes the two to allow easy testing of PSGI
+applications.")
+    (license (package-license perl))))
+
 (define-public perl-uri
   (package
     (name "perl-uri")
@@ -1319,6 +1772,29 @@ represent \"Uniform Resource Identifier references\" as specified in RFC 2396
 and updated by RFC 2732.")
     (home-page "http://search.cpan.org/dist/URI/")))
 
+(define-public perl-uri-find
+  (package
+    (name "perl-uri-find")
+    (version "20140709")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/M/MS/MSCHWERN/"
+                           "URI-Find-" version ".tar.gz"))
+       (sha256
+        (base32
+         "0czc4h182s7sx3k123m7qlg7yybnwxgh369hap3c3b6xgrglrhy0"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-uri" ,perl-uri)))
+    (home-page "http://search.cpan.org/dist/URI-Find")
+    (synopsis "Find URIs in arbitrary text")
+    (description "This module finds URIs and URLs (according to what URI.pm
+considers a URI) in plain text.  It only finds URIs which include a
+scheme (http:// or the like), for something a bit less strict, consider
+URI::Find::Schemeless.  For a command-line interface, urifind is provided.")
+    (license (package-license perl))))
+
 (define-public perl-uri-ws
   (package
     (name "perl-uri-ws")
@@ -1363,6 +1839,33 @@ library.")
     (license (package-license perl))
     (home-page "http://search.cpan.org/~szbalint/WWW-Curl-4.17/lib/WWW/Curl.pm")))
 
+(define-public perl-www-mechanize
+  (package
+    (name "perl-www-mechanize")
+    (version "1.73")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://cpan/authors/id/E/ET/ETHER/"
+                           "WWW-Mechanize-" version ".tar.gz"))
+       (sha256
+        (base32
+         "1zrw8aadhwy48q51x2z2rqlkwf17bya4j4h3hy89mw783j96rmg9"))))
+    (build-system perl-build-system)
+    (propagated-inputs
+     `(("perl-html-form" ,perl-html-form)
+       ("perl-html-parser" ,perl-html-parser)
+       ("perl-http-message" ,perl-http-message)
+       ("perl-http-server-simple" ,perl-http-server-simple)
+       ("perl-libwww" ,perl-libwww)
+       ("perl-test-warn" ,perl-test-warn)
+       ("perl-uri" ,perl-uri)))
+    (home-page "http://search.cpan.org/dist/WWW-Mechanize")
+    (synopsis "Web browsing in a Perl object")
+    (description "WWW::Mechanize is a Perl module for stateful programmatic
+web browsing, used for automating interaction with websites.")
+    (license (package-license perl))))
+
 (define-public perl-www-robotrules
   (package
     (name "perl-www-robotrules")
diff --git a/gnu/packages/wxwidgets.scm b/gnu/packages/wxwidgets.scm
index 5406aedc6e..1f80130198 100644
--- a/gnu/packages/wxwidgets.scm
+++ b/gnu/packages/wxwidgets.scm
@@ -79,8 +79,8 @@ and many other languages.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "https://sourceforge.net/projects/wxwindows/files/"
-                           version "/wxGTK-" version ".tar.gz"))
+       (uri (string-append
+             "mirror://sourceforge/wxwindows/wxGTK-" version ".tar.gz"))
        (sha256
         (base32 "1gjs9vfga60mk4j4ngiwsk9h6c7j22pw26m3asxr1jwvqbr8kkqk"))))
     (inputs
diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm
index 64e2358fe4..776c858c16 100644
--- a/gnu/packages/xorg.scm
+++ b/gnu/packages/xorg.scm
@@ -4344,12 +4344,12 @@ graphics cards.")
             "1b95p3l84ppv6j7dbbmg0zrz6k8xdwvnag1l6ajm3gk9qwdb79ya"))))
     (build-system gnu-build-system)
     (propagated-inputs
-      `(("libxext" ,libxext)
-        ("randrproto" ,randrproto)))
-    (inputs
-      `(("libxrender" ,libxrender)
-        ("xproto" ,xproto)
-        ("libx11" ,libx11)))
+      ;; In accordance with xrandr.pc.
+      `(("libx11" ,libx11)
+        ("libxext" ,libxext)
+        ("libxrender" ,libxrender)
+        ("randrproto" ,randrproto)
+        ("xproto" ,xproto)))
     (native-inputs
        `(("pkg-config" ,pkg-config)))
     (home-page "http://www.x.org/wiki/")
diff --git a/gnu/services/base.scm b/gnu/services/base.scm
index 84bac94d9f..a9126032bb 100644
--- a/gnu/services/base.scm
+++ b/gnu/services/base.scm
@@ -28,6 +28,8 @@
   #:use-module ((gnu packages base)
                 #:select (canonical-package glibc))
   #:use-module (gnu packages package-management)
+  #:use-module (gnu packages lsh)
+  #:use-module (gnu packages lsof)
   #:use-module ((gnu build file-systems)
                 #:select (mount-flags->bit-mask))
   #:use-module (guix gexp)
@@ -612,7 +614,8 @@ failed to register hydra.gnu.org public key: ~a~%" status))))))))
 (define* (guix-service #:key (guix guix) (builder-group "guixbuild")
                        (build-accounts 10) (authorize-hydra-key? #t)
                        (use-substitutes? #t)
-                       (extra-options '()))
+                       (extra-options '())
+                       (lsof lsof) (lsh lsh))
   "Return a service that runs the build daemon from @var{guix}, and has
 @var{build-accounts} user accounts available under @var{builder-group}.
 
@@ -646,7 +649,13 @@ passed to @command{guix-daemon}."
                        #$@(if use-substitutes?
                               '()
                               '("--no-substitutes"))
-                       #$@extra-options)))
+                       #$@extra-options)
+
+                 ;; Add 'lsof' (for the GC) and 'lsh' (for offloading) to the
+                 ;; daemon's $PATH.
+                 #:environment-variables
+                 (list (string-append "PATH=" #$lsof "/bin:"
+                                      #$lsh "/bin"))))
              (stop #~(make-kill-destructor))
              (user-accounts (guix-build-accounts build-accounts
                                                  #:group builder-group))
diff --git a/guix/derivations.scm b/guix/derivations.scm
index 4b0048b54b..7737e39b2d 100644
--- a/guix/derivations.scm
+++ b/guix/derivations.scm
@@ -60,6 +60,7 @@
             derivation-input-path
             derivation-input-sub-derivations
             derivation-input-output-paths
+            valid-derivation-input?
 
             &derivation-error
             derivation-error?
@@ -187,12 +188,25 @@ download with a fixed hash (aka. `fetchurl')."
      (map (cut derivation-path->output-path path <>)
           sub-drvs))))
 
-(define (derivation-prerequisites drv)
-  "Return the list of derivation-inputs required to build DRV, recursively."
+(define (valid-derivation-input? store input)
+  "Return true if INPUT is valid--i.e., if all the outputs it requests are in
+the store."
+  (every (cut valid-path? store <>)
+         (derivation-input-output-paths input)))
+
+(define* (derivation-prerequisites drv #:optional (cut? (const #f)))
+  "Return the list of derivation-inputs required to build DRV, recursively.
+
+CUT? is a predicate that is passed a derivation-input and returns true to
+eliminate the given input and its dependencies from the search.  An example of
+search a predicate is 'valid-derivation-input?'; when it is used as CUT?, the
+result is the set of prerequisites of DRV not already in valid."
   (let loop ((drv       drv)
              (result    '())
              (input-set (set)))
-    (let ((inputs (remove (cut set-contains? input-set <>)
+    (let ((inputs (remove (lambda (input)
+                            (or (set-contains? input-set input)
+                                (cut? input)))
                           (derivation-inputs drv))))
       (fold2 loop
              (append inputs result)
@@ -225,22 +239,36 @@ download with a fixed hash (aka. `fetchurl')."
 (define* (substitution-oracle store drv)
   "Return a one-argument procedure that, when passed a store file name,
 returns #t if it's substitutable and #f otherwise.  The returned procedure
-knows about all substitutes for all the derivations listed in DRV and their
-prerequisites.
+knows about all substitutes for all the derivations listed in DRV; it also
+knows about their prerequisites, unless they are themselves substitutable.
 
 Creating a single oracle (thus making a single 'substitutable-paths' call) and
 reusing it is much more efficient than calling 'has-substitutes?' or similar
 repeatedly, because it avoids the costs associated with launching the
 substituter many times."
+  (define valid?
+    (cut valid-path? store <>))
+
+  (define valid-input?
+    (cut valid-derivation-input? store <>))
+
+  (define (dependencies drv)
+    ;; Skip prerequisite sub-trees of DRV whose root is valid.  This allows us
+    ;; to ask the substituter for just as much as needed, instead of asking it
+    ;; for the whole world, which can be significantly faster when substitute
+    ;; info is not already in cache.
+    (append-map derivation-input-output-paths
+                (derivation-prerequisites drv valid-input?)))
+
   (let* ((paths (delete-duplicates
                  (fold (lambda (drv result)
                          (let ((self (match (derivation->output-paths drv)
                                        (((names . paths) ...)
-                                        paths)))
-                               (deps (append-map derivation-input-output-paths
-                                                 (derivation-prerequisites
-                                                  drv))))
-                           (append self deps result)))
+                                        paths))))
+                           (if (every valid? self)
+                               result
+                               (append (append self (dependencies drv))
+                                       result))))
                        '()
                        drv)))
          (subst (list->set (substitutable-paths store paths))))
diff --git a/guix/ftp-client.scm b/guix/ftp-client.scm
index 761980ac8f..ab72405df0 100644
--- a/guix/ftp-client.scm
+++ b/guix/ftp-client.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2010, 2011, 2012, 2013, 2014 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2010, 2011, 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -144,6 +144,11 @@ or a TCP port number), and return it."
 
 (define (ftp-size conn file)
   "Return the size in bytes of FILE."
+
+  ;; Ask for "binary mode", otherwise some servers, such as sourceware.org,
+  ;; fail with 550 ("SIZE not allowed in ASCII mode").
+  (%ftp-command "TYPE I" 200 (ftp-connection-socket conn))
+
   (let ((message (%ftp-command (string-append "SIZE " file) 213
                                (ftp-connection-socket conn))))
     (string->number (string-trim-both message))))
diff --git a/guix/gexp.scm b/guix/gexp.scm
index f8646a081c..01290dba18 100644
--- a/guix/gexp.scm
+++ b/guix/gexp.scm
@@ -127,6 +127,12 @@ cross-compiling.)"
                        body ...)))
     (register-compiler! name)))
 
+(define-gexp-compiler (derivation-compiler (drv derivation?) system target)
+  ;; Derivations are the lowest-level representation, so this is the identity
+  ;; compiler.
+  (with-monad %store-monad
+    (return drv)))
+
 
 ;;;
 ;;; Inputs & outputs.
@@ -165,8 +171,6 @@ the cross-compilation target triplet."
   (with-monad %store-monad
     (sequence %store-monad
               (map (match-lambda
-                    ((and ((? derivation?) sub-drv ...) input)
-                     (return input))
                     ((and ((? struct? thing) sub-drv ...) input)
                      (mlet* %store-monad ((lower -> (lookup-compiler thing))
                                           (drv (lower thing system target)))
@@ -197,6 +201,11 @@ names and file names suitable for the #:allowed-references argument to
       (match-lambda
        ((? string? output)
         (return output))
+       (($ <gexp-input> thing output native?)
+        (mlet* %store-monad ((lower -> (lookup-compiler thing))
+                             (drv      (lower thing system
+                                              (if native? #f target))))
+          (return (derivation->output-path drv output))))
        (thing
         (mlet* %store-monad ((lower -> (lookup-compiler thing))
                              (drv      (lower thing system target)))
@@ -262,6 +271,7 @@ The other arguments are as for 'derivation'."
   (define (graphs-file-names graphs)
     ;; Return a list of (FILE-NAME . STORE-PATH) pairs made from GRAPHS.
     (map (match-lambda
+          ;; TODO: Remove 'derivation?' special cases.
            ((file-name (? derivation? drv))
             (cons file-name (derivation->output-path drv)))
            ((file-name (? derivation? drv) sub-drv)
@@ -343,15 +353,23 @@ The other arguments are as for 'derivation'."
                       #:allowed-references allowed
                       #:local-build? local-build?))))
 
-(define* (gexp-inputs exp #:optional (references gexp-references))
-  "Return the input list for EXP, using REFERENCES to get its list of
-references."
+(define* (gexp-inputs exp #:key native?)
+  "Return the input list for EXP.  When NATIVE? is true, return only native
+references; otherwise, return only non-native references."
   (define (add-reference-inputs ref result)
     (match ref
-      (($ <gexp-input> (? derivation? drv) output)
-       (cons `(,drv ,output) result))
-      (($ <gexp-input> (? gexp? exp))
-       (append (gexp-inputs exp references) result))
+      (($ <gexp-input> (? gexp? exp) _ #t)
+       (if native?
+           (append (gexp-inputs exp)
+                   (gexp-inputs exp #:native? #t)
+                   result)
+           result))
+      (($ <gexp-input> (? gexp? exp) _ #f)
+       (if native?
+           (append (gexp-inputs exp #:native? #t)
+                   result)
+           (append (gexp-inputs exp)
+                   result)))
       (($ <gexp-input> (? string? str))
        (if (direct-store-path? str)
            (cons `(,str) result)
@@ -361,13 +379,13 @@ references."
            ;; THING is a derivation, or a package, or an origin, etc.
            (cons `(,thing ,output) result)
            result))
-      (($ <gexp-input> (lst ...) output native?)
+      (($ <gexp-input> (lst ...) output n?)
        (fold-right add-reference-inputs result
                    ;; XXX: For now, automatically convert LST to a list of
                    ;; gexp-inputs.
                    (map (match-lambda
                          ((? gexp-input? x) x)
-                         (x (%gexp-input x "out" native?)))
+                         (x (%gexp-input x "out" (or n? native?))))
                         lst)))
       (_
        ;; Ignore references to other kinds of objects.
@@ -375,10 +393,12 @@ references."
 
   (fold-right add-reference-inputs
               '()
-              (references exp)))
+              (if native?
+                  (gexp-native-references exp)
+                  (gexp-references exp))))
 
 (define gexp-native-inputs
-  (cut gexp-inputs <> gexp-native-references))
+  (cut gexp-inputs <> #:native? #t))
 
 (define (gexp-outputs exp)
   "Return the outputs referred to by EXP as a list of strings."
@@ -411,8 +431,6 @@ and in the current monad setting (system type, etc.)"
   (define* (reference->sexp ref #:optional native?)
     (with-monad %store-monad
       (match ref
-        (($ <gexp-input> (? derivation? drv) output)
-         (return (derivation->output-path drv output)))
         (($ <gexp-output> output)
          ;; Output file names are not known in advance but the daemon defines
          ;; an environment variable for each of them at build time, so use
@@ -468,13 +486,20 @@ and in the current monad setting (system type, etc.)"
       ;; Return all the 'ungexp' present in EXP.
       (let loop ((exp    exp)
                  (result '()))
-        (syntax-case exp (ungexp ungexp-splicing)
+        (syntax-case exp (ungexp
+                          ungexp-splicing
+                          ungexp-native
+                          ungexp-native-splicing)
           ((ungexp _)
            (cons exp result))
           ((ungexp _ _)
            (cons exp result))
           ((ungexp-splicing _ ...)
            (cons exp result))
+          ((ungexp-native _ ...)
+           result)
+          ((ungexp-native-splicing _ ...)
+           result)
           ((exp0 exp ...)
            (let ((result (loop #'exp0 result)))
              (fold loop result #'(exp ...))))
@@ -485,13 +510,20 @@ and in the current monad setting (system type, etc.)"
       ;; Return all the 'ungexp-native' forms present in EXP.
       (let loop ((exp    exp)
                  (result '()))
-        (syntax-case exp (ungexp-native ungexp-native-splicing)
+        (syntax-case exp (ungexp
+                          ungexp-splicing
+                          ungexp-native
+                          ungexp-native-splicing)
           ((ungexp-native _)
            (cons exp result))
           ((ungexp-native _ _)
            (cons exp result))
           ((ungexp-native-splicing _ ...)
            (cons exp result))
+          ((ungexp _ ...)
+           result)
+          ((ungexp-splicing _ ...)
+           result)
           ((exp0 exp ...)
            (let ((result (loop #'exp0 result)))
              (fold loop result #'(exp ...))))
diff --git a/guix/scripts/lint.scm b/guix/scripts/lint.scm
index 69717b6317..c40d76b558 100644
--- a/guix/scripts/lint.scm
+++ b/guix/scripts/lint.scm
@@ -259,20 +259,20 @@ response from URI, and additional details, such as the actual HTTP response."
       ('ftp
        (catch #t
          (lambda ()
-           (let ((port (ftp-open (uri-host uri) 21)))
+           (let ((conn (ftp-open (uri-host uri) 21)))
              (define response
                (dynamic-wind
                  (const #f)
                  (lambda ()
-                   (ftp-chdir port (dirname (uri-path uri)))
-                   (ftp-size port (basename (uri-path uri))))
+                   (ftp-chdir conn (dirname (uri-path uri)))
+                   (ftp-size conn (basename (uri-path uri))))
                  (lambda ()
-                   (ftp-close port))))
-             (values 'ftp-response #t)))
+                   (ftp-close conn))))
+             (values 'ftp-response '(ok))))
          (lambda (key . args)
            (case key
-             ((or ftp-error)
-              (values 'ftp-response #f))
+             ((ftp-error)
+              (values 'ftp-response `(error ,@args)))
              ((getaddrinfo-error system-error gnutls-error)
               (values key args))
              (else
@@ -296,11 +296,14 @@ warning for PACKAGE mentionning the FIELD."
                                  (response-reason-phrase argument))
                          field)))
       ((ftp-response)
-       (when (not argument)
-         (emit-warning package
-                       (format #f
-                               (_ "URI ~a not reachable")
-                               (uri->string uri)))))
+       (match argument
+         (('ok) #t)
+         (('error port command code message)
+          (emit-warning package
+                        (format #f
+                                (_ "URI ~a not reachable: ~a (~s)")
+                                (uri->string uri)
+                                code (string-trim-both message))))))
       ((getaddrinfo-error)
        (emit-warning package
                      (format #f
diff --git a/guix/scripts/package.scm b/guix/scripts/package.scm
index a24c657ef6..3cc7ae760f 100644
--- a/guix/scripts/package.scm
+++ b/guix/scripts/package.scm
@@ -240,28 +240,27 @@ DURATION-RELATION with the current time."
 (define (find-packages-by-description rx)
   "Return the list of packages whose name, synopsis, or description matches
 RX."
-  (define (same-location? p1 p2)
-    ;; Compare locations of two packages.
-    (equal? (package-location p1) (package-location p2)))
-
-  (delete-duplicates
-   (sort
-    (fold-packages (lambda (package result)
-                     (define matches?
-                       (cut regexp-exec rx <>))
-
-                     (if (or (matches? (package-name package))
-                             (and=> (package-synopsis package)
-                                    (compose matches? P_))
-                             (and=> (package-description package)
-                                    (compose matches? P_)))
-                         (cons package result)
-                         result))
-                   '())
-    (lambda (p1 p2)
-      (string<? (package-name p1)
-                (package-name p2))))
-   same-location?))
+  (define version<? (negate version>=?))
+
+  (sort
+   (fold-packages (lambda (package result)
+                    (define matches?
+                      (cut regexp-exec rx <>))
+
+                    (if (or (matches? (package-name package))
+                            (and=> (package-synopsis package)
+                                   (compose matches? P_))
+                            (and=> (package-description package)
+                                   (compose matches? P_)))
+                        (cons package result)
+                        result))
+                  '())
+   (lambda (p1 p2)
+     (case (string-compare (package-name p1) (package-name p2)
+                           (const '<) (const '=) (const '>))
+       ((=)  (version<? (package-version p1) (package-version p2)))
+       ((<)  #t)
+       (else #f)))))
 
 (define-syntax-rule (leave-on-EPIPE exp ...)
   "Run EXP... in a context when EPIPE errors are caught and lead to 'exit'
diff --git a/guix/scripts/substitute-binary.scm b/guix/scripts/substitute.scm
index 50e3db2fb9..adf94a7ac3 100755
--- a/guix/scripts/substitute-binary.scm
+++ b/guix/scripts/substitute.scm
@@ -17,7 +17,7 @@
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-(define-module (guix scripts substitute-binary)
+(define-module (guix scripts substitute)
   #:use-module (guix ui)
   #:use-module (guix store)
   #:use-module (guix utils)
@@ -28,13 +28,12 @@
   #:use-module (guix base64)
   #:use-module (guix pk-crypto)
   #:use-module (guix pki)
-  #:use-module ((guix build utils) #:select (mkdir-p))
+  #:use-module ((guix build utils) #:select (mkdir-p dump-port))
   #:use-module ((guix build download)
                 #:select (progress-proc uri-abbreviation))
   #:use-module (ice-9 rdelim)
   #:use-module (ice-9 regex)
   #:use-module (ice-9 match)
-  #:use-module (ice-9 threads)
   #:use-module (ice-9 format)
   #:use-module (ice-9 ftw)
   #:use-module (ice-9 binary-ports)
@@ -48,11 +47,13 @@
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
   #:use-module (web uri)
+  #:use-module (web request)
+  #:use-module (web response)
   #:use-module (guix http-client)
   #:export (narinfo-signature->canonical-sexp
             read-narinfo
             write-narinfo
-            guix-substitute-binary))
+            guix-substitute))
 
 ;;; Comment:
 ;;;
@@ -68,8 +69,8 @@
 (define %narinfo-cache-directory
   ;; A local cache of narinfos, to avoid going to the network.
   (or (and=> (getenv "XDG_CACHE_HOME")
-             (cut string-append <> "/guix/substitute-binary"))
-      (string-append %state-directory "/substitute-binary/cache")))
+             (cut string-append <> "/guix/substitute"))
+      (string-append %state-directory "/substitute/cache")))
 
 (define %allow-unauthenticated-substitutes?
   ;; Whether to allow unchecked substitutes.  This is useful for testing
@@ -94,15 +95,6 @@ disabled!~%"))
   ;; How often we want to remove files corresponding to expired cache entries.
   (* 7 24 3600))
 
-;; In Guile 2.0.9, `regexp-exec' is thread-unsafe, so work around it.
-;; See <http://bugs.gnu.org/14404>.
-(set! regexp-exec
-      (let ((real regexp-exec)
-            (lock (make-mutex)))
-        (lambda (rx str . rest)
-          (with-mutex lock
-            (apply real rx str rest)))))
-
 (define fields->alist
   ;; The narinfo format is really just like recutils.
   recutils->alist)
@@ -218,7 +210,7 @@ failure."
 gonna have to wait."
   (delay (begin
            (format (current-error-port)
-                   (_ "updating list of substitutes from '~a'...~%")
+                   (_ "updating list of substitutes from '~a'...\r")
                    url)
            (open-cache url))))
 
@@ -309,12 +301,16 @@ NARINFO, doesn't match HASH, a bytevector containing the hash of NARINFO."
       (corrupt-signature
        (leave (_ "signature on '~a' is corrupt~%") uri)))))
 
-(define* (read-narinfo port #:optional url)
+(define* (read-narinfo port #:optional url
+                       #:key size)
   "Read a narinfo from PORT.  If URL is true, it must be a string used to
-build full URIs from relative URIs found while reading PORT.
+build full URIs from relative URIs found while reading PORT.  When SIZE is
+true, read at most SIZE bytes from PORT; otherwise, read as much as possible.
 
 No authentication and authorization checks are performed here!"
-  (let ((str (utf8->string (get-bytevector-all port))))
+  (let ((str (utf8->string (if size
+                               (get-bytevector-n port size)
+                               (get-bytevector-all port)))))
     (alist->record (call-with-input-string str fields->alist)
                    (narinfo-maker str url)
                    '("StorePath" "URL" "Compression"
@@ -376,40 +372,56 @@ or is signed by an unauthorized key."
 the cache STR originates form."
   (call-with-input-string str (cut read-narinfo <> cache-uri)))
 
-(define (fetch-narinfo cache path)
-  "Return the <narinfo> record for PATH, or #f if CACHE does not hold PATH."
-  (define (download url)
-    ;; Download the .narinfo from URL, and return its contents as a list of
-    ;; key/value pairs.  Don't emit an error message upon 404.
-    (false-if-exception (fetch (string->uri url)
-                               #:quiet-404? #t)))
-
-  (and (string=? (cache-store-directory cache) (%store-prefix))
-       (and=> (download (string-append (cache-url cache) "/"
-                                       (store-path-hash-part path)
-                                       ".narinfo"))
-              (cute read-narinfo <> (cache-url cache)))))
-
 (define (obsolete? date now ttl)
   "Return #t if DATE is obsolete compared to NOW + TTL seconds."
   (time>? (subtract-duration now (make-time time-duration 0 ttl))
           (make-time time-monotonic 0 date)))
 
-(define %lookup-threads
-  ;; Number of threads spawned to perform lookup operations.  This means we
-  ;; can have this many simultaneous HTTP GET requests to the server, which
-  ;; limits the impact of connection latency.
-  20)
 
-(define (lookup-narinfo cache path)
-  "Check locally if we have valid info about PATH, otherwise go to CACHE and
-check what it has."
+(define (narinfo-cache-file path)
+  "Return the name of the local file that contains an entry for PATH."
+  (string-append %narinfo-cache-directory "/"
+                 (store-path-hash-part path)))
+
+(define (cached-narinfo path)
+  "Check locally if we have valid info about PATH.  Return two values: a
+Boolean indicating whether we have valid cached info, and that info, which may
+be either #f (when PATH is unavailable) or the narinfo for PATH."
   (define now
     (current-time time-monotonic))
 
   (define cache-file
-    (string-append %narinfo-cache-directory "/"
-                   (store-path-hash-part path)))
+    (narinfo-cache-file path))
+
+  (catch 'system-error
+    (lambda ()
+      (call-with-input-file cache-file
+        (lambda (p)
+          (match (read p)
+            (('narinfo ('version 1)
+                       ('cache-uri cache-uri)
+                       ('date date) ('value #f))
+             ;; A cached negative lookup.
+             (if (obsolete? date now %narinfo-negative-ttl)
+                 (values #f #f)
+                 (values #t #f)))
+            (('narinfo ('version 1)
+                       ('cache-uri cache-uri)
+                       ('date date) ('value value))
+             ;; A cached positive lookup
+             (if (obsolete? date now %narinfo-ttl)
+                 (values #f #f)
+                 (values #t (string->narinfo value cache-uri))))
+            (('narinfo ('version v) _ ...)
+             (values #f #f))))))
+    (lambda _
+      (values #f #f))))
+
+(define (cache-narinfo! cache path narinfo)
+  "Cache locally NARNIFO for PATH, which originates from CACHE.  NARINFO may
+be #f, in which case it indicates that PATH is unavailable at CACHE."
+  (define now
+    (current-time time-monotonic))
 
   (define (cache-entry cache-uri narinfo)
     `(narinfo (version 1)
@@ -417,43 +429,153 @@ check what it has."
               (date ,(time-second now))
               (value ,(and=> narinfo narinfo->string))))
 
-  (let*-values (((valid? cached)
-                 (catch 'system-error
-                   (lambda ()
-                     (call-with-input-file cache-file
-                       (lambda (p)
-                         (match (read p)
-                           (('narinfo ('version 1)
-                                      ('cache-uri cache-uri)
-                                      ('date date) ('value #f))
-                            ;; A cached negative lookup.
-                            (if (obsolete? date now %narinfo-negative-ttl)
-                                (values #f #f)
-                                (values #t #f)))
-                           (('narinfo ('version 1)
-                                      ('cache-uri cache-uri)
-                                      ('date date) ('value value))
-                            ;; A cached positive lookup
-                            (if (obsolete? date now %narinfo-ttl)
-                                (values #f #f)
-                                (values #t (string->narinfo value
-                                                            cache-uri))))
-                           (('narinfo ('version v) _ ...)
-                            (values #f #f))))))
-                   (lambda _
-                     (values #f #f)))))
-    (if valid?
-        cached                                    ; including negative caches
+  (with-atomic-file-output (narinfo-cache-file path)
+    (lambda (out)
+      (write (cache-entry (cache-url cache) narinfo) out)))
+  narinfo)
+
+(define (narinfo-request cache-url path)
+  "Return an HTTP request for the narinfo of PATH at CACHE-URL."
+  (let ((url (string-append cache-url "/" (store-path-hash-part path)
+                            ".narinfo")))
+    (build-request (string->uri url) #:method 'GET)))
+
+(define (http-multiple-get base-url requests proc)
+  "Send all of REQUESTS to the server at BASE-URL.  Call PROC for each
+response, passing it the request object, the response, and a port from which
+to read the response body.  Return the list of results."
+  (let connect ((requests requests)
+                (result   '()))
+    ;; (format (current-error-port) "connecting (~a requests left)..."
+    ;;         (length requests))
+    (let ((p (open-socket-for-uri base-url)))
+      ;; Send all of REQUESTS in a row.
+      (setvbuf p _IOFBF (expt 2 16))
+      (for-each (cut write-request <> p) requests)
+      (force-output p)
+
+      ;; Now start processing responses.
+      (let loop ((requests requests)
+                 (result   result))
+        (match requests
+          (()
+           (reverse result))
+          ((head tail ...)
+           (let* ((resp (read-response p))
+                  (body (response-body-port resp)))
+             ;; The server can choose to stop responding at any time, in which
+             ;; case we have to try again.  Check whether that is the case.
+             (match (assq 'connection (response-headers resp))
+               (('connection 'close)
+                (connect requests result))        ;try again
+               (_
+                (loop tail                        ;keep going
+                      (cons (proc head resp body) result)))))))))))
+
+(define (read-to-eof port)
+  "Read from PORT until EOF is reached.  The data are discarded."
+  (dump-port port (%make-void-port "w")))
+
+(define (narinfo-from-file file url)
+  "Attempt to read a narinfo from FILE, using URL as the cache URL.  Return #f
+if file doesn't exist, and the narinfo otherwise."
+  (catch 'system-error
+    (lambda ()
+      (call-with-input-file file
+        (cut read-narinfo <> url)))
+    (lambda args
+      (if (= ENOENT (system-error-errno args))
+          #f
+          (apply throw args)))))
+
+(define (fetch-narinfos cache paths)
+  "Retrieve all the narinfos for PATHS from CACHE and return them."
+  (define url
+    (cache-url cache))
+
+  (define update-progress!
+    (let ((done 0))
+      (lambda ()
+        (display #\cr (current-error-port))
+        (force-output (current-error-port))
+        (format (current-error-port)
+                (_ "updating list of substitutes from '~a'... ~5,1f%")
+                url (* 100. (/ done (length paths))))
+        (set! done (+ 1 done)))))
+
+  (define (handle-narinfo-response request response port)
+    (let ((len (response-content-length response)))
+      ;; Make sure to read no more than LEN bytes since subsequent bytes may
+      ;; belong to the next response.
+      (case (response-code response)
+        ((200)                                     ; hit
+         (let ((narinfo (read-narinfo port url #:size len)))
+           (cache-narinfo! cache (narinfo-path narinfo) narinfo)
+           (update-progress!)
+           narinfo))
+        ((404)                                     ; failure
+         (let* ((path      (uri-path (request-uri request)))
+                (hash-part (string-drop-right path 8))) ; drop ".narinfo"
+           (if len
+               (get-bytevector-n port len)
+               (read-to-eof port))
+           (cache-narinfo! cache
+                           (find (cut string-contains <> hash-part) paths)
+                           #f)
+           (update-progress!))
+         #f)
+        (else                                      ; transient failure
+         (if len
+             (get-bytevector-n port len)
+             (read-to-eof port))
+         #f))))
+
+  (and (string=? (cache-store-directory cache) (%store-prefix))
+       (let ((uri (string->uri url)))
+         (case (and=> uri uri-scheme)
+           ((http)
+            (let ((requests (map (cut narinfo-request url <>) paths)))
+              (update-progress!)
+              (let ((result (http-multiple-get url requests
+                                               handle-narinfo-response)))
+                (newline (current-error-port))
+                result)))
+           ((file #f)
+            (let* ((base  (string-append (uri-path uri) "/"))
+                   (files (map (compose (cut string-append base <> ".narinfo")
+                                        store-path-hash-part)
+                               paths)))
+              (filter-map (cut narinfo-from-file <> url) files)))
+           (else
+            (leave (_ "~s: unsupported server URI scheme~%")
+                   (if uri (uri-scheme uri) url)))))))
+
+(define (lookup-narinfos cache paths)
+  "Return the narinfos for PATHS, invoking the server at CACHE when no
+information is available locally."
+  (let-values (((cached missing)
+                (fold2 (lambda (path cached missing)
+                         (let-values (((valid? value)
+                                       (cached-narinfo path)))
+                           (if valid?
+                               (values (cons value cached) missing)
+                               (values cached (cons path missing)))))
+                       '()
+                       '()
+                       paths)))
+    (if (null? missing)
+        cached
         (let* ((cache   (force cache))
-               (narinfo (and cache (fetch-narinfo cache path))))
-          ;; Cache NARINFO only when CACHE was actually accessible.  This
-          ;; avoids caching negative hits when in fact we just lacked network
-          ;; access.
-          (when cache
-            (with-atomic-file-output cache-file
-              (lambda (out)
-                (write (cache-entry (cache-url cache) narinfo) out))))
-          narinfo))))
+               (missing (if cache
+                            (fetch-narinfos cache missing)
+                            '())))
+          (append cached missing)))))
+
+(define (lookup-narinfo cache path)
+  "Return the narinfo for PATH in CACHE, or #f when no substitute for PATH was
+found."
+  (match (lookup-narinfos cache (list path))
+    ((answer) answer)))
 
 (define (remove-expired-cached-narinfos)
   "Remove expired narinfo entries from the cache.  The sole purpose of this
@@ -553,7 +675,7 @@ PORT.  REPORT-PROGRESS is a two-argument procedure such as that returned by
 ;;;
 
 (define (show-help)
-  (display (_ "Usage: guix substitute-binary [OPTION]...
+  (display (_ "Usage: guix substitute [OPTION]...
 Internal tool to substitute a pre-built binary to a local build.\n"))
   (display (_ "
       --query            report on the availability of substitutes for the
@@ -576,16 +698,6 @@ Internal tool to substitute a pre-built binary to a local build.\n"))
 ;;; Entry point.
 ;;;
 
-(define n-par-map*
-  ;; We want the ability to run many threads in parallel, regardless of the
-  ;; number of cores.  However, Guile 2.0.5 has a bug whereby 'n-par-map' ends
-  ;; up consuming a lot of memory, possibly leading to death.  Thus, resort to
-  ;; 'par-map' on 2.0.5.
-  (if (guile-version>? "2.0.5")
-      n-par-map
-      (lambda (n proc lst)
-        (par-map proc lst))))
-
 (define (check-acl-initialized)
   "Warn if the ACL is uninitialized."
   (define (singleton? acl)
@@ -631,12 +743,11 @@ found."
   (assoc-ref (daemon-options) option))
 
 (define %cache-url
-  (match (and=> (string-append
-                 ;; TODO: Uncomment the following lines when multiple
-                 ;; substitute sources are supported.
-                 ;; (find-daemon-option "untrusted-substitute-urls") ;client
-                 ;; " "
-                 (find-daemon-option "substitute-urls"))          ;admin
+  (match (and=> ;; TODO: Uncomment the following lines when multiple
+                ;; substitute sources are supported.
+                ;; (find-daemon-option "untrusted-substitute-urls") ;client
+                ;; " "
+                (find-daemon-option "substitute-urls")          ;admin
                 string-tokenize)
     ((url)
      url)
@@ -650,7 +761,7 @@ found."
      ;; daemon.
      "http://hydra.gnu.org")))
 
-(define (guix-substitute-binary . args)
+(define (guix-substitute . args)
   "Implement the build daemon's substituter protocol."
   (mkdir-p %narinfo-cache-directory)
   (maybe-remove-expired-cached-narinfo)
@@ -695,9 +806,7 @@ substituter disabled~%")
                      ;; Return the subset of PATHS available in CACHE.
                      (let ((substitutable
                             (if cache
-                                (n-par-map* %lookup-threads
-                                            (cut lookup-narinfo cache <>)
-                                            paths)
+                                (lookup-narinfos cache paths)
                                 '())))
                        (for-each (lambda (narinfo)
                                    (format #t "~a~%" (narinfo-path narinfo)))
@@ -707,9 +816,7 @@ substituter disabled~%")
                      ;; Reply info about PATHS if it's in CACHE.
                      (let ((substitutable
                             (if cache
-                                (n-par-map* %lookup-threads
-                                            (cut lookup-narinfo cache <>)
-                                            paths)
+                                (lookup-narinfos cache paths)
                                 '())))
                        (for-each (lambda (narinfo)
                                    (format #t "~a\n~a\n~a\n"
@@ -775,7 +882,7 @@ substituter disabled~%")
 
             (every (compose zero? cdr waitpid) pids))))
        (("--version")
-        (show-version-and-exit "guix substitute-binary"))
+        (show-version-and-exit "guix substitute"))
        (("--help")
         (show-help))
        (opts
@@ -786,4 +893,4 @@ substituter disabled~%")
 ;;; eval: (put 'with-timeout 'scheme-indent-function 1)
 ;;; End:
 
-;;; substitute-binary.scm ends here
+;;; substitute.scm ends here
diff --git a/guix/store.scm b/guix/store.scm
index 45c555b12c..3d6b06989c 100644
--- a/guix/store.scm
+++ b/guix/store.scm
@@ -447,6 +447,10 @@ encoding conversion errors."
                               (message "invalid error code")
                               (status   k))))))))
 
+(define %default-substitute-urls
+  ;; Default list of substituters.
+  '("http://hydra.gnu.org"))
+
 (define* (set-build-options server
                             #:key keep-failed? keep-going? fallback?
                             (verbosity 0)
@@ -459,7 +463,12 @@ encoding conversion errors."
                             (print-build-trace #t)
                             (build-cores (current-processor-count))
                             (use-substitutes? #t)
-                            (substitute-urls '())) ; client "untrusted" cache URLs
+
+                            ;; Client-provided substitute URLs.  For
+                            ;; unprivileged clients, these are considered
+                            ;; "untrusted"; for root, they override the
+                            ;; daemon's settings.
+                            (substitute-urls %default-substitute-urls))
   ;; Must be called after `open-connection'.
 
   (define socket
diff --git a/guix/tests.scm b/guix/tests.scm
index 0896e842da..080ee9cc74 100644
--- a/guix/tests.scm
+++ b/guix/tests.scm
@@ -126,7 +126,7 @@ Deriver: ~a~%"
 (define* (call-with-derivation-narinfo drv thunk
                                        #:key (sha256 (make-bytevector 32 0)))
   "Call THUNK in a context where fake substituter data, as read by 'guix
-substitute-binary', has been installed for DRV.  SHA256 is the hash of the
+substitute', has been installed for DRV.  SHA256 is the hash of the
 expected output of DRV."
   (let* ((output  (derivation->output-path drv))
          (dir     (%substitute-directory))
@@ -178,7 +178,7 @@ CONTENTS."
     (lambda ()
       (let ((hash (call-with-input-file (string-append dir "/example.nar")
                     port-sha256)))
-        ;; Create fake substituter data, to be read by `substitute-binary'.
+        ;; Create fake substituter data, to be read by 'guix substitute'.
         (call-with-derivation-narinfo drv
           thunk
           #:sha256 (or sha256 hash))))
diff --git a/guix/ui.scm b/guix/ui.scm
index ae37c8e6ca..4929f93590 100644
--- a/guix/ui.scm
+++ b/guix/ui.scm
@@ -815,7 +815,7 @@ parameter of 'args-fold'."
 
 (define (show-guix-help)
   (define (internal? command)
-    (member command '("substitute-binary" "authenticate" "offload")))
+    (member command '("substitute" "authenticate" "offload")))
 
   (format #t (_ "Usage: guix COMMAND ARGS...
 Run COMMAND with ARGS.\n"))
diff --git a/nix/scripts/substitute-binary.in b/nix/scripts/substitute-binary.in
deleted file mode 100644
index 48d7bb8ff1..0000000000
--- a/nix/scripts/substitute-binary.in
+++ /dev/null
@@ -1,11 +0,0 @@
-#!@SHELL@
-# A shorthand for "guix substitute-binary", for use by the daemon.
-
-if test "x$GUIX_UNINSTALLED" = "x"
-then
-    prefix="@prefix@"
-    exec_prefix="@exec_prefix@"
-    exec "@bindir@/guix" substitute-binary "$@"
-else
-    exec guix substitute-binary "$@"
-fi
diff --git a/nix/scripts/substitute.in b/nix/scripts/substitute.in
new file mode 100644
index 0000000000..5a2eeb7259
--- /dev/null
+++ b/nix/scripts/substitute.in
@@ -0,0 +1,11 @@
+#!@SHELL@
+# A shorthand for "guix substitute", for use by the daemon.
+
+if test "x$GUIX_UNINSTALLED" = "x"
+then
+    prefix="@prefix@"
+    exec_prefix="@exec_prefix@"
+    exec "@bindir@/guix" substitute "$@"
+else
+    exec guix substitute "$@"
+fi
diff --git a/pre-inst-env.in b/pre-inst-env.in
index ef9a3ce3c3..fe56da6944 100644
--- a/pre-inst-env.in
+++ b/pre-inst-env.in
@@ -44,7 +44,7 @@ export PATH
 # Daemon helpers.
 
 NIX_ROOT_FINDER="$abs_top_builddir/nix/scripts/list-runtime-roots"
-NIX_SUBSTITUTERS="$abs_top_builddir/nix/scripts/substitute-binary"
+NIX_SUBSTITUTERS="$abs_top_builddir/nix/scripts/substitute"
 NIX_BUILD_HOOK="$abs_top_builddir/nix/scripts/offload"
 NIX_LIBEXEC_DIR="@abs_top_builddir@/nix/scripts" # for 'guix-authenticate'
 
diff --git a/tests/derivations.scm b/tests/derivations.scm
index 72d253c465..a8cccac34a 100644
--- a/tests/derivations.scm
+++ b/tests/derivations.scm
@@ -499,6 +499,20 @@
            (string=? path (derivation-file-name (%guile-for-build)))))
          (derivation-prerequisites drv))))
 
+(test-assert "derivation-prerequisites and derivation-input-is-valid?"
+  (let* ((a (build-expression->derivation %store "a" '(mkdir %output)))
+         (b (build-expression->derivation %store "b" `(list ,(random-text))))
+         (c (build-expression->derivation %store "c" `(mkdir %output)
+                                          #:inputs `(("a" ,a) ("b" ,b)))))
+    (build-derivations %store (list a))
+    (match (derivation-prerequisites c
+                                     (cut valid-derivation-input? %store
+                                          <>))
+      ((($ <derivation-input> file ("out")))
+       (string=? file (derivation-file-name b)))
+      (x
+       (pk 'fail x #f)))))
+
 (test-assert "build-expression->derivation without inputs"
   (let* ((builder    '(begin
                         (mkdir %output)
diff --git a/tests/gexp.scm b/tests/gexp.scm
index 4c31e22f15..0540969503 100644
--- a/tests/gexp.scm
+++ b/tests/gexp.scm
@@ -160,6 +160,12 @@
          (equal? `(list ,guile ,cu ,libc ,bu)
                  (gexp->sexp* exp target)))))
 
+(test-equal "ungexp + ungexp-native, nested"
+  (list `((,%bootstrap-guile "out")) '<> `((,coreutils "out")))
+  (let* ((exp (gexp (list (ungexp-native (gexp (ungexp coreutils)))
+                          (ungexp %bootstrap-guile)))))
+    (list (gexp-inputs exp) '<> (gexp-native-inputs exp))))
+
 (test-assert "input list"
   (let ((exp   (gexp (display
                       '(ungexp (list %bootstrap-guile coreutils)))))
@@ -497,6 +503,23 @@
                                              (list "out" %bootstrap-guile))))
     (built-derivations (list drv))))
 
+(test-assertm "gexp->derivation #:allowed-references, specific output"
+  (mlet* %store-monad ((in  (gexp->derivation "thing"
+                                              #~(begin
+                                                  (mkdir #$output:ok)
+                                                  (mkdir #$output:not-ok))))
+                       (drv (gexp->derivation "allowed-refs"
+                                              #~(begin
+                                                  (pk #$in:not-ok)
+                                                  (mkdir #$output)
+                                                  (chdir #$output)
+                                                  (symlink #$output "self")
+                                                  (symlink #$in:ok "ok"))
+                                              #:allowed-references
+                                              (list "out"
+                                                    (gexp-input in "ok")))))
+    (built-derivations (list drv))))
+
 (test-assert "gexp->derivation #:allowed-references, disallowed"
   (let ((drv (run-with-store %store
                (gexp->derivation "allowed-refs"
diff --git a/tests/store.scm b/tests/store.scm
index 9ed78be085..f778c2086d 100644
--- a/tests/store.scm
+++ b/tests/store.scm
@@ -367,15 +367,15 @@
   (with-store s
     (let* ((d (package-derivation s %bootstrap-guile (%current-system)))
            (o (derivation->output-path d)))
-      ;; Create fake substituter data, to be read by `substitute-binary'.
+      ;; Create fake substituter data, to be read by 'guix substitute'.
       (with-derivation-narinfo d
         ;; Remove entry from the local cache.
         (false-if-exception
          (delete-file (string-append (getenv "XDG_CACHE_HOME")
-                                     "/guix/substitute-binary/"
+                                     "/guix/substitute/"
                                      (store-path-hash-part o))))
 
-        ;; Make sure `substitute-binary' correctly communicates the above
+        ;; Make sure 'guix substitute' correctly communicates the above
         ;; data.
         (set-build-options s #:use-substitutes? #t)
         (and (has-substitutes? s o)
@@ -439,7 +439,7 @@
       (with-derivation-substitute d c
         (sha256 => (make-bytevector 32 0)) ;select a hash that doesn't match C
 
-        ;; Make sure we use `substitute-binary'.
+        ;; Make sure we use 'guix substitute'.
         (set-build-options s
                            #:use-substitutes? #t
                            #:fallback? #f)
@@ -464,9 +464,9 @@
                  #:guile-for-build
                  (package-derivation s %bootstrap-guile (%current-system))))
            (o   (derivation->output-path d)))
-      ;; Create fake substituter data, to be read by `substitute-binary'.
+      ;; Create fake substituter data, to be read by 'guix substitute'.
       (with-derivation-narinfo d
-        ;; Make sure we use `substitute-binary'.
+        ;; Make sure we use 'guix substitute'.
         (set-build-options s #:use-substitutes? #t)
         (and (has-substitutes? s o)
              (guard (c ((nix-protocol-error? c)
diff --git a/tests/substitute-binary.scm b/tests/substitute.scm
index 7c1204c1ab..85698127fa 100644
--- a/tests/substitute-binary.scm
+++ b/tests/substitute.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Nikita Karetnikov <nikita@karetnikov.org>
-;;; Copyright © 2014 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -17,8 +17,8 @@
 ;;; You should have received a copy of the GNU General Public License
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
-(define-module (test-substitute-binary)
-  #:use-module (guix scripts substitute-binary)
+(define-module (test-substitute)
+  #:use-module (guix scripts substitute)
   #:use-module (guix base64)
   #:use-module (guix hash)
   #:use-module (guix serialization)
@@ -95,7 +95,7 @@ version identifier.."
 
 
 
-(test-begin "substitute-binary")
+(test-begin "substitute")
 
 (test-quit "not a number"
     "signature version"
@@ -132,7 +132,7 @@ a file for NARINFO."
                                                 "GUIX_BINARY_SUBSTITUTE_URL"))
                                   uri-path))
         (cache-directory   (string-append (getenv "XDG_CACHE_HOME")
-                                          "/guix/substitute-binary/")))
+                                          "/guix/substitute/")))
     (dynamic-wind
       (lambda ()
         (when (file-exists? cache-directory)
@@ -156,7 +156,7 @@ a file for NARINFO."
           (cute write-file
                 (string-append narinfo-directory "/example.out") <>))
 
-        (set! (@@ (guix scripts substitute-binary)
+        (set! (@@ (guix scripts substitute)
                   %allow-unauthenticated-substitutes?)
               #f))
       thunk
@@ -166,8 +166,8 @@ a file for NARINFO."
 (define-syntax-rule (with-narinfo narinfo body ...)
   (call-with-narinfo narinfo (lambda () body ...)))
 
-;; Transmit these options to 'guix substitute-binary'.
-(set! (@@ (guix scripts substitute-binary) %cache-url)
+;; Transmit these options to 'guix substitute'.
+(set! (@@ (guix scripts substitute) %cache-url)
       (getenv "GUIX_BINARY_SUBSTITUTE_URL"))
 
 (test-equal "query narinfo without signature"
@@ -180,7 +180,7 @@ a file for NARINFO."
          (with-input-from-string (string-append "have " (%store-prefix)
                                                 "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
            (lambda ()
-             (guix-substitute-binary "--query"))))))))
+             (guix-substitute "--query"))))))))
 
 (test-equal "query narinfo with invalid hash"
   ;; The hash in the signature differs from the hash of %NARINFO.
@@ -195,7 +195,7 @@ a file for NARINFO."
          (with-input-from-string (string-append "have " (%store-prefix)
                                                 "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
            (lambda ()
-             (guix-substitute-binary "--query"))))))))
+             (guix-substitute "--query"))))))))
 
 (test-equal "query narinfo signed with authorized key"
   (string-append (%store-prefix) "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
@@ -209,7 +209,7 @@ a file for NARINFO."
          (with-input-from-string (string-append "have " (%store-prefix)
                                                 "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
            (lambda ()
-             (guix-substitute-binary "--query"))))))))
+             (guix-substitute "--query"))))))))
 
 (test-equal "query narinfo signed with unauthorized key"
   ""                                              ; not substitutable
@@ -225,15 +225,15 @@ a file for NARINFO."
          (with-input-from-string (string-append "have " (%store-prefix)
                                                 "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
            (lambda ()
-             (guix-substitute-binary "--query"))))))))
+             (guix-substitute "--query"))))))))
 
 (test-quit "substitute, no signature"
     "lacks a signature"
   (with-narinfo %narinfo
-    (guix-substitute-binary "--substitute"
-                            (string-append (%store-prefix)
-                                           "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
-                            "foo")))
+    (guix-substitute "--substitute"
+                     (string-append (%store-prefix)
+                                    "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
+                     "foo")))
 
 (test-quit "substitute, invalid hash"
     "hash"
@@ -241,10 +241,10 @@ a file for NARINFO."
   (with-narinfo (string-append %narinfo "Signature: "
                                (signature-field "different body")
                                "\n")
-    (guix-substitute-binary "--substitute"
-                            (string-append (%store-prefix)
-                                           "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
-                            "foo")))
+    (guix-substitute "--substitute"
+                     (string-append (%store-prefix)
+                                    "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
+                     "foo")))
 
 (test-quit "substitute, unauthorized key"
     "unauthorized"
@@ -253,10 +253,10 @@ a file for NARINFO."
                                 %narinfo
                                 #:public-key %wrong-public-key)
                                "\n")
-    (guix-substitute-binary "--substitute"
-                            (string-append (%store-prefix)
-                                           "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
-                            "foo")))
+    (guix-substitute "--substitute"
+                     (string-append (%store-prefix)
+                                    "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
+                     "foo")))
 
 (test-equal "substitute, authorized key"
   "Substitutable data."
@@ -265,15 +265,15 @@ a file for NARINFO."
     (dynamic-wind
       (const #t)
       (lambda ()
-        (guix-substitute-binary "--substitute"
-                                (string-append (%store-prefix)
-                                               "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
-                                "substitute-retrieved")
+        (guix-substitute "--substitute"
+                         (string-append (%store-prefix)
+                                        "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-foo")
+                         "substitute-retrieved")
         (call-with-input-file "substitute-retrieved" get-string-all))
       (lambda ()
         (false-if-exception (delete-file "substitute-retrieved"))))))
 
-(test-end "substitute-binary")
+(test-end "substitute")
 
 
 (exit (= (test-runner-fail-count (test-runner-current)) 0))