summary refs log tree commit diff
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/build/linux-modules.scm20
-rw-r--r--gnu/build/vm.scm19
-rw-r--r--gnu/packages.scm69
-rw-r--r--gnu/packages/abduco.scm7
-rw-r--r--gnu/packages/admin.scm79
-rw-r--r--gnu/packages/adns.scm6
-rw-r--r--gnu/packages/aidc.scm14
-rw-r--r--gnu/packages/algebra.scm4
-rw-r--r--gnu/packages/audio.scm46
-rw-r--r--gnu/packages/augeas.scm59
-rw-r--r--gnu/packages/base.scm9
-rw-r--r--gnu/packages/bioinformatics.scm274
-rw-r--r--gnu/packages/bittorrent.scm6
-rw-r--r--gnu/packages/compression.scm2
-rw-r--r--gnu/packages/cpio.scm3
-rw-r--r--gnu/packages/curl.scm11
-rw-r--r--gnu/packages/databases.scm34
-rw-r--r--gnu/packages/dav.scm4
-rw-r--r--gnu/packages/dictionaries.scm5
-rw-r--r--gnu/packages/docker.scm1
-rw-r--r--gnu/packages/dvtm.scm7
-rw-r--r--gnu/packages/ebook.scm4
-rw-r--r--gnu/packages/emacs.scm120
-rw-r--r--gnu/packages/engineering.scm68
-rw-r--r--gnu/packages/feh.scm5
-rw-r--r--gnu/packages/finance.scm7
-rw-r--r--gnu/packages/fonts.scm9
-rw-r--r--gnu/packages/fontutils.scm37
-rw-r--r--gnu/packages/freedesktop.scm31
-rw-r--r--gnu/packages/fribidi.scm5
-rw-r--r--gnu/packages/games.scm32
-rw-r--r--gnu/packages/gcc.scm4
-rw-r--r--gnu/packages/gdb.scm6
-rw-r--r--gnu/packages/ghostscript.scm2
-rw-r--r--gnu/packages/gl.scm4
-rw-r--r--gnu/packages/glib.scm4
-rw-r--r--gnu/packages/gnome.scm185
-rw-r--r--gnu/packages/gnunet.scm43
-rw-r--r--gnu/packages/gnupg.scm11
-rw-r--r--gnu/packages/gnuzilla.scm9
-rw-r--r--gnu/packages/gps.scm19
-rw-r--r--gnu/packages/gstreamer.scm134
-rw-r--r--gnu/packages/gtk.scm27
-rw-r--r--gnu/packages/guile.scm64
-rw-r--r--gnu/packages/icu4c.scm11
-rw-r--r--gnu/packages/kde-frameworks.scm23
-rw-r--r--gnu/packages/kde.scm229
-rw-r--r--gnu/packages/ldc.scm45
-rw-r--r--gnu/packages/libcanberra.scm2
-rw-r--r--gnu/packages/linux.scm84
-rw-r--r--gnu/packages/lsh.scm57
-rw-r--r--gnu/packages/lua.scm2
-rw-r--r--gnu/packages/lxqt.scm9
-rw-r--r--gnu/packages/mail.scm42
-rw-r--r--gnu/packages/mate.scm211
-rw-r--r--gnu/packages/maths.scm10
-rw-r--r--gnu/packages/mit-krb5.scm70
-rw-r--r--gnu/packages/moe.scm5
-rw-r--r--gnu/packages/mpd.scm23
-rw-r--r--gnu/packages/music.scm156
-rw-r--r--gnu/packages/nano.scm4
-rw-r--r--gnu/packages/nettle.scm28
-rw-r--r--gnu/packages/ocaml.scm57
-rw-r--r--gnu/packages/openbox.scm7
-rw-r--r--gnu/packages/openstack.scm20
-rw-r--r--gnu/packages/owncloud.scm6
-rw-r--r--gnu/packages/package-management.scm51
-rw-r--r--gnu/packages/parallel.scm90
-rw-r--r--gnu/packages/patches/cpio-CVE-2016-2037.patch49
-rw-r--r--gnu/packages/patches/glibc-CVE-2015-7547.patch559
-rw-r--r--gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch142
-rw-r--r--gnu/packages/patches/icecat-update-graphite2.patch9988
-rw-r--r--gnu/packages/patches/libsndfile-CVE-2014-9496.patch55
-rw-r--r--gnu/packages/patches/libsndfile-CVE-2015-7805.patch95
-rw-r--r--gnu/packages/patches/libssh-0.6.5-CVE-2016-0739.patch77
-rw-r--r--gnu/packages/patches/libssh-CVE-2014-0017.patch89
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch569
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch65
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2696.patch736
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2697.patch55
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch43
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch132
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-8629.patch51
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-8630.patch81
-rw-r--r--gnu/packages/patches/mit-krb5-CVE-2015-8631.patch576
-rw-r--r--gnu/packages/patches/mit-krb5-init-context-null-spnego.patch49
-rw-r--r--gnu/packages/patches/ocaml-findlib-make-install.patch20
-rw-r--r--gnu/packages/patches/python-paste-remove-timing-test.patch16
-rw-r--r--gnu/packages/patches/python-paste-remove-website-test.patch21
-rw-r--r--gnu/packages/patches/qemu-CVE-2015-8619.patch119
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-1981.patch95
-rw-r--r--gnu/packages/patches/qemu-CVE-2016-2197.patch40
-rw-r--r--gnu/packages/patches/qemu-usb-ehci-oob-read.patch49
-rw-r--r--gnu/packages/patches/slurm-configure-remove-nonfree-contribs.patch43
-rw-r--r--gnu/packages/patches/tclxml-3.2-install.patch17
-rw-r--r--gnu/packages/patches/xf86-video-mga-glibc-2.20.patch17
-rw-r--r--gnu/packages/patches/xf86-video-r128-glibc-2.20.patch17
-rw-r--r--gnu/packages/patches/xf86-video-siliconmotion-remove-mibstore.patch16
-rw-r--r--gnu/packages/patches/xf86-video-sis-fix-exa-crash.patch45
-rw-r--r--gnu/packages/patches/xf86-video-sis-update-api.patch128
-rw-r--r--gnu/packages/patches/xf86-video-tdfx-remove-mibstore.patch26
-rw-r--r--gnu/packages/patches/xf86-video-trident-remove-mibstore.patch23
-rw-r--r--gnu/packages/patches/xf86-video-vmware-glibc-2.20.patch15
-rw-r--r--gnu/packages/pdf.scm2
-rw-r--r--gnu/packages/perl.scm29
-rw-r--r--gnu/packages/pkg-config.scm14
-rw-r--r--gnu/packages/polkit.scm9
-rw-r--r--gnu/packages/pulseaudio.scm20
-rw-r--r--gnu/packages/pumpio.scm1
-rw-r--r--gnu/packages/python.scm1029
-rw-r--r--gnu/packages/qemu.scm6
-rw-r--r--gnu/packages/qt.scm37
-rw-r--r--gnu/packages/rdf.scm31
-rw-r--r--gnu/packages/ruby.scm2
-rw-r--r--gnu/packages/scheme.scm8
-rw-r--r--gnu/packages/screen.scm2
-rw-r--r--gnu/packages/ssh.scm61
-rw-r--r--gnu/packages/statistics.scm23
-rw-r--r--gnu/packages/tcl.scm75
-rw-r--r--gnu/packages/texlive.scm76
-rw-r--r--gnu/packages/textutils.scm31
-rw-r--r--gnu/packages/tls.scm98
-rw-r--r--gnu/packages/version-control.scm8
-rw-r--r--gnu/packages/video.scm98
-rw-r--r--gnu/packages/vim.scm8
-rw-r--r--gnu/packages/wine.scm18
-rw-r--r--gnu/packages/xdisorg.scm28
-rw-r--r--gnu/packages/xfce.scm46
-rw-r--r--gnu/packages/xnee.scm2
-rw-r--r--gnu/packages/xorg.scm365
-rw-r--r--gnu/packages/yasm.scm5
-rw-r--r--gnu/packages/yubico.scm9
-rw-r--r--gnu/packages/zsh.scm8
-rw-r--r--gnu/services/databases.scm3
-rw-r--r--gnu/services/desktop.scm2
-rw-r--r--gnu/services/herd.scm8
-rw-r--r--gnu/services/xorg.scm45
-rw-r--r--gnu/system.scm32
-rw-r--r--gnu/system/install.scm8
-rw-r--r--gnu/system/locale.scm32
-rw-r--r--gnu/system/vm.scm10
141 files changed, 15659 insertions, 3499 deletions
diff --git a/gnu/build/linux-modules.scm b/gnu/build/linux-modules.scm
index bbe1a74d85..d7feb3a080 100644
--- a/gnu/build/linux-modules.scm
+++ b/gnu/build/linux-modules.scm
@@ -96,10 +96,20 @@ contains module names, not actual file names."
       name
       (dot-ko name)))
 
+(define (normalize-module-name module)
+  "Return the \"canonical\" name for MODULE, replacing hyphens with
+underscores."
+  ;; See 'modname_normalize' in libkmod.
+  (string-map (lambda (chr)
+                (case chr
+                  ((#\-) #\_)
+                  (else chr)))
+              module))
+
 (define (file-name->module-name file)
-  "Return the module name corresponding to FILE, stripping the trailing '.ko',
-etc."
-  (basename file ".ko"))
+  "Return the module name corresponding to FILE, stripping the trailing '.ko'
+and normalizing it."
+  (normalize-module-name (basename file ".ko")))
 
 (define* (recursive-module-dependencies files
                                         #:key (lookup-module dot-ko))
@@ -138,7 +148,9 @@ LOOKUP-MODULE to the module name."
 (define (module-black-list)
   "Return the black list of modules that must not be loaded.  This black list
 is specified using 'modprobe.blacklist=MODULE1,MODULE2,...' on the kernel
-command line; it is honored by libkmod."
+command line; it is honored by libkmod for users that pass
+'KMOD_PROBE_APPLY_BLACKLIST', which includes 'modprobe --use-blacklist' and
+udev."
   (define parameter
     "modprobe.blacklist=")
 
diff --git a/gnu/build/vm.scm b/gnu/build/vm.scm
index a095f9de8a..48e701adbe 100644
--- a/gnu/build/vm.scm
+++ b/gnu/build/vm.scm
@@ -1,5 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -97,7 +99,7 @@ the #:references-graphs parameter of 'derivation'."
     (_ #f))
 
   (unless (zero?
-           (apply system* qemu "-enable-kvm" "-nographic" "-no-reboot"
+           (apply system* qemu "-nographic" "-no-reboot"
                   "-m" (number->string memory-size)
                   "-net" "nic,model=virtio"
                   "-virtfs"
@@ -111,10 +113,17 @@ the #:references-graphs parameter of 'derivation'."
                   "-initrd" initrd
                   "-append" (string-append "console=ttyS0 --load="
                                            builder)
-                  (if make-disk-image?
-                      `("-drive" ,(string-append "file=" image-file
-                                                 ",if=virtio"))
-                      '())))
+                  (append
+                   (if make-disk-image?
+                       `("-drive" ,(string-append "file=" image-file
+                                                  ",if=virtio"))
+                       '())
+                   ;; Only enable kvm if we see /dev/kvm exists.
+                   ;; This allows users without hardware virtualization to still
+                   ;; use these commands.
+                   (if (file-exists? "/dev/kvm")
+                       '("-enable-kvm")
+                       '()))))
     (error "qemu failed" qemu))
 
   (if make-disk-image?
diff --git a/gnu/packages.scm b/gnu/packages.scm
index b309a7806d..64a695d970 100644
--- a/gnu/packages.scm
+++ b/gnu/packages.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
+;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -22,9 +23,6 @@
   #:use-module (guix packages)
   #:use-module (guix ui)
   #:use-module (guix utils)
-  #:use-module ((guix ftp-client) #:select (ftp-open))
-  #:use-module (guix gnu-maintenance)
-  #:use-module (guix upstream)
   #:use-module (ice-9 ftw)
   #:use-module (ice-9 vlist)
   #:use-module (ice-9 match)
@@ -46,8 +44,6 @@
             find-best-packages-by-name
             find-newest-available-packages
 
-            check-package-freshness
-
             specification->package
             specification->package+output))
 
@@ -280,69 +276,6 @@ return its return value."
                     (lambda (k signum)
                       (handler signum))))
 
-(define-syntax-rule (waiting exp fmt rest ...)
-  "Display the given message while EXP is being evaluated."
-  (let* ((message (format #f fmt rest ...))
-         (blank   (make-string (string-length message) #\space)))
-    (display message (current-error-port))
-    (force-output (current-error-port))
-    (call-with-sigint-handler
-     (lambda ()
-       (dynamic-wind
-         (const #f)
-         (lambda () exp)
-         (lambda ()
-           ;; Clear the line.
-           (display #\cr (current-error-port))
-           (display blank (current-error-port))
-           (display #\cr (current-error-port))
-           (force-output (current-error-port)))))
-     (lambda (signum)
-       (format (current-error-port) "  interrupted by signal ~a~%" SIGINT)
-       #f))))
-
-(define ftp-open*
-  ;; Memoizing version of `ftp-open'.  The goal is to avoid initiating a new
-  ;; FTP connection for each package, esp. since most of them are to the same
-  ;; server.  This has a noticeable impact when doing "guix upgrade -u".
-  (memoize ftp-open))
-
-(define (check-package-freshness package)
-  "Check whether PACKAGE has a newer version available upstream, and report
-it."
-  ;; TODO: Automatically inject the upstream version when desired.
-
-  (catch #t
-    (lambda ()
-      (when (false-if-exception (gnu-package? package))
-        (let ((name      (package-name package))
-              (full-name (package-full-name package)))
-          ;; XXX: This could work with non-GNU packages as well.  However,
-          ;; GNU's FTP-based updater would be too slow if it weren't memoized,
-          ;; and the generic interface in (guix upstream) doesn't support
-          ;; that.
-          (match (waiting (latest-release name
-                                          #:ftp-open ftp-open*
-                                          #:ftp-close (const #f))
-                          (_ "looking for the latest release of GNU ~a...") name)
-            ((? upstream-source? source)
-             (let ((latest-version
-                    (string-append (upstream-source-package source) "-"
-                                   (upstream-source-version source))))
-              (when (version>? latest-version full-name)
-                (format (current-error-port)
-                        (_ "~a: note: using ~a \
-but ~a is available upstream~%")
-                        (location->string (package-location package))
-                        full-name latest-version))))
-            (_ #t)))))
-    (lambda (key . args)
-      ;; Silently ignore networking errors rather than preventing
-      ;; installation.
-      (case key
-        ((getaddrinfo-error ftp-error) #f)
-        (else (apply throw key args))))))
-
 (define (specification->package spec)
   "Return a package matching SPEC.  SPEC may be a package name, or a package
 name followed by a hyphen and a version number.  If the version number is not
diff --git a/gnu/packages/abduco.scm b/gnu/packages/abduco.scm
index 79865f2211..ae67f81849 100644
--- a/gnu/packages/abduco.scm
+++ b/gnu/packages/abduco.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2015, 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -25,14 +25,15 @@
 (define-public abduco
   (package
    (name "abduco")
-   (version "0.4")
+   (version "0.5")
    (source (origin
             (method url-fetch)
             (uri (string-append
                   "http://www.brain-dump.org/projects/abduco/abduco-"
                   version ".tar.gz"))
             (sha256
-             (base32 "1fxwg2s5w183p0rwzsxizy9jdnilv5qqs647l3wl3khny6fp58xx"))))
+             (base32
+              "11phry5wnvwm9ckij5gxbrjfgdz3x38vpnm505q5ldc88im248mz"))))
    (build-system gnu-build-system)
    (arguments
     `(#:make-flags (list "CC=gcc"
diff --git a/gnu/packages/admin.scm b/gnu/packages/admin.scm
index eca4d9208f..b0b2046d2e 100644
--- a/gnu/packages/admin.scm
+++ b/gnu/packages/admin.scm
@@ -7,6 +7,8 @@
 ;;; Copyright © 2015 Alex Sassmannshausen <alex.sassmannshausen@gmail.com>
 ;;; Copyright © 2015 Eric Dvorsak <eric@dvorsak.fr>
 ;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2016 Pjotr Prins <pjotr.guix@thebird.nl>
+;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -35,6 +37,7 @@
   #:use-module (guix build-system trivial)
   #:use-module (gnu packages)
   #:use-module (gnu packages base)
+  #:use-module (gnu packages cyrus-sasl)
   #:use-module (gnu packages ncurses)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages linux)
@@ -48,6 +51,7 @@
   #:use-module (gnu packages bison)
   #:use-module (gnu packages flex)
   #:use-module (gnu packages glib)
+  #:use-module (gnu packages openldap)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages popt)
   #:use-module (gnu packages texinfo)
@@ -81,8 +85,8 @@
                          ;; is used by a bunch of services.
                          (method url-fetch)
                          (uri (string-append
-                               "http://git.savannah.gnu.org/cgit/dmd.git/patch/"
-                               "?id=d1d0ff30b3ed2b86b0a3c9bc048d2a855f8e31e6"))
+                               "http://git.savannah.gnu.org/cgit/shepherd.git/"
+                               "patch?id=d1d0ff30b3ed2b86b0a3c9bc048d2a855f8e31e6"))
                          (sha256
                           (base32
                            "1lqymypixfiyb72d6bn24m06ry2q1ljnnv0qrc89pbb4z9azaa4d"))
@@ -152,14 +156,14 @@ graphs and can export its output to different formats.")
 (define-public htop
   (package
    (name "htop")
-   (version "1.0.3")
+   (version "2.0.0")
    (source (origin
             (method url-fetch)
             (uri (string-append "http://hisham.hm/htop/releases/"
                   version "/htop-" version ".tar.gz"))
             (sha256
              (base32
-              "0a8qbpsifzjwc4f45xfwm48jhm59g6q5hlib4bf7z13mgy95fp05"))))
+              "1d944hn0ldxvxfrz9acr26lpmzlwj91m0s7x2xnivnfnmfha4p6i"))))
    (build-system gnu-build-system)
    (inputs
     `(("ncurses" ,ncurses)))
@@ -1426,4 +1430,69 @@ frequently used directories by typing only a small pattern.")
 for CPU usage.  It listens to network traffic on a named interface and
 displays a table of current bandwidth usage by pairs of hosts.")
     (home-page "http://www.ex-parrot.com/~pdw/iftop/")
-    (license license:gpl3)))
+    (license license:gpl2+)))
+
+(define-public munge
+  (package
+    (name "munge")
+    (version "0.5.11")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/dun/munge/archive/munge-"
+                                  version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0njplyalwwqh7xr7xc7klc6x06mq0ak8w2pxh85w8n4hxkmqqnf5"))))
+    (inputs
+     `(("openssl" ,openssl)
+       ("libgcrypt" ,libgcrypt)))
+    (build-system gnu-build-system)
+    (home-page "http://dun.github.io/munge/")
+    (synopsis "Cluster computing authentication service")
+    (description
+     "Munge is an authentication service for creating and validating
+credentials.  It allows a process to authenticate the UID and GID of another
+local or remote process within a group of hosts having common users and
+groups.  These hosts form a security realm that is defined by a shared
+cryptographic key.  Clients within this security realm can create and validate
+credentials without the use of root privileges, reserved ports, or
+platform-specific methods.")
+    (license license:gpl3+)))
+
+(define-public audit
+  (package
+    (name "audit")
+    (version "2.4.5")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://people.redhat.com/sgrubb/audit/"
+                                  "audit-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1q1q51dvxscbi4kbakmd4bn0xrvwwaiwvaya79925cbrqwzxsg77"))))
+    (build-system gnu-build-system)
+    (home-page "http://people.redhat.com/sgrubb/audit/")
+    (arguments
+     `(#:configure-flags (list "--with-python=no")
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'unpack 'fix-tests
+           (lambda _
+             ;; In the build environmnte /etc/passwd does not contain an entry
+             ;; for root/0, so we have to patch the expected value.
+             (substitute* "auparse/test/auparse_test.ref"
+               (("=0 \\(root\\)") "=0 (unknown(0))"))
+             #t)))))
+    (inputs
+     `(("openldap" ,openldap)
+       ("openssl" ,openssl)
+       ("sasl" ,cyrus-sasl)))
+    (synopsis "User-space component to the Linux auditing system")
+    (description
+     "auditd is the user-space component to the Linux auditing system, which
+allows logging of system calls made by user-land processes.  It's responsible
+for writing audit records to the disk.  Viewing the logs is done with the
+@code{ausearch} or @code{aureport} utilities.  Configuring the audit rules is
+done with the @code{auditctl} utility.")
+    (license license:gpl2+)))
diff --git a/gnu/packages/adns.scm b/gnu/packages/adns.scm
index 1af735b6eb..a6fbc1add8 100644
--- a/gnu/packages/adns.scm
+++ b/gnu/packages/adns.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Ludovic Courtès <ludo@gnu.org>
-;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -59,7 +59,7 @@ scripts.")
 (define-public c-ares
   (package
     (name "c-ares")
-    (version "1.10.0")
+    (version "1.11.0")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -67,7 +67,7 @@ scripts.")
                     ".tar.gz"))
               (sha256
                (base32
-                "1nyka87yf2jfd0y6sspll0yxwb8zi7kyvajrdbjmh4axc5s1cw1x"))))
+                "1z9y1f835dpi1ka2a2vzjygm3djdvr01036ml4l2js6r2xk2wqdk"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)))
diff --git a/gnu/packages/aidc.scm b/gnu/packages/aidc.scm
index 3ef5d28fbb..32093265a9 100644
--- a/gnu/packages/aidc.scm
+++ b/gnu/packages/aidc.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 John Darringon <jmd@gnu.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -49,14 +50,15 @@ formats.")
 (define-public qrencode
   (package
     (name "qrencode")
-    (version "3.4.3")
+    (version "3.4.4")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "http://fukuchi.org/works/qrencode/qrencode-" version
-                    ".tar.bz2"))
-              (sha256 (base32
-                       "163sb580p570p27imc6jhkfdw15kzp8vy1jq92nip1rwa63i9myz"))))
+                    "https://fukuchi.org/works/qrencode/qrencode-" version
+                    ".tar.gz"))
+              (sha256
+               (base32
+                "0wiagx7i8p9zal53smf5abrnh9lr31mv0p36wg017401jrmf5577"))))
     (build-system gnu-build-system)
     (inputs `(("libpng" ,libpng)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -66,4 +68,4 @@ symbol, a kind of 2D symbology that can be scanned by handy terminals such as
 a mobile phone with CCD.  The capacity of QR Code is up to 7000 digits or 4000
 characters, and is highly robust.")
     (license license:lgpl2.1+)
-    (home-page "http://fukuchi.org/works/qrencode")))
+    (home-page "https://fukuchi.org/works/qrencode")))
diff --git a/gnu/packages/algebra.scm b/gnu/packages/algebra.scm
index 0f17403868..85ec61c1b1 100644
--- a/gnu/packages/algebra.scm
+++ b/gnu/packages/algebra.scm
@@ -26,6 +26,7 @@
   #:use-module (gnu packages perl)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages flex)
+  #:use-module (gnu packages texlive)
   #:use-module (gnu packages xorg)
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix packages)
@@ -125,12 +126,13 @@ solve the shortest vector problem.")
               (base32
                 "0c8l83a0gjq73r9hndsrzkypwxvnnm4pxkkzbg6jm95m80nzwh11"))))
    (build-system gnu-build-system)
+   (native-inputs `(("texlive" ,texlive-minimal)))
    (inputs `(("gmp" ,gmp)
              ("libx11" ,libx11)
              ("perl" ,perl)
              ("readline" ,readline)))
    (arguments
-    '(#:make-flags '("gp")
+    '(#:make-flags '("all")
       ;; FIXME: building the documentation requires tex; once this is
       ;; available, replace "gp" by "all"
       #:test-target "dobench"
diff --git a/gnu/packages/audio.scm b/gnu/packages/audio.scm
index 7f0d87ddf7..865394a726 100644
--- a/gnu/packages/audio.scm
+++ b/gnu/packages/audio.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
@@ -30,6 +30,7 @@
   #:use-module (guix build-system waf)
   #:use-module (guix build-system trivial)
   #:use-module (guix build-system cmake)
+  #:use-module (guix build-system python)
   #:use-module (gnu packages)
   #:use-module (gnu packages algebra)
   #:use-module (gnu packages autotools)
@@ -158,24 +159,24 @@ streams from live audio.")
 (define-public ardour
   (package
     (name "ardour")
-    (version "4.4")
+    (version "4.7")
     (source (origin
               (method git-fetch)
               (uri (git-reference
                     (url "git://git.ardour.org/ardour/ardour.git")
                     (commit version)))
               (snippet
-               ;; Ardour expects this file to exist at build time.  It can be
-               ;; created from a git checkout with:
-               ;;   ./waf create_stored_revision
+               ;; Ardour expects this file to exist at build time.  The revision
+               ;; is the output of
+               ;;    git describe HEAD | sed 's/^[A-Za-z]*+//'
                '(call-with-output-file
                     "libs/ardour/revision.cc"
                   (lambda (port)
                     (format port "#include \"ardour/revision.h\"
-namespace ARDOUR { const char* revision = \"4.4-210-ga4daf93\" ; }"))))
+namespace ARDOUR { const char* revision = \"4.7-219-g0e36f8e\" ; }"))))
               (sha256
                (base32
-                "1gnrcnq2ksnh7fsa301v1c4p5dqrbqpjylf02rg3za3ab58wxi7l"))
+                "149gswphz77m3pkzsn2nqbm6yvcfa3fva560bcvjzlgb73f64q5l"))
               (file-name (string-append name "-" version))))
     (build-system waf-build-system)
     (arguments
@@ -946,6 +947,34 @@ essential distortions.")
 implementation of the Open Sound Control (OSC) protocol.")
     (license license:lgpl2.1+)))
 
+(define-public python-pyliblo
+  (package
+    (name "python-pyliblo")
+    (version "0.10.0")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "http://das.nasophon.de/download/pyliblo-"
+                                 version ".tar.gz"))
+             (sha256
+              (base32
+               "13vry6xhxm7adnbyj28w1kpwrh0kf7nw83cz1yq74wl21faz2rzw"))))
+    (build-system python-build-system)
+    (arguments `(#:tests? #f)) ;no tests
+    (inputs
+     `(("python-cython" ,python-cython)
+       ("liblo" ,liblo)))
+    (home-page "http://das.nasophon.de/pyliblo/")
+    (synopsis "Python bindings for liblo")
+    (description
+     "Pyliblo is a Python wrapper for the liblo Open Sound Control (OSC)
+library.  It supports almost the complete functionality of liblo, allowing you
+to send and receive OSC messages using a nice and simple Python API.  Also
+included are the command line utilities @code{send_osc} and @code{dump_osc}.")
+    (license license:lgpl2.1+)))
+
+(define-public python2-pyliblo
+  (package-with-python2 python-pyliblo))
+
 (define-public lilv
   (package
     (name "lilv")
@@ -2032,4 +2061,5 @@ utility.  File formats are abstracted from its core, so it can process any file
 that contains WAVE data, compressed or not---provided there exists a format
 module to handle that particular file type.")
     (home-page "http://etree.org/shnutils/shntool/")
-    (license license:gpl3+)))
+    ;; 'install-sh' bears the x11 license
+    (license (list license:gpl2+ license:x11))))
diff --git a/gnu/packages/augeas.scm b/gnu/packages/augeas.scm
new file mode 100644
index 0000000000..95b96ca25c
--- /dev/null
+++ b/gnu/packages/augeas.scm
@@ -0,0 +1,59 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 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 augeas)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix utils)
+  #:use-module (guix build-system gnu)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages readline)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages xml))
+
+(define-public augeas
+  (package
+    (name "augeas")
+    (version "1.4.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://download.augeas.net/augeas-"
+                                  version ".tar.gz"))
+              (sha256
+               (base32
+                "0c2vncn0afmgwggnqa5s5z7m3zbcc66bi8v9m1h9w0i9q9xax7v5"))))
+    (build-system gnu-build-system)
+    ;; Marked as "required" in augeas.pc
+    (propagated-inputs
+     `(("libxml2" ,libxml2)))
+    (inputs
+     `(("readline" ,readline)))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)))
+    (home-page "http://augeas.net/")
+    (synopsis "Edit configuration files programmatically")
+    (description
+     "Augeas is a library and command line tool for programmatically editing
+configuration files in a controlled manner.  Augeas exposes a tree of all
+configuration settings and a simple local API for manipulating the tree.
+Augeas then modifies underlying configuration files according to the changes
+that have been made to the tree; it does as little modeling of configurations
+as possible, and focuses exclusivley on transforming the tree-oriented syntax
+of its public API to the myriad syntaxes of individual configuration files.")
+    (license license:lgpl2.1+)))
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 0b07ea196d..3c6b189120 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -2,7 +2,7 @@
 ;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2014 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2012 Nikita Karetnikov <nikita@karetnikov.org>
-;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2014, 2015, 2016 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014 Alex Kost <alezost@gmail.com>
 ;;; Copyright © 2014, 2015 Manolis Fragkiskos Ragkousis <manolis837@gmail.com>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
@@ -173,7 +173,7 @@ standard utility.")
                 "16d2r9kpivaak948mxzc0bai45mqfw73m113wrkmbffnalv1b5gx"))
               (patches (list (search-patch "patch-hurd-path-max.patch")))))
    (build-system gnu-build-system)
-   (native-inputs `(("ed", ed)))
+   (native-inputs `(("ed" ,ed)))
    (synopsis "Apply differences to originals, with optional backups")
    (description
     "Patch is a program that applies changes to files based on differences
@@ -318,7 +318,7 @@ functionality beyond that which is outlined in the POSIX standard.")
               "19gwwhik3wdwn0r42b7xcihkbxvjl9r2bdal8nifc3k5i4rn3iqb"))
             (patches (list (search-patch "make-impure-dirs.patch")))))
    (build-system gnu-build-system)
-   (native-inputs `(("pkg-config", pkg-config)))  ; to detect Guile
+   (native-inputs `(("pkg-config" ,pkg-config)))  ; to detect Guile
    (inputs `(("guile" ,guile-2.0)))
    (outputs '("out" "debug"))
    (arguments
@@ -479,7 +479,8 @@ store.")
                           '("glibc-ldd-x86_64.patch"
                             "glibc-locale-incompatibility.patch"
                             "glibc-versioned-locpath.patch"
-                            "glibc-o-largefile.patch")))))
+                            "glibc-o-largefile.patch"
+                            "glibc-CVE-2015-7547.patch")))))
    (build-system gnu-build-system)
 
    ;; Glibc's <limits.h> refers to <linux/limit.h>, for instance, so glibc
diff --git a/gnu/packages/bioinformatics.scm b/gnu/packages/bioinformatics.scm
index e277f890a1..7b3838d36f 100644
--- a/gnu/packages/bioinformatics.scm
+++ b/gnu/packages/bioinformatics.scm
@@ -1,3 +1,4 @@
+
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015, 2016 Ben Woodcroft <donttrustben@gmail.com>
@@ -39,6 +40,8 @@
   #:use-module (gnu packages boost)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages cpio)
+  #:use-module (gnu packages curl)
+  #:use-module (gnu packages doxygen)
   #:use-module (gnu packages file)
   #:use-module (gnu packages gawk)
   #:use-module (gnu packages gcc)
@@ -1080,6 +1083,52 @@ preparation protocols.")
 other types of unwanted sequence from high-throughput sequencing reads.")
     (license license:expat)))
 
+(define-public libbigwig
+  (package
+    (name "libbigwig")
+    (version "0.1.4")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/dpryan79/libBigWig/"
+                                  "archive/" version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "098rjh35pi4a9q83n8wiwvyzykjqj6l8q189p1xgfw4ghywdlvw1"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:test-target "test"
+       #:make-flags
+       (list "CC=gcc"
+             (string-append "prefix=" (assoc-ref %outputs "out")))
+       #:phases
+       (modify-phases %standard-phases
+         (delete 'configure)
+         (add-before 'check 'disable-curl-test
+           (lambda _
+             (substitute* "Makefile"
+               (("./test/testRemote.*") ""))
+             #t))
+         ;; This has been fixed with the upstream commit 4ff6959cd8a0, but
+         ;; there has not yet been a release containing this change.
+         (add-before 'install 'create-target-dirs
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let ((out (assoc-ref outputs "out")))
+               (mkdir-p (string-append out "/lib"))
+               (mkdir-p (string-append out "/include"))
+               #t))))))
+    (inputs
+     `(("zlib" ,zlib)
+       ("curl" ,curl)))
+    (native-inputs
+     `(("doxygen" ,doxygen)))
+    (home-page "https://github.com/dpryan79/libBigWig")
+    (synopsis "C library for handling bigWig files")
+    (description
+     "This package provides a C library for parsing local and remote BigWig
+files.")
+    (license license:expat)))
+
 (define-public deeptools
   (package
     (name "deeptools")
@@ -1741,7 +1790,7 @@ particular, reads spanning multiple exons.")
                (base32
                 "0djmgc0pfli0jilfx8hql1axhwhqxqb8rxg2r5rg07aw73sfs5nx"))))
     (build-system gnu-build-system)
-    (native-inputs `(("perl", perl)))
+    (native-inputs `(("perl" ,perl)))
     (home-page "http://hmmer.janelia.org")
     (synopsis "Biosequence analysis using profile hidden Markov models")
     (description
@@ -1773,6 +1822,8 @@ HMMs).")
     ;; Numpy needs to be propagated when htseq is used as a Python library.
     (propagated-inputs
      `(("python-numpy" ,python2-numpy)))
+    (inputs
+     `(("python-pysam" ,python2-pysam)))
     (native-inputs
      `(("python-setuptools" ,python2-setuptools)))
     (home-page "http://www-huber.embl.de/users/anders/HTSeq/")
@@ -1964,15 +2015,13 @@ command, or queried for specific k-mers with @code{jellyfish query}.")
 (define-public macs
   (package
     (name "macs")
-    (version "2.1.0.20140616")
+    (version "2.1.0.20151222")
     (source (origin
               (method url-fetch)
-              (uri (string-append
-                    "https://pypi.python.org/packages/source/M/MACS2/MACS2-"
-                    version ".tar.gz"))
+              (uri (pypi-uri "MACS2" version))
               (sha256
                (base32
-                "11lmiw6avqhwn75sn59g4lfkrr2kk20r3rgfbx9xfqb8rg9mi2n6"))))
+                "1r2hcz6irhcq7lwbafjks98jbn34hv05avgbdjnp6w6mlfjkf8x5"))))
     (build-system python-build-system)
     (arguments
      `(#:python ,python-2 ; only compatible with Python 2.7
@@ -2359,7 +2408,7 @@ generated using the PacBio Iso-Seq protocol.")
 (define-public prodigal
   (package
     (name "prodigal")
-    (version "2.6.2")
+    (version "2.6.3")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -2368,7 +2417,7 @@ generated using the PacBio Iso-Seq protocol.")
               (file-name (string-append name "-" version ".tar.gz"))
               (sha256
                (base32
-                "0m8sb0fg6lmxrlpzna0am6svbnlmd3dckrhgzxxgb3gxr5fyj284"))))
+                "17srxkqd3jc77xk15pfbgg1a9xahqg7337w95mrsia7mpza4l2c9"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f ;no check target
@@ -3311,6 +3360,61 @@ features; exactSNP: a SNP caller that discovers SNPs by testing signals
 against local background noises.")
     (license license:gpl3+)))
 
+(define-public stringtie
+  (package
+    (name "stringtie")
+    (version "1.2.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://ccb.jhu.edu/software/stringtie/dl/"
+                                  "stringtie-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1cqllsc1maq4kh92isi8yadgzbmnf042hlnalpk3y59aph1z3bfz"))
+              (modules '((guix build utils)))
+              (snippet
+               '(begin
+                  (delete-file-recursively "samtools-0.1.18")
+                  #t))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ;no test suite
+       #:phases
+       (modify-phases %standard-phases
+         ;; no configure script
+         (delete 'configure)
+         (add-before 'build 'use-system-samtools
+           (lambda _
+             (substitute* "Makefile"
+               (("stringtie: \\$\\{BAM\\}/libbam\\.a")
+                "stringtie: "))
+             (substitute* '("gclib/GBam.h"
+                            "gclib/GBam.cpp")
+               (("#include \"(bam|sam|kstring).h\"" _ header)
+                (string-append "#include <samtools/" header ".h>")))
+             #t))
+         (replace 'install
+          (lambda* (#:key outputs #:allow-other-keys)
+            (let ((bin (string-append (assoc-ref outputs "out") "/bin/")))
+              (install-file "stringtie" bin)
+              #t))))))
+    (inputs
+     `(("samtools" ,samtools-0.1)
+       ("zlib" ,zlib)))
+    (home-page "http://ccb.jhu.edu/software/stringtie/")
+    (synopsis "Transcript assembly and quantification for RNA-Seq data")
+    (description
+     "StringTie is a fast and efficient assembler of RNA-Seq sequence
+alignments into potential transcripts.  It uses a novel network flow algorithm
+as well as an optional de novo assembly step to assemble and quantitate
+full-length transcripts representing multiple splice variants for each gene
+locus.  Its input can include not only the alignments of raw reads used by
+other transcript assemblers, but also alignments of longer sequences that have
+been assembled from those reads.  To identify differentially expressed genes
+between experiments, StringTie's output can be processed either by the
+Cuffdiff or Ballgown programs.")
+    (license license:artistic2.0)))
+
 (define-public vcftools
   (package
     (name "vcftools")
@@ -3355,7 +3459,7 @@ data in the form of VCF files.")
 (define-public vsearch
   (package
     (name "vsearch")
-    (version "1.4.1")
+    (version "1.10.0")
     (source
      (origin
        (method url-fetch)
@@ -3365,7 +3469,7 @@ data in the form of VCF files.")
        (file-name (string-append name "-" version ".tar.gz"))
        (sha256
         (base32
-         "0b1359wbzgb2cm04h7dq05v80vik88hnsv298xxd1q1f2q4ydni7"))
+         "1i3bad7gnn2y3a1yfixzshd99xdkjc8w5bxzgifpysc6jiljwvb5"))
        (modules '((guix build utils)))
        (snippet
         '(begin
@@ -3375,14 +3479,24 @@ data in the form of VCF files.")
 -O3 -mtune=native -Wall -Wsign-compare")
               (string-append "AM_CXXFLAGS=-lcityhash"
                              " -O3 -Wall -Wsign-compare"))
-             (("^__top_builddir__bin_vsearch_SOURCES = cityhash/city.h \\\\")
+             (("^__top_builddir__bin_vsearch_SOURCES = city.h \\\\")
               "__top_builddir__bin_vsearch_SOURCES = \\")
-             (("^cityhash/config.h \\\\") "\\")
-             (("^cityhash/city.cc \\\\") "\\"))
+             (("^city.h \\\\") "\\")
+             (("^citycrc.h \\\\") "\\")
+             (("^libcityhash_a.*") "")
+             (("noinst_LIBRARIES = libcpu_sse2.a libcpu_ssse3.a \
+libcityhash.a")
+              "noinst_LIBRARIES = libcpu_sse2.a libcpu_ssse3.a")
+             (("__top_builddir__bin_vsearch_LDADD = libcpu_ssse3.a \
+libcpu_sse2.a libcityhash.a")
+              "__top_builddir__bin_vsearch_LDADD = libcpu_ssse3.a \
+libcpu_sse2.a -lcityhash"))
            (substitute* "src/vsearch.h"
-             (("^\\#include \"cityhash/city.h\"")
-              "#include <city.h>"))
-           (delete-file-recursively "src/cityhash")
+             (("^\\#include \"city.h\"") "#include <city.h>")
+             (("^\\#include \"citycrc.h\"") "#include <citycrc.h>"))
+           (delete-file "src/city.h")
+           (delete-file "src/citycrc.h")
+           (delete-file "src/city.cc")
            #t))))
     (build-system gnu-build-system)
     (arguments
@@ -3725,13 +3839,13 @@ on Bioconductor or which replace R functions.")
 (define-public r-annotationdbi
   (package
     (name "r-annotationdbi")
-    (version "1.32.2")
+    (version "1.32.3")
     (source (origin
               (method url-fetch)
               (uri (bioconductor-uri "AnnotationDbi" version))
               (sha256
                (base32
-                "08ncdjvq0l44kqyiv32kn9wnbw1xgfb6qjfzfbjpqrcfp1jygz9j"))))
+                "1v6x62hgys5827yg2xayjrd9xawbayzm6wy0q4vxh1s6yxc9bklj"))))
     (properties
      `((upstream-name . "AnnotationDbi")))
     (build-system r-build-system)
@@ -4043,6 +4157,25 @@ extracting the desired features in a convenient format.")
 information about the latest version of the Gene Ontologies.")
     (license license:artistic2.0)))
 
+(define-public r-graph
+  (package
+    (name "r-graph")
+    (version "1.48.0")
+    (source (origin
+              (method url-fetch)
+              (uri (bioconductor-uri "graph" version))
+              (sha256
+               (base32
+                "16w75rji3kv24gfv44w66y1a2y75ax26rl470y3ypna0ndc3rrcd"))))
+    (build-system r-build-system)
+    (propagated-inputs
+     `(("r-biocgenerics" ,r-biocgenerics)))
+    (home-page "http://bioconductor.org/packages/graph")
+    (synopsis "Handle graph data structures in R")
+    (description
+     "This package implements some simple graph handling capabilities for R.")
+    (license license:artistic2.0)))
+
 (define-public r-topgo
   (package
     (name "r-topgo")
@@ -4061,6 +4194,7 @@ information about the latest version of the Gene Ontologies.")
        ("r-biobase" ,r-biobase)
        ("r-biocgenerics" ,r-biocgenerics)
        ("r-go-db" ,r-go-db)
+       ("r-graph" ,r-graph)
        ("r-sparsem" ,r-sparsem)))
     (home-page "http://bioconductor.org/packages/topGO")
     (synopsis "Enrichment analysis for gene ontology")
@@ -4191,6 +4325,110 @@ genomic feature data as long as it has minimal information on the locations of
 genomic intervals.  In addition, it can use BAM or BigWig files as input.")
     (license license:artistic2.0)))
 
+(define-public r-org-hs-eg-db
+  (package
+    (name "r-org-hs-eg-db")
+    (version "3.2.3")
+    (source (origin
+              (method url-fetch)
+              ;; We cannot use bioconductor-uri here because this tarball is
+              ;; located under "data/annotation/" instead of "bioc/".
+              (uri (string-append "http://www.bioconductor.org/packages/"
+                                  "release/data/annotation/src/contrib/"
+                                  "org.Hs.eg.db_" version ".tar.gz"))
+              (sha256
+               (base32
+                "0xicgkbh6xkvs74s1piafqac63dyz2ycdyil4pj4ghhxx2sabm6p"))))
+    (properties
+     `((upstream-name . "org.Hs.eg.db")))
+    (build-system r-build-system)
+    (propagated-inputs
+     `(("r-annotationdbi" ,r-annotationdbi)))
+    (home-page "http://www.bioconductor.org/packages/org.Hs.eg.db/")
+    (synopsis "Genome wide annotation for Human")
+    (description
+     "This package provides mappings from Entrez gene identifiers to various
+annotations for the human genome.")
+    (license license:artistic2.0)))
+
+(define-public r-org-ce-eg-db
+  (package
+    (name "r-org-ce-eg-db")
+    (version "3.2.3")
+    (source (origin
+              (method url-fetch)
+              ;; We cannot use bioconductor-uri here because this tarball is
+              ;; located under "data/annotation/" instead of "bioc/".
+              (uri (string-append "http://www.bioconductor.org/packages/"
+                                  "release/data/annotation/src/contrib/"
+                                  "org.Ce.eg.db_" version ".tar.gz"))
+              (sha256
+               (base32
+                "1d0lx00ybq34yqs6mziaa0lrh77xm0ggsmi76g6k95f77gi7m1sw"))))
+    (properties
+     `((upstream-name . "org.Ce.eg.db")))
+    (build-system r-build-system)
+    (propagated-inputs
+     `(("r-annotationdbi" ,r-annotationdbi)))
+    (home-page "http://www.bioconductor.org/packages/org.Ce.eg.db/")
+    (synopsis "Genome wide annotation for Worm")
+    (description
+     "This package provides mappings from Entrez gene identifiers to various
+annotations for the genome of the model worm Caenorhabditis elegans.")
+    (license license:artistic2.0)))
+
+(define-public r-org-dm-eg-db
+  (package
+    (name "r-org-dm-eg-db")
+    (version "3.2.3")
+    (source (origin
+              (method url-fetch)
+              ;; We cannot use bioconductor-uri here because this tarball is
+              ;; located under "data/annotation/" instead of "bioc/".
+              (uri (string-append "http://www.bioconductor.org/packages/"
+                                  "release/data/annotation/src/contrib/"
+                                  "org.Dm.eg.db_" version ".tar.gz"))
+              (sha256
+               (base32
+                "0mib46c7nr00l7mh290n383za9hyl91a1dc6jhjbk884jmxaxyz6"))))
+    (properties
+     `((upstream-name . "org.Dm.eg.db")))
+    (build-system r-build-system)
+    (propagated-inputs
+     `(("r-annotationdbi" ,r-annotationdbi)))
+    (home-page "http://www.bioconductor.org/packages/org.Dm.eg.db/")
+    (synopsis "Genome wide annotation for Fly")
+    (description
+     "This package provides mappings from Entrez gene identifiers to various
+annotations for the genome of the model fruit fly Drosophila melanogaster.")
+    (license license:artistic2.0)))
+
+(define-public r-org-mm-eg-db
+  (package
+    (name "r-org-mm-eg-db")
+    (version "3.2.3")
+    (source (origin
+              (method url-fetch)
+              ;; We cannot use bioconductor-uri here because this tarball is
+              ;; located under "data/annotation/" instead of "bioc/".
+              (uri (string-append "http://www.bioconductor.org/packages/"
+                                  "release/data/annotation/src/contrib/"
+                                  "org.Mm.eg.db_" version ".tar.gz"))
+              (sha256
+               (base32
+                "0wh1pm3npdg7070875kfgiid3bqkz3q7rq6snhk6bxfvph00298y"))))
+    (properties
+     `((upstream-name . "org.Mm.eg.db")))
+    (build-system r-build-system)
+    (propagated-inputs
+     `(("r-annotationdbi" ,r-annotationdbi)))
+    (home-page "http://www.bioconductor.org/packages/org.Mm.eg.db/")
+    (synopsis "Genome wide annotation for Mouse")
+    (description
+     "This package provides mappings from Entrez gene identifiers to various
+annotations for the genome of the model mouse Mus musculus.")
+    (license license:artistic2.0)))
+
 (define-public r-qtl
  (package
   (name "r-qtl")
diff --git a/gnu/packages/bittorrent.scm b/gnu/packages/bittorrent.scm
index 16673edf68..ae67988d71 100644
--- a/gnu/packages/bittorrent.scm
+++ b/gnu/packages/bittorrent.scm
@@ -202,7 +202,7 @@ interface, for the Transmission BitTorrent daemon.")
 (define-public aria2
   (package
     (name "aria2")
-    (version "1.19.3")
+    (version "1.20.0")
     (source (origin
               (method url-fetch)
               (uri (string-append "https://github.com/tatsuhiro-t/aria2/"
@@ -210,7 +210,7 @@ interface, for the Transmission BitTorrent daemon.")
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
-                "1qwr4al6wlh5f558r0mr1hvdnf7d8ss6qwqn2361k99phk1cdg3a"))))
+                "1l4gzz3yr0cl6a9xdy7843c5sb7afyq0i80wi2hasfpfdx5k95mz"))))
     (build-system gnu-build-system)
     (arguments
      `(#:configure-flags '("--enable-libaria2")
@@ -225,7 +225,7 @@ interface, for the Transmission BitTorrent daemon.")
                (("CPPUNIT_TEST_SUITE_REGISTRATION\\(LpdMessageReceiverTest\\);" text)
                 (string-append "// " text))))))))
     (native-inputs
-     `(("pkg-config", pkg-config)))
+     `(("pkg-config" ,pkg-config)))
     (inputs
      `(("c-ares" ,c-ares)
        ("cppunit" ,cppunit) ; for the tests
diff --git a/gnu/packages/compression.scm b/gnu/packages/compression.scm
index 4a31bf79e2..938d4b8718 100644
--- a/gnu/packages/compression.scm
+++ b/gnu/packages/compression.scm
@@ -244,7 +244,7 @@ decompression.")
                "1vk6065dv3a47p86vmp8hv3n1ygd9hraz0gq89gvzlx7lmcb6fsp"))))
     (build-system gnu-build-system)
     (inputs
-     `(("bzip2", bzip2)))
+     `(("bzip2" ,bzip2)))
     (arguments
      `(#:tests? #f ; no tests
        #:phases (modify-phases %standard-phases
diff --git a/gnu/packages/cpio.scm b/gnu/packages/cpio.scm
index 925b0eed5b..e8eede6524 100644
--- a/gnu/packages/cpio.scm
+++ b/gnu/packages/cpio.scm
@@ -35,7 +35,8 @@
                                  version ".tar.bz2"))
              (sha256
               (base32
-               "0vi9q475h1rki53100zml75vxsykzyhrn70hidy41s5c2rc8r6bh"))))
+               "0vi9q475h1rki53100zml75vxsykzyhrn70hidy41s5c2rc8r6bh"))
+             (patches (list (search-patch "cpio-CVE-2016-2037.patch")))))
     (build-system gnu-build-system)
     (home-page "https://www.gnu.org/software/cpio/")
     (synopsis "Manage cpio and tar file archives")
diff --git a/gnu/packages/curl.scm b/gnu/packages/curl.scm
index 222910b655..46e0fa0f16 100644
--- a/gnu/packages/curl.scm
+++ b/gnu/packages/curl.scm
@@ -54,7 +54,16 @@
    (inputs `(("gnutls" ,gnutls)
              ("gss" ,gss)
              ("libidn" ,libidn)
-             ("libssh2" ,libssh2)
+
+             ;; XXX libssh2-1.4 is a temporary package for use only by curl,
+             ;; to allow most users of libssh2 to get the security update for
+             ;; CVE-2016-7087 while postponing the large number of rebuilds
+             ;; entailed by updating curl.  Soon, curl should be updated to
+             ;; use the latest libssh2 and libssh2-1.4 should be removed.
+
+             ;; XXX libssh2-1.4 is vulnerable to CVE-2016-0787.
+             ("libssh2" ,libssh2-1.4)
+
              ("openldap" ,openldap)
              ("zlib" ,zlib)))
    (native-inputs
diff --git a/gnu/packages/databases.scm b/gnu/packages/databases.scm
index df7101b34f..79254eafb9 100644
--- a/gnu/packages/databases.scm
+++ b/gnu/packages/databases.scm
@@ -8,6 +8,7 @@
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
 ;;; Copyright © 2015 Leo Famulari <leo@famulari.name>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 Nils Gillmann <niasterisk@grrlz.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -273,14 +274,14 @@ as a drop-in replacement of MySQL.")
 (define-public postgresql
   (package
     (name "postgresql")
-    (version "9.3.8")
+    (version "9.3.11")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://ftp.postgresql.org/pub/source/v"
                                   version "/postgresql-" version ".tar.bz2"))
               (sha256
                (base32
-                "1ymd98szvx12gyjdb9gr2hlkrb5bjx7mcshqq3xzdifzapkkqp5w"))))
+                "08ba951nfiy516flaw352shj1zslxg4ryx3w5k0adls1r682l8ix"))))
     (build-system gnu-build-system)
     (inputs
      `(("readline" ,readline)
@@ -320,7 +321,7 @@ pictures, sounds, or video.")
     (native-inputs `(("emacs" ,emacs-no-x)
                      ("bc" ,bc)
                      ("bash:include" ,bash "include")
-                     ("libuuid", util-linux)))
+                     ("libuuid" ,util-linux)))
 
     ;; TODO: Add more optional inputs.
     (inputs `(("curl" ,curl)
@@ -822,3 +823,30 @@ supports many data structures including strings, hashes, lists, sets, sorted
 sets, bitmaps and hyperloglogs.")
     (home-page "http://redis.io/")
     (license bsd-3)))
+
+(define-public kyotocabinet
+  (package
+    (name "kyotocabinet")
+    (version "1.2.76")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://fallabs.com/kyotocabinet/pkg/"
+                                  name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0g6js20x7vnpq4p8ghbw3mh9wpqksya9vwhzdx6dnlf354zjsal1"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags
+       (list
+        (string-append "LDFLAGS=-Wl,-rpath="
+                       (assoc-ref %outputs "out") "/lib"))))
+    (inputs `(("zlib" ,zlib)))
+    (home-page "http://fallabs.com/kyotocabinet/")
+    (synopsis
+     "Kyoto Cabinet is a modern implementation of the DBM database")
+    (description
+     "Kyoto Cabinet is a standalone file-based database that supports Hash
+and B+ Tree data storage models.  It is a fast key-value lightweight
+database and supports many programming languages.  It is a NoSQL database.")
+    (license gpl3+)))
diff --git a/gnu/packages/dav.scm b/gnu/packages/dav.scm
index 25b665f292..4562193114 100644
--- a/gnu/packages/dav.scm
+++ b/gnu/packages/dav.scm
@@ -52,13 +52,13 @@ clients.")
 (define-public vdirsyncer
   (package
     (name "vdirsyncer")
-    (version "0.8.1")
+    (version "0.9.0")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "vdirsyncer" version))
              (sha256
               (base32
-               "1abflqw6x30xd2dlj58cr5n62x98kc0ia9f9vr8l64k2z1fjlq78"))))
+               "0s9awjr9v60rr80xcpwmdhkf4v1yqnydahjmxwvxmh64565is465"))))
     (build-system python-build-system)
     (arguments
       `(#:phases (modify-phases %standard-phases
diff --git a/gnu/packages/dictionaries.scm b/gnu/packages/dictionaries.scm
index 1ecfc3f674..ac020b27c8 100644
--- a/gnu/packages/dictionaries.scm
+++ b/gnu/packages/dictionaries.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -28,14 +29,14 @@
 (define-public vera
   (package
     (name "vera")
-    (version "1.22")
+    (version "1.23")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnu/vera/vera-" version
                                   ".tar.gz"))
               (sha256
                (base32
-                "1anx6ikwlkg7bn3c5a8xxrp33bvhfgxmncvnqbn2fp1hnbhqh5i7"))))
+                "1az0v563jja8xb4896jyr8yv7jd9zacqyfkjd7psb73v7clg1mzz"))))
     (build-system trivial-build-system)
     (arguments
      `(#:builder (begin
diff --git a/gnu/packages/docker.scm b/gnu/packages/docker.scm
index 06b72ee376..0760001da7 100644
--- a/gnu/packages/docker.scm
+++ b/gnu/packages/docker.scm
@@ -90,7 +90,6 @@ client.")
      `(("python-docker-py" ,python-docker-py)
        ("python-dockerpty" ,python-dockerpty)
        ("python-docopt" ,python-docopt)
-       ("python-enum34" ,python-enum34)
        ("python-jsonschema" ,python-jsonschema)
        ("python-pyyaml" ,python-pyyaml)
        ("python-requests" ,python-requests-2.7)
diff --git a/gnu/packages/dvtm.scm b/gnu/packages/dvtm.scm
index 17c720575c..af16aa8f91 100644
--- a/gnu/packages/dvtm.scm
+++ b/gnu/packages/dvtm.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Leo Famulari <leo@famulari.name>
+;;; Copyright © 2015, 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -26,13 +26,14 @@
 (define-public dvtm
   (package
    (name "dvtm")
-   (version "0.14")
+   (version "0.15")
    (source (origin
             (method url-fetch)
             (uri (string-append "http://www.brain-dump.org/projects/dvtm/dvtm-"
                                  version ".tar.gz"))
             (sha256
-             (base32 "0ykl8dz7ivjgdzhmhlgidnp2ffh5gxq9lbg276w7iid4z10v76wa"))))
+             (base32
+              "0475w514b7i3gxk6khy8pfj2gx9l7lv2pwacmq92zn1abv01a84g"))))
    (build-system gnu-build-system)
    (arguments
     `(#:make-flags (list "CC=gcc"
diff --git a/gnu/packages/ebook.scm b/gnu/packages/ebook.scm
index a551c1d075..bf7fe70772 100644
--- a/gnu/packages/ebook.scm
+++ b/gnu/packages/ebook.scm
@@ -60,7 +60,7 @@
 (define-public calibre
   (package
     (name "calibre")
-    (version "2.49.0")
+    (version "2.51.0")
     (source
       (origin
         (method url-fetch)
@@ -69,7 +69,7 @@
                             version ".tar.xz"))
         (sha256
           (base32
-           "0jc476pg07c0nwccprhwgjdlvvb2fdzza9xrjqzc0c42c5v7qzxa"))
+           "1rhpcxic4g2zyr5s3xn8dayyb45l9r8zyniaig8j7pl5kmsfjijn"))
         ;; Remove non-free or doubtful code, see
         ;; https://lists.gnu.org/archive/html/guix-devel/2015-02/msg00478.html
         (modules '((guix build utils)))
diff --git a/gnu/packages/emacs.scm b/gnu/packages/emacs.scm
index fc940eb487..7270fc4932 100644
--- a/gnu/packages/emacs.scm
+++ b/gnu/packages/emacs.scm
@@ -4,7 +4,8 @@
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014, 2015, 2016 Alex Kost <alezost@gmail.com>
 ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
-;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2016 Nils Gillmann <niasterisk@grrlz.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -349,10 +350,35 @@ when typing parentheses directly or commenting out code line by line.")
 configuration files, such as .gitattributes, .gitignore, and .git/config.")
     (license license:gpl3+)))
 
+(define-public emacs-with-editor
+  (package
+    (name "emacs-with-editor")
+    (version "2.5.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/magit/with-editor/archive/v"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "19gb381z61l2icg5v5pymgi1a11g3zdp5aysl2j5fh7fxxg4d4c0"))))
+    (build-system emacs-build-system)
+    (propagated-inputs
+     `(("emacs-dash" ,emacs-dash)))
+    (home-page "https://github.com/magit/with-editor")
+    (synopsis "Emacs library for using Emacsclient as EDITOR")
+    (description
+     "This package provides an Emacs library to use the Emacsclient as
+@code{$EDITOR} of child processes, making sure they know how to call home.
+For remote processes a substitute is provided, which communicates with Emacs
+on stdout instead of using a socket as the Emacsclient does.")
+    (license license:gpl3+)))
+
 (define-public magit
   (package
     (name "magit")
-    (version "2.4.0")
+    (version "2.5.0")
     (source (origin
              (method url-fetch)
              (uri (string-append
@@ -360,12 +386,14 @@ configuration files, such as .gitattributes, .gitignore, and .git/config.")
                    version "/" name "-" version ".tar.gz"))
              (sha256
               (base32
-               "1wbam4l36061mj79qlgzrv4xbzhk2dk6gnv45610zwfnf24ikdsp"))))
+               "0i6qpx5szzc4kyfcdhaic8gif0sqdqcya1niyj93lpvw66jcxsxa"))))
     (build-system gnu-build-system)
     (native-inputs `(("texinfo" ,texinfo)
                      ("emacs" ,emacs-no-x)))
     (inputs `(("git" ,git)))
-    (propagated-inputs `(("dash" ,emacs-dash)))
+    (propagated-inputs
+     `(("dash" ,emacs-dash)
+       ("with-editor" ,emacs-with-editor)))
     (arguments
      `(#:modules ((guix build gnu-build-system)
                   (guix build utils)
@@ -383,7 +411,11 @@ configuration files, such as .gitattributes, .gitignore, and .git/config.")
              (string-append "DASH_DIR="
                             (assoc-ref %build-inputs "dash")
                             "/share/emacs/site-lisp/guix.d/dash-"
-                            ,(package-version emacs-dash)))
+                            ,(package-version emacs-dash))
+             (string-append "WITH_EDITOR_DIR="
+                            (assoc-ref %build-inputs "with-editor")
+                            "/share/emacs/site-lisp/guix.d/with-editor-"
+                            ,(package-version emacs-with-editor)))
 
        #:phases
        (modify-phases %standard-phases
@@ -890,6 +922,27 @@ like.  It can be linked with various Emacs mail clients (Message and Mail
 mode, Rmail, Gnus, MH-E, and VM).  BBDB is fully customizable.")
     (license license:gpl3+)))
 
+(define-public emacs-async
+  (package
+    (name "emacs-async")
+    (version "1.6")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://elpa.gnu.org/packages/async-"
+                                  version ".tar"))
+              (sha256
+               (base32
+                "17psvz75n42x33my967wkgi7r0blx46n3jdv510j0z5jswv66039"))))
+    (build-system emacs-build-system)
+    (home-page "http://elpa.gnu.org/packages/async.html")
+    (synopsis "Asynchronous processing in Emacs")
+    (description
+     "This package provides the ability to call asynchronous functions and
+processes.  For example, it can be used to run dired commands (for copying,
+moving, etc.) asynchronously using @code{dired-async-mode}.  Also it is used
+as a library for other Emacs packages.")
+    (license license:gpl3+)))
+
 (define-public emacs-auctex
   (package
     (name "emacs-auctex")
@@ -1136,15 +1189,17 @@ source code using IPython.")
 (define-public emacs-debbugs
   (package
     (name "emacs-debbugs")
-    (version "0.7")
+    (version "0.9")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://elpa.gnu.org/packages/debbugs-"
                                   version ".tar"))
               (sha256
                (base32
-                "0pbglx3paa8icazgxlg4jf40wl8war63y9j2jmbb7gbd1xp95v72"))))
+                "1wc6kw7hihqqdx8qyl01akygycnan44x400hwrcf54m3hb4isa0k"))))
     (build-system emacs-build-system)
+    (propagated-inputs
+     `(("emacs-async" ,emacs-async)))
     (home-page "http://elpa.gnu.org/packages/debbugs.html")
     (synopsis "Access the Debbugs bug tracker in Emacs")
     (description
@@ -1398,3 +1453,54 @@ supports editing Lisp source files, @{slime-mode} adds support for
 interacting with a running Common Lisp process for compilation,
 debugging, documentation lookup, and so on.")
     (license license:gpl2+)))
+
+(define-public emacs-popup
+  (package
+    (name "emacs-popup")
+    (version "0.5.3")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/auto-complete/popup-el/archive/v"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1yrgfj8y69xmcb6kwgplhq68ndm9410qwh7sd2knnd1gchpphdc0"))))
+    (build-system emacs-build-system)
+    (native-inputs
+     `(("emacs" ,emacs-no-x)))
+    (home-page "https://github.com/auto-complete/popup-el")
+    (synopsis "Visual Popup User Interface for Emacs")
+    (description
+     "Popup.el is a visual popup user interface library for Emacs.
+This provides a basic API and common UI widgets such as popup tooltips
+and popup menus.")
+    (license license:gpl3+)))
+
+(define-public emacs-god-mode
+  (let ((commit "6cf0807b6555eb6fcf8387a4e3b667071ef38964")
+        (revision "1"))
+    (package
+      (name "emacs-god-mode")
+      (version (string-append "20151005.925."
+                              revision "-" (string-take commit 9)))
+      (source
+       (origin
+         (method git-fetch)
+         (uri (git-reference
+               (url "https://github.com/chrisdone/god-mode.git")
+               (commit commit)))
+         (file-name (string-append name "-" version "-checkout"))
+         (sha256
+          (base32
+           "1am415k4xxcva6y3vbvyvknzc6bma49pq3p85zmpjsdmsp18qdix"))))
+      (build-system emacs-build-system)
+      (home-page "https://github.com/chrisdone/god-mode")
+      (synopsis "Minor mode for entering commands without modifier keys")
+      (description
+       "This package provides a global minor mode for entering Emacs commands
+without modifier keys.  It's similar to Vim's separation of commands and
+insertion mode.  When enabled all keys are implicitly prefixed with
+@samp{C-} (among other helpful shortcuts).")
+      (license license:gpl3+))))
diff --git a/gnu/packages/engineering.scm b/gnu/packages/engineering.scm
index ba11f528cb..9a36ffbb31 100644
--- a/gnu/packages/engineering.scm
+++ b/gnu/packages/engineering.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Federico Beffa <beffa@fbengineering.ch>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -55,47 +56,43 @@
 (define-public librecad
   (package
     (name "librecad")
-    (version "2.0.6-rc")
+    (version "2.0.9")
     (source (origin
               (method url-fetch)
               (uri (string-append
                     "https://github.com/LibreCAD/LibreCAD/archive/"
                     version ".tar.gz"))
-              (file-name (string-append name "-" version))
+              (file-name (string-append name "-" version ".tar.gz"))
               (sha256
                (base32
-                "1n1mh8asj6yrl5hi438dvizmrbqk1kni5xkizhi3pdmkg7z3hksm"))))
+                "0xyn4ps9ia94h0vg53rsww8xfd1bgp4200phl8ihyhv7w5v4d8d0"))))
     (build-system gnu-build-system)
     (arguments
      '(#:phases
-       (alist-cons-after
-        'unpack
-        'patch-paths
-        (lambda* (#:key outputs #:allow-other-keys)
-          (let ((out (assoc-ref outputs "out")))
-            (substitute* "librecad/src/lib/engine/rs_system.cpp"
-              (("/usr/share") (string-append out "/share")))))
-        (alist-replace
-         'configure
+       (modify-phases %standard-phases
+        (add-after 'unpack 'patch-paths
+         (lambda* (#:key outputs #:allow-other-keys)
+           (let ((out (assoc-ref outputs "out")))
+             (substitute* "librecad/src/lib/engine/rs_system.cpp"
+               (("/usr/share") (string-append out "/share"))))))
+        (replace 'configure
          (lambda* (#:key inputs #:allow-other-keys)
            (system* "qmake" (string-append "BOOST_DIR="
-                                           (assoc-ref inputs "boost"))))
-         (alist-replace
-          'install
-          (lambda* (#:key outputs #:allow-other-keys)
-            (let ((out (assoc-ref outputs "out")))
-              (mkdir-p (string-append out "/bin"))
-              (mkdir-p (string-append out "/share/librecad"))
-              (copy-file "unix/librecad"
-                         (string-append out "/bin/librecad"))
-              (copy-recursively "unix/resources"
-                                (string-append out "/share/librecad"))))
-          %standard-phases)))))
+                                           (assoc-ref inputs "boost")))))
+        (replace 'install
+         (lambda* (#:key outputs #:allow-other-keys)
+           (let ((out (assoc-ref outputs "out")))
+             (mkdir-p (string-append out "/bin"))
+             (mkdir-p (string-append out "/share/librecad"))
+             (copy-file "unix/librecad"
+                        (string-append out "/bin/librecad"))
+             (copy-recursively "unix/resources"
+                               (string-append out "/share/librecad"))))))))
     (inputs
      `(("boost" ,boost)
        ("muparser" ,muparser)
        ("freetype" ,freetype)
-       ("qt" ,qt-4)))
+       ("qt" ,qt)))
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("which" ,which)))
@@ -206,31 +203,12 @@ and design rule checking.  It also includes an autorouter and a trace
 optimizer; and it can produce photorealistic and design review images.")
     (license license:gpl2+)))
 
-(define* (broken-tarball-fetch url hash-algo hash
-                               #:optional name
-                               #:key (system (%current-system))
-                               (guile (default-guile)))
-  (mlet %store-monad ((drv (url-fetch url hash-algo hash
-                                      (string-append "tarbomb-" name)
-                                      #:system system
-                                      #:guile guile)))
-    ;; Take the tar bomb, and simply unpack it as a directory.
-    (gexp->derivation name
-                      #~(begin
-                          (mkdir #$output)
-                          (setenv "PATH"
-                                  (string-append #$gzip "/bin"))
-                          (chdir #$output)
-                          (zero? (system* (string-append #$tar "/bin/tar")
-                                          "xf" #$drv))))))
-
-
 (define-public fastcap
   (package
     (name "fastcap")
     (version "2.0-18Sep92")
     (source (origin
-              (method broken-tarball-fetch)
+              (method url-fetch/tarbomb)
               (file-name (string-append name "-" version ".tar.gz"))
               (uri (string-append "http://www.rle.mit.edu/cpg/codes/"
                                   name "-" version ".tgz"))
diff --git a/gnu/packages/feh.scm b/gnu/packages/feh.scm
index ee3fcc6b8b..6b998aa983 100644
--- a/gnu/packages/feh.scm
+++ b/gnu/packages/feh.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,7 +30,7 @@
 (define-public feh
   (package
     (name "feh")
-    (version "2.14")
+    (version "2.14.1")
     (home-page "https://feh.finalrewind.org/")
     (source (origin
               (method url-fetch)
@@ -37,7 +38,7 @@
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
-                "0j5wxpqccnd0hl74z2vwv25n7qnik1n2mcm2jn0c0z7cjn4wsa9q"))))
+                "1hlzgr0masgbm1vdn085vz81s9kpnah8kjkb1w1xfsxr1b99x8f0"))))
     (build-system gnu-build-system)
     (arguments
       '(#:phases (alist-delete 'configure %standard-phases)
diff --git a/gnu/packages/finance.scm b/gnu/packages/finance.scm
index 264cfbf7f3..e9487d4207 100644
--- a/gnu/packages/finance.scm
+++ b/gnu/packages/finance.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -35,7 +36,7 @@
 (define-public bitcoin-core
   (package
     (name "bitcoin-core")
-    (version "0.11.0")
+    (version "0.11.2")
     (source (origin
              (method url-fetch)
              (uri
@@ -44,11 +45,11 @@
                              version ".tar.gz"))
              (sha256
               (base32
-               "17yh6lq13xzzi5v2i48qaxiqm40x3hrj4gwyamkib9yzmmb1gfji"))))
+               "1lwh0vhw1gf3h6zrhynvad9y9qbpmhc8cw1zvj11yzsz5rjbvlm4"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
-       ("python" ,python-wrapper) ; for the tests
+       ("python" ,python-2) ; for the tests
        ("util-linux" ,util-linux))) ; provides the hexdump command for tests
     (inputs
      `(("bdb" ,bdb)
diff --git a/gnu/packages/fonts.scm b/gnu/packages/fonts.scm
index cfdcac8f7f..69e195dbf0 100644
--- a/gnu/packages/fonts.scm
+++ b/gnu/packages/fonts.scm
@@ -6,6 +6,7 @@
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
 ;;; Copyright © 2015 Eric Dvorsak <eric@dvorsak.fr>
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2016 Nils Gillmann <niasterisk@grrlz.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -354,7 +355,7 @@ The Liberation Fonts are sponsored by Red Hat.")
 (define-public font-terminus
   (package
     (name "font-terminus")
-    (version "4.39")
+    (version "4.40")
     (source
       (origin
         (method url-fetch)
@@ -365,14 +366,14 @@ The Liberation Fonts are sponsored by Red Hat.")
                version
                ".tar.gz"))
         (sha256
-          (base32
-            "1gzmn7zakvy6yrvmswyjfklnsvqrjm0imhq8rjws8rdkhqwkh21i"))))
+         (base32
+          "0487cyx5h1f0crbny5sg73a22gmym5vk1i7646gy7hgiscj2rxb4"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("perl" ,perl)
        ("bdftopcf" ,bdftopcf)
-       ("font-util", font-util)
+       ("font-util" ,font-util)
        ("mkfontdir" ,mkfontdir)))
     (arguments
      `(#:configure-flags (list
diff --git a/gnu/packages/fontutils.scm b/gnu/packages/fontutils.scm
index f31b905156..b8d931fc82 100644
--- a/gnu/packages/fontutils.scm
+++ b/gnu/packages/fontutils.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
+;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -75,7 +76,7 @@ anti-aliased glyph bitmap generation with 256 gray levels.")
    (source (origin
             (method url-fetch)
             (uri (string-append
-                   "http://www.freedesktop.org/software/fontconfig/release/fontconfig-"
+                   "https://www.freedesktop.org/software/fontconfig/release/fontconfig-"
                    version ".tar.bz2"))
             (sha256 (base32
                      "1psrl4b4gi4wmbvwwh43lk491wsl8lgvqj146prlcha3vwjc0qyp"))))
@@ -203,16 +204,16 @@ applications should be.")
 (define-public graphite2
   (package
    (name "graphite2")
-   (version "1.3.3")
+   (version "1.3.5")
    (source
      (origin
        (method url-fetch)
-       (uri (string-append
-              "mirror://sourceforge/silgraphite/graphite2/graphite2-"
-              version ".tgz"))
+       (uri (string-append "https://github.com/silnrsi/graphite/archive/"
+                           version ".tar.gz"))
+       (file-name (string-append name "-" version ".tar.gz"))
        (sha256
          (base32
-           "1n22vvi4jl83m4sqhvd7v31bhyhyd8j6c3yjgh4zjfyrvid16jrg"))))
+           "0jrjb56zim57xg2pckfdyrw46c624mqz9zywgwza0g1bxg26940w"))))
    (build-system cmake-build-system)
    (native-inputs
     `(("python" ,python-2) ; because of "import imap" in tests
@@ -226,7 +227,7 @@ engine.  Graphite is a smart font technology designed to facilitate the
 process known as shaping.  This process takes an input Unicode text string
 and returns a sequence of positioned glyphids from the font.")
    (license license:lgpl2.1+)
-   (home-page "http://projects.palaso.org/projects/graphitedev")))
+   (home-page "https://github.com/silnrsi/graphite")))
 
 (define-public potrace
   (package
@@ -258,6 +259,28 @@ resolution.")
     (license license:gpl2+)
     (home-page "http://potrace.sourceforge.net/")))
 
+(define-public libotf
+  (package
+    (name "libotf")
+    (version "0.9.13")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "mirror://savannah/releases/m17n/libotf-"
+                    version ".tar.gz"))
+              (sha256
+               (base32 "0239zvfan56w7vrppriwy77fzb10ag9llaz15nsraps2a2x6di3v"))))
+    (build-system gnu-build-system)
+    (propagated-inputs
+     `(("freetype" ,freetype)))
+    (home-page "http://www.nongnu.org/m17n/")
+    (synopsis "Library for handling OpenType Font")
+    (description "This library can read Open Type Layout Tables from an OTF
+file.  Currently these tables are supported; head, name, cmap, GDEF, GSUB, and
+GPOS.  It can convert a Unicode character sequence to a glyph code sequence by
+using the above tables.")
+    (license license:lgpl2.0+)))
+
 (define-public libspiro
   (package
     (name "libspiro")
diff --git a/gnu/packages/freedesktop.scm b/gnu/packages/freedesktop.scm
index e87b4a3b0d..bfe6e4569c 100644
--- a/gnu/packages/freedesktop.scm
+++ b/gnu/packages/freedesktop.scm
@@ -61,12 +61,15 @@
       (origin
         (method url-fetch)
           (uri (string-append
-                 "http://portland.freedesktop.org/download/xdg-utils-"
+                 "https://portland.freedesktop.org/download/xdg-utils-"
                  version ".tgz"))
           (sha256
             (base32
              "1b019d3r1379b60p33d6z44kx589xjgga62ijz9vha95dg8vgbi1"))))
     (build-system gnu-build-system)
+    (propagated-inputs
+     `(("xprop" ,xprop) ; for Xfce detecting
+       ("xset" ,xset))) ; for xdg-screensaver
     (arguments
      `(#:tests? #f)) ; no check target
     (home-page "http://portland.freedesktop.org/")
@@ -79,14 +82,14 @@ freedesktop.org project.")
 (define-public libinput
   (package
     (name "libinput")
-    (version "0.21.0")
+    (version "1.1.902")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://freedesktop.org/software/libinput/"
+              (uri (string-append "https://freedesktop.org/software/libinput/"
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
-                "0l7mhdr50g11hxg2pz8ihsgzbm0810syj05d3555rzhda6g7mkkw"))))
+                "19wa5yizc3nfq3gibyqb3ygdvcs7v7bz1m5ifv0f4va3igxc3nk3"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)))
@@ -94,7 +97,8 @@ freedesktop.org project.")
      `(("libudev" ,eudev))) ; required by libinput.pc
     (inputs
      `(("libevdev" ,libevdev)
-       ("mtdev" ,mtdev)))
+       ("mtdev" ,mtdev)
+       ("libwacom" ,libwacom)))
     (home-page "http://www.freedesktop.org/wiki/Software/libinput/")
     (synopsis "Input devices handling library")
     (description
@@ -174,7 +178,7 @@ the freedesktop.org XDG Base Directory specification.")
        ("xsltproc" ,libxslt)
        ("m4" ,m4)
        ("libxml2" ,libxml2)                     ;for XML_CATALOG_FILES
-       ("pkg-config", pkg-config)
+       ("pkg-config" ,pkg-config)
        ("gperf" ,gperf)))
     (inputs
      `(("linux-pam" ,linux-pam)
@@ -246,7 +250,7 @@ Python.")
     (version "1.9.0")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://wayland.freedesktop.org/releases/"
+              (uri (string-append "https://wayland.freedesktop.org/releases/"
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
@@ -281,7 +285,7 @@ applications, X servers (rootless or fullscreen) or other display servers.")
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://libopenraw.freedesktop.org/download/"
+                   "https://libopenraw.freedesktop.org/download/"
                    name "-" version ".tar.bz2"))
              (sha256
               (base32
@@ -330,7 +334,7 @@ Analysis and Reporting Technology) functionality.")
     (version "2.1.6")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://udisks.freedesktop.org/releases/"
+              (uri (string-append "https://udisks.freedesktop.org/releases/"
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
@@ -500,7 +504,7 @@ which speak the Qualcomm MSM Interface (QMI) protocol.")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "http://www.freedesktop.org/software/ModemManager/"
+                    "https://www.freedesktop.org/software/ModemManager/"
                     "ModemManager-" version ".tar.xz"))
               (sha256
                (base32
@@ -540,14 +544,15 @@ modems and setup connections with them.")
     (version "0.8.2")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://telepathy.freedesktop.org/releases/"
+              (uri (string-append "https://telepathy.freedesktop.org/releases/"
                                   name "/" name "-" version ".tar.bz2"))
               (sha256
                (base32
                 "1bjx85k7jyfi5pvl765fzc7q2iz9va51anrc2djv7caksqsdbjlg"))))
     (build-system gnu-build-system)
     (arguments
-     '(#:phases
+     '(#:parallel-tests? #f
+       #:phases
        (modify-phases %standard-phases
          (add-before 'check 'pre-check
           (lambda _
@@ -579,7 +584,7 @@ different sorts of messages in different formats.")
     (version "0.1.26")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://www.freedesktop.org/software/colord"
+              (uri (string-append "https://www.freedesktop.org/software/colord"
                                   "/releases/" name "-" version ".tar.xz"))
               (sha256
                (base32
diff --git a/gnu/packages/fribidi.scm b/gnu/packages/fribidi.scm
index eb13aa1c6d..735fdab8e8 100644
--- a/gnu/packages/fribidi.scm
+++ b/gnu/packages/fribidi.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Marek Benc <merkur32@gmail.com>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -25,7 +26,7 @@
 (define-public fribidi
   (package
     (name "fribidi")
-    (version "0.19.6")
+    (version "0.19.7")
     (source
       (origin
         (method url-fetch)
@@ -33,7 +34,7 @@
           (string-append "http://fribidi.org/download/" name "-" version
                          ".tar.bz2"))
         (sha256
-          (base32 "0zg1hpaml34ny74fif97j7ngrshlkl3wk3nja3gmlzl17i1bga6b"))))
+          (base32 "13jsb5qadlhsaxkbrb49nqslmbh904vvzhsm5mm2ghmv29i2l8h8"))))
 
     (build-system gnu-build-system)
     (synopsis "Implementation of the Unicode bidirectional algorithm")
diff --git a/gnu/packages/games.scm b/gnu/packages/games.scm
index 7eb0e7a630..991fa24697 100644
--- a/gnu/packages/games.scm
+++ b/gnu/packages/games.scm
@@ -14,6 +14,7 @@
 ;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
 ;;; Copyright © 2015 Paul van der Walt <paul@denknerd.org>
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
+;;; Copyright © 2016 Rodger Fox <thylakoid@openmailbox.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -44,6 +45,7 @@
   #:use-module (gnu packages base)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages audio)
+  #:use-module (gnu packages avahi)
   #:use-module (gnu packages boost)
   #:use-module (gnu packages fribidi)
   #:use-module (gnu packages game-development)
@@ -845,7 +847,7 @@ either by Infocom or created using the Inform compiler.")
 (define-public retroarch
   (package
     (name "retroarch")
-    (version "1.2.2")
+    (version "1.3.1")
     (source
      (origin
        (method url-fetch)
@@ -853,7 +855,7 @@ either by Infocom or created using the Inform compiler.")
                            version ".tar.gz"))
        (file-name (string-append name "-" version ".tar.gz"))
        (sha256
-        (base32 "1bxr8yhk3ad4df544qljsfjfhxa8zy1grq7rn1s02yfvdmgzf4qi"))))
+        (base32 "1wydzvligyby05x8c4lpg6xcnw9qkmvkskyhzc28xq10vm3q57fv"))))
     (build-system gnu-build-system)
     (arguments
      '(#:tests? #f ; no tests
@@ -995,7 +997,7 @@ This game is based on the GPL version of the famous game TuxRacer.")
           (lambda _ (setenv "LIBS" "-lm"))))))
     (inputs
      `(("glu" ,glu)
-       ("mesa", mesa)
+       ("mesa" ,mesa)
        ("sdl" ,sdl)
        ("sdl-image" ,sdl-image)
        ("sdl-mixer" ,sdl-mixer)))
@@ -1891,3 +1893,27 @@ and a game metadata scraper.")
     (description "The Emilia Pinball Project is a pinball simulator.  There
 are only two levels to play with, but they are very addictive.")
     (license license:gpl2)))
+
+(define-public pioneers
+  (package
+    (name "pioneers")
+    (version "15.3")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://downloads.sourceforge.net/pio/"
+                                  "pioneers-" version ".tar.gz"))
+              (sha256
+               (base32
+                "128s718nnraiznbg2rajjqb7cfkdg24hy6spdd9narb4f4dsbbv9"))))
+    (build-system gnu-build-system)
+    (inputs `(("gtk+" ,gtk+)
+              ("librsvg" ,librsvg)
+              ("avahi" ,avahi)))
+    (native-inputs `(("intltool" ,intltool)
+                     ("pkg-config" ,pkg-config)))
+    (synopsis "Board game inspired by The Settlers of Catan")
+    (description "Pioneers is an emulation of the board game The Settlers of
+Catan.  It can be played on a local network, on the internet, and with AI
+players.")
+    (home-page "http://pio.sourceforge.net/")
+    (license license:gpl2+)))
diff --git a/gnu/packages/gcc.scm b/gnu/packages/gcc.scm
index 832e57bc77..e15b07752b 100644
--- a/gnu/packages/gcc.scm
+++ b/gnu/packages/gcc.scm
@@ -470,8 +470,8 @@ as the 'native-search-paths' field."
   (custom-gcc gcc-5 "gfortran" '("fortran")
               %generic-search-paths))
 
-(define-public gccgo-4.8
-  (custom-gcc gcc-4.8 "gccgo" '("go")
+(define-public gccgo-4.9
+  (custom-gcc gcc-4.9 "gccgo" '("go")
               %generic-search-paths
               ;; Suppress the separate "lib" output, because otherwise the
               ;; "lib" and "out" outputs would refer to each other, creating
diff --git a/gnu/packages/gdb.scm b/gnu/packages/gdb.scm
index 81d6a8950d..9065732c78 100644
--- a/gnu/packages/gdb.scm
+++ b/gnu/packages/gdb.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -37,14 +37,14 @@
 (define-public gdb
   (package
     (name "gdb")
-    (version "7.10.1")
+    (version "7.11")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnu/gdb/gdb-"
                                  version ".tar.xz"))
              (sha256
               (base32
-               "1mfnjcwnwm5cg4rc9pncs9v356a0bz6ymjyac56mbj6784yjzir5"))))
+               "1hg5kwwdvi9b9nxzxfjnx8fx3gip75fqyvkp82xpf3b3rcb42hvs"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f ; FIXME "make check" fails on single-processor systems.
diff --git a/gnu/packages/ghostscript.scm b/gnu/packages/ghostscript.scm
index 818072ac5e..d2eb066817 100644
--- a/gnu/packages/ghostscript.scm
+++ b/gnu/packages/ghostscript.scm
@@ -282,7 +282,7 @@ Ghostscript.  It currently includes the 35 standard PostScript fonts.")
    (version "0.2.7")
    (source (origin
             (method url-fetch)
-            (uri (string-append "http://libspectre.freedesktop.org/releases/libspectre-"
+            (uri (string-append "https://libspectre.freedesktop.org/releases/libspectre-"
                                 version ".tar.gz"))
             (sha256 (base32
                      "1v63lqc6bhhxwkpa43qmz8phqs8ci4dhzizyy16d3vkb20m846z8"))))
diff --git a/gnu/packages/gl.scm b/gnu/packages/gl.scm
index 33312ba127..907e3bf30a 100644
--- a/gnu/packages/gl.scm
+++ b/gnu/packages/gl.scm
@@ -192,7 +192,7 @@ also known as DXTn or DXTC) for Mesa.")
 (define-public mesa
   (package
     (name "mesa")
-    (version "11.0.3")
+    (version "11.0.9")
     (source
       (origin
         (method url-fetch)
@@ -200,7 +200,7 @@ also known as DXTn or DXTC) for Mesa.")
                             version "/mesa-" version ".tar.xz"))
         (sha256
          (base32
-          "1mikw0biw0wxq0fn3cp18bm6kjrkd66fy84774yc5b91rvp94adb"))))
+          "009b3nq8ly5nzy9cxi9cxf4qasrhggjz0v0q87rwq5kaqvqjy9m1"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("glproto" ,glproto)
diff --git a/gnu/packages/glib.scm b/gnu/packages/glib.scm
index f8e1541f56..b925704aa0 100644
--- a/gnu/packages/glib.scm
+++ b/gnu/packages/glib.scm
@@ -384,7 +384,7 @@ translated.")
     (source (origin
              (method url-fetch)
              (uri
-              (string-append "http://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-"
+              (string-append "https://dbus.freedesktop.org/releases/dbus-glib/dbus-glib-"
                              version ".tar.gz"))
              (sha256
               (base32
@@ -574,7 +574,7 @@ useful for C++.")
       (method url-fetch)
        (uri
         (string-append
-         "http://telepathy.freedesktop.org/releases/telepathy-glib/"
+         "https://telepathy.freedesktop.org/releases/telepathy-glib/"
          "telepathy-glib-" version ".tar.gz"))
        (sha256
         (base32
diff --git a/gnu/packages/gnome.scm b/gnu/packages/gnome.scm
index 49e61973a0..0960b534f1 100644
--- a/gnu/packages/gnome.scm
+++ b/gnu/packages/gnome.scm
@@ -13,6 +13,7 @@
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Rene Saavedra <rennes@openmailbox.org>
+;;; Copyright © 2016 Jochem Raat <jchmrt@riseup.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -36,6 +37,7 @@
   #:use-module (guix utils)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system glib-or-gtk)
+  #:use-module (guix build-system trivial)
   #:use-module (gnu packages)
   #:use-module (gnu packages admin)
   #:use-module (gnu packages autotools)
@@ -500,7 +502,7 @@ for settings shared by various components of the GNOME desktop.")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "http://tango.freedesktop.org/releases/icon-naming-utils-"
+      (uri (string-append "https://tango.freedesktop.org/releases/icon-naming-utils-"
                           version ".tar.bz2"))
       (sha256
        (base32
@@ -536,7 +538,7 @@ GNOME and KDE desktops to the icon names proposed in the specification.")
     (version "0.22")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://www.freedesktop.org/software/" name
+              (uri (string-append "https://www.freedesktop.org/software/" name
                                   "/releases/" name "-" version ".tar.xz"))
               (sha256
                (base32
@@ -608,7 +610,7 @@ update-desktop-database: updates the database containing a cache of MIME types
     (version "1.2")
     (source (origin
              (method url-fetch)
-             (uri (string-append "http://freedesktop.org/~hadess/"
+             (uri (string-append "https://freedesktop.org/~hadess/"
                                  "shared-mime-info-" version ".tar.xz"))
              (sha256
               (base32
@@ -640,7 +642,7 @@ database is translated at Transifex.")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "http://icon-theme.freedesktop.org/releases/"
+      (uri (string-append "https://icon-theme.freedesktop.org/releases/"
                           "hicolor-icon-theme-" version ".tar.gz"))
       (sha256
        (base32
@@ -939,7 +941,7 @@ library.")
     (inputs `(("glib" ,glib)))
     (native-inputs
      `(("pkg-config" ,pkg-config)
-       ("flex", flex)
+       ("flex" ,flex)
        ("bison" ,bison)))
     (home-page "http://freecode.com/projects/libidl")
     (synopsis "Create trees of CORBA Interface Definition Language files")
@@ -1583,7 +1585,7 @@ Hints specification (EWMH).")
        ("libxml2" ,libxml2)
        ("libxslt" ,libxslt)
        ("python" ,python-2)
-       ("python2-pygobject", python2-pygobject-2)
+       ("python2-pygobject" ,python2-pygobject-2)
        ("zlib" ,zlib)))
     (native-inputs
      `(("intltool" ,intltool)
@@ -2259,7 +2261,7 @@ keyboard shortcuts.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://www.freedesktop.org/software/colord/releases/"
+       (uri (string-append "https://www.freedesktop.org/software/colord/releases/"
                            name "-" version ".tar.xz"))
        (sha256
         (base32
@@ -2323,7 +2325,7 @@ output devices.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://www.freedesktop.org/software/" name
+       (uri (string-append "https://www.freedesktop.org/software/" name
                            "/releases/" (version-major+minor version) "/"
                            name "-" version ".tar.xz"))
        (sha256
@@ -2403,7 +2405,7 @@ faster results and to avoid unnecessary server load.")
     (version "0.99.3")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://upower.freedesktop.org/releases/"
+              (uri (string-append "https://upower.freedesktop.org/releases/"
                                   name "-" version ".tar.xz"))
               (sha256
                (base32
@@ -3228,7 +3230,7 @@ supports playlists, song ratings, and any codecs installed through gstreamer.")
     `(("dconf" ,dconf)))
    (native-inputs
     `(("intltool" ,intltool)
-      ("itstool", itstool)
+      ("itstool" ,itstool)
       ("glib" ,glib "bin")
       ("gobject-introspection" ,gobject-introspection)
       ("pkg-config" ,pkg-config)
@@ -3879,7 +3881,7 @@ javascript engine and the GObject introspection framework.")
      `(("dconf" ,dconf)))
     (native-inputs
      `(("intltool" ,intltool)
-       ("itstool", itstool)
+       ("itstool" ,itstool)
        ("gobject-introspection" ,gobject-introspection)
        ("pkg-config" ,pkg-config)))
     (inputs
@@ -4648,3 +4650,164 @@ as SASL, TLS and VeNCrypt.  Additionally it supports encoding extensions.")
 design and behaviour, giving the user a simple way to navigate and manage its
 files.")
     (license license:gpl2+)))
+
+(define-public baobab
+  (package
+    (name "baobab")
+    (version "3.18.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "mirror://gnome/sources/" name "/"
+                    (version-major+minor version) "/"
+                    name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "1da4bdkw5bnxansl1xr4lb03d6f4h0a0qaba8i3p3rwhcd191b62"))))
+    (build-system glib-or-gtk-build-system)
+    (native-inputs
+     `(("intltool" ,intltool)
+       ("pkg-config" ,pkg-config)
+       ("itstool" ,itstool)
+       ("xmllint" ,libxml2)
+       ("glib" ,glib "bin")
+       ("vala" ,vala)))
+    (inputs
+     `(("gtk+" ,gtk+)))
+    (synopsis "Disk usage analyzer for GNOME")
+    (description
+     "Baobab (Disk Usage Analyzer) is a graphical application to analyse disk
+usage in the GNOME desktop environment.  It can easily scan device volumes or
+a specific user-requested directory branch (local or remote).  Once the scan
+is complete it provides a graphical representation of each selected folder.")
+    (home-page "https://wiki.gnome.org/Apps/Baobab")
+    (license license:gpl2+)))
+
+(define-public gnome-backgrounds
+  (package
+    (name "gnome-backgrounds")
+    (version "3.18.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://gnome/sources/" name "/"
+                           (version-major+minor version) "/"
+                           name "-" version ".tar.xz"))
+       (sha256
+        (base32
+         "1fd7y8dh3iy88ayb8irgsihvssli6bzjzb5a6vfhi8qjbw70ymma"))))
+    (build-system glib-or-gtk-build-system)
+    (native-inputs
+     `(("intltool" ,intltool)))
+    (home-page "https://git.gnome.org/browse/gnome-backgrounds")
+    (synopsis "Background images for the GNOME desktop")
+    (description
+     "GNOME backgrounds package contains a collection of graphics files which
+can be used as backgrounds in the GNOME Desktop environment.  Additionally,
+the package creates the proper framework and directory structure so that you
+can add your own files to the collection.")
+    (license (list license:gpl2+
+                   license:cc-by2.0
+                   license:cc-by-sa2.0
+                   license:cc-by-sa3.0))))
+
+(define-public gnome-screenshot
+  (package
+    (name "gnome-screenshot")
+    (version "3.18.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://gnome/sources/" name "/"
+                           (version-major+minor version) "/"
+                           name "-" version ".tar.xz"))
+       (sha256
+        (base32
+         "0hc8m435q7yzvrw7jpi53kaxpmrd9w59sm7c5wibh2ng9azlv9pb"))))
+    (build-system glib-or-gtk-build-system)
+    (native-inputs
+     `(("glib:bin" ,glib "bin") ; for glib-compile-schemas, etc.
+       ("intltool" ,intltool)
+       ("pkg-config" ,pkg-config)))
+    (inputs
+     `(("gtk+" ,gtk+)
+       ("libcanberra" ,libcanberra)
+       ("libx11" ,libx11)
+       ("libxext" ,libxext)))
+    (home-page "https://git.gnome.org/browse/gnome-screenshot")
+    (synopsis "Take pictures of your screen")
+    (description
+     "GNOME Screenshot is a utility used for taking screenshots of the entire
+screen, a window or a user defined area of the screen, with optional
+beautifying border effects.")
+    (license license:gpl2+)))
+
+(define-public dconf-editor
+  (package
+    (name "dconf-editor")
+    (version "3.18.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append "mirror://gnome/sources/" name "/"
+                           (version-major+minor version) "/"
+                           name "-" version ".tar.xz"))
+       (sha256
+        (base32
+         "0xdwi7g1xdmgrc9m8ii62fp2zj114gsfpmgazlnhrcmmfi97z5d7"))))
+    (build-system glib-or-gtk-build-system)
+    (native-inputs
+     `(("glib:bin" ,glib "bin") ; for glib-compile-schemas, gio-2.0.
+       ("intltool" ,intltool)
+       ("pkg-config" ,pkg-config)))
+    (inputs
+     `(("dconf" ,dconf)
+       ("gtk+" ,gtk+)
+       ("libxml2" ,libxml2)))
+    (home-page "https://git.gnome.org/browse/dconf-editor")
+    (synopsis "Graphical editor for GNOME's dconf configuration system")
+    (description
+     "Dconf-editor is a graphical tool for browsing and editing the dconf
+configuration system for GNOME.  It allows users to configure desktop
+software that do not provide their own configuration interface.")
+    (license license:lgpl2.1+)))
+
+(define-public gnome
+  (package
+    (name "gnome")
+    (version (package-version gnome-shell))
+    (source #f)
+    (build-system trivial-build-system)
+    (arguments '(#:builder (mkdir %output)))
+    (propagated-inputs
+     ;; TODO: Add more packages according to:
+     ;;       <https://packages.debian.org/jessie/gnome-core>.
+     `(("adwaita-icon-theme"        ,adwaita-icon-theme)
+       ("at-spi2-core"              ,at-spi2-core)
+       ("dbus"                      ,dbus)
+       ("dconf"                     ,dconf)
+       ("eog"                       ,eog)
+       ("epiphany"                  ,epiphany)
+       ("evince"                    ,evince)
+       ("gedit"                     ,gedit)
+       ("glib-networking"           ,glib-networking)
+       ("gnome-control-center"      ,gnome-control-center)
+       ("gnome-keyring"             ,gnome-keyring)
+       ("gnome-session"             ,gnome-session)
+       ("gnome-settings-daemon"     ,gnome-settings-daemon)
+       ("gnome-shell"               ,gnome-shell)
+       ("gnome-terminal"            ,gnome-terminal)
+       ("gnome-themes-standard"     ,gnome-themes-standard)
+       ("hicolor-icon-theme"        ,hicolor-icon-theme)
+       ("nautilus"                  ,nautilus)
+       ("pulseaudio"                ,pulseaudio)
+       ("shared-mime-info"          ,shared-mime-info)
+       ("totem"                     ,totem)
+       ("yelp"                      ,yelp)
+       ("zenity"                    ,zenity)))
+    (synopsis "Desktop environment (meta-package)")
+    (home-page "https://www.gnome.org/")
+    (description
+     "GNOME is an intutive and attractive desktop environment.  It aims to be
+an easy and elegant way to use your computer.")
+    (license license:gpl2+)))
diff --git a/gnu/packages/gnunet.scm b/gnu/packages/gnunet.scm
index 11e5aa8733..eb0c4cbe83 100644
--- a/gnu/packages/gnunet.scm
+++ b/gnu/packages/gnunet.scm
@@ -3,6 +3,8 @@
 ;;; Copyright © 2014 Sree Harsha Totakura <sreeharsha@totakura.in>
 ;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 Ni* Gillmann <ng@niasterisk.space>
+;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -22,14 +24,17 @@
 (define-module (gnu packages gnunet)
   #:use-module (gnu packages)
   #:use-module (gnu packages file)
+  #:use-module (gnu packages aidc)
   #:use-module (gnu packages autotools)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages curl)
   #:use-module (gnu packages geeqie)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages glib)
+  #:use-module (gnu packages gnome)
   #:use-module (gnu packages gnupg)
   #:use-module (gnu packages groff)
+  #:use-module (gnu packages gtk)
   #:use-module (gnu packages guile)
   #:use-module (gnu packages gstreamer)
   #:use-module (gnu packages libidn)
@@ -208,6 +213,8 @@ supports HTTPS, HTTPS and GnuTLS.")
    (inputs
     `(("glpk" ,glpk)
       ("gnurl" ,gnurl)
+      ("gstreamer" ,gstreamer)
+      ("gst-plugins-base" ,gst-plugins-base)
       ("gnutls" ,gnutls)
       ("libextractor" ,libextractor)
       ("libgcrypt" ,libgcrypt)
@@ -217,14 +224,16 @@ supports HTTPS, HTTPS and GnuTLS.")
       ("libunistring" ,libunistring)
       ("openssl" ,openssl)
       ("opus" ,opus)
-      ("pulseaudio", pulseaudio)
+      ("pulseaudio" ,pulseaudio)
       ("sqlite" ,sqlite)
       ("zlib" ,zlib)))
    (native-inputs
     `(("pkg-config" ,pkg-config)
       ("python" ,python-2)))
    (arguments
-    '(#:parallel-tests? #f
+    '(#:configure-flags
+      (list (string-append "--with-nssdir=" %output "/lib"))
+      #:parallel-tests? #f
       ;; test_gnunet_service_arm fails; reported upstream
       #:tests? #f
       #:phases
@@ -286,3 +295,33 @@ GNUnet services, including the @dfn{identity} and @dfn{file sharing}
 services.")
       (home-page "http://gnu.org/software/guix")
       (license license:gpl3+))))
+
+;; FIXME: "gnunet-setup" segfaults under certain conditions and "gnunet-gtk"
+;; does not seem to be fully functional.  This has been reported upstream:
+;; http://lists.gnu.org/archive/html/gnunet-developers/2016-02/msg00004.html
+(define-public gnunet-gtk
+  (package (inherit gnunet)
+    (name "gnunet-gtk")
+    (version (package-version gnunet))
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://gnu/gnunet/gnunet-gtk-"
+                                  version ".tar.gz"))
+              (sha256
+               (base32
+                "1p38k1s6a2fmcfc9a7cf1zrdycm9h06kqdyand4s3k500nj6mb4g"))))
+    (arguments
+     `(#:configure-flags
+       (list "--without-libunique"
+             "--with-qrencode")))
+    (inputs
+     `(("gnunet" ,gnunet)
+       ("libgcrypt" ,libgcrypt)
+       ("gtk+" ,gtk+)
+       ("libextractor" ,libextractor)
+       ("glade3" ,glade3)
+       ("qrencode" ,qrencode)))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("libglade" ,libglade)))
+    (synopsis "Graphical front-end tools for GNUnet")))
diff --git a/gnu/packages/gnupg.scm b/gnu/packages/gnupg.scm
index a35e8fc401..350865addb 100644
--- a/gnu/packages/gnupg.scm
+++ b/gnu/packages/gnupg.scm
@@ -2,7 +2,7 @@
 ;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2013, 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
-;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2014, 2015, 2016 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 Paul van der Walt <paul@denknerd.org>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
@@ -70,14 +70,14 @@ Daemon and possibly more in the future.")
 (define-public libgcrypt
   (package
     (name "libgcrypt")
-    (version "1.6.4")
+    (version "1.6.5")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://gnupg/libgcrypt/libgcrypt-"
                                  version ".tar.bz2"))
              (sha256
               (base32
-               "09k06gs27gxfha07sa9rpf4xh6mvphj9sky7n09ymx75w9zjrg69"))))
+               "0959mwfzsxhallxdqlw359xg180ll2skxwyy35qawmfl89cbr7pl"))))
     (build-system gnu-build-system)
     (propagated-inputs
      `(("libgpg-error-host" ,libgpg-error)))
@@ -206,7 +206,10 @@ compatible to GNU Pth.")
                                   ".tar.bz2"))
               (sha256
                (base32
-                "06mn2viiwsyq991arh5i5fhr9jyxq2bi0jkdj7ndfisxihngpc5p"))))
+                "06mn2viiwsyq991arh5i5fhr9jyxq2bi0jkdj7ndfisxihngpc5p"))
+              (patches
+               (list (search-patch
+                      "gnupg-simple-query-ignore-status-messages.patch")))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)))
diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm
index 2ddad9afe2..dca461f5d4 100644
--- a/gnu/packages/gnuzilla.scm
+++ b/gnu/packages/gnuzilla.scm
@@ -72,7 +72,7 @@
                  (("defined\\(@TEMPLATE_FILE)") "@TEMPLATE_FILE")))))
     (build-system gnu-build-system)
     (native-inputs
-      `(("perl", perl)
+      `(("perl" ,perl)
         ("python" ,python-2)))
     (arguments
       `(#:phases
@@ -154,7 +154,7 @@ in C/C++.")
                "01ria9wk6329hxqsy75p9dkxiqkq4nkz0jjzll7hslih3jbi8dil"))))
     (build-system gnu-build-system)
     (native-inputs
-      `(("perl", perl)))
+      `(("perl" ,perl)))
     (arguments
      `(#:tests? #f ; no check target
        #:configure-flags (list "--enable-64bit"
@@ -289,7 +289,8 @@ standards.")
         "0bd4k5cwr8ynscaxffvj2x3kgky3dmjq0qhpcb931l98bh0103lx"))
       (patches (map search-patch
                     '("icecat-avoid-bundled-includes.patch"
-                      "icecat-re-enable-DHE-cipher-suites.patch")))
+                      "icecat-re-enable-DHE-cipher-suites.patch"
+                      "icecat-update-graphite2.patch")))
       (modules '((guix build utils)))
       (snippet
        '(begin
@@ -318,6 +319,8 @@ standards.")
                       ;; TODO: Use system harfbuzz.  Waiting for:
                       ;; <https://bugzilla.mozilla.org/show_bug.cgi?id=847568>
                       ;;
+                      ;; TODO: Use system graphite2.
+                      ;;
                       "modules/freetype2"
                       "modules/zlib"
                       "modules/libbz2"
diff --git a/gnu/packages/gps.scm b/gnu/packages/gps.scm
index bede89e373..fd045b1f1a 100644
--- a/gnu/packages/gps.scm
+++ b/gnu/packages/gps.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -34,7 +35,7 @@
 (define-public gpsbabel
   (package
     (name "gpsbabel")
-    (version "1.5.0")
+    (version "1.5.2")
     (source (origin
               (method url-fetch)
               ;; XXX: Downloads from gpsbabel.org are hidden behind a POST, so
@@ -44,16 +45,16 @@
                     version ".orig.tar.gz"))
               (sha256
                (base32
-                "1pd01kra9l5ihy1by87qia0mpbpcif7g5yg7r9z2bnw7711jm3yb"))))
+                "0xf7wmy2m29g2lm8lqc74yf8rf7sxfl3cfwbk7dpf0yf42pb0b6w"))))
     (build-system gnu-build-system)
     (arguments
      `(#:configure-flags '("--with-zlib=system")
-       #:phases (alist-cons-before
-                 'configure 'pre-configure
-                 (lambda _
-                   (chdir "gpsbabel"))
-                 ;; TODO: "make doc" requires Docbook & co.
-                 %standard-phases)
+       #:phases
+       (modify-phases %standard-phases
+        (add-before 'configure 'pre-configure
+                    (lambda _
+                      (chdir "gpsbabel"))))
+                    ;; TODO: "make doc" requires Docbook & co.
 
        ;; On i686, 'raymarine.test' fails because of a rounding error:
        ;; <http://hydra.gnu.org/build/133040>.  As a workaround, disable tests
@@ -62,7 +63,7 @@
     (inputs
      `(("expat" ,expat)
        ("zlib" ,zlib)
-       ("qt4" ,qt-4)))
+       ("qt" ,qt)))
     (native-inputs
      `(("which" ,which)
        ("libxml2" ,libxml2)))              ;'xmllint' needed for the KML tests
diff --git a/gnu/packages/gstreamer.scm b/gnu/packages/gstreamer.scm
index 1235b3185a..45dded1a6e 100644
--- a/gnu/packages/gstreamer.scm
+++ b/gnu/packages/gstreamer.scm
@@ -28,21 +28,33 @@
   #:use-module (gnu packages audio)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages cdrom)
+  #:use-module (gnu packages curl)
   #:use-module (gnu packages compression)
   #:use-module (gnu packages flex)
+  #:use-module (gnu packages freedesktop)
+  #:use-module (gnu packages gl)
   #:use-module (gnu packages glib)
   #:use-module (gnu packages gnome)
+  #:use-module (gnu packages gnupg)
+  #:use-module (gnu packages graphics)
   #:use-module (gnu packages gtk)
   #:use-module (gnu packages image)
+  #:use-module (gnu packages libusb)
   #:use-module (gnu packages linux)
   #:use-module (gnu packages mp3)
   #:use-module (gnu packages perl)
   #:use-module (gnu packages pulseaudio)
+  #:use-module (gnu packages qt)
+  #:use-module (gnu packages rdf)
   #:use-module (gnu packages video)
   #:use-module (gnu packages xorg)
   #:use-module (gnu packages xiph)
   #:use-module (gnu packages pkg-config)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages ssh)
+  #:use-module (gnu packages telephony)
+  #:use-module (gnu packages tls)
+  #:use-module (gnu packages version-control)
   #:use-module (gnu packages yasm)
   #:use-module (gnu packages xml))
 
@@ -52,7 +64,7 @@
     (version "0.4.24")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://gstreamer.freedesktop.org/data/src/"
+              (uri (string-append "https://gstreamer.freedesktop.org/data/src/"
                                   "orc/orc-" version ".tar.xz"))
               (sha256
                (base32
@@ -83,16 +95,16 @@ arrays of data.")
 (define-public gstreamer
   (package
     (name "gstreamer")
-    (version "1.6.1")
+    (version "1.6.3")
     (source
      (origin
       (method url-fetch)
       (uri (string-append
-            "http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-"
+            "https://gstreamer.freedesktop.org/src/gstreamer/gstreamer-"
             version ".tar.xz"))
       (sha256
        (base32
-        "172w1bpnkn6mm1wi37n03apdbb6cdkykhzjf1vfxchcd7hhkyflp"))))
+        "093zldafh7xh3lrlwzm7j0vvjz6k9ca83wqil40gfz5qcy6mdy92"))))
     (build-system gnu-build-system)
     (outputs '("out" "doc"))
     (arguments
@@ -113,7 +125,7 @@ arrays of data.")
      (list (search-path-specification
             (variable "GST_PLUGIN_SYSTEM_PATH")
             (files '("lib/gstreamer-1.0")))))
-    (home-page "http://gstreamer.freedesktop.org/")
+    (home-page "https://gstreamer.freedesktop.org/")
     (synopsis "Multimedia library")
     (description
      "GStreamer is a library for constructing graphs of media-handling
@@ -131,15 +143,15 @@ This package provides the core library and elements.")
 (define-public gst-plugins-base
   (package
     (name "gst-plugins-base")
-    (version "1.6.1")
+    (version "1.6.3")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "http://gstreamer.freedesktop.org/src/" name "/"
+      (uri (string-append "https://gstreamer.freedesktop.org/src/" name "/"
                           name "-" version ".tar.xz"))
       (sha256
        (base32
-        "18sbyjcp281zb3bsqji3pglsdsxi0s6ai7rx90sx8cpflkxdqcwm"))))
+        "0xbskifk95rw7jd85sqjrmqh2kys1bpi0inrxyapx1x4vf7ly5dn"))))
     (build-system gnu-build-system)
     (outputs '("out" "doc"))
     (propagated-inputs
@@ -168,12 +180,11 @@ This package provides the core library and elements.")
                             (assoc-ref %outputs "doc")
                             "/share/gtk-doc/html"))
        #:phases
-       (alist-cons-before
-        'configure 'patch
-        (lambda _
-          (substitute* "tests/check/libs/pbutils.c"
-            (("/bin/sh") (which "sh"))))
-        %standard-phases)))
+       (modify-phases %standard-phases
+         (add-before 'configure 'patch
+           (lambda _
+             (substitute* "tests/check/libs/pbutils.c"
+               (("/bin/sh") (which "sh"))))))))
     (home-page "http://gstreamer.freedesktop.org/")
     (synopsis
      "Plugins for the GStreamer multimedia library")
@@ -185,16 +196,16 @@ for the GStreamer multimedia library.")
 (define-public gst-plugins-good
   (package
     (name "gst-plugins-good")
-    (version "1.6.1")
+    (version "1.6.3")
     (source
      (origin
       (method url-fetch)
       (uri (string-append
-            "http://gstreamer.freedesktop.org/src/gst-plugins-good/gst-plugins-good-"
-            version ".tar.xz"))
+            "https://gstreamer.freedesktop.org/src/" name "/"
+            name "-" version ".tar.xz"))
       (sha256
        (base32
-        "0darc3058kbnql3mnlpizl0sq0hhli7vkm0rpqb7nywz14abim46"))))
+        "0xx16h0q63gs3pxlzdflnpyssba3vcrh1qnzplg4d0ra1fvrvc94"))))
     (build-system gnu-build-system)
     (inputs
      `(("aalib" ,aalib)
@@ -228,7 +239,7 @@ for the GStreamer multimedia library.")
           'unpack 'disable-failing-rtprtx-tests
           (lambda _
             ;; Disable rtprtx tests that frequently fail.
-            ;; XXX FIXME: Try removing this for version > 1.6.1.
+            ;; XXX FIXME: Try removing this for version > 1.6.3.
             (substitute* "tests/check/elements/rtprtx.c"
               (("tcase_add_test \\(tc_chain,\
  (test_rtxsender_max_size_packets|test_rtxreceive_data_reconstruction)\\);" all)
@@ -242,18 +253,91 @@ GStreamer multimedia library.  This set contains those plug-ins which the
 developers consider to have good quality code and correct functionality.")
     (license lgpl2.0+)))
 
+(define-public gst-plugins-bad
+  (package
+    (name "gst-plugins-bad")
+    (version "1.6.3")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://gstreamer.freedesktop.org/src/"
+                                  name "/" name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "0q9s5da54819gwncmdi95l5qzx97l9vxk6adx4zmx73a3l82j6wp"))))
+    (outputs '("out" "doc"))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:tests? #f ; XXX: 11 of 54 tests fail
+       #:configure-flags
+       (list (string-append "--with-html-dir="
+                            (assoc-ref %outputs "doc")
+                            "/share/gtk-doc/html"))))
+    (propagated-inputs
+     `(("gst-plugins-base" ,gst-plugins-base)))
+    (native-inputs
+     `(("glib:bin" ,glib "bin") ; for glib-mkenums, etc.
+       ("gobject-introspection" ,gobject-introspection)
+       ("pkg-config" ,pkg-config)
+       ("python" ,python)))
+    (inputs
+     ;; XXX: The following dependencies are missing:
+     ;;  vo-amrwbenc, vo-aacenc, bs2b, chromaprint, directfb, daala, libdts,
+     ;;  faac, flite, libgsm, libde265, libmms, libmimic, mjpegtools,
+     ;;  mpeg2enc, libofa, opencv, openh264, openni2, libtimemmgr, wildmidi,
+     ;;  openspc, gme, sbc, schroedinger, zbar, librtmp, spandsp, x265
+     `(("bluez" ,bluez)
+       ("curl" ,curl)
+       ("faad2" ,faad2)
+       ("fluidsynth" ,fluidsynth)
+       ("gtk+" ,gtk+)
+       ("ladspa" ,ladspa)
+       ("libass" ,libass)
+       ("libdvdnav" ,libdvdnav)
+       ("libdvdread" ,libdvdread)
+       ("libgcrypt" ,libgcrypt)
+       ("libgudev" ,libgudev)
+       ("libkate" ,libkate)
+       ("libmodplug" ,libmodplug)
+       ("librsvg" ,librsvg)
+       ("libsndfile" ,libsndfile)
+       ("libsrtp" ,libsrtp)
+       ("libssh2" ,libssh2)
+       ("libusb" ,libusb)
+       ("libvdpau" ,libvdpau)
+       ("libwebp" ,libwebp)
+       ("libxml2" ,libxml2)
+       ("lrdf" ,lrdf)
+       ("mesa" ,mesa)
+       ("mpg123" ,mpg123)
+       ("neon" ,neon)
+       ("openal" ,openal)
+       ("openexr" ,openexr)
+       ("openjpeg" ,openjpeg)
+       ("openssl" ,openssl)
+       ("opus" ,opus)
+       ("orc" ,orc)
+       ("qt" ,qt)
+       ("soundtouch" ,soundtouch)
+       ("wayland" ,wayland)))
+    (home-page "http://gstreamer.freedesktop.org/")
+    (synopsis "Plugins for the GStreamer multimedia library")
+    (description
+     "GStreamer Bad Plug-ins is a set of plug-ins whose quality aren't up to
+par compared to the rest.")
+    (license lgpl2.0+)))
+
 (define-public gst-plugins-ugly
   (package
     (name "gst-plugins-ugly")
-    (version "1.6.1")
+    (version "1.6.3")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://gstreamer.freedesktop.org/src/"
+       (uri (string-append "https://gstreamer.freedesktop.org/src/"
                            name "/" name "-" version ".tar.xz"))
        (sha256
         (base32
-         "0mvasl1pwq70w2kmrkcrg77kggl5q7jqybi7fkvy3vr28c7gkhqc"))))
+         "0r6h3ys5n90jv3c06crxzcac561z07s4h04hy5i8ybw8qyvzgv1g"))))
     (build-system gnu-build-system)
     (inputs
      `(("gst-plugins-base" ,gst-plugins-base)
@@ -283,15 +367,15 @@ distribution problems in some jurisdictions, e.g. due to patent threats.")
 (define-public gst-libav
   (package
     (name "gst-libav")
-    (version "1.6.1")
+    (version "1.6.3")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "http://gstreamer.freedesktop.org/src/" name "/"
+                    "https://gstreamer.freedesktop.org/src/" name "/"
                     name "-" version ".tar.xz"))
               (sha256
                (base32
-                "1a9pc7zp5rg0cvpx8gqkr21w73i6p9xa505a34day9f8p3lfim94"))))
+                "1aylbg1xnm68c3wc49mzx813qhsjfg23hqnjqqwdwdq31839qyw5"))))
     (build-system gnu-build-system)
     (arguments
      '(#:configure-flags '("--with-system-libav")
diff --git a/gnu/packages/gtk.scm b/gnu/packages/gtk.scm
index 6e2a67d25c..1a10e9b551 100644
--- a/gnu/packages/gtk.scm
+++ b/gnu/packages/gtk.scm
@@ -150,7 +150,7 @@ affine transformation (scale, rotation, shear, etc.).")
    (version "1.0.6")
    (source (origin
              (method url-fetch)
-             (uri (string-append "http://www.freedesktop.org/software/"
+             (uri (string-append "https://www.freedesktop.org/software/"
                                  "harfbuzz/release/harfbuzz-"
                                  version ".tar.bz2"))
              (sha256
@@ -365,7 +365,7 @@ printing and other features typical of a source code editor.")
    (native-inputs
     `(("glib:bin" ,glib "bin") ; for glib-genmarshal, etc.
       ("intltool" ,intltool)
-      ("itstool", itstool)
+      ("itstool" ,itstool)
       ("gobject-introspection" ,gobject-introspection)
       ("pkg-config" ,pkg-config)
       ("vala" ,vala)
@@ -425,7 +425,7 @@ highlighting and other features typical of a source code editor.")
    (native-inputs
      `(("pkg-config" ,pkg-config)
        ("glib" ,glib "bin")                               ; glib-mkenums, etc.
-       ("gobject-introspection", gobject-introspection))) ; g-ir-compiler, etc.
+       ("gobject-introspection" ,gobject-introspection))) ; g-ir-compiler, etc.
    (synopsis "GNOME image loading and manipulation library")
    (description
     "GdkPixbuf is a library for image loading and manipulation developed
@@ -1013,6 +1013,7 @@ extensive documentation, including API reference and a tutorial.")
      `(("pkg-config" ,pkg-config)))
     (inputs
      `(("python" ,python-2)
+       ("libglade" ,libglade)
        ("glib"   ,glib)))
     (propagated-inputs
      `(("python-pycairo"   ,python2-pycairo)     ;loaded at runtime
@@ -1107,7 +1108,25 @@ information.")
                 "12xmmcnq4138dlbhmqa45wqza8dky4lf856sp80h6xjwl2g7a85l"))))
     (build-system gnu-build-system)
     (arguments
-     `(#:configure-flags
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-before
+             'configure 'fix-docbook
+           (lambda* (#:key inputs #:allow-other-keys)
+             (substitute* "configure"
+               ;; The configure check is overzealous about making sure that
+               ;; things are in place -- it uses the xmlcatalog tool to make
+               ;; sure that docbook-xsl is available, but this tool can only
+               ;; look in one catalog file, unlike the $XML_CATALOG_FILES
+               ;; variable that Guix defines.  Fool the test by using the
+               ;; docbook-xsl catalog explicitly and get on with life.
+               (("\"\\$XML_CATALOG_FILE\" \
+\"http://docbook.sourceforge.net/release/xsl/")
+                (string-append (car (find-files (assoc-ref inputs "docbook-xsl")
+                                                "^catalog.xml$"))
+                               " \"http://docbook.sourceforge.net/release/xsl/")))
+             #t)))
+       #:configure-flags
        (list (string-append "--with-xml-catalog="
                             (assoc-ref %build-inputs "docbook-xml")
                             "/xml/dtd/docbook/catalog.xml"))))
diff --git a/gnu/packages/guile.scm b/gnu/packages/guile.scm
index 6cbca7a478..5349fda081 100644
--- a/gnu/packages/guile.scm
+++ b/gnu/packages/guile.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016 Alex Sassmannshausen <alex@pompo.co>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -210,7 +211,15 @@ without requiring the source code to be rewritten.")
               ;; times (almost 3 hours on a 4-core Intel i5).
               (snippet '(for-each delete-file
                                   (find-files "prebuilt" "\\.go$")))))
-    (synopsis "Snapshot of what will become version 2.2 of GNU Guile")))
+    (synopsis "Snapshot of what will become version 2.2 of GNU Guile")
+    (native-search-paths
+     (list (search-path-specification
+            (variable "GUILE_LOAD_PATH")
+            (files '("share/guile/site/2.2")))
+           (search-path-specification
+            (variable "GUILE_LOAD_COMPILED_PATH")
+            (files '("lib/guile/2.2/ccache"
+                     "share/guile/site/2.2")))))))
 
 (define-public guile-for-guile-emacs
   (package (inherit guile-next)
@@ -440,14 +449,14 @@ for Guile\".")
 (define-public guile-json
   (package
     (name "guile-json")
-    (version "0.4.0")
+    (version "0.5.0")
     (source (origin
              (method url-fetch)
              (uri (string-append "mirror://savannah/guile-json/guile-json-"
                                  version ".tar.gz"))
              (sha256
               (base32
-               "0v06272rw4ycwzssjf3fzpk2vhpslvl55hz94q80vc6f74j0d5h6"))
+               "0l8a34l92nrdszy7ykycfvr8y0n0yi5qb3ccliycvpvf9mzk5n8d"))
              (modules '((guix build utils)))
              (snippet
               ;; Make sure everything goes under .../site/2.0, like Guile's
@@ -700,6 +709,28 @@ Guile's foreign function interface.")
                (base32
                 "15q1qwjnay7k90ppqrzqsmikvwyj61mjvf1zahyd9gm4vi2fgb3x"))))
     (build-system gnu-build-system)
+    (arguments
+     `(#:modules ((ice-9 match) (ice-9 ftw)
+                  ,@%gnu-build-system-modules)
+
+       #:phases (modify-phases %standard-phases
+                  (add-after 'install 'wrap-haunt
+                    (lambda* (#:key outputs #:allow-other-keys)
+                      ;; Wrap the 'haunt' command to refer to the right
+                      ;; modules.
+                      (let* ((out  (assoc-ref outputs "out"))
+                             (bin  (string-append out "/bin"))
+                             (site (string-append
+                                    out "/share/guile/site")))
+                        (match (scandir site)
+                          (("." ".." version)
+                           (let ((modules (string-append site "/" version)))
+                             (wrap-program (string-append bin "/haunt")
+                               `("GUILE_LOAD_PATH" ":" prefix
+                                 (,modules))
+                               `("GUILE_LOAD_COMPILED_PATH" ":" prefix
+                                 (,modules)))
+                             #t)))))))))
     (inputs
      `(("guile" ,guile-2.0)))
     (synopsis "Functional static site generator")
@@ -709,6 +740,33 @@ interface for reading articles in any format.")
     (home-page "http://haunt.dthompson.us")
     (license gpl3+)))
 
+(define-public guile-config
+  (package
+    (name "guile-config")
+    (version "0.1.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "http://alex.pompo.co/software/" name "-" version
+                    ".tar.gz"))
+              (sha256
+               (base32
+                "1b719bn192f9wg24rr0zx8jpmygsvyhfi35iy778pb5p392snrn8"))))
+    (build-system gnu-build-system)
+    (inputs
+     `(("guile" ,guile-2.0)))
+    (synopsis "Guile application configuration parsing library")
+    (description
+     "Guile Config is a library providing a declarative approach to
+application configuration specification.  The library provides clean
+configuration declaration forms, and processors that take care of:
+configuration file creation; configuration file parsing; command-line
+parameter parsing using getopt-long; basic GNU command-line parameter
+generation (--help, --usage, --version); automatic output generation for the
+above command-line parameters.")
+    (home-page "https://github.com/a-sassmannshausen/guile-config")
+    (license agpl3+)))
+
 (define-public guile-redis
   (package
     (name "guile-redis")
diff --git a/gnu/packages/icu4c.scm b/gnu/packages/icu4c.scm
index d442b5e69a..a6f5acd4f2 100644
--- a/gnu/packages/icu4c.scm
+++ b/gnu/packages/icu4c.scm
@@ -31,11 +31,12 @@
    (version "55.1")
    (source (origin
             (method url-fetch)
-            (uri (string-append "http://download.icu-project.org/files/icu4c/"
-                   version
-                   "/icu4c-"
-                   (string-map (lambda (x) (if (char=? x #\.) #\_ x)) version)
-                   "-src.tgz"))
+            (uri (string-append
+                  "mirror://sourceforge/icu/ICU4C/"
+                  version
+                  "/icu4c-"
+                  (string-map (lambda (x) (if (char=? x #\.) #\_ x)) version)
+                  "-src.tgz"))
             (sha256
              (base32 "0ys5f5spizg45qlaa31j2lhgry0jka2gfha527n4ndfxxz5j4sz1"))
             (patches (map search-patch '("icu4c-CVE-2014-6585.patch"
diff --git a/gnu/packages/kde-frameworks.scm b/gnu/packages/kde-frameworks.scm
index 5e73a6b7fa..ec637e55d1 100644
--- a/gnu/packages/kde-frameworks.scm
+++ b/gnu/packages/kde-frameworks.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -26,7 +27,7 @@
   #:use-module (gnu packages qt)
   #:use-module (gnu packages xorg))
 
-(define kde-frameworks-version "5.12.0")
+(define kde-frameworks-version "5.19.0")
 
 (define-public extra-cmake-modules
   (package
@@ -39,7 +40,8 @@
                             (version-major+minor version) "/"
                             name "-" version ".tar.xz"))
         (sha256
-          (base32 "14n77sn493m8kzr42wv13mdgxpnbx7x64bvw37ircrx8wmf4002i"))))
+         (base32
+          "1dl3hhbara7iswb5wsc5dp17ar3ljw5f0nrncl8vry9smaz2zl63"))))
     ;; The package looks for Qt5LinguistTools provided by Qt, but apparently
     ;; compiles without it; it might be needed for building the
     ;; documentation, which requires the additional Sphinx package.
@@ -63,18 +65,19 @@ common build settings used in software produced by the KDE community.")
                             (version-major+minor version) "/"
                             name "-" version ".tar.xz"))
         (sha256
-          (base32 "0fjxhf07r186cmp0mjvinrwxg4z90zlyvycqhy0n18fdp67szckl"))))
+         (base32
+          "115xs34r74j9zcsw69glnh8w59iyh764n3gniawwrk23c6yb8fch"))))
     (build-system cmake-build-system)
     (native-inputs
-      `(("pkg-config" ,pkg-config)
-        ("xorg-server" ,xorg-server))) ; for the tests
+     `(("pkg-config" ,pkg-config)
+       ("xorg-server" ,xorg-server))) ; for the tests
     (inputs
-      `(("extra-cmake-modules" ,extra-cmake-modules)
-        ("libxrender" ,libxrender)
-        ("qt" ,qt)
-        ("xcb-utils-keysyms" ,xcb-util-keysyms)))
+     `(("extra-cmake-modules" ,extra-cmake-modules)
+       ("libxrender" ,libxrender)
+       ("qt" ,qt)
+       ("xcb-utils-keysyms" ,xcb-util-keysyms)))
     (arguments
-      `(#:tests? #f)) ; FIXME: The first seven tests fail with "Exception".
+     `(#:tests? #f)) ; FIXME: The first seven tests fail with "Exception".
     (home-page "https://community.kde.org/Frameworks")
     (synopsis "KDE access to the windowing system")
     (description "KWindowSystem provides information about and allows
diff --git a/gnu/packages/kde.scm b/gnu/packages/kde.scm
deleted file mode 100644
index 1409e7c0b1..0000000000
--- a/gnu/packages/kde.scm
+++ /dev/null
@@ -1,229 +0,0 @@
-;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013, 2014, 2015 Andreas Enge <andreas@enge.fr>
-;;;
-;;; 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 kde)
-  #:use-module ((guix licenses) #:select (bsd-2 lgpl2.0+ lgpl2.1 lgpl2.1+ lgpl3+))
-  #:use-module (guix packages)
-  #:use-module (guix download)
-  #:use-module (guix build-system cmake)
-  #:use-module (gnu packages compression)
-  #:use-module (gnu packages doxygen)
-  #:use-module (gnu packages geeqie)
-  #:use-module (gnu packages glib)
-  #:use-module (gnu packages perl)
-  #:use-module (gnu packages pkg-config)
-  #:use-module (gnu packages pulseaudio)
-  #:use-module (gnu packages python)
-  #:use-module (gnu packages qt)
-  #:use-module (gnu packages rdf)
-  #:use-module (gnu packages ruby)
-  #:use-module (gnu packages video)
-  #:use-module (gnu packages xml)
-  #:use-module (gnu packages xorg))
-
-(define-public automoc4
-  (package
-    (name "automoc4")
-    (version "0.9.88")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "http://download.kde.org/stable/" name
-                                "/" version "/" name "-"
-                                 version ".tar.bz2"))
-             (sha256
-              (base32
-               "0jackvg0bdjg797qlbbyf9syylm0qjs55mllhn11vqjsq3s1ch93"))))
-    (build-system cmake-build-system)
-    (inputs
-     `(("qt" ,qt-4)))
-    (arguments
-     `(#:tests? #f)) ; no check target
-    (home-page "http://techbase.kde.org/Development/Tools/Automoc4")
-    (synopsis "Build tool for KDE")
-    (description "AutoMoc4 automatically generates moc-files for KDE.")
-    (license bsd-2)))
-
-(define-public phonon
-  (package
-    (name "phonon")
-    (version "4.8.3")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "http://download.kde.org/stable/" name
-                                "/" version "/src/"
-                                name "-" version ".tar.xz"))
-             (sha256
-              (base32
-               "05nshngk03ln90vsjz44dx8al576f4vd5fvhs1l0jmx13jb9q551"))))
-    (build-system cmake-build-system)
-    ;; FIXME: Add optional input libqzeitgeist once available.
-    (native-inputs
-     `(("automoc4" ,automoc4)
-       ("pkg-config" ,pkg-config)))
-    (inputs
-     `(("glib" ,glib)
-       ("libx11" ,libx11)
-       ("pulseaudio" ,pulseaudio)))
-    (propagated-inputs
-     `(("qt" ,qt-4))) ; according to phonon.pc
-    (arguments
-     `(#:tests? #f)) ; no test target
-    (home-page "http://phonon.kde.org/")
-    (synopsis "Qt 4 multimedia API")
-    (description "KDE desktop environment")
-    (license lgpl2.1+)))
-
-(define-public qjson
-  (package
-    (name "qjson")
-    (version "0.8.1")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "https://github.com/flavio/qjson/archive/"
-                                 version ".tar.gz"))
-             (file-name (string-append name "-" version ".tar.gz"))
-             (sha256
-              (base32
-               "163fspi0xc705irv79qw861fmh68pjyla9vx3kqiq6xrdhb9834j"))))
-    (build-system cmake-build-system)
-    (inputs
-     `(("qt" ,qt-4)))
-    (arguments
-     `(#:tests? #f)) ; no test target
-    (home-page "http://qjson.sourceforge.net/")
-    (synopsis "Qt-based library for handling JSON")
-    (description "QJson is a Qt-based library that maps JSON data to QVariant
-objects and vice versa.  JSON arrays are mapped to QVariantList instances,
-while JSON objects are mapped to QVariantMap.")
-    (license lgpl2.1+)))
-
-(define-public libdbusmenu-qt
-  (package
-    (name "libdbusmenu-qt")
-    (version "0.9.2")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "https://launchpad.net/" name "/trunk/"
-                                 version "/+download/"
-                                 name "-" version ".tar.bz2"))
-             (sha256
-              (base32
-               "1v0ri5g9xw2z64ik0kx0ra01v8rpjn2kxprrxppkls1wvav1qv5f"))))
-    (build-system cmake-build-system)
-    (native-inputs
-     `(("doxygen" ,doxygen) ; used for static documentation
-       ("pkg-config" ,pkg-config)
-       ("qjson", qjson))) ; used for the tests
-    (inputs
-     `(("qt" ,qt-4)))
-    (arguments
-     `(#:tests? #f)) ; no check target
-    (home-page "https://launchpad.net/libdbusmenu-qt/")
-    (synopsis "Qt implementation of the DBusMenu protocol")
-    (description "The library provides a Qt implementation of the DBusMenu
-protocol.  The DBusMenu protocol makes it possible for applications to export
-and import their menus over DBus.")
-    (license lgpl2.0+)))
-
-(define-public attica
-  (package
-    (name "attica")
-    (version "0.4.2")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "http://download.kde.org/stable/"
-                                 name "/"
-                                 name "-" version ".tar.bz2"))
-             (sha256
-              (base32
-               "1y74gsyzi70dfr9d1f1b08k130rm3jaibsppg8dv5h3211vm771v"))))
-    (build-system cmake-build-system)
-    (inputs
-     `(("qt" ,qt-4)))
-    (home-page "https://projects.kde.org/projects/frameworks/attica")
-    (synopsis "Qt library for the Open Collaboration Services API")
-    (description "Attica is a Qt library that implements the Open
-Collaboration Services API version 1.6.  It grants easy access to the
-services such as querying information about persons and contents.  The
-library is used in KNewStuff3 as content provider.  In order to integrate
-with KDE's Plasma Desktop, a platform plugin exists in kdebase.")
-    (license lgpl2.1+)))
-
-(define-public strigi
-  (package
-    (name "strigi")
-    (version "0.7.8")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "http://www.vandenoever.info/software/"
-                                 name "/"
-                                 name "-" version ".tar.bz2"))
-             (sha256
-              (base32
-               "12grxzqwnvbyqw7q1gnz42lypadxmq89vk2qpxczmpmc4nk63r23"))))
-    (build-system cmake-build-system)
-    (native-inputs
-     `(("pkg-config" ,pkg-config)))
-    ;; FIXME: Add optional inputs XAttr, FAM, Log4cxx
-    (inputs
-     `(("clucene" ,clucene)
-       ("dbus" ,dbus)
-       ("exiv2" ,exiv2)
-       ("ffmpeg" ,ffmpeg)
-       ("libxml2" ,libxml2)
-       ("perl" ,perl)
-       ("python" ,python-wrapper)
-       ("qt" ,qt-4)
-       ("zlib" ,zlib)))
-    (arguments
-     `(#:tests? #f)) ; FIXME: Test 23/25 ProcessInputStreamTest fails.
-    (home-page "http://www.vandenoever.info/software/strigi/")
-    (synopsis "Desktop search daemon")
-    (description "Strigi is a desktop search daemon with the following
-main features:
-very fast crawling;
-very small memory footprint;
-no hammering of the system;
-pluggable backend, currently clucene and hyperestraier, sqlite3 and xapian
-are in the works;
-communication between daemon and search program over an abstract interface,
-currently a simple socket;
-simple interface for implementing plugins for extracting information;
-calculation of sha1 for every file crawled
-(allows fast finding of duplicates).")
-    (license lgpl2.0+)))
-
-(define-public oxygen-icons
-  (package
-    (name "oxygen-icons")
-    (version "4.14.2")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "http://download.kde.org/stable/" version
-                                "/src/" name "-"
-                                 version ".tar.xz"))
-             (sha256
-              (base32
-               "1mz73f54qh2vd8ibp60f6fjflrprz0lvqfkgh805l7wfhrv4ckbz"))))
-    (build-system cmake-build-system)
-    (arguments
-     `(#:tests? #f)) ; no test target
-    (home-page "http://www.kde.org/")
-    (synopsis "Oxygen icon theme for the KDE desktop")
-    (description "KDE desktop environment")
-    (license lgpl3+)))
diff --git a/gnu/packages/ldc.scm b/gnu/packages/ldc.scm
index 1981bc115d..66da63581c 100644
--- a/gnu/packages/ldc.scm
+++ b/gnu/packages/ldc.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Roel Janssen <roel@gnu.org>
+;;; Copyright © 2015, 2016 Roel Janssen <roel@gnu.org>
 ;;; Copyright © 2015 Pjotr Prins <pjotr.guix@thebird.nl>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -21,6 +21,8 @@
   #: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 (gnu packages)
   #:use-module (gnu packages base)
@@ -29,6 +31,47 @@
   #:use-module (gnu packages textutils)
   #:use-module (gnu packages zip))
 
+(define-public rdmd
+  (let ((commit "da0a2e0a379b08294015eec9d531f1e5dd4226f0"))
+    (package
+      (name "rdmd")
+      (version (string-append "v2.070.0-1." (string-take commit 7)))
+      (source (origin
+        (method git-fetch)
+        (uri (git-reference
+              (url "https://github.com/D-Programming-Language/tools.git")
+              (commit commit)))
+        (file-name (string-append name "-" version "-checkout"))
+        (sha256
+         (base32
+          "1pcx5lyqzrip86f4vv60x292rpvnwsq2hvl1znm9x9rn68f34m45"))))
+      (build-system gnu-build-system)
+      (arguments
+       '(#:phases
+         (modify-phases %standard-phases
+           (delete 'configure)
+           (delete 'check) ; There is no Makefile, so there's no 'make check'.
+           (replace
+            'build
+            (lambda _
+              (zero? (system* "ldc2" "rdmd.d"))))
+           (replace
+            'install
+            (lambda* (#:key outputs #:allow-other-keys)
+              (let ((bin (string-append (assoc-ref outputs "out") "/bin")))
+                (install-file "rdmd" bin)))))))
+      (native-inputs
+       `(("ldc" ,ldc)))
+      (home-page "https://github.com/D-Programming-Language/tools/")
+      (synopsis "Specialized equivalent to 'make' for the D language")
+      (description
+       "rdmd is a companion to the dmd compiler that simplifies the typical
+edit-compile-link-run or edit-make-run cycle to a rapid edit-run cycle.  Like
+make and other tools, rdmd uses the relative dates of the files involved to
+minimize the amount of work necessary.  Unlike make, rdmd tracks dependencies
+and freshness without requiring additional information from the user.")
+      (license license:boost1.0))))
+
 (define-public ldc
   (package
     (name "ldc")
diff --git a/gnu/packages/libcanberra.scm b/gnu/packages/libcanberra.scm
index 50c0f80eed..bfa7715160 100644
--- a/gnu/packages/libcanberra.scm
+++ b/gnu/packages/libcanberra.scm
@@ -110,7 +110,7 @@ null) and is designed to be portable.")
     (version "0.8")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://people.freedesktop.org/~mccann/dist/"
+              (uri (string-append "https://people.freedesktop.org/~mccann/dist/"
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
diff --git a/gnu/packages/linux.scm b/gnu/packages/linux.scm
index 9bfdc66f46..414570eccd 100644
--- a/gnu/packages/linux.scm
+++ b/gnu/packages/linux.scm
@@ -7,6 +7,8 @@
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016 Tobias Geerinckx-Rice <tobias.geerinckx.rice@gmail.com>
+;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -218,7 +220,7 @@ for SYSTEM and optionally VARIANT, or #f if there is no such configuration."
     (search-path %load-path file)))
 
 (define-public linux-libre
-  (let* ((version "4.4.1")
+  (let* ((version "4.4.3")
          (build-phase
           '(lambda* (#:key system inputs #:allow-other-keys #:rest args)
              ;; Apply the neat patch.
@@ -292,7 +294,7 @@ for SYSTEM and optionally VARIANT, or #f if there is no such configuration."
              (uri (linux-libre-urls version))
              (sha256
               (base32
-               "1d6wzhbpz0g79iwlkv10qmig518risz9bi3qw8wdn7j2xs7ij1j2"))))
+               "06wl6gvhds6j6aaryzpz4jngdf3v70spvp1xb7k2c03kvm9v5f4v"))))
     (build-system gnu-build-system)
     (supported-systems '("x86_64-linux" "i686-linux"))
     (native-inputs `(("perl" ,perl)
@@ -327,13 +329,13 @@ It has been modified to remove all non-free binary blobs.")
 (define-public linux-libre-4.1
   (package
     (inherit linux-libre)
-    (version "4.1.17")
+    (version "4.1.18")
     (source (origin
               (method url-fetch)
               (uri (linux-libre-urls version))
               (sha256
                (base32
-                "0mkvj5sab8l2k0mgfca3y4n5g9cxs3px0ysvdwa2zwl52n7dsfk4"))))
+                "1bddh2rg645lavhjkk9z75vflba5y0g73z2fjwgbfrj5jb44x9i7"))))
     (native-inputs
      (let ((conf (kernel-config (or (%current-target-system)
                                     (%current-system))
@@ -794,14 +796,14 @@ MIDI functionality to the Linux-based operating system.")
 (define-public alsa-utils
   (package
     (name "alsa-utils")
-    (version "1.0.27.2")
+    (version "1.1.0")
     (source (origin
              (method url-fetch)
-             (uri (string-append "ftp://ftp.alsa-project.org/pub/utils/alsa-utils-"
-                                 version ".tar.bz2"))
+             (uri (string-append "ftp://ftp.alsa-project.org/pub/utils/"
+                                 name "-" version ".tar.bz2"))
              (sha256
               (base32
-               "1sjjngnq50jv5ilwsb4zys6smifni3bd6fn28gbnhfrg14wsrgq2"))))
+               "1wa88wvqcfhak9x3y65wzzwxmmyxb5bv2gyj7lnm653fnwsk271v"))))
     (build-system gnu-build-system)
     (arguments
      ;; XXX: Disable man page creation until we have DocBook.
@@ -867,15 +869,15 @@ packet filter.")
 (define-public iproute
   (package
     (name "iproute2")
-    (version "3.12.0")
+    (version "4.4.0")
     (source (origin
-             (method url-fetch)
-             (uri (string-append
-                   "mirror://kernel.org/linux/utils/net/iproute2/iproute2-"
-                   version ".tar.xz"))
-             (sha256
-              (base32
-               "04gi11gh087bg2nlxhj0lxrk8l9qxkpr88nsiil23917bm3h1xj4"))))
+              (method url-fetch)
+              (uri (string-append
+                    "mirror://kernel.org/linux/utils/net/iproute2/iproute2-"
+                    version ".tar.xz"))
+              (sha256
+               (base32
+                "05351m4m0whsivlblvs3m0nz5q9v6r06ik80z27gf6ca51kw74dw"))))
     (build-system gnu-build-system)
     (arguments
      `(#:tests? #f                                ; no test suite
@@ -887,13 +889,12 @@ packet filter.")
                             (string-append "DOCDIR=" out "/share/doc/"
                                            ,name "-" ,version)
                             (string-append "MANDIR=" out "/share/man")))
-       #:phases (alist-cons-before
-                 'install 'pre-install
-                 (lambda _
-                   ;; Don't attempt to create /var/lib/arpd.
-                   (substitute* "Makefile"
-                     (("^.*ARPDDIR.*$") "")))
-                 %standard-phases)))
+       #:phases (modify-phases %standard-phases
+                  (add-before 'install 'pre-install
+                    (lambda _
+                      ;; Don't attempt to create /var/lib/arpd.
+                      (substitute* "Makefile"
+                        (("^.*ARPDDIR.*$") "")))))))
     (inputs
      `(("iptables" ,iptables)
        ("db4" ,bdb)))
@@ -2467,3 +2468,40 @@ write access to exFAT devices.")
 applications running on the Linux console.  It allows users to select items
 and copy/paste text in the console and in xterm.")
     (license license:gpl2+)))
+
+(define-public btrfs-progs
+  (package
+    (name "btrfs-progs")
+    (version "4.4")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://kernel.org/linux/kernel/"
+                                  "people/kdave/btrfs-progs/"
+                                  "btrfs-progs-v" version ".tar.xz"))
+              (sha256
+               (base32
+                "0jssv1ys4nw2jf7mkp58c19yspaa8ybf48fxsrhhp0683mzpr73p"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:test-target "test"
+       #:parallel-tests? #f)) ; tests fail when run in parallel
+    (inputs `(("e2fsprogs" ,e2fsprogs)
+              ("libblkid" ,util-linux)
+              ("libuuid" ,util-linux)
+              ("zlib" ,zlib)
+              ("lzo" ,lzo)))
+    (native-inputs `(("pkg-config" ,pkg-config)
+                     ("asciidoc" ,asciidoc)
+                     ("xmlto" ,xmlto)
+                     ;; For building documentation
+                     ("libxml2" ,libxml2)
+                     ("docbook-xml" ,docbook-xml)
+                     ("docbook-xsl" ,docbook-xsl)))
+    (home-page "https://btrfs.wiki.kernel.org/")
+    (synopsis "Create and manage btrfs copy-on-write file systems")
+    (description "Btrfs is a copy-on-write (CoW) filesystem for Linux aimed at
+implementing advanced features while focusing on fault tolerance, repair and
+easy administration.")
+    ;; GPL2+: crc32.c, radix-tree.c, raid6.c, rbtree.c.
+    ;; GPL2: Everything else.
+    (license (list license:gpl2 license:gpl2+))))
diff --git a/gnu/packages/lsh.scm b/gnu/packages/lsh.scm
index e034d66940..3b6487f38c 100644
--- a/gnu/packages/lsh.scm
+++ b/gnu/packages/lsh.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2012, 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,7 +29,8 @@
   #:use-module (gnu packages multiprecision)
   #:use-module (gnu packages readline)
   #:use-module (gnu packages gperf)
-  #:use-module (gnu packages guile))
+  #:use-module (gnu packages guile)
+  #:use-module (gnu packages xorg))
 
 (define-public liboop
   (package
@@ -100,7 +101,11 @@ basis for almost any application.")
 
        ("liboop" ,liboop)
        ("zlib" ,guix:zlib)
-       ("gmp" ,gmp)))
+       ("gmp" ,gmp)
+
+       ;; The server (lshd) invokes xauth when X11 forwarding is requested.
+       ;; This adds 24 MiB (or 27%) to the closure of lsh.
+       ("xauth" ,xauth)))
     (arguments
      '(;; Skip the `configure' test that checks whether /dev/ptmx &
        ;; co. work as expected, because it relies on impurities (for
@@ -113,26 +118,36 @@ basis for almost any application.")
        #:tests? #f
 
        #:phases
-       (alist-cons-before
-        'configure 'pre-configure
-        (lambda* (#:key inputs #:allow-other-keys)
-          (let* ((nettle    (assoc-ref inputs "nettle"))
-                 (sexp-conv (string-append nettle "/bin/sexp-conv")))
-            ;; Make sure 'lsh' and 'lshd' pick 'sexp-conv' in the right place
-            ;; by default.
-            (substitute* "src/environ.h.in"
-              (("^#define PATH_SEXP_CONV.*")
-               (string-append "#define PATH_SEXP_CONV \""
-                              sexp-conv "\"\n")))
+       (modify-phases %standard-phases
+         (add-before 'configure 'pre-configure
+           (lambda* (#:key inputs #:allow-other-keys)
+             (let* ((nettle    (assoc-ref inputs "nettle"))
+                    (sexp-conv (string-append nettle "/bin/sexp-conv")))
+               ;; Make sure 'lsh' and 'lshd' pick 'sexp-conv' in the right place
+               ;; by default.
+               (substitute* "src/environ.h.in"
+                 (("^#define PATH_SEXP_CONV.*")
+                  (string-append "#define PATH_SEXP_CONV \""
+                                 sexp-conv "\"\n")))
+
+               ;; Same for the 'lsh-authorize' script.
+               (substitute* "src/lsh-authorize"
+                 (("=sexp-conv")
+                  (string-append "=" sexp-conv)))
 
-            ;; Same for the 'lsh-authorize' script.
-            (substitute* "src/lsh-authorize"
-              (("=sexp-conv")
-               (string-append "=" sexp-conv))))
+               ;; Tell lshd where 'xauth' lives.  Another option would be to
+               ;; hardcode "/run/current-system/profile/bin/xauth", thereby
+               ;; reducing the closure size, but that wouldn't work on foreign
+               ;; distros.
+               (with-fluids ((%default-port-encoding "ISO-8859-1"))
+                 (substitute* "src/server_x11.c"
+                   (("define XAUTH_PROGRAM.*")
+                    (string-append "define XAUTH_PROGRAM \""
+                                   (assoc-ref inputs "xauth")
+                                   "/bin/xauth\"\n")))))
 
-          ;; Tests rely on $USER being set.
-          (setenv "USER" "guix"))
-        %standard-phases)))
+             ;; Tests rely on $USER being set.
+             (setenv "USER" "guix"))))))
     (home-page "http://www.lysator.liu.se/~nisse/lsh/")
     (synopsis "GNU implementation of the Secure Shell (ssh) protocols")
     (description
diff --git a/gnu/packages/lua.scm b/gnu/packages/lua.scm
index d27c024cfb..fcb41831eb 100644
--- a/gnu/packages/lua.scm
+++ b/gnu/packages/lua.scm
@@ -40,7 +40,7 @@
              (patches (list (search-patch "lua-pkgconfig.patch")
                             (search-patch "lua52-liblua-so.patch")))))
     (build-system gnu-build-system)
-    (inputs `(("readline", readline)))
+    (inputs `(("readline" ,readline)))
     (arguments
      '(#:modules ((guix build gnu-build-system)
                     (guix build utils)
diff --git a/gnu/packages/lxqt.scm b/gnu/packages/lxqt.scm
index d840ff0098..677b580bed 100644
--- a/gnu/packages/lxqt.scm
+++ b/gnu/packages/lxqt.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
+;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -36,7 +37,7 @@
      (origin
        (method url-fetch)
        (uri
-         (string-append "http://downloads.lxqt.org/libqtxdg/" version "/"
+         (string-append "https://downloads.lxqt.org/libqtxdg/" version "/"
                         name "-" version ".tar.xz"))
        (sha256
         (base32
@@ -63,7 +64,7 @@ in Qt.")
      (origin
        (method url-fetch)
        (uri
-         (string-append "http://downloads.lxqt.org/lxqt/" version "/"
+         (string-append "https://downloads.lxqt.org/lxqt/" version "/"
                         name "-" version ".tar.xz"))
        (sha256
         (base32
@@ -91,7 +92,7 @@ components of the LXQt desktop environment.")
      (origin
        (method url-fetch)
        (uri
-         (string-append "http://downloads.lxqt.org/lxqt/" version "/"
+         (string-append "https://downloads.lxqt.org/lxqt/" version "/"
                         name "-" version ".tar.xz"))
        (sha256
         (base32
@@ -142,7 +143,7 @@ desktop environment.")
      (origin
        (method url-fetch)
        (uri
-         (string-append "http://downloads.lxqt.org/lxqt/" version "/"
+         (string-append "https://downloads.lxqt.org/lxqt/" version "/"
                         name "-" version ".tar.xz"))
        (sha256
         (base32
diff --git a/gnu/packages/mail.scm b/gnu/packages/mail.scm
index d41479e83f..5a9f420b43 100644
--- a/gnu/packages/mail.scm
+++ b/gnu/packages/mail.scm
@@ -10,6 +10,7 @@
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016 Al McElrath <hello@yrns.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -414,6 +415,47 @@ attachments, create new maildirs, and so on.")
 ing, and tagging large collections of email messages.")
     (license gpl3+)))
 
+(define-public notmuch-addrlookup-c
+  (package
+    (name "notmuch-addrlookup-c")
+    (version "7")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append
+                    "https://github.com/aperezdc/" name "/archive/v"
+                    version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0rslg2ifgyhl6asv3yr1f62m9xjfcinv7i6qb07h2k217jqlmrri"))))
+    (build-system gnu-build-system)
+    (arguments
+     '(#:tests? #f ; no tests
+       #:make-flags (list "CC=gcc"
+                          (string-append "PREFIX="
+                                         (assoc-ref %outputs "out")))
+       #:phases (modify-phases %standard-phases
+                  (delete 'configure)
+                  ;; Remove vim code completion config, it's not needed to
+                  ;; build (or be patched).
+                  (add-before 'patch-source-shebangs 'delete-ycm-file
+                              (lambda _ (delete-file ".ycm_extra_conf.py")))
+                  (replace 'install
+                           (lambda* (#:key outputs #:allow-other-keys)
+                             (let ((bin (string-append
+                                         (assoc-ref outputs "out") "/bin")))
+                               (install-file "notmuch-addrlookup" bin)))))))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)))
+    (inputs
+     `(("glib" ,glib)
+       ("notmuch" ,notmuch)))
+    (home-page "https://github.com/aperezdc/notmuch-addrlookup-c")
+    (synopsis "Address lookup tool for Notmuch")
+    (description "This is an address lookup tool using a Notmuch database,
+useful for email address completion.")
+    (license license:expat)))
+
 (define-public python2-notmuch
   (package
     (name "python2-notmuch")
diff --git a/gnu/packages/mate.scm b/gnu/packages/mate.scm
new file mode 100644
index 0000000000..c4b75f8609
--- /dev/null
+++ b/gnu/packages/mate.scm
@@ -0,0 +1,211 @@
+;;; GNU Guix --- Functional package management for GNU
+;;; Copyright © 2016 Fabian Harfert <fhmgufs@web.de>
+;;;
+;;; 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 mate)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
+  #:use-module (guix download)
+  #:use-module (guix utils)
+  #:use-module (guix build-system gnu)
+  #:use-module (gnu packages)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages glib)
+  #:use-module (gnu packages gtk)
+  #:use-module (gnu packages gnome)
+  #:use-module (gnu packages xorg)
+  #:use-module (gnu packages xdisorg)
+  #:use-module (gnu packages base)
+  #:use-module (gnu packages xml)
+  #:use-module (gnu packages python))
+
+(define-public mate-icon-theme
+  (package
+    (name "mate-icon-theme")
+    (version "1.12.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://pub.mate-desktop.org/releases/"
+                                  (version-major+minor version) "/"
+                                  name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "0d91rvl9rw3xl8hmdcbb6xvi880kfmh2ra5chhrjimrjqgl57qkp"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("intltool" ,intltool)
+       ("gtk+" ,gtk+)
+       ("icon-naming-utils" ,icon-naming-utils)))
+    (home-page "http://mate-desktop.org/")
+    (synopsis "The MATE desktop environment icon theme")
+    (description
+     "This package contains the default icon theme used by the MATE desktop.")
+    (license license:lgpl3+)))
+
+(define-public mate-themes
+  (package
+    (name "mate-themes")
+    (version "1.12.2")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://pub.mate-desktop.org/releases/"
+                                  (version-major+minor version) "/"
+                                  name "-gtk"
+                                  (version-major+minor (package-version gtk+))
+                                  "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "0kyrlgs5azzj60gnxx2n9qszcligxn959wr42wr0iqnrpiygk5nf"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("intltool" ,intltool)))
+    (inputs
+     `(("gtk+" ,gtk+-2)
+       ("gdk-pixbuf" ,gdk-pixbuf)
+       ("gtk-engines" ,gtk-engines)
+       ("murrine" ,murrine)))
+    (home-page "http://mate-desktop.org/")
+    (synopsis
+     "Official themes for the MATE desktop")
+    (description
+     "This package includes the standard themes for the MATE desktop, for
+example Menta, TraditionalOk, GreenLaguna or BlackMate.")
+    (license (list license:lgpl2.1+ license:cc-by-sa3.0 license:gpl3+
+                   license:gpl2+))))
+
+(define-public mate-desktop
+  (package
+    (name "mate-desktop")
+    (version "1.12.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://pub.mate-desktop.org/releases/"
+                                  (version-major+minor version) "/"
+                                  name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "00ssrzm07xyrjra075jhir1f8iy382lla7923fhic29lap26mffr"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("intltool" ,intltool)
+       ("glib:bin" ,glib "bin")
+       ("gobject-introspection" ,gobject-introspection)
+       ("yelp-tools" ,yelp-tools)))
+       ;;("gtk-doc" ,gtk-doc))) ; add back in when gtk-doc builds
+    (inputs
+     `(("libxrandr" ,libxrandr)))
+    (propagated-inputs
+     `(("dconf" ,dconf)
+       ("gtk+" ,gtk+-2)
+       ("startup-notification" ,startup-notification)))
+    (home-page "http://mate-desktop.org/")
+    (synopsis "Library with common API for various MATE modules")
+    (description
+     "This package contains a public API shared by several applications on the
+desktop and the mate-about program.")
+    (license (list license:gpl2+ license:lgpl2.0+ license:fdl1.1+))))
+
+(define-public libmateweather
+  (package
+    (name "libmateweather")
+    (version "1.12.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://pub.mate-desktop.org/releases/"
+                                  (version-major+minor version) "/"
+                                  name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "0qrq6z6knybixnxmsvkw58hm033m91inf523mbvzgv2r822fpakl"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:configure-flags
+       `(,(string-append "--with-zoneinfo-dir="
+                         (assoc-ref %build-inputs "tzdata")
+                         "/share/zoneinfo"))
+       #:phases
+       (modify-phases %standard-phases
+         (add-before
+          'check 'pre-check
+          (lambda* (#:key inputs #:allow-other-keys)
+            (substitute* "data/check-timezones.sh"
+              (("/usr/share/zoneinfo/zone.tab")
+               (string-append (assoc-ref inputs "tzdata")
+                              "/share/zoneinfo/zone.tab")))
+            #t)))))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("intltool" ,intltool)
+       ("glib:bin" ,glib "bin")))
+    (inputs
+     `(("dconf" ,dconf)
+       ("tzdata" ,tzdata)))
+    (propagated-inputs
+     `(("gtk+" ,gtk+-2)
+       ("gdk-pixbuf" ,gdk-pixbuf)
+       ("libxml2" ,libxml2)
+       ("libsoup" ,libsoup)))
+    (home-page "http://mate-desktop.org/")
+    (synopsis "MATE library for weather information from the Internet")
+    (description
+     "This library provides acess to weather information from the internet for
+the MATE desktop environment.")
+    (license license:lgpl2.1+)))
+
+(define-public mate-menus
+  (package
+    (name "mate-menus")
+    (version "1.12.0")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://pub.mate-desktop.org/releases/"
+                                  (version-major+minor version) "/"
+                                  name "-" version ".tar.xz"))
+              (sha256
+               (base32
+                "1i4m3fj0vd85zyhqhm8x9yr0h5i08aa4l99zqvbk59ncj6z3bdxh"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-after
+          'unpack 'fix-introspection-install-dir
+          (lambda* (#:key outputs #:allow-other-keys)
+            (let ((out (assoc-ref outputs "out")))
+              (substitute* '("configure")
+                (("`\\$PKG_CONFIG --variable=girdir gobject-introspection-1.0`")
+                 (string-append "\"" out "/share/gir-1.0/\""))
+                (("\\$\\(\\$PKG_CONFIG --variable=typelibdir gobject-introspection-1.0\\)")
+                 (string-append out "/lib/girepository-1.0/")))))))))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)
+       ("intltool" ,intltool)
+       ("gobject-introspection" ,gobject-introspection)))
+    (inputs
+     `(("python" ,python-2)))
+    (propagated-inputs
+     `(("glib" ,glib)))
+    (home-page "http://mate-desktop.org/")
+    (synopsis "Freedesktop menu specification implementation for MATE")
+    (description
+     "The package contains an implementation of the freedesktop menu
+specification, the MATE menu layout configuration files, .directory files and
+assorted menu related utility programs.")
+    (license (list license:gpl2+ license:lgpl2.0+))))
diff --git a/gnu/packages/maths.scm b/gnu/packages/maths.scm
index 51d9cc1ce4..6a9715db73 100644
--- a/gnu/packages/maths.scm
+++ b/gnu/packages/maths.scm
@@ -8,7 +8,7 @@
 ;;; Copyright © 2015 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2015 Fabian Harfert <fhmgufs@web.de>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -177,7 +177,7 @@ numbers.")
 (define-public glpk
   (package
     (name "glpk")
-    (version "4.57")
+    (version "4.58")
     (source
      (origin
       (method url-fetch)
@@ -185,7 +185,7 @@ numbers.")
                           version ".tar.gz"))
       (sha256
        (base32
-        "0p17jj1ixd2m9lnsvx8nywmfmnplfk5gvw25r1gy84qzrjkv48vk"))))
+        "1jmrya04hgwnrxrqqs40i6m9cqka3q601cx3nh9ijyvlg90zlq24"))))
     (build-system gnu-build-system)
     (inputs
      `(("gmp" ,gmp)))
@@ -339,7 +339,7 @@ singular value problems.")
 (define-public gnuplot
   (package
     (name "gnuplot")
-    (version "5.0.1")
+    (version "5.0.2")
     (source
      (origin
       (method url-fetch)
@@ -347,7 +347,7 @@ singular value problems.")
                           version "/gnuplot-" version ".tar.gz"))
       (sha256
        (base32
-        "0irwig94w3f8bn4a444hrjnp7w55vqwv8gqj42jiwn6zf5z5bg3w"))))
+        "146qn414z96c7cc42a1kb9a4kpjc2q2hfdwk44kjjvgmfp9k2ass"))))
     (build-system gnu-build-system)
     (inputs `(("readline" ,readline)
               ("cairo" ,cairo)
diff --git a/gnu/packages/mit-krb5.scm b/gnu/packages/mit-krb5.scm
index 16bef8d97d..5f9868979a 100644
--- a/gnu/packages/mit-krb5.scm
+++ b/gnu/packages/mit-krb5.scm
@@ -1,6 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013 Andreas Enge <andreas@enge.fr>
-;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2015, 2016 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -21,7 +21,6 @@
   #:use-module (gnu packages)
   #:use-module (gnu packages bison)
   #:use-module (gnu packages perl)
-  #:use-module (gnu packages gcc)
   #:use-module (guix licenses)
   #:use-module (guix packages)
   #:use-module (guix download)
@@ -31,70 +30,31 @@
 (define-public mit-krb5
   (package
     (name "mit-krb5")
-    (version "1.13.2")
+    (version "1.13.3")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://web.mit.edu/kerberos/www/dist/krb5/"
+              (uri (string-append "http://web.mit.edu/kerberos/dist/krb5/"
                                   (version-major+minor version)
-                                  "/krb5-" version "-signed.tar"))
-              (sha256 (base32
-                       "1qbdzyrws7d0q4filsibh28z54pd5l987jr0ygv43iq9085w6a75"))))
+                                  "/krb5-" version ".tar.gz"))
+              (sha256
+               (base32
+                "1gpscn78lv48dxccxq9ncyj53w9l2a15xmngjfa1wylvmn7g0jjx"))
+              (patches
+               (map search-patch '("mit-krb5-init-context-null-spnego.patch"
+                                   "mit-krb5-CVE-2015-8629.patch"
+                                   "mit-krb5-CVE-2015-8630.patch"
+                                   "mit-krb5-CVE-2015-8631.patch")))))
     (build-system gnu-build-system)
     (native-inputs
      `(("bison" ,bison)
-       ("perl" ,perl)
-
-       ;; Include the patches as native-inputs.
-       ,@(map (lambda (label)
-                (let ((input-name (string-append "patch/" label))
-                      (file-name  (string-append name "-" label ".patch")))
-                  `(,input-name ,(search-patch file-name))))
-              '("CVE-2015-2695-pt1"
-                "CVE-2015-2695-pt2"
-                "CVE-2015-2696"
-                "CVE-2015-2697"
-                "CVE-2015-2698-pt1"
-                "CVE-2015-2698-pt2"))))
+       ("perl" ,perl)))
     (arguments
-     `(#:modules ((ice-9 ftw)
-                  (ice-9 match)
-                  (srfi srfi-1)
-                  ,@%gnu-build-system-modules)
-       #:phases
+     `(#:phases
        (modify-phases %standard-phases
-         (replace 'unpack
-           (lambda* (#:key source #:allow-other-keys)
-             (define (sub-directory? name)
-               (and (not (member name '("." "..")))
-                    (equal? (stat:type (stat name))
-                            'directory)))
-             (and (zero? (system* "tar" "xvf" source))
-                  (match (find-files "." "\\.tar\\.gz$")
-                    ((inner-tar-file)
-                     (zero? (system* "tar" "xvf" inner-tar-file))))
-                  (match (scandir "." sub-directory?)
-                    ((directory)
-                     (chdir directory)
-                     #t)))))
-
-         (add-after 'unpack 'apply-patches
-           (lambda* (#:key inputs native-inputs #:allow-other-keys)
-             (let ((patches (filter (match-lambda
-                                      ((name . file)
-                                       (string-prefix? "patch/" name)))
-                                    (or native-inputs inputs))))
-               (every (match-lambda
-                        ((name . file)
-                         (format (current-error-port)
-                                 "applying '~a'...~%" name)
-                         (zero? (system* "patch" "-p1" "--force" "-i" file))))
-                      patches))))
-
-         (add-after 'apply-patches 'enter-source-directory
+         (add-after 'unpack 'enter-source-directory
            (lambda _
              (chdir "src")
              #t))
-
          (add-before 'check 'pre-check
            (lambda* (#:key inputs #:allow-other-keys)
              (let ((perl (assoc-ref inputs "perl")))
diff --git a/gnu/packages/moe.scm b/gnu/packages/moe.scm
index 675ecb6ce2..12929b327a 100644
--- a/gnu/packages/moe.scm
+++ b/gnu/packages/moe.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 Eric Bavier <bavier@member.fsf.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -27,7 +28,7 @@
 (define-public moe
   (package
     (name "moe")
-    (version "1.7")
+    (version "1.8")
     (source
      (origin
       (method url-fetch)
@@ -35,7 +36,7 @@
                           version ".tar.lz"))
       (sha256
        (base32
-        "1fzimk1qpmsm7wzfnjzzrp4dvdn7ipdb5j7969910g1m93wndfik"))))
+        "0mv4pg38p0dq88xmxxv08rykn7vv4x7gskmdk7nfp3vx37r4xzvy"))))
     (build-system gnu-build-system)
     (native-inputs `(("lzip" ,lzip)))
     (inputs `(("ncurses" ,ncurses)))
diff --git a/gnu/packages/mpd.scm b/gnu/packages/mpd.scm
index b5a0d94a74..5a6377224d 100644
--- a/gnu/packages/mpd.scm
+++ b/gnu/packages/mpd.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2014 Cyrill Schenkel <cyrill.schenkel@gmail.com>
 ;;; Copyright © 2014 Ian Denhardt <ian@zenhack.net>
 ;;; Copyright © 2015 Paul van der Walt <paul@denknerd.org>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -69,7 +70,7 @@ interfacing MPD in the C, C++ & Objective C languages.")
 (define-public mpd
   (package
     (name "mpd")
-    (version "0.19.10")
+    (version "0.19.12")
     (source (origin
               (method url-fetch)
               (uri
@@ -78,7 +79,7 @@ interfacing MPD in the C, C++ & Objective C languages.")
                               "/mpd-" version ".tar.xz"))
               (sha256
                (base32
-                "0laqn68iggqf0h06hg282cvpd9wsjqpjfg5fnn9wk3gr48yyp1n3"))))
+                "0xg8w5vn6xd0yfw55qj6wnav7v14nmr00s3d4w5gixbjrv3ycvvv"))))
     (build-system gnu-build-system)
     (inputs `(("ao" ,ao)
               ("alsa-lib" ,alsa-lib)
@@ -178,7 +179,7 @@ terminal using ncurses.")
 (define-public ncmpcpp
   (package
     (name "ncmpcpp")
-    (version "0.6.7")
+    (version "0.7.3")
     (source (origin
               (method url-fetch)
               (uri
@@ -186,13 +187,14 @@ terminal using ncurses.")
                               version ".tar.bz2"))
               (sha256
                (base32
-                "0yr1ib14qkgbsv839anpzkfbwkm6gg8wv4bf98ar7q5l2p2pv008"))))
+                "04mj6r0whikliblxfbz92pibwcd7a3ywkryf01a89zd4bi1jk2rc"))))
     (build-system gnu-build-system)
     (inputs `(("libmpdclient" ,libmpdclient)
               ("boost"  ,boost)
               ("readline" ,readline)
               ("ncurses" ,ncurses)
-              ("taglib" ,taglib)))
+              ("taglib" ,taglib)
+              ("icu4c" ,icu4c)))
     (native-inputs
      `(("pkg-config" ,pkg-config)
        ("automake" ,automake)
@@ -202,12 +204,11 @@ terminal using ncurses.")
      '(#:configure-flags
        '("BOOST_LIB_SUFFIX=" "--with-taglib")
        #:phases
-       (alist-cons-after
-        'unpack 'autogen
-        (lambda _
-          (setenv "NOCONFIGURE" "true")
-          (zero? (system* "sh" "autogen.sh")))
-        %standard-phases)))
+       (modify-phases %standard-phases
+        (add-after 'unpack 'autogen
+         (lambda _
+           (setenv "NOCONFIGURE" "true")
+           (zero? (system* "sh" "autogen.sh")))))))
     (synopsis "Featureful ncurses based MPD client inspired by ncmpc")
     (description "Ncmpcpp is an mpd client with a UI very similar to ncmpc,
 but it provides new useful features such as support for regular expressions
diff --git a/gnu/packages/music.scm b/gnu/packages/music.scm
index a60ba4bccd..d789cc394f 100644
--- a/gnu/packages/music.scm
+++ b/gnu/packages/music.scm
@@ -2,6 +2,8 @@
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
 ;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Paul van der Walt <paul@denknerd.org>
+;;; Copyright © 2016 Al McElrath <hello@yrns.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -32,13 +34,15 @@
   #:use-module (gnu packages algebra)
   #:use-module (gnu packages audio)
   #:use-module (gnu packages autotools)
+  #:use-module (gnu packages backup)
   #:use-module (gnu packages base) ;libbdf
-  #:use-module (gnu packages boost)
   #:use-module (gnu packages bison)
+  #:use-module (gnu packages boost)
   #:use-module (gnu packages cdrom)
   #:use-module (gnu packages code)
   #:use-module (gnu packages check)
   #:use-module (gnu packages compression)
+  #:use-module (gnu packages curl)
   #:use-module (gnu packages docbook)
   #:use-module (gnu packages doxygen)
   #:use-module (gnu packages flex)
@@ -46,6 +50,7 @@
   #:use-module (gnu packages fonts)
   #:use-module (gnu packages fontutils)
   #:use-module (gnu packages gcc)
+  #:use-module (gnu packages gnupg)
   #:use-module (gnu packages gettext)
   #:use-module (gnu packages ghostscript)
   #:use-module (gnu packages gl)
@@ -145,64 +150,32 @@ many input formats and provides a customisable Vi-style user interface.")
 (define-public hydrogen
   (package
     (name "hydrogen")
-    (version "0.9.5.1")
+    (version "0.9.6.1")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "mirror://sourceforge/hydrogen/Hydrogen/"
-                    (version-prefix version 3) "%20Sources/"
-                    "hydrogen-" version ".tar.gz"))
+                    "https://github.com/hydrogen-music/hydrogen/archive/"
+                    version ".tar.gz"))
               (sha256
                (base32
-                "1fvyp6gfzcqcc90dmaqbm11p272zczz5pfz1z4lj33nfr7z0bqgb"))))
-    (build-system gnu-build-system)
+                "0vxnaqfmcv7hhk0cj67imdcqngspnck7f0wfmvhfgfqa7x1xznll"))))
+    (build-system cmake-build-system)
     (arguments
-     `(#:tests? #f ;no "check" target
-       #:phases
-       ;; TODO: Add scons-build-system and use it here.
-       (modify-phases %standard-phases
-         (delete 'configure)
-         (add-after 'unpack 'scons-propagate-environment
-                    (lambda _
-                      ;; By design, SCons does not, by default, propagate
-                      ;; environment variables to subprocesses.  See:
-                      ;; <http://comments.gmane.org/gmane.linux.distributions.nixos/4969>
-                      ;; Here, we modify the Sconstruct file to arrange for
-                      ;; environment variables to be propagated.
-                      (substitute* "Sconstruct"
-                        (("^env = Environment\\(")
-                         "env = Environment(ENV=os.environ, "))))
-         (replace 'build
-                  (lambda* (#:key inputs outputs #:allow-other-keys)
-                    (let ((out (assoc-ref outputs "out")))
-                      (zero? (system* "scons"
-                                      (string-append "prefix=" out)
-                                      "lrdf=0" ; cannot be found
-                                      "lash=1")))))
-         (add-before
-          'install
-          'fix-img-install
-          (lambda _
-            ;; The whole ./data/img directory is copied to the target first.
-            ;; Scons complains about existing files when we try to install all
-            ;; images a second time.
-            (substitute* "Sconstruct"
-              (("os.path.walk\\(\"./data/img/\",install_images,env\\)") ""))
-            #t))
-         (replace 'install (lambda _ (zero? (system* "scons" "install")))))))
+    `(#:test-target "tests"))
     (native-inputs
-     `(("scons" ,scons)
-       ("python" ,python-2)
+     `(("cppunit" ,cppunit)
        ("pkg-config" ,pkg-config)))
     (inputs
-     `(("zlib" ,zlib)
-       ("libtar" ,libtar)
-       ("alsa-lib" ,alsa-lib)
+     `(("alsa-lib" ,alsa-lib)
        ("jack" ,jack-1)
+       ;; ("ladspa" ,ladspa) ; cannot find during configure
        ("lash" ,lash)
-       ;;("lrdf" ,lrdf) ;FIXME: cannot be found by scons
+       ("libarchive" ,libarchive)
+       ("libsndfile" ,libsndfile)
+       ("libtar" ,libtar)
+       ("lrdf" ,lrdf)
        ("qt" ,qt-4)
-       ("libsndfile" ,libsndfile)))
+       ("zlib" ,zlib)))
     (home-page "http://www.hydrogen-music.org")
     (synopsis "Drum machine")
     (description
@@ -252,6 +225,54 @@ enable professional yet simple and intuitive pattern-based drum programming.")
 you to define complex tempo maps for entire songs or performances.")
     (license license:gpl2+)))
 
+(define-public gtklick
+  (package
+    (name "gtklick")
+    (version "0.6.4")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://das.nasophon.de/download/gtklick-"
+                                  version ".tar.gz"))
+              (sha256
+               (base32
+                "0dq1km6njnzsqdqyf6wzir9g733z0mc9vmxfg2383k3c2a2di6bp"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f ; no tests
+       #:python ,python-2
+       #:phases
+       (modify-phases %standard-phases
+         (add-before 'build 'add-sitedirs
+           ;; .pth files are not automatically interpreted unless the
+           ;; directories containing them are added as "sites".  The directories
+           ;; are then added to those in the PYTHONPATH.  This is required for
+           ;; the operation of pygtk.
+           (lambda _
+             (substitute* "gtklick/gtklick.py"
+               (("import pygtk")
+                "import pygtk, site, sys
+for path in [path for path in sys.path if 'site-packages' in path]: site.addsitedir(path)"))))
+         (add-after 'unpack 'inject-store-path-to-klick
+           (lambda* (#:key inputs #:allow-other-keys)
+             (substitute* "gtklick/klick_backend.py"
+               (("KLICK_PATH = 'klick'")
+                (string-append "KLICK_PATH = '"
+                               (assoc-ref inputs "klick")
+                               "/bin/klick'")))
+             #t)))))
+    (inputs
+     `(("klick" ,klick)
+       ("python2-pyliblo" ,python2-pyliblo)
+       ("python2-pygtk" ,python2-pygtk)))
+    (native-inputs
+     `(("gettext" ,gnu-gettext)))
+    (home-page "http://das.nasophon.de/gtklick/")
+    (synopsis "Simple metronome with an easy-to-use graphical interface")
+    (description
+     "Gtklick is a simple metronome with an easy-to-use graphical user
+interface.  It is implemented as a frontend to @code{klick}.")
+    (license license:gpl2+)))
+
 (define-public lilypond
   (package
     (name "lilypond")
@@ -916,15 +937,15 @@ instrument or MIDI file player.")
 (define-public zynaddsubfx
   (package
     (name "zynaddsubfx")
-    (version "2.5.2")
+    (version "2.5.3")
     (source (origin
               (method url-fetch)
               (uri (string-append
                     "mirror://sourceforge/zynaddsubfx/zynaddsubfx/"
-                    version "/zynaddsubfx-" version ".tar.gz"))
+                    version "/zynaddsubfx-" version ".tar.bz2"))
               (sha256
                (base32
-                "11yrady7xwfrzszkk2fvq81ymv99mq474h60qnirk27khdygk24m"))))
+                "04da54p19p7f5wm6vm7abbjbsil1qf7n5f4adj01jm6b0wqigvgb"))))
     (build-system cmake-build-system)
     (arguments
      `(#:phases
@@ -1078,3 +1099,38 @@ computer's keyboard.")
 JACK for audio and ALSA sequencer for MIDI as multimedia infrastructures and
 follows a traditional multi-track tape recorder control paradigm.")
     (license license:gpl2+)))
+
+(define-public pianobar
+  (package
+    (name "pianobar")
+    (version "2015.11.22")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "https://github.com/PromyLOPh/"
+                                  name "/archive/" version ".tar.gz"))
+              (file-name (string-append name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "022df19bhxqvkhy0qy21xahba5s1fm17b13y0p9p9dnf2yl44wfv"))))
+    (build-system gnu-build-system)
+    (arguments
+     `(#:tests? #f ; no tests
+       #:make-flags (list "CC=gcc" "CFLAGS=-std=c99"
+                          (string-append "PREFIX=" %output))
+       #:phases (modify-phases %standard-phases
+                  (delete 'configure))))
+    (inputs
+     `(("ao" ,ao)
+       ("curl" ,curl)
+       ("libgcrypt" ,libgcrypt)
+       ("json-c" ,json-c)
+       ("ffmpeg" ,ffmpeg)))
+    (native-inputs
+     `(("pkg-config" ,pkg-config)))
+    (home-page "http://6xq.net/projects/pianobar/")
+    (synopsis "Console-based pandora.com player")
+    (description "pianobar is a console-based music player for the
+personalized online radio pandora.com.  It has configurable keys for playing
+and managing stations, can be controlled remotely via fifo, and can run
+event-based scripts for scrobbling, notifications, etc.")
+    (license license:expat)))
diff --git a/gnu/packages/nano.scm b/gnu/packages/nano.scm
index 352e2b47e0..a1f7019c0d 100644
--- a/gnu/packages/nano.scm
+++ b/gnu/packages/nano.scm
@@ -28,7 +28,7 @@
 (define-public nano
   (package
     (name "nano")
-    (version "2.5.1")
+    (version "2.5.2")
     (source
      (origin
       (method url-fetch)
@@ -36,7 +36,7 @@
                           version ".tar.gz"))
       (sha256
        (base32
-        "1piv8prj6w3rvsrrx41ra8c10b8fzkgjhnm6399lsgqqpw0wlvz0"))))
+        "0hgbmqzjy1pashb1g3qby75pqb7r5g9bmn1iajlx50082b2nmgc9"))))
     (build-system gnu-build-system)
     (inputs
      `(("gettext" ,gnu-gettext)
diff --git a/gnu/packages/nettle.scm b/gnu/packages/nettle.scm
index b20ddfad26..d1203dfe75 100644
--- a/gnu/packages/nettle.scm
+++ b/gnu/packages/nettle.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2012, 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Mark H Weaver <mhw@netris.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -59,30 +60,17 @@ themselves.")
   ;; This version is not API-compatible with version 2.  In particular, lsh
   ;; cannot use it yet.  So keep it separate.
   (package (inherit nettle-2)
-    (version "3.1.1")
+    (version "3.2")
     (source (origin
               (method url-fetch)
               (uri (string-append "mirror://gnu/nettle/nettle-"
                                   version ".tar.gz"))
               (sha256
                (base32
-                "0k1x57zviysvi91lkk66cg8v819vywm5g5yqs22wppfqcifx5m2z"))))
+                "15wxhk52yc62rx0pddmry66hqm6z5brrrkx4npd3wh9nybg86hpa"))))
     (arguments
-     `(#:phases
-       (modify-phases %standard-phases
-         (add-after
-          'configure 'disable-ifunc-init-method
-          (lambda _
-            ;; Work around problems with the ifunc initialization method in
-            ;; nettle.  For details, see
-            ;; <http://lists.lysator.liu.se/pipermail/nettle-bugs/2015/003389.html>
-            ;; and <https://sourceware.org/ml/libc-help/2015-06/msg00010.html>.
-            (substitute* "config.h"
-              (("#define HAVE_LINK_IFUNC 1")
-               "/* #undef HAVE_LINK_IFUNC */"))
-            #t)))
-       ,@(substitute-keyword-arguments (package-arguments nettle-2)
-           ((#:configure-flags flags)
-            ;; Build "fat" binaries where the right implementation is chosen
-            ;; at run time based on CPU features (starting from 3.1.)
-            `(cons "--enable-fat" ,flags)))))))
+     (substitute-keyword-arguments (package-arguments nettle-2)
+       ((#:configure-flags flags)
+        ;; Build "fat" binaries where the right implementation is chosen
+        ;; at run time based on CPU features (starting from 3.1.)
+        `(cons "--enable-fat" ,flags))))))
diff --git a/gnu/packages/ocaml.scm b/gnu/packages/ocaml.scm
index 1311b1bc37..4b5ac617d5 100644
--- a/gnu/packages/ocaml.scm
+++ b/gnu/packages/ocaml.scm
@@ -4,6 +4,7 @@
 ;;; Copyright © 2015 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015 David Hashe <david.hashe@dhashe.com>
 ;;; Copyright © 2016 Eric Bavier <bavier@member.fsf.org>
+;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -42,6 +43,7 @@
   #:use-module (gnu packages lynx)
   #:use-module (gnu packages perl)
   #:use-module (gnu packages python)
+  #:use-module (gnu packages m4)
   #:use-module (gnu packages ncurses)
   #:use-module (gnu packages version-control)
   #:use-module (gnu packages curl))
@@ -60,6 +62,10 @@
                (base32
                 "1qwwvy8nzd87hk8rd9sm667nppakiapnx4ypdwcrlnav2dz6kil3"))))
     (build-system gnu-build-system)
+    (native-search-paths
+     (list (search-path-specification
+            (variable "OCAMLPATH")
+            (files (list (string-append "lib/ocaml"))))))
     (native-inputs
      `(("perl" ,perl)
        ("pkg-config" ,pkg-config)))
@@ -471,6 +477,8 @@ provers.")
     (arguments
      `(#:tests? #f ; no check target
 
+       ;; opt: also install cmxa files
+       #:make-flags (list "all" "opt")
        ;; Occasionally we would get "Error: Unbound module GtkThread" when
        ;; compiling 'gtkThInit.ml', with 'make -j'.  So build sequentially.
        #:parallel-build? #f
@@ -613,3 +621,52 @@ a collection of files and directories to be stored on different hosts
 brought up to date by propagating the changes in each replica
 to the other.")
     (license gpl3+)))
+
+(define-public ocaml-findlib
+  (package
+    (name "ocaml-findlib")
+    (version "1.6.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://download.camlcity.org/download/"
+                                  "findlib" "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "02abg1lsnwvjg3igdyb8qjgr5kv1nbwl4gaf8mdinzfii5p82721"))
+              (patches
+               (list (search-patch "ocaml-findlib-make-install.patch")))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("camlp4" ,camlp4)
+       ("m4" ,m4)
+       ("ocaml" ,ocaml)))
+    (arguments
+     `(#:tests? #f  ; no test suite
+       #:parallel-build? #f
+       #:make-flags (list "all" "opt")
+       #:phases (modify-phases %standard-phases
+                  (replace
+                   'configure
+                   (lambda* (#:key inputs outputs #:allow-other-keys)
+                     (let ((out (assoc-ref outputs "out")))
+                       (system*
+                        "./configure"
+                        "-bindir" (string-append out "/bin")
+                        "-config" (string-append out "/etc/ocamfind.conf")
+                        "-mandir" (string-append out "/share/man")
+                        "-sitelib" (string-append out "/lib/ocaml/site-lib")
+                        "-with-toolbox")))))))
+    (home-page "http://projects.camlcity.org/projects/findlib.html")
+    (synopsis "Management tool for OCaml libraries")
+    (description
+     "The \"findlib\" library provides a scheme to manage reusable software
+components (packages), and includes tools that support this scheme.  Packages
+are collections of OCaml modules for which metainformation can be stored.  The
+packages are kept in the filesystem hierarchy, but with strict directory
+structure.  The library contains functions to look the directory up that
+stores a package, to query metainformation about a package, and to retrieve
+dependency information about multiple packages.  There is also a tool that
+allows the user to enter queries on the command-line.  In order to simplify
+compilation and linkage, there are new frontends of the various OCaml
+compilers that can directly deal with packages.")
+    (license x11)))
diff --git a/gnu/packages/openbox.scm b/gnu/packages/openbox.scm
index 9dd756d9f3..3135756e7b 100644
--- a/gnu/packages/openbox.scm
+++ b/gnu/packages/openbox.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Julien Lepiller <julien@lepiller.eu>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -31,15 +32,15 @@
 (define-public openbox
   (package
     (name "openbox")
-    (version "3.5.2")
+    (version "3.6.1")
     (source (origin
               (method url-fetch)
               (uri (string-append
                     "http://www.icculus.org/openbox/releases/" name "-"
-                    version ".tar.gz"))
+                    version ".tar.xz"))
               (sha256
                (base32
-                "0cxgb334zj6aszwiki9g10i56sm18i7w1kw52vdnwgzq27pv93qj"))))
+                "0vg2y1qddsdxkjv806mzpvmkgzliab8ll4s7zm7ma5jnriamirxb"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (inputs `(("imlib2" ,imlib2)
diff --git a/gnu/packages/openstack.scm b/gnu/packages/openstack.scm
index e258b89e2f..0fa488f842 100644
--- a/gnu/packages/openstack.scm
+++ b/gnu/packages/openstack.scm
@@ -304,12 +304,7 @@ portions of your testing code.")
     (license asl2.0)))
 
 (define-public python2-requests-mock
-  (let ((requests-mock (package-with-python2 python-requests-mock)))
-    (package (inherit requests-mock)
-      (propagated-inputs
-       `(("python2-requests" ,python2-requests)
-         ,@(alist-delete "python-requests"
-                         (package-propagated-inputs requests-mock)))))))
+  (package-with-python2 python-requests-mock))
 
 (define-public python-stevedore
   (package
@@ -392,12 +387,7 @@ common features used in Tempest.")
     (license asl2.0)))
 
 (define-public python2-tempest-lib
-  (let ((tempest-lib (package-with-python2 python-tempest-lib)))
-    (package (inherit tempest-lib)
-      (propagated-inputs
-       `(("python2-jsonschema", python2-jsonschema)
-         ,@(alist-delete "python-jsonschema"
-                         (package-propagated-inputs tempest-lib)))))))
+  (package-with-python2 python-tempest-lib))
 
 ;; Packages from the Oslo library
 (define-public python-oslo.config
@@ -606,9 +596,7 @@ from the OpenStack project.")
     (license asl2.0)))
 
 (define-public python2-oslosphinx
-  (let ((oslosphinx (package-with-python2 python-oslosphinx)))
-    (package (inherit oslosphinx)
-      (propagated-inputs `(("python2-requests" ,python2-requests))))))
+  (package-with-python2 python-oslosphinx))
 
 (define-public python-oslotest
   (package
@@ -782,7 +770,7 @@ LDAP.")
           "1j33l4z9vqh0scfncl4fxg01zr1hgqxhhai6gvcih1gccqm4nd7p"))))
     (build-system python-build-system)
     (native-inputs
-     `(("python-pbr", python-pbr)
+     `(("python-pbr" ,python-pbr)
        ("python-setuptools" ,python-setuptools)
        ("python-sphinx" ,python-sphinx)
        ;; The folloing packages are needed for the tests.
diff --git a/gnu/packages/owncloud.scm b/gnu/packages/owncloud.scm
index 084a0a2863..e75426e579 100644
--- a/gnu/packages/owncloud.scm
+++ b/gnu/packages/owncloud.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -34,14 +34,14 @@
 (define-public owncloud-client
   (package
     (name "owncloud-client")
-    (version "2.1.0")
+    (version "2.1.1")
     (source
      (origin
        (method url-fetch)
        (uri (string-append "https://download.owncloud.com/desktop/stable/"
                            "owncloudclient-" version ".tar.xz"))
        (sha256
-        (base32 "0gyhll4yfxcpyc5m73zar5f33qgnmpwiggw2adxdiqy55hc3ymbk"))))
+        (base32 "1jxi439qff4acvyvszjprj42kvzhlz255wv8g4p3jrf55svzwz2f"))))
     (build-system cmake-build-system)
     (arguments
      `(#:phases
diff --git a/gnu/packages/package-management.scm b/gnu/packages/package-management.scm
index c7494c1b8d..ac6d84813f 100644
--- a/gnu/packages/package-management.scm
+++ b/gnu/packages/package-management.scm
@@ -239,14 +239,14 @@ the Nix package manager.")
 (define-public nix
   (package
     (name "nix")
-    (version "1.10")
+    (version "1.11.2")
     (source (origin
              (method url-fetch)
              (uri (string-append "http://nixos.org/releases/nix/nix-"
                                  version "/nix-" version ".tar.xz"))
              (sha256
               (base32
-               "1xhh7l1dqwn6i3m51xp8l0aa95da3823w4h8n8hfxlcxaixcl4jn"))))
+               "1mk9z75gklxcv6kzwwz1h5r2ci5kjy6bh7qwk4m5lf5v9s0k64pw"))))
     (build-system gnu-build-system)
     ;; XXX: Should we pass '--with-store-dir=/gnu/store'?  But then we'd also
     ;; need '--localstatedir=/var'.  But then!  The thing would use /var/nix
@@ -389,21 +389,23 @@ transactions from C or Python.")
 (define-public diffoscope
   (package
     (name "diffoscope")
-    (version "34")
+    (version "49")
     (source (origin
-              (method git-fetch)
-              (uri (git-reference
-                    (url
-                     "https://anonscm.debian.org/cgit/reproducible/diffoscope.git")
-                    (commit version)))
+              (method url-fetch)
+              (uri (pypi-uri name version))
               (sha256
                (base32
-                "1g8b7bpkmns0355gkr3a244affwx4xzqwahwsl6ivw4z0qv7dih8"))
-              (file-name (string-append name "-" version "-checkout"))))
+                "1mf6b7j82ckn90ggz6bp6c2jydz87xj8r8jmfl4hg7jcmf7dxmim"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2
-       #:phases (modify-phases %standard-phases
+     `(#:phases (modify-phases %standard-phases
+                  ;; setup.py mistakenly requires python-magic from PyPi, even
+                  ;; though the Python bindings of `file` are sufficient.
+                  ;; https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815844
+                  (add-after 'unpack 'dependency-on-python-magic
+                    (lambda _
+                      (substitute* "setup.py"
+                        (("'python-magic',") ""))))
                   (add-before 'build 'disable-egg-zipping
                     (lambda _
                       ;; Leave the .egg file uncompressed.
@@ -411,27 +413,16 @@ transactions from C or Python.")
                         (display "\n[easy_install]\nzip_ok = 0\n"
                                  port)
                         (close-port port)
-                        #t)))
-                  (add-before 'build 'dependency-on-rpm
-                    (lambda _
-                      (substitute* "setup.py"
-                        ;; Somehow this requirement is reported as not met,
-                        ;; even though rpm.py is in the search path.  So
-                        ;; delete it.
-                        (("'rpm-python',") ""))
-                      #t)))
-       ;; FIXME: Some obscure test failures.
-       #:tests? #f))
+                        #t))))))
     (inputs `(("rpm" ,rpm)                        ;for rpm-python
-              ("python-file" ,python2-file)
-              ("python-debian" ,python2-debian)
-              ("python-libarchive-c" ,python2-libarchive-c)
-              ("python-tlsh" ,python2-tlsh)
+              ("python-file" ,python-file)
+              ("python-debian" ,python-debian)
+              ("python-libarchive-c" ,python-libarchive-c)
+              ("python-tlsh" ,python-tlsh)
 
               ;; Below are modules used for tests.
-              ("python-pytest" ,python2-pytest)
-              ("python-chardet" ,python2-chardet)))
-    (native-inputs `(("python-setuptools" ,python2-setuptools)))
+              ("python-pytest" ,python-pytest)
+              ("python-chardet" ,python-chardet)))
     (home-page "http://diffoscope.org/")
     (synopsis "Compare files, archives, and directories in depth")
     (description
diff --git a/gnu/packages/parallel.scm b/gnu/packages/parallel.scm
index 8f63bda25c..e336afb40d 100644
--- a/gnu/packages/parallel.scm
+++ b/gnu/packages/parallel.scm
@@ -1,7 +1,9 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2013,2014 Eric Bavier <bavier@member.fsf.org>
+;;; Copyright © 2013, 2014 Eric Bavier <bavier@member.fsf.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 Pjotr Prins <pjotr.guix@thebird.nl>
+;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -19,17 +21,28 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu packages parallel)
-  #:use-module (guix packages)
-  #:use-module (guix licenses)
-  #:use-module (guix download)
   #:use-module (guix build-system gnu)
+  #:use-module (guix download)
+  #:use-module ((guix licenses) #:prefix license:)
+  #:use-module (guix packages)
   #:use-module (gnu packages)
-  #:use-module (gnu packages perl))
+  #:use-module (gnu packages admin)
+  #:use-module (gnu packages autotools)
+  #:use-module (gnu packages freeipmi)
+  #:use-module (gnu packages linux)
+  #:use-module (gnu packages mpi)
+  #:use-module (gnu packages perl)
+  #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages python)
+  #:use-module (gnu packages readline)
+  #:use-module (gnu packages tcl)
+  #:use-module (gnu packages tls)
+  #:use-module (gnu packages web))
 
 (define-public parallel
   (package
     (name "parallel")
-    (version "20151222")
+    (version "20160122")
     (source
      (origin
       (method url-fetch)
@@ -37,7 +50,7 @@
                           version ".tar.bz2"))
       (sha256
        (base32
-        "03czpnsj77xxzqxzzr1b39ym9acn94hknzbilbh28v5q1wk7r4mf"))))
+        "1xs8y8jh7wyjs27079xz0ja7xfi4dywz8d6hbkl44mafdnnfjfiy"))))
     (build-system gnu-build-system)
     (inputs `(("perl" ,perl)))
     (home-page "http://www.gnu.org/software/parallel/")
@@ -46,4 +59,65 @@
      "GNU Parallel is a tool for executing shell jobs in parallel using one
 or more computers.  Jobs can consist of single commands or of scripts
 and they are executed on lists of files, hosts, users or other items.")
-    (license gpl3+)))
+    (license license:gpl3+)))
+
+(define-public slurm
+  (package
+   (name "slurm")
+   (version "15.08.7.1")
+   (source (origin
+            (method url-fetch)
+            (uri (string-append
+                  "https://github.com/SchedMD/slurm/archive/slurm-"
+                  (string-join (string-split version #\.) "-") ".tar.gz"))
+            (file-name (string-append name "-" version ".tar.gz"))
+            (sha256
+             (base32
+              "1rmi35l4img00dr4vic8cv8s7b6n1yx1mkq2s7kjf5hvqdh6s2ki"))
+            (patches (list
+             (search-patch "slurm-configure-remove-nonfree-contribs.patch")))
+            (modules '((guix build utils)))
+            (snippet
+             '(begin
+                (delete-file-recursively "contribs")
+                #t))))
+   ;; FIXME: More optional inputs could be added,
+   ;; in particular mysql and gtk+.
+   (inputs `(("expect" ,expect)
+             ("freeipmi" ,freeipmi)
+             ("hwloc" ,hwloc)
+             ("json-c" ,json-c)
+             ("linux-pam" , linux-pam)
+             ("munge" ,munge)
+             ("numactl" ,numactl)
+             ("openssl" ,openssl)
+             ("perl" ,perl)
+             ("python" ,python-wrapper)
+             ("readline" ,readline)))
+   (native-inputs
+    `(("autoconf" ,autoconf)
+      ("pkg-config" ,pkg-config)))
+   (build-system gnu-build-system)
+   (arguments
+    `(#:configure-flags
+      (list "--enable-pam"
+            (string-append "--with-freeipmi=" (assoc-ref %build-inputs "freeipmi"))
+            (string-append "--with-hwloc=" (assoc-ref %build-inputs "hwloc"))
+            (string-append "--with-json=" (assoc-ref %build-inputs "json-c"))
+            (string-append "--with-munge=" (assoc-ref %build-inputs "munge"))
+            (string-append "--with-ssl=" (assoc-ref %build-inputs "openssl")))
+      #:phases
+      (modify-phases %standard-phases
+       (add-before
+        'configure 'autogen
+        (lambda _ (zero? (system* "autoconf"))))))) ; configure.ac was patched
+   (home-page "http://slurm.schedmd.com/")
+   (synopsis "Workload manager for cluster computing")
+   (description
+    "SLURM is a fault-tolerant and highly scalable cluster management and job
+scheduling system for large and small clusters.  It allocates access to
+resources (computer nodes) to users for some duration of time, provides a
+framework for starting, executing, and monitoring work (typically a parallel
+job) on a set of allocated nodes, and arbitrates contention for resources
+by managing a queue of pending work.")
+   (license license:gpl2+)))
diff --git a/gnu/packages/patches/cpio-CVE-2016-2037.patch b/gnu/packages/patches/cpio-CVE-2016-2037.patch
new file mode 100644
index 0000000000..f1e068fb45
--- /dev/null
+++ b/gnu/packages/patches/cpio-CVE-2016-2037.patch
@@ -0,0 +1,49 @@
+Fix CVE-2016-2037 (out of bounds write in process_copy_in()).
+
+Copied from upstream mailing list:
+https://lists.gnu.org/archive/html/bug-cpio/2016-01/msg00005.html
+
+---
+
+ Other calls to cpio_safer_name_suffix seem to be safe.
+ .
+ * src/copyin.c (process_copy_in):  Make sure that file_hdr.c_name
+ has at least two bytes allocated.
+ * src/util.c (cpio_safer_name_suffix): Document that use of this
+ function requires to be careful.
+Author: Pavel Raiskup <praiskup@redhat.com>
+
+---
+ src/copyin.c | 2 ++
+ src/util.c   | 5 ++++-
+ 2 files changed, 6 insertions(+), 1 deletion(-)
+
+Index: cpio-2.11+dfsg/src/copyin.c
+===================================================================
+--- cpio-2.11+dfsg.orig/src/copyin.c
++++ cpio-2.11+dfsg/src/copyin.c
+@@ -1433,6 +1433,8 @@ process_copy_in ()
+ 	  break;
+ 	}
+ 
++      if (file_hdr.c_namesize <= 1)
++        file_hdr.c_name = xrealloc(file_hdr.c_name, 2);
+       cpio_safer_name_suffix (file_hdr.c_name, false, !no_abs_paths_flag,
+ 			      false);
+       
+Index: cpio-2.11+dfsg/src/util.c
+===================================================================
+--- cpio-2.11+dfsg.orig/src/util.c
++++ cpio-2.11+dfsg/src/util.c
+@@ -1374,7 +1374,10 @@ set_file_times (int fd,
+ }
+ 
+ /* Do we have to ignore absolute paths, and if so, does the filename
+-   have an absolute path?  */
++   have an absolute path?
++   Before calling this function make sure that the allocated NAME buffer has
++   capacity at least 2 bytes to allow us to store the "." string inside.  */
++
+ void
+ cpio_safer_name_suffix (char *name, bool link_target, bool absolute_names,
+ 			bool strip_leading_dots)
diff --git a/gnu/packages/patches/glibc-CVE-2015-7547.patch b/gnu/packages/patches/glibc-CVE-2015-7547.patch
new file mode 100644
index 0000000000..9a0909af74
--- /dev/null
+++ b/gnu/packages/patches/glibc-CVE-2015-7547.patch
@@ -0,0 +1,559 @@
+Copied from Fedora:
+http://pkgs.fedoraproject.org/cgit/rpms/glibc.git/tree/glibc-CVE-2015-7547.patch?h=f23&id=9f1734eb6ce3257b788d6e9203572e8204c6c584
+
+Adapted to apply cleanly to glibc-2.22.
+
+Index: b/resolv/nss_dns/dns-host.c
+===================================================================
+--- a/resolv/nss_dns/dns-host.c
++++ b/resolv/nss_dns/dns-host.c
+@@ -1031,7 +1031,10 @@ gaih_getanswer_slice (const querybuf *an
+   int h_namelen = 0;
+ 
+   if (ancount == 0)
+-    return NSS_STATUS_NOTFOUND;
++    {
++      *h_errnop = HOST_NOT_FOUND;
++      return NSS_STATUS_NOTFOUND;
++    }
+ 
+   while (ancount-- > 0 && cp < end_of_message && had_error == 0)
+     {
+@@ -1208,7 +1211,14 @@ gaih_getanswer_slice (const querybuf *an
+   /* Special case here: if the resolver sent a result but it only
+      contains a CNAME while we are looking for a T_A or T_AAAA record,
+      we fail with NOTFOUND instead of TRYAGAIN.  */
+-  return canon == NULL ? NSS_STATUS_TRYAGAIN : NSS_STATUS_NOTFOUND;
++  if (canon != NULL)
++    {
++      *h_errnop = HOST_NOT_FOUND;
++      return NSS_STATUS_NOTFOUND;
++    }
++
++  *h_errnop = NETDB_INTERNAL;
++  return NSS_STATUS_TRYAGAIN;
+ }
+ 
+ 
+@@ -1222,11 +1232,101 @@ gaih_getanswer (const querybuf *answer1,
+ 
+   enum nss_status status = NSS_STATUS_NOTFOUND;
+ 
++  /* Combining the NSS status of two distinct queries requires some
++     compromise and attention to symmetry (A or AAAA queries can be
++     returned in any order).  What follows is a breakdown of how this
++     code is expected to work and why. We discuss only SUCCESS,
++     TRYAGAIN, NOTFOUND and UNAVAIL, since they are the only returns
++     that apply (though RETURN and MERGE exist).  We make a distinction
++     between TRYAGAIN (recoverable) and TRYAGAIN' (not-recoverable).
++     A recoverable TRYAGAIN is almost always due to buffer size issues
++     and returns ERANGE in errno and the caller is expected to retry
++     with a larger buffer.
++
++     Lastly, you may be tempted to make significant changes to the
++     conditions in this code to bring about symmetry between responses.
++     Please don't change anything without due consideration for
++     expected application behaviour.  Some of the synthesized responses
++     aren't very well thought out and sometimes appear to imply that
++     IPv4 responses are always answer 1, and IPv6 responses are always
++     answer 2, but that's not true (see the implemetnation of send_dg
++     and send_vc to see response can arrive in any order, particlarly
++     for UDP). However, we expect it holds roughly enough of the time
++     that this code works, but certainly needs to be fixed to make this
++     a more robust implementation.
++
++     ----------------------------------------------
++     | Answer 1 Status /   | Synthesized | Reason |
++     | Answer 2 Status     | Status      |        |
++     |--------------------------------------------|
++     | SUCCESS/SUCCESS     | SUCCESS     | [1]    |
++     | SUCCESS/TRYAGAIN    | TRYAGAIN    | [5]    |
++     | SUCCESS/TRYAGAIN'   | SUCCESS     | [1]    |
++     | SUCCESS/NOTFOUND    | SUCCESS     | [1]    |
++     | SUCCESS/UNAVAIL     | SUCCESS     | [1]    |
++     | TRYAGAIN/SUCCESS    | TRYAGAIN    | [2]    |
++     | TRYAGAIN/TRYAGAIN   | TRYAGAIN    | [2]    |
++     | TRYAGAIN/TRYAGAIN'  | TRYAGAIN    | [2]    |
++     | TRYAGAIN/NOTFOUND   | TRYAGAIN    | [2]    |
++     | TRYAGAIN/UNAVAIL    | TRYAGAIN    | [2]    |
++     | TRYAGAIN'/SUCCESS   | SUCCESS     | [3]    |
++     | TRYAGAIN'/TRYAGAIN  | TRYAGAIN    | [3]    |
++     | TRYAGAIN'/TRYAGAIN' | TRYAGAIN'   | [3]    |
++     | TRYAGAIN'/NOTFOUND  | TRYAGAIN'   | [3]    |
++     | TRYAGAIN'/UNAVAIL   | UNAVAIL     | [3]    |
++     | NOTFOUND/SUCCESS    | SUCCESS     | [3]    |
++     | NOTFOUND/TRYAGAIN   | TRYAGAIN    | [3]    |
++     | NOTFOUND/TRYAGAIN'  | TRYAGAIN'   | [3]    |
++     | NOTFOUND/NOTFOUND   | NOTFOUND    | [3]    |
++     | NOTFOUND/UNAVAIL    | UNAVAIL     | [3]    |
++     | UNAVAIL/SUCCESS     | UNAVAIL     | [4]    |
++     | UNAVAIL/TRYAGAIN    | UNAVAIL     | [4]    |
++     | UNAVAIL/TRYAGAIN'   | UNAVAIL     | [4]    |
++     | UNAVAIL/NOTFOUND    | UNAVAIL     | [4]    |
++     | UNAVAIL/UNAVAIL     | UNAVAIL     | [4]    |
++     ----------------------------------------------
++
++     [1] If the first response is a success we return success.
++         This ignores the state of the second answer and in fact
++         incorrectly sets errno and h_errno to that of the second
++	 answer.  However because the response is a success we ignore
++	 *errnop and *h_errnop (though that means you touched errno on
++         success).  We are being conservative here and returning the
++         likely IPv4 response in the first answer as a success.
++
++     [2] If the first response is a recoverable TRYAGAIN we return
++	 that instead of looking at the second response.  The
++	 expectation here is that we have failed to get an IPv4 response
++	 and should retry both queries.
++
++     [3] If the first response was not a SUCCESS and the second
++	 response is not NOTFOUND (had a SUCCESS, need to TRYAGAIN,
++	 or failed entirely e.g. TRYAGAIN' and UNAVAIL) then use the
++	 result from the second response, otherwise the first responses
++	 status is used.  Again we have some odd side-effects when the
++	 second response is NOTFOUND because we overwrite *errnop and
++	 *h_errnop that means that a first answer of NOTFOUND might see
++	 its *errnop and *h_errnop values altered.  Whether it matters
++	 in practice that a first response NOTFOUND has the wrong
++	 *errnop and *h_errnop is undecided.
++
++     [4] If the first response is UNAVAIL we return that instead of
++	 looking at the second response.  The expectation here is that
++	 it will have failed similarly e.g. configuration failure.
++
++     [5] Testing this code is complicated by the fact that truncated
++	 second response buffers might be returned as SUCCESS if the
++	 first answer is a SUCCESS.  To fix this we add symmetry to
++	 TRYAGAIN with the second response.  If the second response
++	 is a recoverable error we now return TRYAGIN even if the first
++	 response was SUCCESS.  */
++
+   if (anslen1 > 0)
+     status = gaih_getanswer_slice(answer1, anslen1, qname,
+ 				  &pat, &buffer, &buflen,
+ 				  errnop, h_errnop, ttlp,
+ 				  &first);
++
+   if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
+        || (status == NSS_STATUS_TRYAGAIN
+ 	   /* We want to look at the second answer in case of an
+@@ -1242,8 +1342,15 @@ gaih_getanswer (const querybuf *answer1,
+ 						     &pat, &buffer, &buflen,
+ 						     errnop, h_errnop, ttlp,
+ 						     &first);
++      /* Use the second response status in some cases.  */
+       if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
+ 	status = status2;
++      /* Do not return a truncated second response (unless it was
++         unavoidable e.g. unrecoverable TRYAGAIN).  */
++      if (status == NSS_STATUS_SUCCESS
++	  && (status2 == NSS_STATUS_TRYAGAIN
++	      && *errnop == ERANGE && *h_errnop != NO_RECOVERY))
++	status = NSS_STATUS_TRYAGAIN;
+     }
+ 
+   return status;
+Index: b/resolv/res_query.c
+===================================================================
+--- a/resolv/res_query.c
++++ b/resolv/res_query.c
+@@ -396,6 +396,7 @@ __libc_res_nsearch(res_state statp,
+ 		  {
+ 		    free (*answerp2);
+ 		    *answerp2 = NULL;
++		    *nanswerp2 = 0;
+ 		    *answerp2_malloced = 0;
+ 		  }
+ 	}
+@@ -447,6 +448,7 @@ __libc_res_nsearch(res_state statp,
+ 			  {
+ 			    free (*answerp2);
+ 			    *answerp2 = NULL;
++			    *nanswerp2 = 0;
+ 			    *answerp2_malloced = 0;
+ 			  }
+ 
+@@ -521,6 +523,7 @@ __libc_res_nsearch(res_state statp,
+ 	  {
+ 	    free (*answerp2);
+ 	    *answerp2 = NULL;
++	    *nanswerp2 = 0;
+ 	    *answerp2_malloced = 0;
+ 	  }
+ 	if (saved_herrno != -1)
+Index: b/resolv/res_send.c
+===================================================================
+--- a/resolv/res_send.c
++++ b/resolv/res_send.c
+@@ -1,3 +1,20 @@
++/* Copyright (C) 2016 Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library 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
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, see
++   <http://www.gnu.org/licenses/>.  */
++
+ /*
+  * Copyright (c) 1985, 1989, 1993
+  *    The Regents of the University of California.  All rights reserved.
+@@ -361,6 +378,8 @@ __libc_res_nsend(res_state statp, const
+ #ifdef USE_HOOKS
+ 	if (__glibc_unlikely (statp->qhook || statp->rhook))       {
+ 		if (anssiz < MAXPACKET && ansp) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *buf = malloc (MAXPACKET);
+ 			if (buf == NULL)
+ 				return (-1);
+@@ -660,6 +679,77 @@ libresolv_hidden_def (res_nsend)
+ 
+ /* Private */
+ 
++/* The send_vc function is responsible for sending a DNS query over TCP
++   to the nameserver numbered NS from the res_state STATP i.e.
++   EXT(statp).nssocks[ns].  The function supports sending both IPv4 and
++   IPv6 queries at the same serially on the same socket.
++
++   Please note that for TCP there is no way to disable sending both
++   queries, unlike UDP, which honours RES_SNGLKUP and RES_SNGLKUPREOP
++   and sends the queries serially and waits for the result after each
++   sent query.  This implemetnation should be corrected to honour these
++   options.
++
++   Please also note that for TCP we send both queries over the same
++   socket one after another.  This technically violates best practice
++   since the server is allowed to read the first query, respond, and
++   then close the socket (to service another client).  If the server
++   does this, then the remaining second query in the socket data buffer
++   will cause the server to send the client an RST which will arrive
++   asynchronously and the client's OS will likely tear down the socket
++   receive buffer resulting in a potentially short read and lost
++   response data.  This will force the client to retry the query again,
++   and this process may repeat until all servers and connection resets
++   are exhausted and then the query will fail.  It's not known if this
++   happens with any frequency in real DNS server implementations.  This
++   implementation should be corrected to use two sockets by default for
++   parallel queries.
++
++   The query stored in BUF of BUFLEN length is sent first followed by
++   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
++   serially on the same socket.
++
++   Answers to the query are stored firstly in *ANSP up to a max of
++   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
++   is non-NULL (to indicate that modifying the answer buffer is allowed)
++   then malloc is used to allocate a new response buffer and ANSCP and
++   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
++   are needed but ANSCP is NULL, then as much of the response as
++   possible is read into the buffer, but the results will be truncated.
++   When truncation happens because of a small answer buffer the DNS
++   packets header feild TC will bet set to 1, indicating a truncated
++   message and the rest of the socket data will be read and discarded.
++
++   Answers to the query are stored secondly in *ANSP2 up to a max of
++   *ANSSIZP2 bytes, with the actual response length stored in
++   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
++   is non-NULL (required for a second query) then malloc is used to
++   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
++   size and *ANSP2_MALLOCED is set to 1.
++
++   The ANSP2_MALLOCED argument will eventually be removed as the
++   change in buffer pointer can be used to detect the buffer has
++   changed and that the caller should use free on the new buffer.
++
++   Note that the answers may arrive in any order from the server and
++   therefore the first and second answer buffers may not correspond to
++   the first and second queries.
++
++   It is not supported to call this function with a non-NULL ANSP2
++   but a NULL ANSCP.  Put another way, you can call send_vc with a
++   single unmodifiable buffer or two modifiable buffers, but no other
++   combination is supported.
++
++   It is the caller's responsibility to free the malloc allocated
++   buffers by detecting that the pointers have changed from their
++   original values i.e. *ANSCP or *ANSP2 has changed.
++
++   If errors are encountered then *TERRNO is set to an appropriate
++   errno value and a zero result is returned for a recoverable error,
++   and a less-than zero result is returned for a non-recoverable error.
++
++   If no errors are encountered then *TERRNO is left unmodified and
++   a the length of the first response in bytes is returned.  */
+ static int
+ send_vc(res_state statp,
+ 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+@@ -669,11 +759,7 @@ send_vc(res_state statp,
+ {
+ 	const HEADER *hp = (HEADER *) buf;
+ 	const HEADER *hp2 = (HEADER *) buf2;
+-	u_char *ans = *ansp;
+-	int orig_anssizp = *anssizp;
+-	// XXX REMOVE
+-	// int anssiz = *anssizp;
+-	HEADER *anhp = (HEADER *) ans;
++	HEADER *anhp = (HEADER *) *ansp;
+ 	struct sockaddr *nsap = get_nsaddr (statp, ns);
+ 	int truncating, connreset, n;
+ 	/* On some architectures compiler might emit a warning indicating
+@@ -766,6 +852,8 @@ send_vc(res_state statp,
+ 	 * Receive length & response
+ 	 */
+ 	int recvresp1 = 0;
++	/* Skip the second response if there is no second query.
++           To do that we mark the second response as received.  */
+ 	int recvresp2 = buf2 == NULL;
+ 	uint16_t rlen16;
+  read_len:
+@@ -802,40 +890,14 @@ send_vc(res_state statp,
+ 	u_char **thisansp;
+ 	int *thisresplenp;
+ 	if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
++		/* We have not received any responses
++		   yet or we only have one response to
++		   receive.  */
+ 		thisanssizp = anssizp;
+ 		thisansp = anscp ?: ansp;
+ 		assert (anscp != NULL || ansp2 == NULL);
+ 		thisresplenp = &resplen;
+ 	} else {
+-		if (*anssizp != MAXPACKET) {
+-			/* No buffer allocated for the first
+-			   reply.  We can try to use the rest
+-			   of the user-provided buffer.  */
+-#if __GNUC_PREREQ (4, 7)
+-			DIAG_PUSH_NEEDS_COMMENT;
+-			DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
+-#endif
+-#if _STRING_ARCH_unaligned
+-			*anssizp2 = orig_anssizp - resplen;
+-			*ansp2 = *ansp + resplen;
+-#else
+-			int aligned_resplen
+-			  = ((resplen + __alignof__ (HEADER) - 1)
+-			     & ~(__alignof__ (HEADER) - 1));
+-			*anssizp2 = orig_anssizp - aligned_resplen;
+-			*ansp2 = *ansp + aligned_resplen;
+-#endif
+-#if __GNUC_PREREQ (4, 7)
+-			DIAG_POP_NEEDS_COMMENT;
+-#endif
+-		} else {
+-			/* The first reply did not fit into the
+-			   user-provided buffer.  Maybe the second
+-			   answer will.  */
+-			*anssizp2 = orig_anssizp;
+-			*ansp2 = *ansp;
+-		}
+-
+ 		thisanssizp = anssizp2;
+ 		thisansp = ansp2;
+ 		thisresplenp = resplen2;
+@@ -843,10 +905,14 @@ send_vc(res_state statp,
+ 	anhp = (HEADER *) *thisansp;
+ 
+ 	*thisresplenp = rlen;
+-	if (rlen > *thisanssizp) {
+-		/* Yes, we test ANSCP here.  If we have two buffers
+-		   both will be allocatable.  */
+-		if (__glibc_likely (anscp != NULL))       {
++	/* Is the answer buffer too small?  */
++	if (*thisanssizp < rlen) {
++		/* If the current buffer is non-NULL and it's not
++		   pointing at the static user-supplied buffer then
++		   we can reallocate it.  */
++		if (thisansp != NULL && thisansp != ansp) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *newp = malloc (MAXPACKET);
+ 			if (newp == NULL) {
+ 				*terrno = ENOMEM;
+@@ -858,6 +924,9 @@ send_vc(res_state statp,
+ 			if (thisansp == ansp2)
+ 			  *ansp2_malloced = 1;
+ 			anhp = (HEADER *) newp;
++			/* A uint16_t can't be larger than MAXPACKET
++			   thus it's safe to allocate MAXPACKET but
++			   read RLEN bytes instead.  */
+ 			len = rlen;
+ 		} else {
+ 			Dprint(statp->options & RES_DEBUG,
+@@ -1021,6 +1090,66 @@ reopen (res_state statp, int *terrno, in
+ 	return 1;
+ }
+ 
++/* The send_dg function is responsible for sending a DNS query over UDP
++   to the nameserver numbered NS from the res_state STATP i.e.
++   EXT(statp).nssocks[ns].  The function supports IPv4 and IPv6 queries
++   along with the ability to send the query in parallel for both stacks
++   (default) or serially (RES_SINGLKUP).  It also supports serial lookup
++   with a close and reopen of the socket used to talk to the server
++   (RES_SNGLKUPREOP) to work around broken name servers.
++
++   The query stored in BUF of BUFLEN length is sent first followed by
++   the query stored in BUF2 of BUFLEN2 length.  Queries are sent
++   in parallel (default) or serially (RES_SINGLKUP or RES_SNGLKUPREOP).
++
++   Answers to the query are stored firstly in *ANSP up to a max of
++   *ANSSIZP bytes.  If more than *ANSSIZP bytes are needed and ANSCP
++   is non-NULL (to indicate that modifying the answer buffer is allowed)
++   then malloc is used to allocate a new response buffer and ANSCP and
++   ANSP will both point to the new buffer.  If more than *ANSSIZP bytes
++   are needed but ANSCP is NULL, then as much of the response as
++   possible is read into the buffer, but the results will be truncated.
++   When truncation happens because of a small answer buffer the DNS
++   packets header feild TC will bet set to 1, indicating a truncated
++   message, while the rest of the UDP packet is discarded.
++
++   Answers to the query are stored secondly in *ANSP2 up to a max of
++   *ANSSIZP2 bytes, with the actual response length stored in
++   *RESPLEN2.  If more than *ANSSIZP bytes are needed and ANSP2
++   is non-NULL (required for a second query) then malloc is used to
++   allocate a new response buffer, *ANSSIZP2 is set to the new buffer
++   size and *ANSP2_MALLOCED is set to 1.
++
++   The ANSP2_MALLOCED argument will eventually be removed as the
++   change in buffer pointer can be used to detect the buffer has
++   changed and that the caller should use free on the new buffer.
++
++   Note that the answers may arrive in any order from the server and
++   therefore the first and second answer buffers may not correspond to
++   the first and second queries.
++
++   It is not supported to call this function with a non-NULL ANSP2
++   but a NULL ANSCP.  Put another way, you can call send_vc with a
++   single unmodifiable buffer or two modifiable buffers, but no other
++   combination is supported.
++
++   It is the caller's responsibility to free the malloc allocated
++   buffers by detecting that the pointers have changed from their
++   original values i.e. *ANSCP or *ANSP2 has changed.
++
++   If an answer is truncated because of UDP datagram DNS limits then
++   *V_CIRCUIT is set to 1 and the return value non-zero to indicate to
++   the caller to retry with TCP.  The value *GOTSOMEWHERE is set to 1
++   if any progress was made reading a response from the nameserver and
++   is used by the caller to distinguish between ECONNREFUSED and
++   ETIMEDOUT (the latter if *GOTSOMEWHERE is 1).
++
++   If errors are encountered then *TERRNO is set to an appropriate
++   errno value and a zero result is returned for a recoverable error,
++   and a less-than zero result is returned for a non-recoverable error.
++
++   If no errors are encountered then *TERRNO is left unmodified and
++   a the length of the first response in bytes is returned.  */
+ static int
+ send_dg(res_state statp,
+ 	const u_char *buf, int buflen, const u_char *buf2, int buflen2,
+@@ -1030,8 +1159,6 @@ send_dg(res_state statp,
+ {
+ 	const HEADER *hp = (HEADER *) buf;
+ 	const HEADER *hp2 = (HEADER *) buf2;
+-	u_char *ans = *ansp;
+-	int orig_anssizp = *anssizp;
+ 	struct timespec now, timeout, finish;
+ 	struct pollfd pfd[1];
+ 	int ptimeout;
+@@ -1064,6 +1191,8 @@ send_dg(res_state statp,
+ 	int need_recompute = 0;
+ 	int nwritten = 0;
+ 	int recvresp1 = 0;
++	/* Skip the second response if there is no second query.
++           To do that we mark the second response as received.  */
+ 	int recvresp2 = buf2 == NULL;
+ 	pfd[0].fd = EXT(statp).nssocks[ns];
+ 	pfd[0].events = POLLOUT;
+@@ -1227,55 +1356,56 @@ send_dg(res_state statp,
+ 		int *thisresplenp;
+ 
+ 		if ((recvresp1 | recvresp2) == 0 || buf2 == NULL) {
++			/* We have not received any responses
++			   yet or we only have one response to
++			   receive.  */
+ 			thisanssizp = anssizp;
+ 			thisansp = anscp ?: ansp;
+ 			assert (anscp != NULL || ansp2 == NULL);
+ 			thisresplenp = &resplen;
+ 		} else {
+-			if (*anssizp != MAXPACKET) {
+-				/* No buffer allocated for the first
+-				   reply.  We can try to use the rest
+-				   of the user-provided buffer.  */
+-#if _STRING_ARCH_unaligned
+-				*anssizp2 = orig_anssizp - resplen;
+-				*ansp2 = *ansp + resplen;
+-#else
+-				int aligned_resplen
+-				  = ((resplen + __alignof__ (HEADER) - 1)
+-				     & ~(__alignof__ (HEADER) - 1));
+-				*anssizp2 = orig_anssizp - aligned_resplen;
+-				*ansp2 = *ansp + aligned_resplen;
+-#endif
+-			} else {
+-				/* The first reply did not fit into the
+-				   user-provided buffer.  Maybe the second
+-				   answer will.  */
+-				*anssizp2 = orig_anssizp;
+-				*ansp2 = *ansp;
+-			}
+-
+ 			thisanssizp = anssizp2;
+ 			thisansp = ansp2;
+ 			thisresplenp = resplen2;
+ 		}
+ 
+ 		if (*thisanssizp < MAXPACKET
+-		    /* Yes, we test ANSCP here.  If we have two buffers
+-		       both will be allocatable.  */
+-		    && anscp
++		    /* If the current buffer is non-NULL and it's not
++		       pointing at the static user-supplied buffer then
++		       we can reallocate it.  */
++		    && (thisansp != NULL && thisansp != ansp)
+ #ifdef FIONREAD
++		    /* Is the size too small?  */
+ 		    && (ioctl (pfd[0].fd, FIONREAD, thisresplenp) < 0
+ 			|| *thisanssizp < *thisresplenp)
+ #endif
+                     ) {
++			/* Always allocate MAXPACKET, callers expect
++			   this specific size.  */
+ 			u_char *newp = malloc (MAXPACKET);
+ 			if (newp != NULL) {
+-				*anssizp = MAXPACKET;
+-				*thisansp = ans = newp;
++				*thisanssizp = MAXPACKET;
++				*thisansp = newp;
+ 				if (thisansp == ansp2)
+ 				  *ansp2_malloced = 1;
+ 			}
+ 		}
++		/* We could end up with truncation if anscp was NULL
++		   (not allowed to change caller's buffer) and the
++		   response buffer size is too small.  This isn't a
++		   reliable way to detect truncation because the ioctl
++		   may be an inaccurate report of the UDP message size.
++		   Therefore we use this only to issue debug output.
++		   To do truncation accurately with UDP we need
++		   MSG_TRUNC which is only available on Linux.  We
++		   can abstract out the Linux-specific feature in the
++		   future to detect truncation.  */
++		if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
++			Dprint(statp->options & RES_DEBUG,
++			       (stdout, ";; response may be truncated (UDP)\n")
++			);
++		}
++
+ 		HEADER *anhp = (HEADER *) *thisansp;
+ 		socklen_t fromlen = sizeof(struct sockaddr_in6);
+ 		assert (sizeof(from) <= fromlen);
diff --git a/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch b/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch
new file mode 100644
index 0000000000..153f71c38f
--- /dev/null
+++ b/gnu/packages/patches/gnupg-simple-query-ignore-status-messages.patch
@@ -0,0 +1,142 @@
+Copied from upstream:
+http://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commitdiff;h=acac103ba5772ae738ce5409d17feab80596cde6
+
+Fixes: https://debbugs.gnu.org/22558
+Upstream bug: https://bugs.gnupg.org/gnupg/issue2229
+
+From acac103ba5772ae738ce5409d17feab80596cde6 Mon Sep 17 00:00:00 2001
+From: "Neal H. Walfield" <neal@g10code.com>
+Date: Fri, 12 Feb 2016 22:12:21 +0100
+Subject: [PATCH] common: Change simple_query to ignore status messages.
+
+* common/simple-pwquery.c (simple_query): Ignore status messages.
+
+--
+Signed-off-by: Neal H. Walfield <neal@g10code.com>
+GnuPG-bug-id: 2229
+---
+ common/simple-pwquery.c | 95 ++++++++++++++++++++++++++++++++++---------------
+ 1 file changed, 67 insertions(+), 28 deletions(-)
+
+diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c
+index 90d04c0..b2d666c 100644
+--- a/common/simple-pwquery.c
++++ b/common/simple-pwquery.c
+@@ -618,6 +618,7 @@ simple_query (const char *query)
+   int fd = -1;
+   int nread;
+   char response[500];
++  int have = 0;
+   int rc;
+ 
+   rc = agent_open (&fd);
+@@ -628,40 +629,78 @@ simple_query (const char *query)
+   if (rc)
+     goto leave;
+ 
+-  /* get response */
+-  nread = readline (fd, response, 499);
+-  if (nread < 0)
+-    {
+-      rc = -nread;
+-      goto leave;
+-    }
+-  if (nread < 3)
++  while (1)
+     {
+-      rc = SPWQ_PROTOCOL_ERROR;
+-      goto leave;
+-    }
++      if (! have || ! strchr (response, '\n'))
++        /* get response */
++        {
++          nread = readline (fd, &response[have],
++                            sizeof (response) - 1 /* NUL */ - have);
++          if (nread < 0)
++            {
++              rc = -nread;
++              goto leave;
++            }
++          have += nread;
++          if (have < 3)
++            {
++              rc = SPWQ_PROTOCOL_ERROR;
++              goto leave;
++            }
++          response[have] = 0;
++        }
+ 
+-  if (response[0] == 'O' && response[1] == 'K')
+-    /* OK, do nothing.  */;
+-  else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
+-            && (response[7] == ' ' || response[7] == '\n') )
+-           || ((nread > 4 && !memcmp (response, "ERR ", 4)
+-                && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
+-    {
+-      /* 111 is the old Assuan code for canceled which might still
+-         be in use by old installations. 99 is GPG_ERR_CANCELED as
+-         used by modern gpg-agents; 0xffff is used to mask out the
+-         error source.  */
++      if (response[0] == 'O' && response[1] == 'K')
++        /* OK, do nothing.  */;
++      else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
++                && (response[7] == ' ' || response[7] == '\n') )
++               || ((nread > 4 && !memcmp (response, "ERR ", 4)
++                    && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
++        {
++          /* 111 is the old Assuan code for canceled which might still
++             be in use by old installations. 99 is GPG_ERR_CANCELED as
++             used by modern gpg-agents; 0xffff is used to mask out the
++             error source.  */
+ #ifdef SPWQ_USE_LOGGING
+-      log_info (_("canceled by user\n") );
++          log_info (_("canceled by user\n") );
+ #endif
+-    }
+-  else
+-    {
++        }
++      else if (response[0] == 'S' && response[1] == ' ')
++        {
++          char *nextline;
++          int consumed;
++
++          nextline = strchr (response, '\n');
++          if (! nextline)
++            /* Point to the NUL.  */
++            nextline = &response[have];
++          else
++            /* Move past the \n.  */
++            nextline ++;
++
++          consumed = (size_t) nextline - (size_t) response;
++
++          /* Skip any additional newlines.  */
++          while (consumed < have && response[consumed] == '\n')
++            consumed ++;
++
++          have -= consumed;
++
++          if (have)
++            memmove (response, &response[consumed], have + 1);
++
++          continue;
++        }
++      else
++        {
+ #ifdef SPWQ_USE_LOGGING
+-      log_error (_("problem with the agent\n"));
++          log_error (_("problem with the agent (unexpected response \"%s\"\n"),
++                     response);
+ #endif
+-      rc = SPWQ_ERR_RESPONSE;
++          rc = SPWQ_ERR_RESPONSE;
++        }
++
++      break;
+     }
+ 
+  leave:
+-- 
+2.6.3
+
diff --git a/gnu/packages/patches/icecat-update-graphite2.patch b/gnu/packages/patches/icecat-update-graphite2.patch
new file mode 100644
index 0000000000..af2c47bef7
--- /dev/null
+++ b/gnu/packages/patches/icecat-update-graphite2.patch
@@ -0,0 +1,9988 @@
+Copied from upstream:
+https://hg.mozilla.org/releases/mozilla-esr38/raw-rev/ed4d2ce6046b
+
+# HG changeset patch
+# User Jonathan Kew <jkew@mozilla.com>
+# Date 1455126706 0
+# Node ID ed4d2ce6046b20287fd13c548dd3982fe1a24875
+# Parent  78d3632feb7b6f6046025352630bd4f5365f3106
+Bug 1246093 - Update graphite2 library to latest release on esr38. r=me,a=sledru+lizzard
+
+diff --git a/gfx/graphite2/COPYING b/gfx/graphite2/COPYING
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/COPYING
+@@ -0,0 +1,26 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++    Alternatively, you may use this library under the terms of the Mozilla
++    Public License (http://mozilla.org/MPL) or under the GNU General Public
++    License, as published by the Free Sofware Foundation; either version
++    2 of the license or (at your option) any later version.
++*/
+diff --git a/gfx/graphite2/LICENSE b/gfx/graphite2/LICENSE
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/LICENSE
+@@ -0,0 +1,510 @@
++
++                  GNU LESSER GENERAL PUBLIC LICENSE
++                       Version 2.1, February 1999
++
++ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
++	51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++ Everyone is permitted to copy and distribute verbatim copies
++ of this license document, but changing it is not allowed.
++
++[This is the first released version of the Lesser GPL.  It also counts
++ as the successor of the GNU Library Public License, version 2, hence
++ the version number 2.1.]
++
++                            Preamble
++
++  The licenses for most software are designed to take away your
++freedom to share and change it.  By contrast, the GNU General Public
++Licenses are intended to guarantee your freedom to share and change
++free software--to make sure the software is free for all its users.
++
++  This license, the Lesser General Public License, applies to some
++specially designated software packages--typically libraries--of the
++Free Software Foundation and other authors who decide to use it.  You
++can use it too, but we suggest you first think carefully about whether
++this license or the ordinary General Public License is the better
++strategy to use in any particular case, based on the explanations
++below.
++
++  When we speak of free software, we are referring to freedom of use,
++not price.  Our General Public Licenses are designed to make sure that
++you have the freedom to distribute copies of free software (and charge
++for this service if you wish); that you receive source code or can get
++it if you want it; that you can change the software and use pieces of
++it in new free programs; and that you are informed that you can do
++these things.
++
++  To protect your rights, we need to make restrictions that forbid
++distributors to deny you these rights or to ask you to surrender these
++rights.  These restrictions translate to certain responsibilities for
++you if you distribute copies of the library or if you modify it.
++
++  For example, if you distribute copies of the library, whether gratis
++or for a fee, you must give the recipients all the rights that we gave
++you.  You must make sure that they, too, receive or can get the source
++code.  If you link other code with the library, you must provide
++complete object files to the recipients, so that they can relink them
++with the library after making changes to the library and recompiling
++it.  And you must show them these terms so they know their rights.
++
++  We protect your rights with a two-step method: (1) we copyright the
++library, and (2) we offer you this license, which gives you legal
++permission to copy, distribute and/or modify the library.
++
++  To protect each distributor, we want to make it very clear that
++there is no warranty for the free library.  Also, if the library is
++modified by someone else and passed on, the recipients should know
++that what they have is not the original version, so that the original
++author's reputation will not be affected by problems that might be
++introduced by others.
++
++  Finally, software patents pose a constant threat to the existence of
++any free program.  We wish to make sure that a company cannot
++effectively restrict the users of a free program by obtaining a
++restrictive license from a patent holder.  Therefore, we insist that
++any patent license obtained for a version of the library must be
++consistent with the full freedom of use specified in this license.
++
++  Most GNU software, including some libraries, is covered by the
++ordinary GNU General Public License.  This license, the GNU Lesser
++General Public License, applies to certain designated libraries, and
++is quite different from the ordinary General Public License.  We use
++this license for certain libraries in order to permit linking those
++libraries into non-free programs.
++
++  When a program is linked with a library, whether statically or using
++a shared library, the combination of the two is legally speaking a
++combined work, a derivative of the original library.  The ordinary
++General Public License therefore permits such linking only if the
++entire combination fits its criteria of freedom.  The Lesser General
++Public License permits more lax criteria for linking other code with
++the library.
++
++  We call this license the "Lesser" General Public License because it
++does Less to protect the user's freedom than the ordinary General
++Public License.  It also provides other free software developers Less
++of an advantage over competing non-free programs.  These disadvantages
++are the reason we use the ordinary General Public License for many
++libraries.  However, the Lesser license provides advantages in certain
++special circumstances.
++
++  For example, on rare occasions, there may be a special need to
++encourage the widest possible use of a certain library, so that it
++becomes a de-facto standard.  To achieve this, non-free programs must
++be allowed to use the library.  A more frequent case is that a free
++library does the same job as widely used non-free libraries.  In this
++case, there is little to gain by limiting the free library to free
++software only, so we use the Lesser General Public License.
++
++  In other cases, permission to use a particular library in non-free
++programs enables a greater number of people to use a large body of
++free software.  For example, permission to use the GNU C Library in
++non-free programs enables many more people to use the whole GNU
++operating system, as well as its variant, the GNU/Linux operating
++system.
++
++  Although the Lesser General Public License is Less protective of the
++users' freedom, it does ensure that the user of a program that is
++linked with the Library has the freedom and the wherewithal to run
++that program using a modified version of the Library.
++
++  The precise terms and conditions for copying, distribution and
++modification follow.  Pay close attention to the difference between a
++"work based on the library" and a "work that uses the library".  The
++former contains code derived from the library, whereas the latter must
++be combined with the library in order to run.
++
++                  GNU LESSER GENERAL PUBLIC LICENSE
++   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
++
++  0. This License Agreement applies to any software library or other
++program which contains a notice placed by the copyright holder or
++other authorized party saying it may be distributed under the terms of
++this Lesser General Public License (also called "this License").
++Each licensee is addressed as "you".
++
++  A "library" means a collection of software functions and/or data
++prepared so as to be conveniently linked with application programs
++(which use some of those functions and data) to form executables.
++
++  The "Library", below, refers to any such software library or work
++which has been distributed under these terms.  A "work based on the
++Library" means either the Library or any derivative work under
++copyright law: that is to say, a work containing the Library or a
++portion of it, either verbatim or with modifications and/or translated
++straightforwardly into another language.  (Hereinafter, translation is
++included without limitation in the term "modification".)
++
++  "Source code" for a work means the preferred form of the work for
++making modifications to it.  For a library, complete source code means
++all the source code for all modules it contains, plus any associated
++interface definition files, plus the scripts used to control
++compilation and installation of the library.
++
++  Activities other than copying, distribution and modification are not
++covered by this License; they are outside its scope.  The act of
++running a program using the Library is not restricted, and output from
++such a program is covered only if its contents constitute a work based
++on the Library (independent of the use of the Library in a tool for
++writing it).  Whether that is true depends on what the Library does
++and what the program that uses the Library does.
++
++  1. You may copy and distribute verbatim copies of the Library's
++complete source code as you receive it, in any medium, provided that
++you conspicuously and appropriately publish on each copy an
++appropriate copyright notice and disclaimer of warranty; keep intact
++all the notices that refer to this License and to the absence of any
++warranty; and distribute a copy of this License along with the
++Library.
++
++  You may charge a fee for the physical act of transferring a copy,
++and you may at your option offer warranty protection in exchange for a
++fee.
++
++  2. You may modify your copy or copies of the Library or any portion
++of it, thus forming a work based on the Library, and copy and
++distribute such modifications or work under the terms of Section 1
++above, provided that you also meet all of these conditions:
++
++    a) The modified work must itself be a software library.
++
++    b) You must cause the files modified to carry prominent notices
++    stating that you changed the files and the date of any change.
++
++    c) You must cause the whole of the work to be licensed at no
++    charge to all third parties under the terms of this License.
++
++    d) If a facility in the modified Library refers to a function or a
++    table of data to be supplied by an application program that uses
++    the facility, other than as an argument passed when the facility
++    is invoked, then you must make a good faith effort to ensure that,
++    in the event an application does not supply such function or
++    table, the facility still operates, and performs whatever part of
++    its purpose remains meaningful.
++
++    (For example, a function in a library to compute square roots has
++    a purpose that is entirely well-defined independent of the
++    application.  Therefore, Subsection 2d requires that any
++    application-supplied function or table used by this function must
++    be optional: if the application does not supply it, the square
++    root function must still compute square roots.)
++
++These requirements apply to the modified work as a whole.  If
++identifiable sections of that work are not derived from the Library,
++and can be reasonably considered independent and separate works in
++themselves, then this License, and its terms, do not apply to those
++sections when you distribute them as separate works.  But when you
++distribute the same sections as part of a whole which is a work based
++on the Library, the distribution of the whole must be on the terms of
++this License, whose permissions for other licensees extend to the
++entire whole, and thus to each and every part regardless of who wrote
++it.
++
++Thus, it is not the intent of this section to claim rights or contest
++your rights to work written entirely by you; rather, the intent is to
++exercise the right to control the distribution of derivative or
++collective works based on the Library.
++
++In addition, mere aggregation of another work not based on the Library
++with the Library (or with a work based on the Library) on a volume of
++a storage or distribution medium does not bring the other work under
++the scope of this License.
++
++  3. You may opt to apply the terms of the ordinary GNU General Public
++License instead of this License to a given copy of the Library.  To do
++this, you must alter all the notices that refer to this License, so
++that they refer to the ordinary GNU General Public License, version 2,
++instead of to this License.  (If a newer version than version 2 of the
++ordinary GNU General Public License has appeared, then you can specify
++that version instead if you wish.)  Do not make any other change in
++these notices.
++
++  Once this change is made in a given copy, it is irreversible for
++that copy, so the ordinary GNU General Public License applies to all
++subsequent copies and derivative works made from that copy.
++
++  This option is useful when you wish to copy part of the code of
++the Library into a program that is not a library.
++
++  4. You may copy and distribute the Library (or a portion or
++derivative of it, under Section 2) in object code or executable form
++under the terms of Sections 1 and 2 above provided that you accompany
++it with the complete corresponding machine-readable source code, which
++must be distributed under the terms of Sections 1 and 2 above on a
++medium customarily used for software interchange.
++
++  If distribution of object code is made by offering access to copy
++from a designated place, then offering equivalent access to copy the
++source code from the same place satisfies the requirement to
++distribute the source code, even though third parties are not
++compelled to copy the source along with the object code.
++
++  5. A program that contains no derivative of any portion of the
++Library, but is designed to work with the Library by being compiled or
++linked with it, is called a "work that uses the Library".  Such a
++work, in isolation, is not a derivative work of the Library, and
++therefore falls outside the scope of this License.
++
++  However, linking a "work that uses the Library" with the Library
++creates an executable that is a derivative of the Library (because it
++contains portions of the Library), rather than a "work that uses the
++library".  The executable is therefore covered by this License.
++Section 6 states terms for distribution of such executables.
++
++  When a "work that uses the Library" uses material from a header file
++that is part of the Library, the object code for the work may be a
++derivative work of the Library even though the source code is not.
++Whether this is true is especially significant if the work can be
++linked without the Library, or if the work is itself a library.  The
++threshold for this to be true is not precisely defined by law.
++
++  If such an object file uses only numerical parameters, data
++structure layouts and accessors, and small macros and small inline
++functions (ten lines or less in length), then the use of the object
++file is unrestricted, regardless of whether it is legally a derivative
++work.  (Executables containing this object code plus portions of the
++Library will still fall under Section 6.)
++
++  Otherwise, if the work is a derivative of the Library, you may
++distribute the object code for the work under the terms of Section 6.
++Any executables containing that work also fall under Section 6,
++whether or not they are linked directly with the Library itself.
++
++  6. As an exception to the Sections above, you may also combine or
++link a "work that uses the Library" with the Library to produce a
++work containing portions of the Library, and distribute that work
++under terms of your choice, provided that the terms permit
++modification of the work for the customer's own use and reverse
++engineering for debugging such modifications.
++
++  You must give prominent notice with each copy of the work that the
++Library is used in it and that the Library and its use are covered by
++this License.  You must supply a copy of this License.  If the work
++during execution displays copyright notices, you must include the
++copyright notice for the Library among them, as well as a reference
++directing the user to the copy of this License.  Also, you must do one
++of these things:
++
++    a) Accompany the work with the complete corresponding
++    machine-readable source code for the Library including whatever
++    changes were used in the work (which must be distributed under
++    Sections 1 and 2 above); and, if the work is an executable linked
++    with the Library, with the complete machine-readable "work that
++    uses the Library", as object code and/or source code, so that the
++    user can modify the Library and then relink to produce a modified
++    executable containing the modified Library.  (It is understood
++    that the user who changes the contents of definitions files in the
++    Library will not necessarily be able to recompile the application
++    to use the modified definitions.)
++
++    b) Use a suitable shared library mechanism for linking with the
++    Library.  A suitable mechanism is one that (1) uses at run time a
++    copy of the library already present on the user's computer system,
++    rather than copying library functions into the executable, and (2)
++    will operate properly with a modified version of the library, if
++    the user installs one, as long as the modified version is
++    interface-compatible with the version that the work was made with.
++
++    c) Accompany the work with a written offer, valid for at least
++    three years, to give the same user the materials specified in
++    Subsection 6a, above, for a charge no more than the cost of
++    performing this distribution.
++
++    d) If distribution of the work is made by offering access to copy
++    from a designated place, offer equivalent access to copy the above
++    specified materials from the same place.
++
++    e) Verify that the user has already received a copy of these
++    materials or that you have already sent this user a copy.
++
++  For an executable, the required form of the "work that uses the
++Library" must include any data and utility programs needed for
++reproducing the executable from it.  However, as a special exception,
++the materials to be distributed need not include anything that is
++normally distributed (in either source or binary form) with the major
++components (compiler, kernel, and so on) of the operating system on
++which the executable runs, unless that component itself accompanies
++the executable.
++
++  It may happen that this requirement contradicts the license
++restrictions of other proprietary libraries that do not normally
++accompany the operating system.  Such a contradiction means you cannot
++use both them and the Library together in an executable that you
++distribute.
++
++  7. You may place library facilities that are a work based on the
++Library side-by-side in a single library together with other library
++facilities not covered by this License, and distribute such a combined
++library, provided that the separate distribution of the work based on
++the Library and of the other library facilities is otherwise
++permitted, and provided that you do these two things:
++
++    a) Accompany the combined library with a copy of the same work
++    based on the Library, uncombined with any other library
++    facilities.  This must be distributed under the terms of the
++    Sections above.
++
++    b) Give prominent notice with the combined library of the fact
++    that part of it is a work based on the Library, and explaining
++    where to find the accompanying uncombined form of the same work.
++
++  8. You may not copy, modify, sublicense, link with, or distribute
++the Library except as expressly provided under this License.  Any
++attempt otherwise to copy, modify, sublicense, link with, or
++distribute the Library is void, and will automatically terminate your
++rights under this License.  However, parties who have received copies,
++or rights, from you under this License will not have their licenses
++terminated so long as such parties remain in full compliance.
++
++  9. You are not required to accept this License, since you have not
++signed it.  However, nothing else grants you permission to modify or
++distribute the Library or its derivative works.  These actions are
++prohibited by law if you do not accept this License.  Therefore, by
++modifying or distributing the Library (or any work based on the
++Library), you indicate your acceptance of this License to do so, and
++all its terms and conditions for copying, distributing or modifying
++the Library or works based on it.
++
++  10. Each time you redistribute the Library (or any work based on the
++Library), the recipient automatically receives a license from the
++original licensor to copy, distribute, link with or modify the Library
++subject to these terms and conditions.  You may not impose any further
++restrictions on the recipients' exercise of the rights granted herein.
++You are not responsible for enforcing compliance by third parties with
++this License.
++
++  11. If, as a consequence of a court judgment or allegation of patent
++infringement or for any other reason (not limited to patent issues),
++conditions are imposed on you (whether by court order, agreement or
++otherwise) that contradict the conditions of this License, they do not
++excuse you from the conditions of this License.  If you cannot
++distribute so as to satisfy simultaneously your obligations under this
++License and any other pertinent obligations, then as a consequence you
++may not distribute the Library at all.  For example, if a patent
++license would not permit royalty-free redistribution of the Library by
++all those who receive copies directly or indirectly through you, then
++the only way you could satisfy both it and this License would be to
++refrain entirely from distribution of the Library.
++
++If any portion of this section is held invalid or unenforceable under
++any particular circumstance, the balance of the section is intended to
++apply, and the section as a whole is intended to apply in other
++circumstances.
++
++It is not the purpose of this section to induce you to infringe any
++patents or other property right claims or to contest validity of any
++such claims; this section has the sole purpose of protecting the
++integrity of the free software distribution system which is
++implemented by public license practices.  Many people have made
++generous contributions to the wide range of software distributed
++through that system in reliance on consistent application of that
++system; it is up to the author/donor to decide if he or she is willing
++to distribute software through any other system and a licensee cannot
++impose that choice.
++
++This section is intended to make thoroughly clear what is believed to
++be a consequence of the rest of this License.
++
++  12. If the distribution and/or use of the Library is restricted in
++certain countries either by patents or by copyrighted interfaces, the
++original copyright holder who places the Library under this License
++may add an explicit geographical distribution limitation excluding those
++countries, so that distribution is permitted only in or among
++countries not thus excluded.  In such case, this License incorporates
++the limitation as if written in the body of this License.
++
++  13. The Free Software Foundation may publish revised and/or new
++versions of the Lesser General Public License from time to time.
++Such new versions will be similar in spirit to the present version,
++but may differ in detail to address new problems or concerns.
++
++Each version is given a distinguishing version number.  If the Library
++specifies a version number of this License which applies to it and
++"any later version", you have the option of following the terms and
++conditions either of that version or of any later version published by
++the Free Software Foundation.  If the Library does not specify a
++license version number, you may choose any version ever published by
++the Free Software Foundation.
++
++  14. If you wish to incorporate parts of the Library into other free
++programs whose distribution conditions are incompatible with these,
++write to the author to ask for permission.  For software which is
++copyrighted by the Free Software Foundation, write to the Free
++Software Foundation; we sometimes make exceptions for this.  Our
++decision will be guided by the two goals of preserving the free status
++of all derivatives of our free software and of promoting the sharing
++and reuse of software generally.
++
++                            NO WARRANTY
++
++  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
++WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
++EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
++OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
++KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
++IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
++PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
++LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
++THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
++
++  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
++WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
++AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
++FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
++CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
++LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
++RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
++FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
++SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
++DAMAGES.
++
++                     END OF TERMS AND CONDITIONS
++
++           How to Apply These Terms to Your New Libraries
++
++  If you develop a new library, and you want it to be of the greatest
++possible use to the public, we recommend making it free software that
++everyone can redistribute and change.  You can do so by permitting
++redistribution under these terms (or, alternatively, under the terms
++of the ordinary General Public License).
++
++  To apply these terms, attach the following notices to the library.
++It is safest to attach them to the start of each source file to most
++effectively convey the exclusion of warranty; and each file should
++have at least the "copyright" line and a pointer to where the full
++notice is found.
++
++
++    <one line to give the library's name and a brief idea of what it does.>
++    Copyright (C) <year>  <name of author>
++
++    This library is free software; you can redistribute it and/or
++    modify it under the terms of the GNU Lesser General Public
++    License as published by the Free Software Foundation; either
++    version 2.1 of the License, or (at your option) any later version.
++
++    This library 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
++    Lesser General Public License for more details.
++
++    You should have received a copy of the GNU Lesser General Public
++    License along with this library; if not, write to the Free Software
++    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
++
++Also add information on how to contact you by electronic and paper mail.
++
++You should also get your employer (if you work as a programmer) or
++your school, if any, to sign a "copyright disclaimer" for the library,
++if necessary.  Here is a sample; alter the names:
++
++  Yoyodyne, Inc., hereby disclaims all copyright interest in the
++  library `Frob' (a library for tweaking knobs) written by James
++  Random Hacker.
++
++  <signature of Ty Coon>, 1 April 1990
++  Ty Coon, President of Vice
++
++That's all there is to it!
++
++
+diff --git a/gfx/graphite2/README.md b/gfx/graphite2/README.md
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/README.md
+@@ -0,0 +1,32 @@
++# Graphite engine
++
++## What is Graphite?
++
++Graphite is a system that can be used to create “smart fonts” capable of displaying writing systems with various complex behaviors. A smart font contains not only letter shapes but also additional instructions indicating how to combine and position the letters in complex ways.
++
++Graphite was primarily developed to provide the flexibility needed for minority languages which often need to be written according to slightly different rules than well-known languages that use the same script.
++
++Examples of complex script behaviors Graphite can handle include:
++
++* contextual shaping
++* ligatures
++* reordering
++* split glyphs
++* bidirectionality
++* stacking diacritics
++* complex positioning
++* shape aware kerning
++* automatic diacritic collision avoidance
++
++See [examples of scripts with complex rendering](http://scripts.sil.org/CmplxRndExamples).
++
++## Graphite system overview
++The Graphite system consists of:
++
++* A rule-based programming language [Graphite Description Language](http://scripts.sil.org/cms/scripts/page.php?site_id=projects&item_id=graphite_devFont#gdl) (GDL) that can be used to describe the behavior of a writing system
++* A compiler for that language
++* A rendering engine that can serve as the layout component of a text-processing application
++
++Graphite renders TrueType fonts that have been extended by means of compiling a GDL program.
++
++Further technical information is available on the [Graphite technical overview](http://scripts.sil.org/cms/scripts/page.php?site_id=projects&item_id=graphite_techAbout) page.
+diff --git a/gfx/graphite2/README.mozilla b/gfx/graphite2/README.mozilla
+--- a/gfx/graphite2/README.mozilla
++++ b/gfx/graphite2/README.mozilla
+@@ -1,6 +1,7 @@
+-This directory contains the Graphite2 library from http://hg.palaso.org/graphitedev
+-
+-Current version derived from upstream changeset 1efd96aeade9
+-
++This directory contains the Graphite2 library release 1.3.5 from
++https://github.com/silnrsi/graphite/releases/download/1.3.5/graphite2-minimal-1.3.5.tgz
+ See gfx/graphite2/moz-gr-update.sh for update procedure.
+ 
++Also includes two post-1.3.5 fixes:
++a8b3ac2aed0eb132cd80efe7de88f8153e73c829
++e569e28d83491fedb31b9220493f3c07f6ec6d80
+diff --git a/gfx/graphite2/include/graphite2/Font.h b/gfx/graphite2/include/graphite2/Font.h
+--- a/gfx/graphite2/include/graphite2/Font.h
++++ b/gfx/graphite2/include/graphite2/Font.h
+@@ -24,18 +24,18 @@
+     General Public License, as published by the Free Software Foundation,
+     either version 2 of the License or (at your option) any later version.
+ */
+ #pragma once
+ 
+ #include "graphite2/Types.h"
+ 
+ #define GR2_VERSION_MAJOR   1
+-#define GR2_VERSION_MINOR   2
+-#define GR2_VERSION_BUGFIX  4
++#define GR2_VERSION_MINOR   3
++#define GR2_VERSION_BUGFIX  5
+ 
+ #ifdef __cplusplus
+ extern "C"
+ {
+ #endif
+ 
+ typedef struct gr_face          gr_face;
+ typedef struct gr_font          gr_font;
+diff --git a/gfx/graphite2/include/graphite2/Segment.h b/gfx/graphite2/include/graphite2/Segment.h
+--- a/gfx/graphite2/include/graphite2/Segment.h
++++ b/gfx/graphite2/include/graphite2/Segment.h
+@@ -115,35 +115,68 @@ enum gr_attrCode {
+     gr_slatJStretch,        
+     /// Amount this slot can shrink (not implemented)
+     gr_slatJShrink,         
+     /// Granularity by which this slot can stretch or shrink (not implemented)
+     gr_slatJStep,           
+     /// Justification weight for this glyph (not implemented)
+     gr_slatJWeight,         
+     /// Amount this slot mush shrink or stretch in design units
+-    gr_slatJWidth,          
++    gr_slatJWidth = 29,
+     /// SubSegment split point
+     gr_slatSegSplit = gr_slatJStretch + 29,
+     /// User defined attribute, see subattr for user attr number
+     gr_slatUserDefn,
+     /// Bidi level
+-    gr_slatBidiLevel,
++    gr_slatBidiLevel = 56,
++    /// Collision flags
++    gr_slatColFlags,
++    /// Collision constraint rectangle left (bl.x)
++    gr_slatColLimitblx,
++    /// Collision constraint rectangle lower (bl.y)
++    gr_slatColLimitbly,
++    /// Collision constraint rectangle right (tr.x)
++    gr_slatColLimittrx,
++    /// Collision constraint rectangle upper (tr.y)
++    gr_slatColLimittry,
++    /// Collision shift x
++    gr_slatColShiftx,
++    /// Collision shift y
++    gr_slatColShifty,
++    /// Collision margin
++    gr_slatColMargin,
++    /// Margin cost weight
++    gr_slatColMarginWt,
++    // Additional glyph that excludes movement near this one:
++    gr_slatColExclGlyph,
++    gr_slatColExclOffx,
++    gr_slatColExclOffy,
++    // Collision sequence enforcing attributes:
++    gr_slatSeqClass,
++    gr_slatSeqProxClass,
++    gr_slatSeqOrder,
++    gr_slatSeqAboveXoff,
++    gr_slatSeqAboveWt,
++    gr_slatSeqBelowXlim,
++    gr_slatSeqBelowWt,
++    gr_slatSeqValignHt,
++    gr_slatSeqValignWt,
+                             
+     /// not implemented
+     gr_slatMax,             
+     /// not implemented
+     gr_slatNoEffect = gr_slatMax + 1    
+ };
+ 
+ enum gr_bidirtl {
+     /// Underlying paragraph direction is RTL
+     gr_rtl = 1,
+     /// Set this to not run the bidi pass internally, even if the font asks for it.
+-    /// This presumes that the segment is in a single direction.
++    /// This presumes that the segment is in a single direction. Most of the time
++    /// this bit should be set unless you know you are passing full paragraphs of text.
+     gr_nobidi = 2,
+     /// Disable auto mirroring for rtl text
+     gr_nomirror = 4
+ };
+ 
+ typedef struct gr_char_info     gr_char_info;
+ typedef struct gr_segment       gr_segment;
+ typedef struct gr_slot          gr_slot;
+diff --git a/gfx/graphite2/include/graphite2/Types.h b/gfx/graphite2/include/graphite2/Types.h
+--- a/gfx/graphite2/include/graphite2/Types.h
++++ b/gfx/graphite2/include/graphite2/Types.h
+@@ -53,17 +53,20 @@ enum gr_encform {
+   #else
+     #if defined __GNUC__
+       #define GR2_API    __attribute__((dllimport))
+     #else
+       #define GR2_API    __declspec(dllimport)
+     #endif
+   #endif
+   #define GR2_LOCAL
++#elif __GNUC__ >= 4
++  #if defined GRAPHITE2_STATIC
++    #define GR2_API      __attribute__ ((visibility("hidden")))
++  #else
++    #define GR2_API      __attribute__ ((visibility("default")))
++  #endif
++  #define GR2_LOCAL      __attribute__ ((visibility("hidden")))
+ #else
+-  #if __GNUC__ >= 4
+-    #define GR2_API      __attribute__ ((visibility("default")))
+-    #define GR2_LOCAL       __attribute__ ((visibility("hidden")))
+-  #else
+-    #define GR2_API
+-    #define GR2_LOCAL
+-  #endif
++  #define GR2_API
++  #define GR2_LOCAL
+ #endif
++
+diff --git a/gfx/graphite2/moz-gr-update.sh b/gfx/graphite2/moz-gr-update.sh
+--- a/gfx/graphite2/moz-gr-update.sh
++++ b/gfx/graphite2/moz-gr-update.sh
+@@ -1,35 +1,49 @@
+ #!/bin/bash
+ 
+ # Script used to update the Graphite2 library in the mozilla source tree
+ 
+ # This script lives in gfx/graphite2, along with the library source,
+ # but must be run from the top level of the mozilla-central tree.
+ 
+-# It expects to find a checkout of the graphite2 tree in a directory "graphitedev"
+-# alongside the current mozilla tree that is to be updated.
+-# Expect error messages from the copy commands if this is not found!
++# Run as
++#
++#    ./gfx/graphite2/moz-gr-update.sh RELEASE
++#
++# where RELEASE is the graphite2 release to be used, e.g. "1.3.4".
+ 
+-# copy the source and headers
+-cp -R ../graphitedev/src/* gfx/graphite2/src
+-cp ../graphitedev/include/graphite2/* gfx/graphite2/include/graphite2
++RELEASE=$1
+ 
+-# record the upstream changeset that was used
+-CHANGESET=$(cd ../graphitedev/ && hg log | head -n 1 | cut -d : -f 1,3 | sed -e 's/:/ /')
+-echo "This directory contains the Graphite2 library from http://hg.palaso.org/graphitedev\n" > gfx/graphite2/README.mozilla
+-echo "Current version derived from upstream" $CHANGESET >> gfx/graphite2/README.mozilla
+-echo "\nSee" $0 "for update procedure.\n" >> gfx/graphite2/README.mozilla
++if [ "x$RELEASE" == "x" ]
++then
++    echo "Must provide the version number to be used."
++    exit 1
++fi
++
++TARBALL="https://github.com/silnrsi/graphite/releases/download/$RELEASE/graphite2-minimal-$RELEASE.tgz"
++
++foo=`basename $0`
++TMPFILE=`mktemp -t ${foo}` || exit 1
++
++curl -L "$TARBALL" -o "$TMPFILE"
++tar -x -z -C gfx/graphite2/ --strip-components 1 -f "$TMPFILE" || exit 1
++rm "$TMPFILE"
++
++echo "This directory contains the Graphite2 library release $RELEASE from" > gfx/graphite2/README.mozilla
++echo "$TARBALL" >> gfx/graphite2/README.mozilla
++echo ""
++echo "See" $0 "for update procedure." >> gfx/graphite2/README.mozilla
+ 
+ # fix up includes because of bug 721839 (cstdio) and bug 803066 (Windows.h)
+-find gfx/graphite2/ -name "*.cpp" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
+-find gfx/graphite2/ -name "*.h" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
++#find gfx/graphite2/ -name "*.cpp" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
++#find gfx/graphite2/ -name "*.h" -exec perl -p -i -e "s/<cstdio>/<stdio.h>/;s/Windows.h/windows.h/;" {} \;
+ 
+ # summarize what's been touched
+-echo Updated to $CHANGESET.
++echo Updated to $RELEASE.
+ echo Here is what changed in the gfx/graphite2 directory:
+ echo
+ 
+ hg stat gfx/graphite2
+ 
+ echo
+ echo If gfx/graphite2/src/files.mk has changed, please make corresponding
+ echo changes to gfx/graphite2/src/moz.build
+diff --git a/gfx/graphite2/src/CMakeLists.txt b/gfx/graphite2/src/CMakeLists.txt
+--- a/gfx/graphite2/src/CMakeLists.txt
++++ b/gfx/graphite2/src/CMakeLists.txt
+@@ -69,29 +69,31 @@ add_library(graphite2 SHARED
+     ${GRAPHITE2_VM_TYPE}_machine.cpp
+     gr_char_info.cpp
+     gr_features.cpp
+     gr_face.cpp
+     gr_font.cpp
+     gr_logging.cpp
+     gr_segment.cpp
+     gr_slot.cpp
+-    Bidi.cpp
+     CachedFace.cpp
+     CmapCache.cpp
+     Code.cpp
++    Collider.cpp
++    Decompressor.cpp
+     Face.cpp
+     FeatureMap.cpp
+     Font.cpp
+     GlyphFace.cpp
+     GlyphCache.cpp
++    Intervals.cpp
+     Justifier.cpp
+     NameTable.cpp
+     Pass.cpp
+-    Rule.cpp
++    Position.cpp
+     Segment.cpp
+     Silf.cpp
+     Slot.cpp
+     Sparse.cpp
+     TtfUtil.cpp
+     UtfCodec.cpp
+     ${FILEFACE}
+     ${SEGCACHE}
+@@ -99,27 +101,28 @@ add_library(graphite2 SHARED
+ 
+ set_target_properties(graphite2 PROPERTIES  PUBLIC_HEADER "${GRAPHITE_HEADERS}"
+                                             SOVERSION ${GRAPHITE_SO_VERSION}
+                                             VERSION ${GRAPHITE_VERSION}
+                                             LT_VERSION_CURRENT ${GRAPHITE_API_CURRENT}
+                                             LT_VERSION_REVISION ${GRAPHITE_API_REVISION}
+                                             LT_VERSION_AGE ${GRAPHITE_API_AGE})
+ 
+-if (${CMAKE_BUILD_TYPE} STREQUAL "ClangASN")
+-    set(GRAPHITE_LINK_FLAGS "-fsanitize=address")
+-else (${CMAKE_BUILD_TYPE} STREQUAL "ClangASN")
+-    set(GRAPHITE_LINK_FLAGS "")
+-endif (${CMAKE_BUILD_TYPE} STREQUAL "ClangASN")
+-
+ if  (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+     set_target_properties(graphite2 PROPERTIES 
+         COMPILE_FLAGS   "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wctor-dtor-privacy -Wnon-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
+         LINK_FLAGS      "-nodefaultlibs ${GRAPHITE_LINK_FLAGS}" 
+         LINKER_LANGUAGE C)
++    if (CMAKE_COMPILER_IS_GNUCXX)
++        add_definitions(-Wdouble-promotion)
++    endif (CMAKE_COMPILER_IS_GNUCXX)
++    message(STATUS "Compiler ID is: ${CMAKE_CXX_COMPILER_ID}")
++    if (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
++        add_definitions(-Wimplicit-fallthrough)
++    endif (${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
+     if (${CMAKE_CXX_COMPILER} MATCHES  ".*mingw.*")
+         target_link_libraries(graphite2 kernel32 msvcr90 mingw32 gcc user32)
+     else (${CMAKE_CXX_COMPILER} MATCHES  ".*mingw.*")
+         if (GRAPHITE2_ASAN)
+             target_link_libraries(graphite2 c gcc_s)
+         else (GRAPHITE2_ASAN)
+             target_link_libraries(graphite2 c gcc)
+         endif (GRAPHITE2_ASAN)
+@@ -127,17 +130,17 @@ if  (${CMAKE_SYSTEM_NAME} STREQUAL "Linu
+         nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
+     endif (${CMAKE_CXX_COMPILER} MATCHES  ".*mingw.*")
+     set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
+     CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
+ endif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
+ 
+ if  (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+     set_target_properties(graphite2 PROPERTIES 
+-        COMPILE_FLAGS   "-Wall -Wextra -Wno-unknown-pragmas -Wendif-labels -Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
++        COMPILE_FLAGS   "-Wall -Wextra -Wno-unknown-pragmas -Wimplicit-fallthrough -Wendif-labels -Wshadow -Wno-ctor-dtor-privacy -Wno-non-virtual-dtor -fno-rtti -fno-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-protector"
+         LINK_FLAGS      "-nodefaultlibs" 
+         LINKER_LANGUAGE C)
+     target_link_libraries(graphite2 c)
+     include(Graphite)
+     nolib_test(stdc++ $<TARGET_SONAME_FILE:graphite2>)
+     set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
+     CREATE_LIBTOOL_FILE(graphite2 "/lib${LIB_SUFFIX}")
+ endif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
+diff --git a/gfx/graphite2/src/CmapCache.cpp b/gfx/graphite2/src/CmapCache.cpp
+--- a/gfx/graphite2/src/CmapCache.cpp
++++ b/gfx/graphite2/src/CmapCache.cpp
+@@ -33,31 +33,31 @@ of the License or (at your option) any l
+ 
+ 
+ using namespace graphite2;
+ 
+ const void * bmp_subtable(const Face::Table & cmap)
+ {
+     const void * stbl;
+     if (!cmap.size()) return 0;
+-    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()))
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()))
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()))
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()))
+-     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size())))
++    if (TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 1, cmap.size()), cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 3, cmap.size()), cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 2, cmap.size()), cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 1, cmap.size()), cmap.size())
++     || TtfUtil::CheckCmapSubtable4(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 0, cmap.size()), cmap.size()))
+         return stbl;
+     return 0;
+ }
+ 
+ const void * smp_subtable(const Face::Table & cmap)
+ {
+     const void * stbl;
+     if (!cmap.size()) return 0;
+-    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()))
+-     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size())))
++    if (TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 3, 10, cmap.size()), cmap.size())
++     || TtfUtil::CheckCmapSubtable12(stbl = TtfUtil::FindCmapSubtable(cmap, 0, 4, cmap.size()), cmap.size()))
+         return stbl;
+     return 0;
+ }
+ 
+ template <unsigned int (*NextCodePoint)(const void *, unsigned int, int *),
+           uint16 (*LookupCodePoint)(const void *, unsigned int, int)>
+ bool cache_subtable(uint16 * blocks[], const void * cst, const unsigned int limit)
+ {
+diff --git a/gfx/graphite2/src/Code.cpp b/gfx/graphite2/src/Code.cpp
+--- a/gfx/graphite2/src/Code.cpp
++++ b/gfx/graphite2/src/Code.cpp
+@@ -37,17 +37,17 @@ of the License or (at your option) any l
+ #include "inc/Code.h"
+ #include "inc/Face.h"
+ #include "inc/GlyphFace.h"
+ #include "inc/GlyphCache.h"
+ #include "inc/Machine.h"
+ #include "inc/Rule.h"
+ #include "inc/Silf.h"
+ 
+-#include <stdio.h>
++#include <cstdio>
+ 
+ #ifdef NDEBUG
+ #ifdef __GNUC__
+ #pragma GCC diagnostic ignored "-Wunused-parameter"
+ #endif
+ #endif
+ 
+ 
+@@ -84,112 +84,119 @@ public:
+     struct limits;
+     struct analysis
+     {
+         uint8     slotref;
+         context   contexts[256];
+         byte      max_ref;
+         
+         analysis() : slotref(0), max_ref(0) {};
+-        void set_ref(int index) throw();
++        void set_ref(int index, bool incinsert=false) throw();
++        void set_noref(int index) throw();
+         void set_changed(int index) throw();
+ 
+     };
+     
+-    decoder(const limits & lims, Code &code) throw();
++    decoder(limits & lims, Code &code, enum passtype pt) throw();
+     
+     bool        load(const byte * bc_begin, const byte * bc_end);
+     void        apply_analysis(instr * const code, instr * code_end);
+     byte        max_ref() { return _analysis.max_ref; }
+     int         pre_context() const { return _pre_context; }
+     
+ private:
+     opcode      fetch_opcode(const byte * bc);
+     void        analyse_opcode(const opcode, const int8 * const dp) throw();
+     bool        emit_opcode(opcode opc, const byte * & bc);
+     bool        validate_opcode(const opcode opc, const byte * const bc);
+     bool        valid_upto(const uint16 limit, const uint16 x) const throw();
++    bool        test_context() const throw();
+     void        failure(const status_t s) const throw() { _code.failure(s); }
+     
+     Code              & _code;
+     int                 _pre_context;
+     uint16              _rule_length;
+     instr             * _instr;
+     byte              * _data;
+-    const limits      & _max;
++    limits            & _max;
+     analysis            _analysis;
++    enum passtype       _passtype;
++    int                 _stack_depth;
++    bool                _in_ctxt_item;
+ };
+ 
+ 
+ struct Machine::Code::decoder::limits
+ {
+-  const byte * const bytecode;
++  const byte       * bytecode;
+   const uint8        pre_context;
+   const uint16       rule_length,
+                      classes,
+                      glyf_attrs,
+                      features;
+   const byte         attrid[gr_slatMax];
+ };
+    
+-inline Machine::Code::decoder::decoder(const limits & lims, Code &code) throw()
++inline Machine::Code::decoder::decoder(limits & lims, Code &code, enum passtype pt) throw()
+ : _code(code),
+   _pre_context(code._constraint ? 0 : lims.pre_context), 
+   _rule_length(code._constraint ? 1 : lims.rule_length), 
+-  _instr(code._code), _data(code._data), _max(lims)
++  _instr(code._code), _data(code._data), _max(lims), _passtype(pt),
++  _stack_depth(0),
++  _in_ctxt_item(false)
+ { }
+     
+ 
+ 
+ Machine::Code::Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
+-           uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face)
++           uint8 pre_context, uint16 rule_length, const Silf & silf, const Face & face,
++           enum passtype pt, byte * * const _out)
+  :  _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0), _status(loaded),
+-    _constraint(is_constraint), _modify(false), _delete(false), _own(true)
++    _constraint(is_constraint), _modify(false), _delete(false), _own(_out==0)
+ {
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::category _code_cat(face.tele.code);
+ #endif
+     assert(bytecode_begin != 0);
+     if (bytecode_begin == bytecode_end)
+     {
+-      ::new (this) Code();
++      // ::new (this) Code();
+       return;
+     }
+     assert(bytecode_end > bytecode_begin);
+     const opcode_t *    op_to_fn = Machine::getOpcodeTable();
+     
+-    // Allocate code and dat target buffers, these sizes are a worst case 
++    // Allocate code and data target buffers, these sizes are a worst case
+     // estimate.  Once we know their real sizes the we'll shrink them.
+-    _code = static_cast<instr *>(malloc((bytecode_end - bytecode_begin)
+-                                             * sizeof(instr)));
+-    _data = static_cast<byte *>(malloc((bytecode_end - bytecode_begin)
+-                                             * sizeof(byte)));
++    if (_out)   _code = reinterpret_cast<instr *>(*_out);
++    else        _code = static_cast<instr *>(malloc(estimateCodeDataOut(bytecode_end-bytecode_begin)));
++    _data = reinterpret_cast<byte *>(_code + (bytecode_end - bytecode_begin));
+     
+     if (!_code || !_data) {
+         failure(alloc_failed);
+         return;
+     }
+     
+-    const decoder::limits lims = {
++    decoder::limits lims = {
+         bytecode_end,
+         pre_context,
+         rule_length,
+         silf.numClasses(),
+         face.glyphs().numAttrs(),
+         face.numFeatures(), 
+         {1,1,1,1,1,1,1,1, 
+          1,1,1,1,1,1,1,255,
+          1,1,1,1,1,1,1,1, 
+          1,1,1,1,1,1,0,0, 
+          0,0,0,0,0,0,0,0, 
+          0,0,0,0,0,0,0,0, 
+          0,0,0,0,0,0,0, silf.numUser()}
+     };
+     
+-    decoder dec(lims, *this);
++    decoder dec(lims, *this, pt);
+     if(!dec.load(bytecode_begin, bytecode_end))
+        return;
+     
+     // Is this an empty program?
+     if (_instr_count == 0)
+     {
+       release_buffers();
+       ::new (this) Code();
+@@ -204,20 +211,25 @@ Machine::Code::Code(bool is_constraint, 
+ 
+     assert((_constraint && immutable()) || !_constraint);
+     dec.apply_analysis(_code, _code + _instr_count);
+     _max_ref = dec.max_ref();
+     
+     // Now we know exactly how much code and data the program really needs
+     // realloc the buffers to exactly the right size so we don't waste any 
+     // memory.
+-    assert((bytecode_end - bytecode_begin) >= std::ptrdiff_t(_instr_count));
+-    assert((bytecode_end - bytecode_begin) >= std::ptrdiff_t(_data_size));
+-    _code = static_cast<instr *>(realloc(_code, (_instr_count+1)*sizeof(instr)));
+-    _data = static_cast<byte *>(realloc(_data, _data_size*sizeof(byte)));
++    assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_instr_count));
++    assert((bytecode_end - bytecode_begin) >= ptrdiff_t(_data_size));
++    memmove(_code + (_instr_count+1), _data, _data_size*sizeof(byte));
++    size_t const total_sz = ((_instr_count+1) + (_data_size + sizeof(instr)-1)/sizeof(instr))*sizeof(instr);
++    if (_out)
++        *_out += total_sz;
++    else
++        _code = static_cast<instr *>(realloc(_code, total_sz));
++   _data = reinterpret_cast<byte *>(_code + (_instr_count+1));
+ 
+     if (!_code)
+     {
+         failure(alloc_failed);
+         return;
+     }
+ 
+     // Make this RET_ZERO, we should never reach this but just in case ...
+@@ -232,16 +244,17 @@ Machine::Code::~Code() throw ()
+ {
+     if (_own)
+         release_buffers();
+ }
+ 
+ 
+ bool Machine::Code::decoder::load(const byte * bc, const byte * bc_end)
+ {
++    _max.bytecode = bc_end;
+     while (bc < bc_end)
+     {
+         const opcode opc = fetch_opcode(bc++);
+         if (opc == vm::MAX_OPCODE)
+             return false;
+         
+         analyse_opcode(opc, reinterpret_cast<const int8 *>(bc));
+         
+@@ -261,141 +274,194 @@ opcode Machine::Code::decoder::fetch_opc
+ 
+     // Do some basic sanity checks based on what we know about the opcode
+     if (!validate_opcode(opc, bc))  return MAX_OPCODE;
+ 
+     // And check it's arguments as far as possible
+     switch (opc)
+     {
+         case NOP :
++            break;
+         case PUSH_BYTE :
+         case PUSH_BYTEU :
+         case PUSH_SHORT :
+         case PUSH_SHORTU :
+         case PUSH_LONG :
++            ++_stack_depth;
++            break;
+         case ADD :
+         case SUB :
+         case MUL :
+         case DIV :
+         case MIN_ :
+         case MAX_ :
+-        case NEG :
+-        case TRUNC8 :
+-        case TRUNC16 :
+-        case COND :
+         case AND :
+         case OR :
+-        case NOT :
+         case EQUAL :
+         case NOT_EQ :
+         case LESS :
+         case GTR :
+         case LESS_EQ :
+         case GTR_EQ :
++        case BITOR :
++        case BITAND :
++            if (--_stack_depth <= 0)
++                failure(underfull_stack);
++            break;
++        case NEG :
++        case TRUNC8 :
++        case TRUNC16 :
++        case NOT :
++        case BITNOT :
++        case BITSET :
++            if (_stack_depth <= 0)
++                failure(underfull_stack);
++            break;
++        case COND :
++            _stack_depth -= 2;
++            if (_stack_depth <= 0)
++                failure(underfull_stack);
+             break;
+         case NEXT :
+         case NEXT_N :           // runtime checked
+         case COPY_NEXT :
++            test_context();
+             ++_pre_context;
+             break;
+         case PUT_GLYPH_8BIT_OBS :
+             valid_upto(_max.classes, bc[0]);
++            test_context();
+             break;
+         case PUT_SUBS_8BIT_OBS :
+             valid_upto(_rule_length, _pre_context + int8(bc[0]));
+             valid_upto(_max.classes, bc[1]);
+             valid_upto(_max.classes, bc[2]);
++            test_context();
+             break;
+         case PUT_COPY :
+             valid_upto(_rule_length, _pre_context + int8(bc[0]));
++            test_context();
+             break;
+         case INSERT :
+-            --_pre_context;
++            if (_passtype >= PASS_TYPE_POSITIONING)
++                failure(invalid_opcode);
++            else
++                --_pre_context;
+             break;
+         case DELETE :
++            if (_passtype >= PASS_TYPE_POSITIONING)
++                failure(invalid_opcode);
++            test_context();
+             break;
+         case ASSOC :
+             for (uint8 num = bc[0]; num; --num)
+                 valid_upto(_rule_length, _pre_context + int8(bc[num]));
++            test_context();
+             break;
+         case CNTXT_ITEM :
+             valid_upto(_max.rule_length, _max.pre_context + int8(bc[0]));
+-            if (bc + 2 + bc[1] >= _max.bytecode)  failure(jump_past_end);
+-            if (_pre_context != 0)                failure(nested_context_item);
++            if (bc + 2 + bc[1] >= _max.bytecode)    failure(jump_past_end);
++            if (_in_ctxt_item)                      failure(nested_context_item);
+             break;
+         case ATTR_SET :
+         case ATTR_ADD :
+         case ATTR_SUB :
+         case ATTR_SET_SLOT :
++            if (--_stack_depth < 0)
++                failure(underfull_stack);
+             valid_upto(gr_slatMax, bc[0]);
++            test_context();
+             break;
+         case IATTR_SET_SLOT :
++            if (--_stack_depth < 0)
++                failure(underfull_stack);
+             if (valid_upto(gr_slatMax, bc[0]))
+                 valid_upto(_max.attrid[bc[0]], bc[1]);
++            test_context();
+             break;
+         case PUSH_SLOT_ATTR :
++            ++_stack_depth;
+             valid_upto(gr_slatMax, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             break;
+         case PUSH_GLYPH_ATTR_OBS :
++            ++_stack_depth;
+             valid_upto(_max.glyf_attrs, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             break;
+         case PUSH_GLYPH_METRIC :
++            ++_stack_depth;
+             valid_upto(kgmetDescent, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             // level: dp[2] no check necessary
+             break;
+         case PUSH_FEAT :
++            ++_stack_depth;
+             valid_upto(_max.features, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             break;
+         case PUSH_ATT_TO_GATTR_OBS :
++            ++_stack_depth;
+             valid_upto(_max.glyf_attrs, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             break;
+         case PUSH_ATT_TO_GLYPH_METRIC :
++            ++_stack_depth;
+             valid_upto(kgmetDescent, bc[0]);
+             valid_upto(_rule_length, _pre_context + int8(bc[1]));
+             // level: dp[2] no check necessary
+             break;
+         case PUSH_ISLOT_ATTR :
++            ++_stack_depth;
+             if (valid_upto(gr_slatMax, bc[0]))
+             {
+                 valid_upto(_rule_length, _pre_context + int8(bc[1]));
+                 valid_upto(_max.attrid[bc[0]], bc[2]);
+             }
+             break;
+         case PUSH_IGLYPH_ATTR :// not implemented
++            ++_stack_depth;
++            break;
+         case POP_RET :
++            if (--_stack_depth < 0)
++                failure(underfull_stack);
++            GR_FALLTHROUGH;
++            // no break
+         case RET_ZERO :
+         case RET_TRUE :
+             break;
+         case IATTR_SET :
+         case IATTR_ADD :
+         case IATTR_SUB :
++            if (--_stack_depth < 0)
++                failure(underfull_stack);
+             if (valid_upto(gr_slatMax, bc[0]))
+                 valid_upto(_max.attrid[bc[0]], bc[1]);
++            test_context();
+             break;
+         case PUSH_PROC_STATE :  // dummy: dp[0] no check necessary
+         case PUSH_VERSION :
++            ++_stack_depth;
+             break;
+         case PUT_SUBS :
+             valid_upto(_rule_length, _pre_context + int8(bc[0]));
+             valid_upto(_max.classes, uint16(bc[1]<< 8) | bc[2]);
+             valid_upto(_max.classes, uint16(bc[3]<< 8) | bc[4]);
++            test_context();
+             break;
+         case PUT_SUBS2 :        // not implemented
+         case PUT_SUBS3 :        // not implemented
+             break;
+         case PUT_GLYPH :
+             valid_upto(_max.classes, uint16(bc[0]<< 8) | bc[1]);
++            test_context();
+             break;
+         case PUSH_GLYPH_ATTR :
+         case PUSH_ATT_TO_GLYPH_ATTR :
++            ++_stack_depth;
+             valid_upto(_max.glyf_attrs, uint16(bc[0]<< 8) | bc[1]);
+             valid_upto(_rule_length, _pre_context + int8(bc[2]));
+             break;
+         default:
+             failure(invalid_opcode);
+             break;
+     }
+ 
+@@ -410,62 +476,77 @@ void Machine::Code::decoder::analyse_opc
+   switch (opc)
+   {
+     case DELETE :
+       _code._delete = true;
+       break;
+     case PUT_GLYPH_8BIT_OBS :
+     case PUT_GLYPH :
+       _code._modify = true;
+-      _analysis.set_changed(_analysis.slotref);
++      _analysis.set_changed(0);
++      break;
++    case ATTR_SET :
++    case ATTR_ADD :
++    case ATTR_SET_SLOT :
++    case IATTR_SET_SLOT :
++    case IATTR_SET :
++    case IATTR_ADD :
++    case IATTR_SUB :
++      _analysis.set_noref(0);
+       break;
+     case NEXT :
+     case COPY_NEXT :
+       if (!_analysis.contexts[_analysis.slotref].flags.inserted)
+         ++_analysis.slotref;
+       _analysis.contexts[_analysis.slotref] = context(_code._instr_count+1);
+-      if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
++      // if (_analysis.slotref > _analysis.max_ref) _analysis.max_ref = _analysis.slotref;
+       break;
+     case INSERT :
+       _analysis.contexts[_analysis.slotref].flags.inserted = true;
+       _code._modify = true;
+       break;
+     case PUT_SUBS_8BIT_OBS :    // slotref on 1st parameter
+     case PUT_SUBS : 
+       _code._modify = true;
+-      _analysis.set_changed(_analysis.slotref);
++      _analysis.set_changed(0);
++      GR_FALLTHROUGH;
+       // no break
+     case PUT_COPY :
+     {
+-      if (arg[0] != 0) { _analysis.set_changed(_analysis.slotref); _code._modify = true; }
++      if (arg[0] != 0) { _analysis.set_changed(0); _code._modify = true; }
+       if (arg[0] <= 0 && -arg[0] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
+-        _analysis.set_ref(_analysis.slotref + arg[0] - _analysis.contexts[_analysis.slotref].flags.inserted);
+-      else if (_analysis.slotref + arg[0] > _analysis.max_ref) _analysis.max_ref = _analysis.slotref + arg[0];
++        _analysis.set_ref(arg[0], true);
++      else if (arg[0] > 0)
++        _analysis.set_ref(arg[0], true);
+       break;
+     }
+     case PUSH_ATT_TO_GATTR_OBS : // slotref on 2nd parameter
+         if (_code._constraint) return;
++        GR_FALLTHROUGH;
+         // no break
+     case PUSH_GLYPH_ATTR_OBS :
+     case PUSH_SLOT_ATTR :
+     case PUSH_GLYPH_METRIC :
+     case PUSH_ATT_TO_GLYPH_METRIC :
+     case PUSH_ISLOT_ATTR :
+     case PUSH_FEAT :
+       if (arg[1] <= 0 && -arg[1] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
+-        _analysis.set_ref(_analysis.slotref + arg[1] - _analysis.contexts[_analysis.slotref].flags.inserted);
+-      else if (_analysis.slotref + arg[1] > _analysis.max_ref) _analysis.max_ref = _analysis.slotref + arg[1];
++        _analysis.set_ref(arg[1], true);
++      else if (arg[1] > 0)
++        _analysis.set_ref(arg[1], true);
+       break;
+     case PUSH_ATT_TO_GLYPH_ATTR :
+         if (_code._constraint) return;
++        GR_FALLTHROUGH;
+         // no break
+     case PUSH_GLYPH_ATTR :
+       if (arg[2] <= 0 && -arg[2] <= _analysis.slotref - _analysis.contexts[_analysis.slotref].flags.inserted)
+-        _analysis.set_ref(_analysis.slotref + arg[2] - _analysis.contexts[_analysis.slotref].flags.inserted);
+-      else if (_analysis.slotref + arg[2] > _analysis.max_ref) _analysis.max_ref = _analysis.slotref + arg[2];
++        _analysis.set_ref(arg[2], true);
++      else if (arg[2] > 0)
++        _analysis.set_ref(arg[2], true);
+       break;
+     case ASSOC :                // slotrefs in varargs
+       break;
+     default:
+         break;
+   }
+ }
+ 
+@@ -494,32 +575,41 @@ bool Machine::Code::decoder::emit_opcode
+         _code._data_size += param_sz;
+     }
+     
+     // recursively decode a context item so we can split the skip into 
+     // instruction and data portions.
+     if (opc == CNTXT_ITEM)
+     {
+         assert(_pre_context == 0);
++        _in_ctxt_item = true;
+         _pre_context = _max.pre_context + int8(_data[-2]);
+         _rule_length = _max.rule_length;
+ 
+         const size_t ctxt_start = _code._instr_count;
+         byte & instr_skip = _data[-1];
+         byte & data_skip  = *_data++;
+         ++_code._data_size;
++        const byte *curr_end = _max.bytecode;
+ 
+         if (load(bc, bc + instr_skip))
+         {
+             bc += instr_skip;
+             data_skip  = instr_skip - (_code._instr_count - ctxt_start);
+             instr_skip = _code._instr_count - ctxt_start;
++            _max.bytecode = curr_end;
+ 
+             _rule_length = 1;
+             _pre_context = 0;
++            _in_ctxt_item = false;
++        }
++        else
++        {
++            _pre_context = 0;
++            return false;
+         }
+     }
+     
+     return bool(_code);
+ }
+ 
+ 
+ void Machine::Code::decoder::apply_analysis(instr * const code, instr * code_end)
+@@ -533,87 +623,115 @@ void Machine::Code::decoder::apply_analy
+     {
+         if (!c->flags.referenced || !c->flags.changed) continue;
+         
+         instr * const tip = code + c->codeRef + tempcount;        
+         memmove(tip+1, tip, (code_end - tip) * sizeof(instr));
+         *tip = temp_copy;
+         ++code_end;
+         ++tempcount;
++        _code._delete = true;
+     }
+     
+     _code._instr_count = code_end - code;
+ }
+ 
+ 
+ inline
+ bool Machine::Code::decoder::validate_opcode(const opcode opc, const byte * const bc)
+ {
+     if (opc >= MAX_OPCODE)
+     {
+         failure(invalid_opcode);
+         return false;
+     }
+     const opcode_t & op = Machine::getOpcodeTable()[opc];
++    if (op.param_sz == VARARGS && bc >= _max.bytecode)
++    {
++        failure(arguments_exhausted);
++        return false;
++    }
+     const size_t param_sz = op.param_sz == VARARGS ? bc[0] + 1 : op.param_sz;
+-    if (bc + param_sz > _max.bytecode)
++    if (bc - 1 + param_sz >= _max.bytecode)
+     {
+         failure(arguments_exhausted);
+         return false;
+     }
+     return true;
+ }
+ 
+ 
+ bool Machine::Code::decoder::valid_upto(const uint16 limit, const uint16 x) const throw()
+ {
+     const bool t = x < limit;
+     if (!t) failure(out_of_range_data);
+     return t;
+ }
+ 
++bool Machine::Code::decoder::test_context() const throw()
++{
++    if (_pre_context >= _rule_length)
++    {
++        failure(out_of_range_data);
++        return false;
++    }
++    return true;
++}
+ 
+ inline 
+ void Machine::Code::failure(const status_t s) throw() {
+     release_buffers();
+     _status = s;
+ }
+ 
+ 
+ inline
+-void Machine::Code::decoder::analysis::set_ref(const int index) throw() {
+-    contexts[index].flags.referenced = true;
+-    if (index > max_ref) max_ref = index;
++void Machine::Code::decoder::analysis::set_ref(int index, bool incinsert) throw() {
++    if (incinsert && contexts[slotref].flags.inserted) --index;
++    if (index + slotref < 0) return;
++    contexts[index + slotref].flags.referenced = true;
++    if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+ }
+ 
+ 
+ inline
+-void Machine::Code::decoder::analysis::set_changed(const int index) throw() {
+-    contexts[index].flags.changed = true;
+-    if (index > max_ref) max_ref = index;
++void Machine::Code::decoder::analysis::set_noref(int index) throw() {
++    if (contexts[slotref].flags.inserted) --index;
++    if (index + slotref < 0) return;
++    if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
++}
++
++
++inline
++void Machine::Code::decoder::analysis::set_changed(int index) throw() {
++    if (contexts[slotref].flags.inserted) --index;
++    if (index + slotref < 0) return;
++    contexts[index + slotref].flags.changed = true;
++    if ((index > 0 || !contexts[index + slotref].flags.inserted) && index + slotref > max_ref) max_ref = index + slotref;
+ }
+ 
+ 
+ void Machine::Code::release_buffers() throw()
+ {
+-    free(_code);
+-    free(_data);
++    if (_own)
++        free(_code);
+     _code = 0;
+     _data = 0;
+     _own  = false;
+ }
+ 
+ 
+ int32 Machine::Code::run(Machine & m, slotref * & map) const
+ {
+-    assert(_own);
++//    assert(_own);
+     assert(*this);          // Check we are actually runnable
+ 
+-    if (m.slotMap().size() <= size_t(_max_ref + m.slotMap().context()))
++    if (m.slotMap().size() <= size_t(_max_ref + m.slotMap().context())
++        || m.slotMap()[_max_ref + m.slotMap().context()] == 0)
+     {
+         m._status = Machine::slot_offset_out_bounds;
+-//        return (m.slotMap().end() - map);
+         return 1;
++//        return m.run(_code, _data, map);
+     }
+ 
+     return  m.run(_code, _data, map);
+ }
+ 
+diff --git a/gfx/graphite2/src/Collider.cpp b/gfx/graphite2/src/Collider.cpp
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/Collider.cpp
+@@ -0,0 +1,1088 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#include <algorithm>
++#include <limits>
++#include <math.h>
++#include <string>
++#include <functional>
++#include "inc/Collider.h"
++#include "inc/Segment.h"
++#include "inc/Slot.h"
++#include "inc/GlyphCache.h"
++#include "inc/Sparse.h"
++
++#define ISQRT2 0.707106781f
++
++// Possible rounding error for subbox boundaries: 0.016 = 1/64 = 1/256 * 4 
++// (values in font range from 0..256)
++// #define SUBBOX_RND_ERR 0.016
++
++using namespace graphite2;
++
++////    SHIFT-COLLIDER    ////
++
++// Initialize the Collider to hold the basic movement limits for the
++// target slot, the one we are focusing on fixing.
++bool ShiftCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float margin, float marginWeight,
++    const Position &currShift, const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout)
++{
++    int i;
++    float mx, mn;
++    float a, shift;
++    const GlyphCache &gc = seg->getFace()->glyphs();
++    unsigned short gid = aSlot->gid();
++    if (!gc.check(gid))
++        return false;
++    const BBox &bb = gc.getBoundingBBox(gid);
++    const SlantBox &sb = gc.getBoundingSlantBox(gid);
++    //float sx = aSlot->origin().x + currShift.x;
++    //float sy = aSlot->origin().y + currShift.y;
++    if (currOffset.x != 0.f || currOffset.y != 0.f)
++        _limit = Rect(limit.bl - currOffset, limit.tr - currOffset);
++    else
++        _limit = limit;
++    // For a ShiftCollider, these indices indicate which vector we are moving by:
++    // each _ranges represents absolute space with respect to the origin of the slot. Thus take into account true origins but subtract the vmin for the slot
++    for (i = 0; i < 4; ++i)
++    {
++        switch (i) {
++            case 0 :	// x direction
++                mn = _limit.bl.x + currOffset.x;
++                mx = _limit.tr.x + currOffset.x;
++                _len[i] = bb.xa - bb.xi;
++                a = currOffset.y + currShift.y;
++                _ranges[i].initialise<XY>(mn, mx, margin, marginWeight, a);
++                break;
++            case 1 :	// y direction
++                mn = _limit.bl.y + currOffset.y;
++                mx = _limit.tr.y + currOffset.y;
++                _len[i] = bb.ya - bb.yi;
++                a = currOffset.x + currShift.x;
++                _ranges[i].initialise<XY>(mn, mx, margin, marginWeight, a);
++                break;
++            case 2 :	// sum (negatively sloped diagonal boundaries)
++                // pick closest x,y limit boundaries in s direction
++                shift = currOffset.x + currOffset.y + currShift.x + currShift.y;
++                mn = -2 * min(currShift.x - _limit.bl.x, currShift.y - _limit.bl.y) + shift;
++                mx = 2 * min(_limit.tr.x - currShift.x, _limit.tr.y - currShift.y) + shift;
++                _len[i] = sb.sa - sb.si;
++                a = currOffset.x - currOffset.y + currShift.x - currShift.y;
++                _ranges[i].initialise<SD>(mn, mx, margin / ISQRT2, marginWeight, a);
++                break;
++            case 3 :	// diff (positively sloped diagonal boundaries)
++                // pick closest x,y limit boundaries in d direction
++                shift = currOffset.x - currOffset.y + currShift.x - currShift.y;
++                mn = -2 * min(currShift.x - _limit.bl.x, _limit.tr.y - currShift.y) + shift;
++                mx = 2 * min(_limit.tr.x - currShift.x, currShift.y - _limit.bl.y) + shift;
++                _len[i] = sb.da - sb.di;
++                a = currOffset.x + currOffset.y + currShift.x + currShift.y;
++                _ranges[i].initialise<SD>(mn, mx, margin / ISQRT2, marginWeight, a);
++                break;
++        }
++    }
++
++	_target = aSlot;
++    if ((dir & 1) == 0)
++    {
++        // For LTR, switch and negate x limits.
++        _limit.bl.x = -1 * limit.tr.x;
++        //_limit.tr.x = -1 * limit.bl.x;
++    }
++    _currOffset = currOffset;
++    _currShift = currShift;
++    _origin = aSlot->origin() - currOffset;     // the original anchor position of the glyph
++
++	_margin = margin;
++	_marginWt = marginWeight;
++    
++    SlotCollision *c = seg->collisionInfo(aSlot);
++    _seqClass = c->seqClass();
++	_seqProxClass = c->seqProxClass();
++    _seqOrder = c->seqOrder();
++    return true;
++}
++
++template <class O>
++float sdm(float vi, float va, float mx, float my, O op)
++{
++    float res = 2 * mx - vi;
++    if (op(res, vi + 2 * my))
++    {
++        res = va + 2 * my;
++        if (op(res, 2 * mx - va))
++            res = mx + my;
++    }
++    return res;
++}
++
++// Mark an area with a cost that can vary along the x or y axis. The region is expressed in terms of the centre of the target glyph in each axis
++void ShiftCollider::addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int axis)
++{
++    float a, c;
++    switch (axis) {
++        case 0 :
++             if (box.bl.y < org.y + bb.ya && box.tr.y > org.y + bb.yi && box.width() > 0)
++            {
++                a = org.y + 0.5f * (bb.yi + bb.ya);
++                c = 0.5f * (bb.xi + bb.xa);
++                if (isx)
++                    _ranges[axis].weighted<XY>(box.bl.x - c, box.tr.x - c, weight, a, m,
++                                                (minright ? box.tr.x : box.bl.x) - c, a, 0, false);
++                else
++                    _ranges[axis].weighted<XY>(box.bl.x - c, box.tr.x - c, weight, a, 0, 0, org.y,
++                                                m * (a * a + sqr((minright ? box.tr.y : box.bl.y) - 0.5f * (bb.yi + bb.ya))), false);
++            }
++            break;
++        case 1 :
++            if (box.bl.x < org.x + bb.xa && box.tr.x > org.x + bb.xi && box.height() > 0)
++            {
++                a = org.x + 0.5f * (bb.xi + bb.xa);
++                c = 0.5f * (bb.yi + bb.ya);
++                if (isx)
++                    _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, 0, 0, org.x,
++                                                m * (a * a + sqr((minright ? box.tr.x : box.bl.x) - 0.5f * (bb.xi + bb.xa))), false);
++                else
++                    _ranges[axis].weighted<XY>(box.bl.y - c, box.tr.y - c, weight, a, m, 
++                                                (minright ? box.tr.y : box.bl.y) - c, a, 0, false);
++            }
++            break;
++        case 2 :
++            if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di)
++            {
++                float d = org.x - org.y + 0.5f * (sb.di + sb.da);
++                c = 0.5f * (sb.si + sb.sa);
++                float smax = min(2 * box.tr.x - d, 2 * box.tr.y + d);
++                float smin = max(2 * box.bl.x - d, 2 * box.bl.y + d);
++                if (smin > smax) return;
++                float si;
++                a = d;
++                if (isx)
++                    si = 2 * (minright ? box.tr.x : box.bl.x) - a;
++                else
++                    si = 2 * (minright ? box.tr.y : box.bl.y) + a;
++                _ranges[axis].weighted<SD>(smin - c, smax - c, weight / 2, a, m / 2, si, 0, 0, isx);
++            }
++            break;
++        case 3 :
++            if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si)
++            {
++                float s = org.x + org.y + 0.5f * (sb.si + sb.sa);
++                c = 0.5f * (sb.di + sb.da);
++                float dmax = min(2 * box.tr.x - s, s - 2 * box.bl.y);
++                float dmin = max(2 * box.bl.x - s, s - 2 * box.tr.y);
++                if (dmin > dmax) return;
++                float di;
++                a = s;
++                if (isx)
++                    di = 2 * (minright ? box.tr.x : box.bl.x) - a;
++                else
++                    di = 2 * (minright ? box.tr.y : box.bl.y) + a;
++                _ranges[axis].weighted<SD>(dmin - c, dmax - c, weight / 2, a, m / 2, di, 0, 0, !isx);
++            }
++            break;
++        default :
++            break;
++    }
++    return;
++}
++
++// Mark an area with an absolute cost, making it completely inaccessible.
++inline void ShiftCollider::removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int axis)
++{
++    float c;
++    switch (axis) {
++        case 0 :
++            if (box.bl.y < org.y + bb.ya && box.tr.y > org.y + bb.yi && box.width() > 0)
++            {
++                c = 0.5f * (bb.xi + bb.xa);
++                _ranges[axis].exclude(box.bl.x - c, box.tr.x - c);
++            }
++            break;
++        case 1 :
++            if (box.bl.x < org.x + bb.xa && box.tr.x > org.x + bb.xi && box.height() > 0)
++            {
++                c = 0.5f * (bb.yi + bb.ya);
++                _ranges[axis].exclude(box.bl.y - c, box.tr.y - c);
++            }
++            break;
++        case 2 :
++            if (box.bl.x - box.tr.y < org.x - org.y + sb.da && box.tr.x - box.bl.y > org.x - org.y + sb.di 
++                && box.width() > 0 && box.height() > 0)
++            {
++                float di = org.x - org.y + sb.di;
++                float da = org.x - org.y + sb.da;
++                float smax = sdm(di, da, box.tr.x, box.tr.y, std::greater<float>());
++                float smin = sdm(da, di, box.bl.x, box.bl.y, std::less<float>());
++                c = 0.5f * (sb.si + sb.sa);
++                _ranges[axis].exclude(smin - c, smax - c);
++            }
++            break;
++        case 3 :
++            if (box.bl.x + box.bl.y < org.x + org.y + sb.sa && box.tr.x + box.tr.y > org.x + org.y + sb.si 
++                && box.width() > 0 && box.height() > 0)
++            {
++                float si = org.x + org.y + sb.si;
++                float sa = org.x + org.y + sb.sa;
++                float dmax = sdm(si, sa, box.tr.x, -box.bl.y, std::greater<float>());
++                float dmin = sdm(sa, si, box.bl.x, -box.tr.y, std::less<float>());
++                c = 0.5f * (sb.di + sb.da);
++                _ranges[axis].exclude(dmin - c, dmax - c);
++            }
++            break;
++        default :
++            break;
++    }
++    return;
++}
++
++// Adjust the movement limits for the target to avoid having it collide
++// with the given neighbor slot. Also determine if there is in fact a collision
++// between the target and the given slot.
++bool ShiftCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift,
++		bool isAfter,  // slot is logically after _target
++		bool sameCluster, bool &hasCol, bool isExclusion,
++        GR_MAYBE_UNUSED json * const dbgout )
++{
++    bool isCol = false;
++    const float sx = slot->origin().x - _origin.x + currShift.x;
++    const float sy = slot->origin().y - _origin.y + currShift.y;
++    const float sd = sx - sy;
++    const float ss = sx + sy;
++    float vmin, vmax;
++    float omin, omax, otmin, otmax;
++    float cmin, cmax;   // target limits
++    float torg;
++    const GlyphCache &gc = seg->getFace()->glyphs();
++    const unsigned short gid = slot->gid();
++    if (!gc.check(gid))
++        return false;
++    const BBox &bb = gc.getBoundingBBox(gid);
++
++    SlotCollision * cslot = seg->collisionInfo(slot);
++    int orderFlags = 0;
++    bool sameClass = _seqProxClass == 0 && cslot->seqClass() == _seqClass;
++    if (sameCluster && _seqClass 
++        && (sameClass || (_seqProxClass != 0 && cslot->seqClass() == _seqProxClass)))
++		// Force the target glyph to be in the specified direction from the slot we're testing.
++        orderFlags = _seqOrder;
++
++    // short circuit if only interested in direct collision and we are out of range
++    if (orderFlags || (sx + bb.xa + _margin >= _limit.bl.x && sx + bb.xi - _margin <= _limit.tr.x)
++                    || (sy + bb.ya + _margin >= _limit.bl.y && sy + bb.yi - _margin <= _limit.tr.y))
++
++    {
++        const float tx = _currOffset.x + _currShift.x;
++        const float ty = _currOffset.y + _currShift.y;
++        const float td = tx - ty;
++        const float ts = tx + ty;
++        const SlantBox &sb = gc.getBoundingSlantBox(gid);
++        const unsigned short tgid = _target->gid();
++        const BBox &tbb = gc.getBoundingBBox(tgid);
++        const SlantBox &tsb = gc.getBoundingSlantBox(tgid);
++        float seq_above_wt = cslot->seqAboveWt();
++        float seq_below_wt = cslot->seqBelowWt();
++        float seq_valign_wt = cslot->seqValignWt();
++        // if isAfter, invert orderFlags for diagonal orders.
++        if (isAfter)
++        {
++            // invert appropriate bits
++            orderFlags ^= (sameClass ? 0x3F : 0x3);
++            // consider 2 bits at a time, non overlapping. If both bits set, clear them
++            orderFlags = orderFlags ^ ((((orderFlags >> 1) & orderFlags) & 0x15) * 3);
++        }
++
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)
++            dbgout->setenv(0, slot);
++#endif
++
++        // Process main bounding octabox.
++        for (int i = 0; i < 4; ++i)
++        {
++            switch (i) {
++                case 0 :	// x direction
++                    vmin = max(max(bb.xi - tbb.xa + sx, sb.di - tsb.da + ty + sd), sb.si - tsb.sa - ty + ss);
++                    vmax = min(min(bb.xa - tbb.xi + sx, sb.da - tsb.di + ty + sd), sb.sa - tsb.si - ty + ss);
++                    otmin = tbb.yi + ty;
++                    otmax = tbb.ya + ty;
++                    omin = bb.yi + sy;
++                    omax = bb.ya + sy;
++                    torg = _currOffset.x;
++                    cmin = _limit.bl.x + torg;
++                    cmax = _limit.tr.x - tbb.xi + tbb.xa + torg;
++                    break;
++                case 1 :	// y direction
++                    vmin = max(max(bb.yi - tbb.ya + sy, tsb.di - sb.da + tx - sd), sb.si - tsb.sa - tx + ss);
++                    vmax = min(min(bb.ya - tbb.yi + sy, tsb.da - sb.di + tx - sd), sb.sa - tsb.si - tx + ss);
++                    otmin = tbb.xi + tx;
++                    otmax = tbb.xa + tx;
++                    omin = bb.xi + sx;
++                    omax = bb.xa + sx;
++                    torg = _currOffset.y;
++                    cmin = _limit.bl.y + torg;
++                    cmax = _limit.tr.y - tbb.yi + tbb.ya + torg;
++                    break;
++                case 2 :    // sum - moving along the positively-sloped vector, so the boundaries are the
++                            // negatively-sloped boundaries.
++                    vmin = max(max(sb.si - tsb.sa + ss, 2 * (bb.yi - tbb.ya + sy) + td), 2 * (bb.xi - tbb.xa + sx) - td);
++                    vmax = min(min(sb.sa - tsb.si + ss, 2 * (bb.ya - tbb.yi + sy) + td), 2 * (bb.xa - tbb.xi + sx) - td);
++                    otmin = tsb.di + td;
++                    otmax = tsb.da + td;
++                    omin = sb.di + sd;
++                    omax = sb.da + sd;
++                    torg = _currOffset.x + _currOffset.y;
++                    cmin = _limit.bl.x + _limit.bl.y + torg;
++                    cmax = _limit.tr.x + _limit.tr.y - tsb.si + tsb.sa + torg;
++                    break;
++                case 3 :    // diff - moving along the negatively-sloped vector, so the boundaries are the
++                            // positively-sloped boundaries.
++                    vmin = max(max(sb.di - tsb.da + sd, 2 * (bb.xi - tbb.xa + sx) - ts), -2 * (bb.ya - tbb.yi + sy) + ts);
++                    vmax = min(min(sb.da - tsb.di + sd, 2 * (bb.xa - tbb.xi + sx) - ts), -2 * (bb.yi - tbb.ya + sy) + ts);
++                    otmin = tsb.si + ts;
++                    otmax = tsb.sa + ts;
++                    omin = sb.si + ss;
++                    omax = sb.sa + ss;
++                    torg = _currOffset.x - _currOffset.y;
++                    cmin = _limit.bl.x - _limit.tr.y + torg;
++                    cmax = _limit.tr.x - _limit.bl.y - tsb.di + tsb.da + torg;
++                    break;
++                default :
++                    continue;
++            }
++            
++#if !defined GRAPHITE2_NTRACING
++            if (dbgout)
++                dbgout->setenv(1, reinterpret_cast<void *>(-1));
++#define DBGTAG(x) if (dbgout) dbgout->setenv(1, reinterpret_cast<void *>(-x));
++#else
++#define DBGTAG(x)
++#endif
++
++            if (orderFlags)
++            {
++                Position org(tx, ty);
++                float xminf = _limit.bl.x + _currOffset.x + tbb.xi;
++                float xpinf = _limit.tr.x + _currOffset.x + tbb.xa;
++                float ypinf = _limit.tr.y + _currOffset.y + tbb.ya;
++                float yminf = _limit.bl.y + _currOffset.y + tbb.yi;
++                switch (orderFlags) {
++                    case SlotCollision::SEQ_ORDER_RIGHTUP :
++                    {
++                        float r1Xedge = cslot->seqAboveXoff() + 0.5f * (bb.xi + bb.xa) + sx;
++                        float r3Xedge = cslot->seqBelowXlim() + bb.xa + sx + 0.5f * (tbb.xa - tbb.xi);
++                        float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy;
++                        
++                        // DBGTAG(1x) means the regions are up and right
++                        // region 1
++                        DBGTAG(11)
++                        addBox_slope(true, Rect(Position(xminf, r2Yedge), Position(r1Xedge, ypinf)),
++                                        tbb, tsb, org, 0, seq_above_wt, true, i);
++                        // region 2
++                        DBGTAG(12)
++                        removeBox(Rect(Position(xminf, yminf), Position(r3Xedge, r2Yedge)), tbb, tsb, org, i);
++                        // region 3, which end is zero is irrelevant since m weight is 0
++                        DBGTAG(13)
++                        addBox_slope(true, Rect(Position(r3Xedge, yminf), Position(xpinf, r2Yedge - cslot->seqValignHt())),
++                                        tbb, tsb, org, seq_below_wt, 0, true, i);
++                        // region 4
++                        DBGTAG(14)
++                        addBox_slope(false, Rect(Position(sx + bb.xi, r2Yedge), Position(xpinf, r2Yedge + cslot->seqValignHt())),
++                                        tbb, tsb, org, 0, seq_valign_wt, true, i);
++                        // region 5
++                        DBGTAG(15)
++                        addBox_slope(false, Rect(Position(sx + bb.xi, r2Yedge - cslot->seqValignHt()), Position(xpinf, r2Yedge)),
++                                        tbb, tsb, org, seq_below_wt, seq_valign_wt, false, i);
++                        break;
++                    }
++                    case SlotCollision::SEQ_ORDER_LEFTDOWN :
++                    {
++                        float r1Xedge = 0.5f * (bb.xi + bb.xa) + cslot->seqAboveXoff() + sx;
++                        float r3Xedge = bb.xi - cslot->seqBelowXlim() + sx - 0.5f * (tbb.xa - tbb.xi);
++                        float r2Yedge = 0.5f * (bb.yi + bb.ya) + sy;
++                        // DBGTAG(2x) means the regions are up and right
++                        // region 1
++                        DBGTAG(21)
++                        addBox_slope(true, Rect(Position(r1Xedge, yminf), Position(xpinf, r2Yedge)),
++                                        tbb, tsb, org, 0, seq_above_wt, false, i);
++                        // region 2
++                        DBGTAG(22)
++                        removeBox(Rect(Position(r3Xedge, r2Yedge), Position(xpinf, ypinf)), tbb, tsb, org, i);
++                        // region 3
++                        DBGTAG(23)
++                        addBox_slope(true, Rect(Position(xminf, r2Yedge - cslot->seqValignHt()), Position(r3Xedge, ypinf)),
++                                        tbb, tsb, org, seq_below_wt, 0, false, i);
++                        // region 4
++                        DBGTAG(24)
++                        addBox_slope(false, Rect(Position(xminf, r2Yedge), Position(sx + bb.xa, r2Yedge + cslot->seqValignHt())),
++                                        tbb, tsb, org, 0, seq_valign_wt, true, i);
++                        // region 5
++                        DBGTAG(25)
++                        addBox_slope(false, Rect(Position(xminf, r2Yedge - cslot->seqValignHt()),
++                                        Position(sx + bb.xa, r2Yedge)), tbb, tsb, org, seq_below_wt, seq_valign_wt, false, i);
++                        break;
++                    }
++                    case SlotCollision::SEQ_ORDER_NOABOVE : // enforce neighboring glyph being above
++                        DBGTAG(31);
++                        removeBox(Rect(Position(bb.xi - tbb.xa + sx, sy + bb.ya), 
++                                        Position(bb.xa - tbb.xi + sx, ypinf)), tbb, tsb, org, i);
++                        break;
++                    case SlotCollision::SEQ_ORDER_NOBELOW :	// enforce neighboring glyph being below
++                        DBGTAG(32);
++                        removeBox(Rect(Position(bb.xi - tbb.xa + sx, yminf),
++                                        Position(bb.xa - tbb.xi + sx, sy + bb.yi)), tbb, tsb, org, i);
++                        break;
++                    case SlotCollision::SEQ_ORDER_NOLEFT :  // enforce neighboring glyph being to the left
++                        DBGTAG(33)
++                        removeBox(Rect(Position(xminf, bb.yi - tbb.ya + sy),
++                                        Position(bb.xi - tbb.xa + sx, bb.ya - tbb.yi + sy)), tbb, tsb, org, i);
++                        break;
++                    case SlotCollision::SEQ_ORDER_NORIGHT : // enforce neighboring glyph being to the right
++                        DBGTAG(34)
++                        removeBox(Rect(Position(bb.xa - tbb.xi + sx, bb.yi - tbb.ya + sy),
++                                        Position(xpinf, bb.ya - tbb.yi + sy)), tbb, tsb, org, i);
++                        break;
++                    default :
++                        break;
++                }
++            }
++
++            if (vmax < cmin - _margin || vmin > cmax + _margin || omax < otmin - _margin || omin > otmax + _margin)
++                continue;
++
++            // Process sub-boxes that are defined for this glyph.
++            // We only need to do this if there was in fact a collision with the main octabox.
++            uint8 numsub = gc.numSubBounds(gid);
++            if (numsub > 0)
++            {
++                bool anyhits = false;
++                for (int j = 0; j < numsub; ++j)
++                {
++                    const BBox &sbb = gc.getSubBoundingBBox(gid, j);
++                    const SlantBox &ssb = gc.getSubBoundingSlantBox(gid, j);
++                    switch (i) {
++                        case 0 :    // x
++                            vmin = max(max(sbb.xi-tbb.xa+sx, ssb.di-tsb.da+sd+ty), ssb.si-tsb.sa+ss-ty);
++                            vmax = min(min(sbb.xa-tbb.xi+sx, ssb.da-tsb.di+sd+ty), ssb.sa-tsb.si+ss-ty);
++                            omin = sbb.yi + sy;
++                            omax = sbb.ya + sy;
++                            break;
++                        case 1 :    // y
++                            vmin = max(max(sbb.yi-tbb.ya+sy, tsb.di-ssb.da-sd+tx), ssb.si-tsb.sa+ss-tx);
++                            vmax = min(min(sbb.ya-tbb.yi+sy, tsb.da-ssb.di-sd+tx), ssb.sa-tsb.si+ss-tx);
++                            omin = sbb.xi + sx;
++                            omax = sbb.xa + sx;
++                            break;
++                        case 2 :    // sum
++                            vmin = max(max(ssb.si-tsb.sa+ss, 2*(sbb.yi-tbb.ya+sy)+td), 2*(sbb.xi-tbb.xa+sx)-td);
++                            vmax = min(min(ssb.sa-tsb.si+ss, 2*(sbb.ya-tbb.yi+sy)+td), 2*(sbb.xa-tbb.xi+sx)-td);
++                            omin = ssb.di + sd;
++                            omax = ssb.da + sd;
++                            break;
++                        case 3 :    // diff
++                            vmin = max(max(ssb.di-tsb.da+sd, 2*(sbb.xi-tbb.xa+sx)-ts), -2*(sbb.ya-tbb.yi+sy)+ts);
++                            vmax = min(min(ssb.da-tsb.di+sd, 2*(sbb.xa-tbb.xi+sx)-ts), -2*(sbb.yi-tbb.ya+sy)+ts);
++                            omin = ssb.si + ss;
++                            omax = ssb.sa + ss;
++                            break;
++                    }
++                    if (vmax < cmin - _margin || vmin > cmax + _margin || omax < otmin - _margin || omin > otmax + _margin)
++                        continue;
++
++#if !defined GRAPHITE2_NTRACING
++                    if (dbgout)
++                        dbgout->setenv(1, reinterpret_cast<void *>(j));
++#endif
++                    if (omin > otmax)
++                        _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
++                                                sqr(_margin - omin + otmax) * _marginWt, false);
++                    else if (omax < otmin)
++                        _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
++                                                sqr(_margin - otmin + omax) * _marginWt, false);
++                    else
++                        _ranges[i].exclude_with_margins(vmin, vmax, i);
++                    anyhits = true;
++                }
++                if (anyhits)
++                    isCol = true;
++            }
++            else // no sub-boxes
++            {
++#if !defined GRAPHITE2_NTRACING
++                    if (dbgout)
++                        dbgout->setenv(1, reinterpret_cast<void *>(-1));
++#endif
++                isCol = true;
++                if (omin > otmax)
++                    _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
++                                            sqr(_margin - omin + otmax) * _marginWt, false);
++                else if (omax < otmin)
++                    _ranges[i].weightedAxis(i, vmin - _margin, vmax + _margin, 0, 0, 0, 0, 0,
++                                            sqr(_margin - otmin + omax) * _marginWt, false);
++                else
++                    _ranges[i].exclude_with_margins(vmin, vmax, i);
++
++            }
++        }
++    }
++    bool res = true;
++    if (cslot->exclGlyph() > 0 && gc.check(cslot->exclGlyph()) && !isExclusion)
++    {
++        // Set up the bogus slot representing the exclusion glyph.
++        Slot *exclSlot = seg->newSlot();
++        exclSlot->setGlyph(seg, cslot->exclGlyph());
++        Position exclOrigin(slot->origin() + cslot->exclOffset());
++        exclSlot->origin(exclOrigin);
++        res &= mergeSlot(seg, exclSlot, currShift, isAfter, sameCluster, isCol, true, dbgout );
++        seg->freeSlot(exclSlot);
++    }
++    hasCol |= isCol;
++    return res;
++    
++}   // end of ShiftCollider::mergeSlot
++
++
++// Figure out where to move the target glyph to, and return the amount to shift by.
++Position ShiftCollider::resolve(GR_MAYBE_UNUSED Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout)
++{
++    float tbase;
++    float totalCost = (float)(std::numeric_limits<float>::max() / 2);
++    Position resultPos = Position(0, 0);
++#if !defined GRAPHITE2_NTRACING
++	int bestAxis = -1;
++    if (dbgout)
++    {
++		outputJsonDbgStartSlot(dbgout, seg);
++        *dbgout << "vectors" << json::array;
++    }
++#endif
++    isCol = true;
++    for (int i = 0; i < 4; ++i)
++    {
++        float bestCost = -1;
++        float bestPos;
++        // Calculate the margin depending on whether we are moving diagonally or not:
++        switch (i) {
++            case 0 :	// x direction
++                tbase = _currOffset.x;
++                break;
++            case 1 :	// y direction
++                tbase = _currOffset.y;
++                break;
++            case 2 :	// sum (negatively-sloped diagonals)
++                tbase = _currOffset.x + _currOffset.y;
++                break;
++            case 3 :	// diff (positively-sloped diagonals)
++                tbase = _currOffset.x - _currOffset.y;
++                break;
++        }
++        Position testp;
++        bestPos = _ranges[i].closest(0, bestCost) - tbase;     // Get the best relative position
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)
++            outputJsonDbgOneVector(dbgout, seg, i, tbase, bestCost, bestPos) ;
++#endif
++        if (bestCost >= 0.0f)
++        {
++            isCol = false;
++            switch (i) {
++                case 0 : testp = Position(bestPos, _currShift.y); break;
++                case 1 : testp = Position(_currShift.x, bestPos); break;
++                case 2 : testp = Position(0.5f * (_currShift.x - _currShift.y + bestPos), 0.5f * (_currShift.y - _currShift.x + bestPos)); break;
++                case 3 : testp = Position(0.5f * (_currShift.x + _currShift.y + bestPos), 0.5f * (_currShift.x + _currShift.y - bestPos)); break;
++            }
++            if (bestCost < totalCost - 0.01f)
++            {
++                totalCost = bestCost;
++                resultPos = testp;
++#if !defined GRAPHITE2_NTRACING
++                bestAxis = i;
++#endif
++            }
++        }
++    }  // end of loop over 4 directions
++
++#if !defined GRAPHITE2_NTRACING
++    if (dbgout)
++        outputJsonDbgEndSlot(dbgout, resultPos, bestAxis, isCol);
++#endif
++
++    return resultPos;
++
++}   // end of ShiftCollider::resolve
++
++
++#if !defined GRAPHITE2_NTRACING
++
++void ShiftCollider::outputJsonDbg(json * const dbgout, Segment *seg, int axis)
++{
++    int axisMax = axis;
++    if (axis < 0) // output all axes
++    {
++        *dbgout << "gid" << _target->gid()
++            << "limit" << _limit
++            << "target" << json::object
++                << "origin" << _target->origin()
++                << "margin" << _margin
++                << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
++                << "slantbox" << seg->getFace()->glyphs().slant(_target->gid())
++                << json::close; // target object
++        *dbgout << "ranges" << json::array;
++        axis = 0;
++        axisMax = 3;
++    }
++    for (int iAxis = axis; iAxis <= axisMax; ++iAxis)
++    {
++        *dbgout << json::flat << json::array << _ranges[iAxis].position();
++        for (Zones::const_iterator s = _ranges[iAxis].begin(), e = _ranges[iAxis].end(); s != e; ++s)
++            *dbgout << json::flat << json::array 
++                        << Position(s->x, s->xm) << s->sm << s->smx << s->c
++                    << json::close;
++        *dbgout << json::close;
++    }
++    if (axis < axisMax) // looped through the _ranges array for all axes
++        *dbgout << json::close; // ranges array
++}
++
++void ShiftCollider::outputJsonDbgStartSlot(json * const dbgout, Segment *seg)
++{
++        *dbgout << json::object // slot - not closed till the end of the caller method
++                << "slot" << objectid(dslot(seg, _target))
++				<< "gid" << _target->gid()
++                << "limit" << _limit
++                << "target" << json::object
++                    << "origin" << _origin
++                    << "currShift" << _currShift
++                    << "currOffset" << seg->collisionInfo(_target)->offset()
++                    << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
++                    << "slantBox" << seg->getFace()->glyphs().slant(_target->gid())
++                    << "fix" << "shift";
++        *dbgout     << json::close; // target object
++}
++
++void ShiftCollider::outputJsonDbgEndSlot(GR_MAYBE_UNUSED json * const dbgout,
++	 Position resultPos, int bestAxis, bool isCol)
++{
++    *dbgout << json::close // vectors array
++    << "result" << resultPos
++	//<< "scraping" << _scraping[bestAxis]
++	<< "bestAxis" << bestAxis
++    << "stillBad" << isCol
++    << json::close; // slot object
++}
++
++void ShiftCollider::outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis,
++	float tleft, float bestCost, float bestVal) 
++{
++	const char * label;
++	switch (axis)
++	{
++		case 0:	label = "x";			break;
++		case 1:	label = "y";			break;
++		case 2:	label = "sum (NE-SW)";	break;
++		case 3:	label = "diff (NW-SE)";	break;
++		default: label = "???";			break;
++	}
++
++	*dbgout << json::object // vector
++		<< "direction" << label
++		<< "targetMin" << tleft;
++            
++	outputJsonDbgRemovals(dbgout, axis, seg);
++    	
++    *dbgout << "ranges";
++    outputJsonDbg(dbgout, seg, axis);
++
++    *dbgout << "bestCost" << bestCost
++        << "bestVal" << bestVal + tleft
++        << json::close; // vectors object
++}
++
++void ShiftCollider::outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg)
++{
++    *dbgout << "removals" << json::array;
++    _ranges[axis].jsonDbgOut(seg);
++    *dbgout << json::close; // removals array
++}
++
++#endif // !defined GRAPHITE2_NTRACING
++
++
++////    KERN-COLLIDER    ////
++
++inline
++static float localmax (float al, float au, float bl, float bu, float x)
++{
++    if (al < bl)
++    { if (au < bu) return au < x ? au : x; }
++    else if (au > bu) return bl < x ? bl : x;
++    return x;
++}
++
++inline
++static float localmin(float al, float au, float bl, float bu, float x)
++{
++    if (bl > al)
++    { if (bu > au) return bl > x ? bl : x; }
++    else if (au > bu) return al > x ? al : x;
++    return x;        
++}
++
++// Return the given edge of the glyph at height y, taking any slant box into account.
++static float get_edge(Segment *seg, const Slot *s, const Position &shift, float y, float width, bool isRight)
++{
++    const GlyphCache &gc = seg->getFace()->glyphs();
++    unsigned short gid = s->gid();
++    float sx = s->origin().x + shift.x;
++    float sy = s->origin().y + shift.y;
++    uint8 numsub = gc.numSubBounds(gid);
++    float res = isRight ? (float)-1e38 : (float)1e38;
++
++    if (numsub > 0)
++    {
++        for (int i = 0; i < numsub; ++i)
++        {
++            const BBox &sbb = gc.getSubBoundingBBox(gid, i);
++            const SlantBox &ssb = gc.getSubBoundingSlantBox(gid, i);
++            if (sy + sbb.yi > y + width / 2 || sy + sbb.ya < y - width / 2)
++                continue;
++            if (isRight)
++            {
++                float x = sx + sbb.xa;
++                if (x > res)
++                {
++                    float td = sx - sy + ssb.da + y;
++                    float ts = sx + sy + ssb.sa - y;
++                    x = localmax(td - width / 2, td + width / 2,  ts - width / 2, ts + width / 2, x);
++                    if (x > res)
++                        res = x;
++                }
++            }
++            else
++            {
++                float x = sx + sbb.xi;
++                if (x < res)
++                {
++                    float td = sx - sy + ssb.di + y;
++                    float ts = sx + sy + ssb.si - y;
++                    x = localmin(td - width / 2, td + width / 2, ts - width / 2, ts + width / 2, x);
++                    if (x < res)
++                        res = x;
++                }
++            }
++        }
++    }
++    else
++    {
++        const BBox &bb = gc.getBoundingBBox(gid);
++        const SlantBox &sb = gc.getBoundingSlantBox(gid);
++        float td = sx - sy + y;
++        float ts = sx + sy - y;
++        if (isRight)
++            res = localmax(td + sb.da - width / 2, td + sb.da + width / 2, ts + sb.sa - width / 2, ts + sb.sa + width / 2, sx + bb.xa);
++        else
++            res = localmin(td + sb.di - width / 2, td + sb.di + width / 2, ts + sb.si - width / 2, ts + sb.si + width / 2, sx + bb.xi);
++    }
++    return res;
++}
++
++
++bool KernCollider::initSlot(Segment *seg, Slot *aSlot, const Rect &limit, float margin,
++    const Position &currShift, const Position &offsetPrev, int dir,
++    float ymin, float ymax, GR_MAYBE_UNUSED json * const dbgout)
++{
++    const GlyphCache &gc = seg->getFace()->glyphs();
++    const Slot *base = aSlot;
++    // const Slot *last = aSlot;
++    const Slot *s;
++    int numSlices;
++    while (base->attachedTo())
++        base = base->attachedTo();
++    if (margin < 10) margin = 10;
++
++    _limit = limit;
++    _offsetPrev = offsetPrev; // kern from a previous pass
++    
++    // Calculate the height of the glyph and how many horizontal slices to use.
++    if (_maxy >= 1e37f)
++    {
++        _maxy = ymax;
++        _miny = ymin;
++        _sliceWidth = margin / 1.5f;
++        numSlices = int((_maxy - _miny + 2) / (_sliceWidth / 1.5f) + 1.f);  // +2 helps with rounding errors
++        _edges.clear();
++        _edges.insert(_edges.begin(), numSlices, (dir & 1) ? 1e38f : -1e38f);
++        _xbound = (dir & 1) ? (float)1e38f : (float)-1e38f;
++    }
++    else if (_maxy != ymax || _miny != ymin)
++    {
++        if (_miny != ymin)
++        {
++            numSlices = int((ymin - _miny) / _sliceWidth - 1);
++            _miny += numSlices * _sliceWidth;
++            if (numSlices < 0)
++                _edges.insert(_edges.begin(), -numSlices, (dir & 1) ? 1e38f : -1e38f);
++            else if ((unsigned)numSlices < _edges.size())    // this shouldn't fire since we always grow the range
++            {
++                Vector<float>::iterator e = _edges.begin();
++                while (numSlices--)
++                    ++e;
++                _edges.erase(_edges.begin(), e);
++            }
++        }
++        if (_maxy != ymax)
++        {
++            numSlices = int((ymax - _miny) / _sliceWidth + 1);
++            _maxy = numSlices * _sliceWidth + _miny;
++            if (numSlices > (int)_edges.size())
++                _edges.insert(_edges.end(), numSlices - _edges.size(), (dir & 1) ? 1e38f : -1e38f);
++            else if (numSlices < (int)_edges.size())   // this shouldn't fire since we always grow the range
++            {
++                while ((int)_edges.size() > numSlices)
++                    _edges.pop_back();
++            }
++        }
++    }
++    numSlices = _edges.size();
++
++#if !defined GRAPHITE2_NTRACING
++    // Debugging
++    _seg = seg;
++    _slotNear.clear();
++    _slotNear.insert(_slotNear.begin(), numSlices, NULL);
++    _nearEdges.clear();
++    _nearEdges.insert(_nearEdges.begin(), numSlices, (dir & 1) ? -1e38f : +1e38f);
++#endif
++    
++    // Determine the trailing edge of each slice (ie, left edge for a RTL glyph).
++    for (s = base; s; s = s->nextInCluster(s))
++    {
++        SlotCollision *c = seg->collisionInfo(s);
++        if (!gc.check(s->gid()))
++            return false;
++        const BBox &bs = gc.getBoundingBBox(s->gid());
++        float x = s->origin().x + c->shift().x + ((dir & 1) ? bs.xi : bs.xa);
++        // Loop over slices.
++        // Note smin might not be zero if glyph s is not at the bottom of the cluster; similarly for smax.
++        float toffset = c->shift().y - _miny + 1 + s->origin().y;
++        int smin = max(0, int((bs.yi + toffset) / _sliceWidth));
++        int smax = min(numSlices - 1, int((bs.ya + toffset) / _sliceWidth + 1));
++        for (int i = smin; i <= smax; ++i)
++        {
++            float t;
++            float y = _miny - 1 + (i + .5f) * _sliceWidth; // vertical center of slice
++            if ((dir & 1) && x < _edges[i])
++            {
++                t = get_edge(seg, s, c->shift(), y, _sliceWidth, false);
++                if (t < _edges[i])
++                {
++                    _edges[i] = t;
++                    if (t < _xbound)
++                        _xbound = t;
++                }
++            }
++            else if (!(dir & 1) && x > _edges[i])
++            {
++                t = get_edge(seg, s, c->shift(), y, _sliceWidth, true);
++                if (t > _edges[i])
++                {
++                    _edges[i] = t;
++                    if (t > _xbound)
++                        _xbound = t;
++                }
++            }
++        }
++    }
++    _mingap = (float)1e38;
++    _target = aSlot;
++    _margin = margin;
++    _currShift = currShift;
++    return true;
++}   // end of KernCollider::initSlot
++
++
++// Determine how much the target slot needs to kern away from the given slot.
++// In other words, merge information from given slot's position with what the target slot knows
++// about how it can kern.
++// Return false if we know there is no collision, true if we think there might be one.
++bool KernCollider::mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, GR_MAYBE_UNUSED json * const dbgout)
++{
++    int rtl = (dir & 1) * 2 - 1;
++    if (!seg->getFace()->glyphs().check(slot->gid()))
++        return false;
++    const Rect &bb = seg->theGlyphBBoxTemporary(slot->gid());
++    const float sx = slot->origin().x + currShift.x;
++    float x = sx + (rtl > 0 ? bb.tr.x : bb.bl.x);
++    // this isn't going to reduce _mingap so skip
++    if ((rtl > 0 && x < _xbound - _mingap - currSpace) || (rtl <= 0 && x > _xbound + _mingap + currSpace))
++        return false;
++
++    const float sy = slot->origin().y + currShift.y;
++    int smin = max(0, int((bb.bl.y + (1 - _miny + sy)) / _sliceWidth + 1));
++    int smax = min((int)_edges.size() - 1, int((bb.tr.y + (1 - _miny + sy)) / _sliceWidth + 1));
++    bool collides = false;
++
++    for (int i = smin; i <= smax; ++i)
++    {
++        float t;
++        float y = (float)(_miny - 1 + (i + .5f) * _sliceWidth);  // vertical center of slice
++        if (x * rtl > _edges[i] * rtl - _mingap - currSpace)
++        {
++            // 2 * currSpace to account for the space that is already separating them and the space we want to add
++            float m = get_edge(seg, slot, currShift, y, _sliceWidth, rtl > 0) + 2 * rtl * currSpace;
++            t = rtl * (_edges[i] - m);
++            // Check slices above and below (if any).
++            if (i < (int)_edges.size() - 1) t = min(t, rtl * (_edges[i+1] - m));
++            if (i > 0) t = min(t, rtl * (_edges[i-1] - m));
++            // _mingap is positive to shrink
++            if (t < _mingap)
++            {
++                _mingap = t;
++                collides = true;
++            }
++#if !defined GRAPHITE2_NTRACING
++            // Debugging - remember the closest neighboring edge for this slice.
++            if (rtl * m > rtl * _nearEdges[i])
++            {
++                _slotNear[i] = slot;
++                _nearEdges[i] = m;
++            }
++#endif
++        }
++    }
++    return collides;   // note that true is not a necessarily reliable value
++    
++}   // end of KernCollider::mergeSlot
++
++
++// Return the amount to kern by.
++Position KernCollider::resolve(GR_MAYBE_UNUSED Segment *seg, GR_MAYBE_UNUSED Slot *slot,
++        int dir, float margin, GR_MAYBE_UNUSED json * const dbgout)
++{
++    float resultNeeded = (1 - 2 * (dir & 1)) * (_mingap - margin);
++    float result = min(_limit.tr.x - _offsetPrev.x, max(resultNeeded, _limit.bl.x - _offsetPrev.x));
++
++#if !defined GRAPHITE2_NTRACING
++    if (dbgout)
++    {
++        *dbgout << json::object // slot
++                << "slot" << objectid(dslot(seg, _target))
++				<< "gid" << _target->gid()
++                << "margin" << _margin
++                << "limit" << _limit
++                << "miny" << _miny
++                << "maxy" << _maxy
++                << "slicewidth" << _sliceWidth
++                << "target" << json::object
++                    << "origin" << _target->origin()
++                    //<< "currShift" << _currShift
++                    << "offsetPrev" << _offsetPrev
++                    << "bbox" << seg->theGlyphBBoxTemporary(_target->gid())
++                    << "slantBox" << seg->getFace()->glyphs().slant(_target->gid())
++                    << "fix" << "kern"
++                    << json::close; // target object
++        
++        *dbgout << "slices" << json::array;
++        for (int is = 0; is < (int)_edges.size(); is++)
++        {
++            *dbgout << json::flat << json::object 
++                << "i" << is 
++                << "targetEdge" << _edges[is]
++                << "neighbor" << objectid(dslot(seg, _slotNear[is]))
++                << "nearEdge" << _nearEdges[is] 
++                << json::close;
++        }
++        *dbgout << json::close; // slices array
++            
++        *dbgout
++            << "xbound" << _xbound
++            << "minGap" << _mingap
++            << "needed" << resultNeeded
++            << "result" << result
++            << "stillBad" << (result != resultNeeded)
++            << json::close; // slot object
++    }
++#endif
++
++    return Position(result, 0.);
++    
++}   // end of KernCollider::resolve
++
++void KernCollider::shift(const Position &mv, int dir)
++{
++    for (Vector<float>::iterator e = _edges.begin(); e != _edges.end(); ++e)
++        *e += mv.x;
++    _xbound += (1 - 2 * (dir & 1)) * mv.x;
++}
++
++////    SLOT-COLLISION    ////
++
++// Initialize the collision attributes for the given slot.
++SlotCollision::SlotCollision(Segment *seg, Slot *slot)
++{
++    initFromSlot(seg, slot);
++}
++
++void SlotCollision::initFromSlot(Segment *seg, Slot *slot)
++{
++    // Initialize slot attributes from glyph attributes.
++	// The order here must match the order in the grcompiler code, 
++	// GrcSymbolTable::AssignInternalGlyphAttrIDs.
++    uint16 gid = slot->gid();
++    uint16 aCol = seg->silf()->aCollision(); // flags attr ID
++    const GlyphFace * glyphFace = seg->getFace()->glyphs().glyphSafe(gid);
++    if (!glyphFace)
++        return;
++    const sparse &p = glyphFace->attrs();
++    _flags = p[aCol];
++    _limit = Rect(Position(p[aCol+1], p[aCol+2]),
++                  Position(p[aCol+3], p[aCol+4]));
++    _margin = p[aCol+5];
++    _marginWt = p[aCol+6];
++
++    _seqClass = p[aCol+7];
++	_seqProxClass = p[aCol+8];
++    _seqOrder = p[aCol+9];
++	_seqAboveXoff = p[aCol+10];
++	_seqAboveWt = p[aCol+11];
++	_seqBelowXlim = p[aCol+12];
++	_seqBelowWt = p[aCol+13];
++	_seqValignHt = p[aCol+14];
++	_seqValignWt = p[aCol+15];    
++
++    // These attributes do not have corresponding glyph attribute:
++    _exclGlyph = 0;
++    _exclOffset = Position(0, 0);
++}
++
++float SlotCollision::getKern(int dir) const
++{
++    if ((_flags & SlotCollision::COLL_KERN) != 0)
++        return float(_shift.x * ((dir & 1) ? -1 : 1));
++    else
++    	return 0;
++}
++
+diff --git a/gfx/graphite2/src/Decompressor.cpp b/gfx/graphite2/src/Decompressor.cpp
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/Decompressor.cpp
+@@ -0,0 +1,113 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2015, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#include <cassert>
++
++#include "inc/Decompressor.h"
++#include "inc/Compression.h"
++
++using namespace lz4;
++
++namespace {
++
++inline
++u32 read_literal(u8 const * &s, u8 const * const e, u32 l) {
++    if (l == 15 && s != e)
++    {
++        u8 b = 0;
++        do { l += b = *s++; } while(b==0xff && s != e);
++    }
++    return l;
++}
++
++bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal, u32 & literal_len, u32 & match_len, u32 & match_dist)
++{
++    u8 const token = *src++;
++    
++    literal_len = read_literal(src, end, token >> 4);
++    literal = src;
++    src += literal_len;
++    
++    if (src > end - 2)
++        return false;
++    
++    match_dist  = *src++;
++    match_dist |= *src++ << 8;
++    match_len = read_literal(src, end, token & 0xf);
++    
++    return src <= end-5;
++}
++
++}
++
++int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
++{
++    if (out_size <= in_size || in_size < sizeof(unsigned long)+1)
++        return -1;
++    
++    u8 const *       src     = static_cast<u8 const *>(in),
++             *       literal = 0,
++             * const src_end = src + in_size;
++
++    u8 *       dst     = static_cast<u8*>(out),
++       * const dst_end = dst + out_size;
++    
++    u32 literal_len = 0,
++        match_len = 0,
++        match_dist = 0;
++    
++    while (read_sequence(src, src_end, literal, literal_len, match_len, match_dist))
++    {
++        if (literal_len != 0)
++        {
++            // Copy in literal. At this point the last full sequence must be at
++            // least MINMATCH + 5 from the end of the output buffer.
++            if (dst + align(literal_len) > dst_end - (MINMATCH+5))
++                return -1;
++            dst = overrun_copy(dst, literal, literal_len);
++        }
++        
++        // Copy, possibly repeating, match from earlier in the
++        //  decoded output.
++        u8 const * const pcpy = dst - match_dist;
++        if (pcpy < static_cast<u8*>(out)
++                  || dst + match_len + MINMATCH > dst_end - 5)
++            return -1;
++        if (dst > pcpy+sizeof(unsigned long) 
++            && dst + align(match_len + MINMATCH) <= dst_end)
++            dst = overrun_copy(dst, pcpy, match_len + MINMATCH);
++        else 
++            dst = safe_copy(dst, pcpy, match_len + MINMATCH);
++    }
++    
++    if (literal + literal_len > src_end
++              || dst + literal_len > dst_end)
++        return -1;
++    dst = fast_copy(dst, literal, literal_len);
++    
++    return dst - (u8*)out;
++}
++
+diff --git a/gfx/graphite2/src/Face.cpp b/gfx/graphite2/src/Face.cpp
+--- a/gfx/graphite2/src/Face.cpp
++++ b/gfx/graphite2/src/Face.cpp
+@@ -23,28 +23,39 @@ Alternatively, the contents of this file
+ Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ #include <cstring>
+ #include "graphite2/Segment.h"
+ #include "inc/CmapCache.h"
+ #include "inc/debug.h"
++#include "inc/Decompressor.h"
+ #include "inc/Endian.h"
+ #include "inc/Face.h"
+ #include "inc/FileFace.h"
+ #include "inc/GlyphFace.h"
+ #include "inc/json.h"
+ #include "inc/SegCacheStore.h"
+ #include "inc/Segment.h"
+ #include "inc/NameTable.h"
+ #include "inc/Error.h"
+ 
+ using namespace graphite2;
+ 
++namespace
++{
++enum compression
++{
++    NONE,
++    LZ4
++};
++
++}
++
+ Face::Face(const void* appFaceHandle/*non-NULL*/, const gr_face_ops & ops)
+ : m_appFaceHandle(appFaceHandle),
+   m_pFileFace(NULL),
+   m_pGlyphFaceCache(NULL),
+   m_cmap(NULL),
+   m_pNames(NULL),
+   m_logger(NULL),
+   m_error(0), m_errcntxt(0),
+@@ -79,55 +90,59 @@ float Face::default_glyph_advance(const 
+ 
+ bool Face::readGlyphs(uint32 faceOptions)
+ {
+     Error e;
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::category _glyph_cat(tele.glyph);
+ #endif
+     error_context(EC_READGLYPHS);
++    m_pGlyphFaceCache = new GlyphCache(*this, faceOptions);
++
++    if (e.test(!m_pGlyphFaceCache, E_OUTOFMEM)
++        || e.test(m_pGlyphFaceCache->numGlyphs() == 0, E_NOGLYPHS)
++        || e.test(m_pGlyphFaceCache->unitsPerEm() == 0, E_BADUPEM))
++    {
++        return error(e);
++    }
++
+     if (faceOptions & gr_face_cacheCmap)
+         m_cmap = new CachedCmap(*this);
+     else
+         m_cmap = new DirectCmap(*this);
+-
+-    m_pGlyphFaceCache = new GlyphCache(*this, faceOptions);
+-    if (e.test(!m_pGlyphFaceCache, E_OUTOFMEM)
+-        || e.test(m_pGlyphFaceCache->numGlyphs() == 0, E_NOGLYPHS)
+-        || e.test(m_pGlyphFaceCache->unitsPerEm() == 0, E_BADUPEM)
+-        || e.test(!m_cmap, E_OUTOFMEM) || e.test(!*m_cmap, E_BADCMAP))
+-    {
++    if (e.test(!m_cmap, E_OUTOFMEM) || e.test(!*m_cmap, E_BADCMAP))
+         return error(e);
+-    }
+ 
+     if (faceOptions & gr_face_preloadGlyphs)
+         nameTable();        // preload the name table along with the glyphs.
+ 
+     return true;
+ }
+ 
+ bool Face::readGraphite(const Table & silf)
+ {
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::category _silf_cat(tele.silf);
+ #endif
+     Error e;
+     error_context(EC_READSILF);
+     const byte * p = silf;
+-    if (e.test(!p, E_NOSILF)) return error(e);
++    if (e.test(!p, E_NOSILF) || e.test(silf.size() < 20, E_BADSIZE)) return error(e);
+ 
+     const uint32 version = be::read<uint32>(p);
+     if (e.test(version < 0x00020000, E_TOOOLD)) return error(e);
+     if (version >= 0x00030000)
+         be::skip<uint32>(p);        // compilerVersion
+     m_numSilf = be::read<uint16>(p);
++
+     be::skip<uint16>(p);            // reserved
+ 
+     bool havePasses = false;
+     m_silfs = new Silf[m_numSilf];
++    if (e.test(!m_silfs, E_OUTOFMEM)) return error(e);
+     for (int i = 0; i < m_numSilf; i++)
+     {
+         error_context(EC_ASILF + (i << 8));
+         const uint32 offset = be::read<uint32>(p),
+                      next   = i == m_numSilf - 1 ? silf.size() : be::peek<uint32>(p);
+         if (e.test(next > silf.size() || offset >= next, E_BADSIZE))
+             return error(e);
+ 
+@@ -153,29 +168,38 @@ bool Face::runGraphite(Segment *seg, con
+     if (dbgout)
+     {
+         *dbgout << json::object
+                     << "id"         << objectid(seg)
+                     << "passes"     << json::array;
+     }
+ #endif
+ 
+-    bool res = aSilf->runGraphite(seg, 0, aSilf->justificationPass(), true);
++//    if ((seg->dir() & 1) != aSilf->dir())
++//        seg->reverseSlots();
++    if ((seg->dir() & 3) == 3 && aSilf->bidiPass() == 0xFF)
++        seg->doMirror(aSilf->aMirror());
++    bool res = aSilf->runGraphite(seg, 0, aSilf->positionPass(), true);
+     if (res)
+-        res = aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
++    {
++        seg->associateChars(0, seg->charInfoCount());
++        if (aSilf->flags() & 0x20)
++            res &= seg->initCollisions();
++        res &= aSilf->runGraphite(seg, aSilf->positionPass(), aSilf->numPasses(), false);
++    }
+ 
+ #if !defined GRAPHITE2_NTRACING
+     if (dbgout)
+ {
++        seg->positionSlots(0, 0, 0, aSilf->dir());
+         *dbgout             << json::item
+                             << json::close // Close up the passes array
+                 << "output" << json::array;
+         for(Slot * s = seg->first(); s; s = s->next())
+             *dbgout     << dslot(seg, s);
+-        seg->finalise(0);                   // Call this here to fix up charinfo back indexes.
+         *dbgout         << json::close
+                 << "advance" << seg->advance()
+                 << "chars"   << json::array;
+         for(size_t i = 0, n = seg->charInfoCount(); i != n; ++i)
+             *dbgout     << json::flat << *seg->charinfo(i);
+         *dbgout         << json::close  // Close up the chars array
+                     << json::close;     // Close up the segment object
+     }
+@@ -208,17 +232,19 @@ uint16 Face::findPseudo(uint32 uid) cons
+ }
+ 
+ uint16 Face::getGlyphMetric(uint16 gid, uint8 metric) const
+ {
+     switch (metrics(metric))
+     {
+         case kgmetAscent : return m_ascent;
+         case kgmetDescent : return m_descent;
+-        default: return glyphs().glyph(gid)->getMetric(metric);
++        default: 
++            if (gid >= glyphs().numGlyphs()) return 0;
++            return glyphs().glyph(gid)->getMetric(metric);
+     }
+ }
+ 
+ void Face::takeFileFace(FileFace* pFileFace GR_MAYBE_UNUSED/*takes ownership*/)
+ {
+ #ifndef GRAPHITE2_NFILEFACE
+     if (m_pFileFace==pFileFace)
+       return;
+@@ -240,30 +266,100 @@ NameTable * Face::nameTable() const
+ uint16 Face::languageForLocale(const char * locale) const
+ {
+     nameTable();
+     if (m_pNames)
+         return m_pNames->getLanguageId(locale);
+     return 0;
+ }
+ 
+-Face::Table::Table(const Face & face, const Tag n) throw()
+-: _f(&face)
++
++
++Face::Table::Table(const Face & face, const Tag n, uint32 version) throw()
++: _f(&face), _compressed(false)
+ {
+     size_t sz = 0;
+-    _p = reinterpret_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
++    _p = static_cast<const byte *>((*_f->m_ops.get_table)(_f->m_appFaceHandle, n, &sz));
+     _sz = uint32(sz);
++
+     if (!TtfUtil::CheckTable(n, _p, _sz))
+     {
+         this->~Table();     // Make sure we release the table buffer even if the table filed it's checks
+-        _p = 0; _sz = 0;
++        return;
+     }
++
++    if (be::peek<uint32>(_p) >= version)
++        decompress();
++}
++
++void Face::Table::releaseBuffers()
++{
++    if (_compressed)
++        free(const_cast<byte *>(_p));
++    else if (_p && _f->m_ops.release_table)
++        (*_f->m_ops.release_table)(_f->m_appFaceHandle, _p);
++    _p = 0; _sz = 0;
+ }
+ 
+ Face::Table & Face::Table::operator = (const Table & rhs) throw()
+ {
+     if (_p == rhs._p)   return *this;
+ 
+     this->~Table();
+     new (this) Table(rhs);
+     return *this;
+ }
+ 
++Error Face::Table::decompress()
++{
++    Error e;
++    if (e.test(_sz < 5 * sizeof(uint32), E_BADSIZE))
++        return e;
++    byte * uncompressed_table = 0;
++    size_t uncompressed_size = 0;
++
++    const byte * p = _p;
++    const uint32 version = be::read<uint32>(p);    // Table version number.
++
++    // The scheme is in the top 5 bits of the 1st uint32.
++    const uint32 hdr = be::read<uint32>(p);
++    switch(compression(hdr >> 27))
++    {
++    case NONE: return e;
++
++    case LZ4:
++    {
++        uncompressed_size  = hdr & 0x07ffffff;
++        uncompressed_table = gralloc<byte>(uncompressed_size);
++        if (!e.test(!uncompressed_table, E_OUTOFMEM))
++            // coverity[forward_null : FALSE] - uncompressed_table has been checked so can't be null
++            // coverity[checked_return : FALSE] - we test e later
++            e.test(lz4::decompress(p, _sz - 2*sizeof(uint32), uncompressed_table, uncompressed_size) != signed(uncompressed_size), E_SHRINKERFAILED);
++        break;
++    }
++
++    default:
++        e.error(E_BADSCHEME);
++    };
++
++    // Check the uncompressed version number against the original.
++    if (!e)
++        // coverity[forward_null : FALSE] - uncompressed_table has already been tested so can't be null
++        // coverity[checked_return : FALSE] - we test e later
++        e.test(be::peek<uint32>(uncompressed_table) != version, E_SHRINKERFAILED);
++
++    // Tell the provider to release the compressed form since were replacing
++    //   it anyway.
++    releaseBuffers();
++
++    if (e)
++    {
++        free(uncompressed_table);
++        uncompressed_table = 0;
++        uncompressed_size  = 0;
++    }
++
++    _p = uncompressed_table;
++    _sz = uncompressed_size;
++    _compressed = true;
++
++    return e;
++}
+diff --git a/gfx/graphite2/src/FeatureMap.cpp b/gfx/graphite2/src/FeatureMap.cpp
+--- a/gfx/graphite2/src/FeatureMap.cpp
++++ b/gfx/graphite2/src/FeatureMap.cpp
+@@ -126,60 +126,61 @@ bool FeatureMap::readFeats(const Face & 
+     unsigned short bits = 0;     //to cause overflow on first Feature
+ 
+     for (int i = 0, ie = m_numFeats; i != ie; i++)
+     {
+         const uint32    label   = version < 0x00020000 ? be::read<uint16>(p) : be::read<uint32>(p);
+         const uint16    num_settings = be::read<uint16>(p);
+         if (version >= 0x00020000)
+             be::skip<uint16>(p);
+-        const byte * const feat_setts = feat_start + be::read<uint32>(p);
++        const uint32    settings_offset = be::read<uint32>(p);
+         const uint16    flags  = be::read<uint16>(p),
+                         uiName = be::read<uint16>(p);
+ 
+-        if (feat_setts + num_settings * FEATURE_SETTING_SIZE > feat_end)
++        if (settings_offset > size_t(feat_end - feat_start) 
++            || settings_offset + num_settings * FEATURE_SETTING_SIZE > size_t(feat_end - feat_start))
+         {
+             free(defVals);
+             return false;
+         }
+ 
+         FeatureSetting *uiSet;
+         uint32 maxVal;
+         if (num_settings != 0)
+         {
+             uiSet = gralloc<FeatureSetting>(num_settings);
+             if (!uiSet)
+             {
+                 free(defVals);
+                 return false;
+             }
+-            maxVal = readFeatureSettings(feat_setts, uiSet, num_settings);
++            maxVal = readFeatureSettings(feat_start + settings_offset, uiSet, num_settings);
+             defVals[i] = uiSet[0].value();
+         }
+         else
+         {
+             uiSet = 0;
+             maxVal = 0xffffffff;
+             defVals[i] = 0;
+         }
+ 
+         ::new (m_feats + i) FeatureRef (face, bits, maxVal,
+                                        label, uiName, flags,
+                                        uiSet, num_settings);
+     }
+-    m_defaultFeatures = new Features(bits/(sizeof(uint32)*8) + 1, *this);
++    new (&m_defaultFeatures) Features(bits/(sizeof(uint32)*8) + 1, *this);
+     m_pNamedFeats = new NameAndFeatureRef[m_numFeats];
+-    if (!m_defaultFeatures || !m_pNamedFeats)
++    if (!m_pNamedFeats)
+     {
+         free(defVals);
+         return false;
+     }
+     for (int i = 0; i < m_numFeats; ++i)
+     {
+-        m_feats[i].applyValToFeature(defVals[i], *m_defaultFeatures);
++        m_feats[i].applyValToFeature(defVals[i], m_defaultFeatures);
+         m_pNamedFeats[i] = m_feats+i;
+     }
+     
+     free(defVals);
+ 
+     qsort(m_pNamedFeats, m_numFeats, sizeof(NameAndFeatureRef), &cmpNameAndFeatures);
+ 
+     return true;
+@@ -209,17 +210,17 @@ bool SillMap::readSill(const Face & face
+     if (sill.size() < m_numLanguages * 8U + 12) return false;
+ 
+     for (int i = 0; i < m_numLanguages; i++)
+     {
+         uint32 langid = be::read<uint32>(p);
+         uint16 numSettings = be::read<uint16>(p);
+         uint16 offset = be::read<uint16>(p);
+         if (offset + 8U * numSettings > sill.size() && numSettings > 0) return false;
+-        Features* feats = new Features(*m_FeatureMap.m_defaultFeatures);
++        Features* feats = new Features(m_FeatureMap.m_defaultFeatures);
+         if (!feats) return false;
+         const byte *pLSet = sill + offset;
+ 
+         // Apply langauge specific settings
+         for (int j = 0; j < numSettings; j++)
+         {
+             uint32 name = be::read<uint32>(pLSet);
+             uint16 val = be::read<uint16>(pLSet);
+@@ -245,17 +246,17 @@ Features* SillMap::cloneFeatures(uint32 
+         // the number of languages in a font is usually small e.g. 8 in Doulos
+         // so this loop is not very expensive
+         for (uint16 i = 0; i < m_numLanguages; i++)
+         {
+             if (m_langFeats[i].m_lang == langname)
+                 return new Features(*m_langFeats[i].m_pFeatures);
+         }
+     }
+-    return new Features (*m_FeatureMap.m_defaultFeatures);
++    return new Features (m_FeatureMap.m_defaultFeatures);
+ }
+ 
+ 
+ 
+ const FeatureRef *FeatureMap::findFeatureRef(uint32 name) const
+ {
+     NameAndFeatureRef *it;
+     
+diff --git a/gfx/graphite2/src/FileFace.cpp b/gfx/graphite2/src/FileFace.cpp
+--- a/gfx/graphite2/src/FileFace.cpp
++++ b/gfx/graphite2/src/FileFace.cpp
+@@ -55,18 +55,22 @@ FileFace::FileFace(const char *filename)
+         if (fread(_header_tbl, 1, tbl_len, _file) != tbl_len) return;
+         if (!TtfUtil::CheckHeader(_header_tbl)) return;
+     }
+ 
+     // Get the table directory
+     if (!TtfUtil::GetTableDirInfo(_header_tbl, tbl_offset, tbl_len)) return;
+     _table_dir = (TtfUtil::Sfnt::OffsetSubTable::Entry*)gralloc<char>(tbl_len);
+     if (fseek(_file, tbl_offset, SEEK_SET)) return;
+-    if (_table_dir)
+-        if (fread(_table_dir, 1, tbl_len, _file) != tbl_len) return;
++    if (_table_dir && fread(_table_dir, 1, tbl_len, _file) != tbl_len)
++    {
++        free(_table_dir);
++        _table_dir = NULL;
++    }
++    return;
+ }
+ 
+ FileFace::~FileFace()
+ {
+     free(_table_dir);
+     free(_header_tbl);
+     if (_file)
+         fclose(_file);
+@@ -78,17 +82,17 @@ const void *FileFace::get_table_fn(const
+     if (appFaceHandle == 0)     return 0;
+     const FileFace & file_face = *static_cast<const FileFace *>(appFaceHandle);
+ 
+     void *tbl;
+     size_t tbl_offset, tbl_len;
+     if (!TtfUtil::GetTableInfo(name, file_face._header_tbl, file_face._table_dir, tbl_offset, tbl_len))
+         return 0;
+ 
+-    if (tbl_offset + tbl_len > file_face._file_len
++    if (tbl_offset > file_face._file_len || tbl_len > file_face._file_len - tbl_offset
+             || fseek(file_face._file, tbl_offset, SEEK_SET) != 0)
+         return 0;
+ 
+     tbl = malloc(tbl_len);
+     if (fread(tbl, 1, tbl_len, file_face._file) != tbl_len)
+     {
+         free(tbl);
+         return 0;
+diff --git a/gfx/graphite2/src/GlyphCache.cpp b/gfx/graphite2/src/GlyphCache.cpp
+--- a/gfx/graphite2/src/GlyphCache.cpp
++++ b/gfx/graphite2/src/GlyphCache.cpp
+@@ -26,16 +26,17 @@ of the License or (at your option) any l
+ */
+ #include "graphite2/Font.h"
+ 
+ #include "inc/Main.h"
+ #include "inc/Face.h"     //for the tags
+ #include "inc/GlyphCache.h"
+ #include "inc/GlyphFace.h"
+ #include "inc/Endian.h"
++#include "inc/bits.h"
+ 
+ using namespace graphite2;
+ 
+ namespace
+ {
+     // Iterator over version 1 or 2 glat entries which consist of a series of
+     //    +-+-+-+-+-+-+-+-+-+-+                +-+-+-+-+-+-+-+-+-+-+-+-+
+     // v1 |k|n|v1 |v2 |...|vN |     or    v2   | k | n |v1 |v2 |...|vN |
+@@ -56,99 +57,127 @@ namespace
+             if (_n == run()) advance_entry();
+             return *this;
+         }
+         _glat_iterator<W>   operator ++ (int)   { _glat_iterator<W> tmp(*this); operator++(); return tmp; }
+ 
+         // This is strictly a >= operator. A true == operator could be
+         // implemented that test for overlap but it would be more expensive a
+         // test.
+-        bool operator == (const _glat_iterator<W> & rhs) { return _v >= rhs._e; }
++        bool operator == (const _glat_iterator<W> & rhs) { return _v >= rhs._e - 1; }
+         bool operator != (const _glat_iterator<W> & rhs) { return !operator==(rhs); }
+ 
+         value_type          operator * () const {
+             return value_type(key(), be::peek<uint16>(_v));
+         }
+ 
+     protected:
+         const byte     * _e, * _v;
+-        ptrdiff_t        _n;
++        size_t        _n;
+     };
+ 
+     typedef _glat_iterator<uint8>   glat_iterator;
+     typedef _glat_iterator<uint16>  glat2_iterator;
+ }
+ 
++const SlantBox SlantBox::empty = {0,0,0,0};
++
+ 
+ class GlyphCache::Loader
+ {
+ public:
+     Loader(const Face & face, const bool dumb_font);    //return result indicates success. Do not use if failed.
+ 
+     operator bool () const throw();
+     unsigned short int units_per_em() const throw();
+     unsigned short int num_glyphs() const throw();
+     unsigned short int num_attrs() const throw();
++    bool has_boxes() const throw();
+ 
+-    const GlyphFace * read_glyph(unsigned short gid, GlyphFace &) const throw();
++    const GlyphFace * read_glyph(unsigned short gid, GlyphFace &, int *numsubs) const throw();
++    GlyphBox * read_box(uint16 gid, GlyphBox *curr, const GlyphFace & face) const throw();
+ 
+     CLASS_NEW_DELETE;
+ private:
+     Face::Table _head,
+                 _hhea,
+                 _hmtx,
+                 _glyf,
+                 _loca,
+                 m_pGlat,
+                 m_pGloc;
+ 
+     bool            _long_fmt;
++    bool            _has_boxes;
+     unsigned short  _num_glyphs_graphics,        //i.e. boundary box and advance
+                     _num_glyphs_attributes,
+                     _num_attrs;                    // number of glyph attributes per glyph
+ };
+ 
+ 
+ 
+ GlyphCache::GlyphCache(const Face & face, const uint32 face_options)
+ : _glyph_loader(new Loader(face, bool(face_options & gr_face_dumbRendering))),
+   _glyphs(_glyph_loader && *_glyph_loader ? grzeroalloc<const GlyphFace *>(_glyph_loader->num_glyphs()) : 0),
++  _boxes(_glyph_loader && _glyph_loader->has_boxes() ? grzeroalloc<GlyphBox *>(_glyph_loader->num_glyphs()) : 0),
+   _num_glyphs(_glyphs ? _glyph_loader->num_glyphs() : 0),
+   _num_attrs(_glyphs ? _glyph_loader->num_attrs() : 0),
+   _upem(_glyphs ? _glyph_loader->units_per_em() : 0)
+ {
+     if ((face_options & gr_face_preloadGlyphs) && _glyph_loader && _glyphs)
+     {
++        int numsubs = 0;
+         GlyphFace * const glyphs = new GlyphFace [_num_glyphs];
+         if (!glyphs)
+             return;
+ 
+         // The 0 glyph is definately required.
+-        _glyphs[0] = _glyph_loader->read_glyph(0, glyphs[0]);
++        _glyphs[0] = _glyph_loader->read_glyph(0, glyphs[0], &numsubs);
+ 
+         // glyphs[0] has the same address as the glyphs array just allocated,
+         //  thus assigning the &glyphs[0] to _glyphs[0] means _glyphs[0] points
+         //  to the entire array.
+         const GlyphFace * loaded = _glyphs[0];
+         for (uint16 gid = 1; loaded && gid != _num_glyphs; ++gid)
+-            _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid]);
++            _glyphs[gid] = loaded = _glyph_loader->read_glyph(gid, glyphs[gid], &numsubs);
+ 
+         if (!loaded)
+         {
+             _glyphs[0] = 0;
+             delete [] glyphs;
+         }
++        else if (numsubs > 0)
++        {
++            GlyphBox * boxes = (GlyphBox *)gralloc<char>(_num_glyphs * sizeof(GlyphBox) + numsubs * 8 * sizeof(float));
++            GlyphBox * currbox = boxes;
++
++            for (uint16 gid = 0; currbox && gid != _num_glyphs; ++gid)
++            {
++                _boxes[gid] = currbox;
++                currbox = _glyph_loader->read_box(gid, currbox, *_glyphs[gid]);
++            }
++            if (!currbox)
++            {
++                free(boxes);
++                _boxes[0] = 0;
++            }
++        }
+         delete _glyph_loader;
+         _glyph_loader = 0;
+     }
+ 
+     if (_glyphs && glyph(0) == 0)
+     {
+         free(_glyphs);
+         _glyphs = 0;
++        if (_boxes)
++        {
++            free(_boxes);
++            _boxes = 0;
++        }
+         _num_glyphs = _num_attrs = _upem = 0;
+     }
+ }
+ 
+ 
+ GlyphCache::~GlyphCache()
+ {
+     if (_glyphs)
+@@ -158,91 +187,130 @@ GlyphCache::~GlyphCache()
+             const GlyphFace *  * g = _glyphs;
+             for(unsigned short n = _num_glyphs; n; --n, ++g)
+                 delete *g;
+         }
+         else
+             delete [] _glyphs[0];
+         free(_glyphs);
+     }
++    if (_boxes)
++    {
++        if (_glyph_loader)
++        {
++            GlyphBox *  * g = _boxes;
++            for (uint16 n = _num_glyphs; n; --n, ++g)
++                free(*g);
++        }
++        else
++            free(_boxes[0]);
++        free(_boxes);
++    }
+     delete _glyph_loader;
+ }
+ 
+ const GlyphFace *GlyphCache::glyph(unsigned short glyphid) const      //result may be changed by subsequent call with a different glyphid
+ { 
+     const GlyphFace * & p = _glyphs[glyphid];
+     if (p == 0 && _glyph_loader)
+     {
++        int numsubs = 0;
+         GlyphFace * g = new GlyphFace();
+-        if (g)  p = _glyph_loader->read_glyph(glyphid, *g);
++        if (g)  p = _glyph_loader->read_glyph(glyphid, *g, &numsubs);
+         if (!p)
+         {
+             delete g;
+             return *_glyphs;
+         }
++        if (_boxes)
++        {
++            _boxes[glyphid] = (GlyphBox *)gralloc<char>(sizeof(GlyphBox) + 8 * numsubs * sizeof(float));
++            if (!_glyph_loader->read_box(glyphid, _boxes[glyphid], *_glyphs[glyphid]))
++            {
++                free(_boxes[glyphid]);
++                _boxes[glyphid] = 0;
++            }
++        }
+     }
+     return p;
+ }
+ 
+ 
+ 
+ GlyphCache::Loader::Loader(const Face & face, const bool dumb_font)
+ : _head(face, Tag::head),
+   _hhea(face, Tag::hhea),
+   _hmtx(face, Tag::hmtx),
+   _glyf(face, Tag::glyf),
+   _loca(face, Tag::loca),
+   _long_fmt(false),
++  _has_boxes(false),
+   _num_glyphs_graphics(0),
+   _num_glyphs_attributes(0),
+   _num_attrs(0)
+ {
+     if (!operator bool())
+         return;
+ 
+     const Face::Table maxp = Face::Table(face, Tag::maxp);
+     if (!maxp) { _head = Face::Table(); return; }
+ 
+     _num_glyphs_graphics = TtfUtil::GlyphCount(maxp);
+     // This will fail if the number of glyphs is wildly out of range.
+-    if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-1))
++    if (_glyf && TtfUtil::LocaLookup(_num_glyphs_graphics-1, _loca, _loca.size(), _head) == size_t(-2))
+     {
+         _head = Face::Table();
+         return;
+     }
+ 
+     if (!dumb_font)
+     {
+-        if ((m_pGlat = Face::Table(face, Tag::Glat)) == NULL
++        if ((m_pGlat = Face::Table(face, Tag::Glat, 0x00030000)) == NULL
+             || (m_pGloc = Face::Table(face, Tag::Gloc)) == NULL
+             || m_pGloc.size() < 6)
+         {
+             _head = Face::Table();
+             return;
+         }
+         const byte    * p = m_pGloc;
+-        const int       version = be::read<uint32>(p);
++        int       version = be::read<uint32>(p);
+         const uint16    flags = be::read<uint16>(p);
+         _num_attrs = be::read<uint16>(p);
+         // We can accurately calculate the number of attributed glyphs by
+         //  subtracting the length of the attribids array (numAttribs long if present)
+         //  and dividing by either 2 or 4 depending on shor or lonf format
+         _long_fmt              = flags & 1;
+-        _num_glyphs_attributes = (m_pGloc.size()
++        int tmpnumgattrs       = (m_pGloc.size()
+                                    - (p - m_pGloc)
+                                    - sizeof(uint16)*(flags & 0x2 ? _num_attrs : 0))
+                                        / (_long_fmt ? sizeof(uint32) : sizeof(uint16)) - 1;
+ 
+-        if (version != 0x00010000
++        if (version >= 0x00020000 || tmpnumgattrs < 0 || tmpnumgattrs > 65535
+             || _num_attrs == 0 || _num_attrs > 0x3000  // is this hard limit appropriate?
+-            || _num_glyphs_graphics > _num_glyphs_attributes)
++            || _num_glyphs_graphics > tmpnumgattrs)
+         {
+             _head = Face::Table();
+             return;
+         }
++
++        _num_glyphs_attributes = static_cast<unsigned short>(tmpnumgattrs);
++        p = m_pGlat;
++        version = be::read<uint32>(p);
++        if (version >= 0x00040000)       // reject Glat tables that are too new
++        {
++            _head = Face::Table();
++            return;
++        }
++        else if (version >= 0x00030000)
++        {
++            unsigned int glatflags = be::read<uint32>(p);
++            _has_boxes = glatflags & 1;
++            // delete this once the compiler is fixed
++            _has_boxes = true;
++        }
+     }
+ }
+ 
+ inline
+ GlyphCache::Loader::operator bool () const throw()
+ {
+     return _head && _hhea && _hmtx && !(bool(_glyf) != bool(_loca));
+ }
+@@ -260,34 +328,44 @@ unsigned short int GlyphCache::Loader::n
+ }
+ 
+ inline
+ unsigned short int GlyphCache::Loader::num_attrs() const throw()
+ {
+     return _num_attrs;
+ }
+ 
+-const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph) const throw()
++inline
++bool GlyphCache::Loader::has_boxes () const throw()
++{
++    return _has_boxes;
++}
++
++const GlyphFace * GlyphCache::Loader::read_glyph(unsigned short glyphid, GlyphFace & glyph, int *numsubs) const throw()
+ {
+     Rect        bbox;
+     Position    advance;
+ 
+     if (glyphid < _num_glyphs_graphics)
+     {
+         int nLsb;
+         unsigned int nAdvWid;
+         if (_glyf)
+         {
+             int xMin, yMin, xMax, yMax;
+             size_t locidx = TtfUtil::LocaLookup(glyphid, _loca, _loca.size(), _head);
+             void *pGlyph = TtfUtil::GlyfLookup(_glyf, locidx, _glyf.size());
+ 
+             if (pGlyph && TtfUtil::GlyfBox(pGlyph, xMin, yMin, xMax, yMax))
++            {
++                if ((xMin > xMax) || (yMin > yMax))
++                    return 0;
+                 bbox = Rect(Position(static_cast<float>(xMin), static_cast<float>(yMin)),
+                     Position(static_cast<float>(xMax), static_cast<float>(yMax)));
++            }
+         }
+         if (TtfUtil::HorMetrics(glyphid, _hmtx, _hmtx.size(), _hhea, nLsb, nAdvWid))
+             advance = Position(static_cast<float>(nAdvWid), 0);
+     }
+ 
+     if (glyphid < _num_glyphs_attributes)
+     {
+         const byte * gloc = m_pGloc;
+@@ -307,35 +385,95 @@ const GlyphFace * GlyphCache::Loader::re
+             glocs = be::read<uint16>(gloc);
+             gloce = be::peek<uint16>(gloc);
+         }
+ 
+         if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
+             return 0;
+ 
+         const uint32 glat_version = be::peek<uint32>(m_pGlat);
++        if (glat_version == 0x00030000)
++        {
++            const byte * p = m_pGlat + glocs;
++            uint16 bmap = be::read<uint16>(p);
++            int num = bit_set_count((uint32)bmap);
++            if (numsubs) *numsubs += num;
++            glocs += 6 + 8 * num;
++            if (glocs > gloce)
++                return 0;
++        }
+         if (glat_version < 0x00020000)
+         {
+             if (gloce - glocs < 2*sizeof(byte)+sizeof(uint16)
+                 || gloce - glocs > _num_attrs*(2*sizeof(byte)+sizeof(uint16)))
+-            {
+-                return 0;
+-            }
+-
++                    return 0;
+             new (&glyph) GlyphFace(bbox, advance, glat_iterator(m_pGlat + glocs), glat_iterator(m_pGlat + gloce));
+         }
+         else
+         {
+-            if (gloce - glocs < 3*sizeof(uint16)
+-                || gloce - glocs > _num_attrs*3*sizeof(uint16))
+-            {
+-                return 0;
+-            }
+-
++            if (gloce - glocs < 3*sizeof(uint16)        // can a glyph have no attributes? why not?
++                || gloce - glocs > _num_attrs*3*sizeof(uint16)
++                || glocs > m_pGlat.size() - 2*sizeof(uint16))
++                    return 0;
+             new (&glyph) GlyphFace(bbox, advance, glat2_iterator(m_pGlat + glocs), glat2_iterator(m_pGlat + gloce));
+         }
+-
+         if (!glyph.attrs() || glyph.attrs().capacity() > _num_attrs)
+             return 0;
+     }
+-
+     return &glyph;
+ }
++
++inline float scale_to(uint8 t, float zmin, float zmax)
++{
++    return (zmin + t * (zmax - zmin) / 255);
++}
++
++Rect readbox(Rect &b, uint8 zxmin, uint8 zymin, uint8 zxmax, uint8 zymax)
++{
++    return Rect(Position(scale_to(zxmin, b.bl.x, b.tr.x), scale_to(zymin, b.bl.y, b.tr.y)),
++                Position(scale_to(zxmax, b.bl.x, b.tr.x), scale_to(zymax, b.bl.y, b.tr.y)));
++}
++
++GlyphBox * GlyphCache::Loader::read_box(uint16 gid, GlyphBox *curr, const GlyphFace & glyph) const throw()
++{
++    if (gid >= _num_glyphs_attributes) return 0;
++
++    const byte * gloc = m_pGloc;
++    size_t      glocs = 0, gloce = 0;
++
++    be::skip<uint32>(gloc);
++    be::skip<uint16>(gloc,2);
++    if (_long_fmt)
++    {
++        be::skip<uint32>(gloc, gid);
++        glocs = be::read<uint32>(gloc);
++        gloce = be::peek<uint32>(gloc);
++    }
++    else
++    {
++        be::skip<uint16>(gloc, gid);
++        glocs = be::read<uint16>(gloc);
++        gloce = be::peek<uint16>(gloc);
++    }
++
++    if (glocs >= m_pGlat.size() || gloce > m_pGlat.size())
++        return 0;
++
++    const byte * p = m_pGlat + glocs;
++    uint16 bmap = be::read<uint16>(p);
++    int num = bit_set_count((uint32)bmap);
++
++    Rect bbox = glyph.theBBox();
++    Rect diamax(Position(bbox.bl.x + bbox.bl.y, bbox.bl.x - bbox.tr.y),
++                Position(bbox.tr.x + bbox.tr.y, bbox.tr.x - bbox.bl.y));
++    Rect diabound = readbox(diamax, p[0], p[2], p[1], p[3]);
++    ::new (curr) GlyphBox(num, bmap, &diabound);
++    be::skip<uint8>(p, 4);
++
++    for (int i = 0; i < num * 2; ++i)
++    {
++        Rect box = readbox((i & 1) ? diamax : bbox, p[0], p[2], p[1], p[3]);
++        curr->addSubBox(i >> 1, i & 1, &box);
++        be::skip<uint8>(p, 4);
++    } 
++    return (GlyphBox *)((char *)(curr) + sizeof(GlyphBox) + 2 * num * sizeof(Rect));
++}
++
+diff --git a/gfx/graphite2/src/Intervals.cpp b/gfx/graphite2/src/Intervals.cpp
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/Intervals.cpp
+@@ -0,0 +1,294 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#include <algorithm>
++#include <cmath>
++#include <limits>
++
++#include "inc/Intervals.h"
++#include "inc/Segment.h"
++#include "inc/Slot.h"
++#include "inc/debug.h"
++#include "inc/bits.h"
++
++using namespace graphite2;
++
++#include <cmath>
++
++inline
++Zones::Exclusion  Zones::Exclusion::split_at(float p) {
++    Exclusion r(*this);
++    r.xm = x = p;
++    return r;
++}
++
++inline
++void Zones::Exclusion::left_trim(float p) {
++    x = p;
++}
++
++inline
++Zones::Exclusion & Zones::Exclusion::operator += (Exclusion const & rhs) {
++    c += rhs.c; sm += rhs.sm; smx += rhs.smx; open = false;
++    return *this;
++}
++
++inline
++uint8 Zones::Exclusion::outcode(float val) const {
++    float p = val;
++    return ((p >= xm) << 1) | (p < x);
++}
++
++void Zones::exclude_with_margins(float xmin, float xmax, int axis) {
++    remove(xmin, xmax);
++    weightedAxis(axis, xmin-_margin_len, xmin, 0, 0, _margin_weight, xmin-_margin_len, 0, 0, false);
++    weightedAxis(axis, xmax, xmax+_margin_len, 0, 0, _margin_weight, xmax+_margin_len, 0, 0, false);
++}
++
++namespace
++{
++
++inline
++bool separated(float a, float b) {
++    return a != b;
++    //return std::fabs(a-b) > std::numeric_limits<float>::epsilon(); // std::epsilon may not work. but 0.5 fails exising 64 bit tests
++    //return std::fabs(a-b) > 0.5f;
++}
++
++}
++
++void Zones::insert(Exclusion e)
++{
++#if !defined GRAPHITE2_NTRACING
++    addDebug(&e);
++#endif
++    e.x = max(e.x, _pos);
++    e.xm = min(e.xm, _posm);
++    if (e.x >= e.xm) return;
++
++    for (iterator i = _exclusions.begin(), ie = _exclusions.end(); i != ie && e.x < e.xm; ++i)
++    {
++        const uint8 oca = e.outcode(i->x),
++                    ocb = e.outcode(i->xm);
++        if ((oca & ocb) != 0) continue;
++
++        switch (oca ^ ocb)  // What kind of overlap?
++        {
++        case 0:     // e completely covers i
++            // split e at i.x into e1,e2
++            // split e2 at i.mx into e2,e3
++            // drop e1 ,i+e2, e=e3
++            *i += e;
++            e.left_trim(i->xm);
++            break;
++        case 1:     // e overlaps on the rhs of i
++            // split i at e->x into i1,i2
++            // split e at i.mx into e1,e2
++            // trim i1, insert i2+e1, e=e2
++            if (!separated(i->xm, e.x)) break;
++            if (separated(i->x,e.x))   { i = _exclusions.insert(i,i->split_at(e.x)); ++i; }
++            *i += e;
++            e.left_trim(i->xm);
++            break;
++        case 2:     // e overlaps on the lhs of i
++            // split e at i->x into e1,e2
++            // split i at e.mx into i1,i2
++            // drop e1, insert e2+i1, trim i2
++            if (!separated(e.xm, i->x)) return;
++            if (separated(e.xm, i->xm)) i = _exclusions.insert(i,i->split_at(e.xm));
++            *i += e;
++            return;
++        case 3:     // i completely covers e
++            // split i at e.x into i1,i2
++            // split i2 at e.mx into i2,i3
++            // insert i1, insert e+i2
++            if (separated(e.xm, i->xm)) i = _exclusions.insert(i,i->split_at(e.xm));
++            i = _exclusions.insert(i, i->split_at(e.x));
++            *++i += e;
++            return;
++        }
++
++        ie = _exclusions.end();
++    }
++}
++
++
++void Zones::remove(float x, float xm)
++{
++#if !defined GRAPHITE2_NTRACING
++    removeDebug(x, xm);
++#endif
++    x = max(x, _pos);
++    xm = min(xm, _posm);
++    if (x >= xm) return;
++
++    for (iterator i = _exclusions.begin(), ie = _exclusions.end(); i != ie; ++i)
++    {
++        const uint8 oca = i->outcode(x),
++                    ocb = i->outcode(xm);
++        if ((oca & ocb) != 0)   continue;
++
++        switch (oca ^ ocb)  // What kind of overlap?
++        {
++        case 0:     // i completely covers e
++            if (separated(i->x, x))  { i = _exclusions.insert(i,i->split_at(x)); ++i; }
++            GR_FALLTHROUGH;
++            // no break
++        case 1:     // i overlaps on the rhs of e
++            i->left_trim(xm);
++            return;
++        case 2:     // i overlaps on the lhs of e
++            i->xm = x;
++            if (separated(i->x, i->xm)) break;
++            GR_FALLTHROUGH;
++            // no break
++        case 3:     // e completely covers i
++            i = _exclusions.erase(i);
++            --i;
++            break;
++        }
++
++        ie = _exclusions.end();
++    }
++}
++
++
++Zones::const_iterator Zones::find_exclusion_under(float x) const
++{
++    int l = 0, h = _exclusions.size();
++
++    while (l < h)
++    {
++        int const p = (l+h) >> 1;
++        switch (_exclusions[p].outcode(x))
++        {
++        case 0 : return _exclusions.begin()+p;
++        case 1 : h = p; break;
++        case 2 : 
++        case 3 : l = p+1; break;
++        }
++    }
++
++    return _exclusions.begin()+l;
++}
++
++
++float Zones::closest(float origin, float & cost) const
++{
++    float best_c = std::numeric_limits<float>::max(),
++          best_x = 0;
++
++    const const_iterator start = find_exclusion_under(origin);
++
++    // Forward scan looking for lowest cost
++    for (const_iterator i = start, ie = _exclusions.end(); i != ie; ++i)
++        if (i->track_cost(best_c, best_x, origin)) break;
++
++    // Backward scan looking for lowest cost
++    //  We start from the exclusion to the immediate left of start since we've
++    //  already tested start with the right most scan above.
++    for (const_iterator i = start-1, ie = _exclusions.begin()-1; i != ie; --i)
++        if (i->track_cost(best_c, best_x, origin)) break;
++
++    cost = (best_c == std::numeric_limits<float>::max() ? -1 : best_c);
++    return best_x;
++}
++
++
++// Cost and test position functions
++
++bool Zones::Exclusion::track_cost(float & best_cost, float & best_pos, float origin) const {
++    const float p = test_position(origin),
++                localc = cost(p - origin);
++    if (open && localc > best_cost) return true;
++
++    if (localc < best_cost)
++    {
++        best_cost = localc;
++        best_pos = p;
++    }
++    return false;
++}
++
++inline
++float Zones::Exclusion::cost(float p) const {
++    return (sm * p - 2 * smx) * p + c;
++}
++
++
++float Zones::Exclusion::test_position(float origin) const {
++    if (sm < 0)
++    {
++        // sigh, test both ends and perhaps the middle too!
++        float res = x;
++        float cl = cost(x);
++        if (x < origin && xm > origin)
++        {
++            float co = cost(origin);
++            if (co < cl)
++            {
++                cl = co;
++                res = origin;
++            }
++        }
++        float cr = cost(xm);
++        return cl > cr ? xm : res;
++    }
++    else
++    {
++        float zerox = smx / sm + origin;
++        if (zerox < x) return x;
++        else if (zerox > xm) return xm;
++        else return zerox;
++    }
++}
++
++
++#if !defined GRAPHITE2_NTRACING
++
++void Zones::jsonDbgOut(Segment *seg) const {
++
++    if (_dbg)
++    {
++        for (Zones::idebugs s = dbgs_begin(), e = dbgs_end(); s != e; ++s)
++        {
++            *_dbg << json::flat << json::array
++                << objectid(dslot(seg, (Slot *)(s->_env[0])))
++                << reinterpret_cast<ptrdiff_t>(s->_env[1]);
++            if (s->_isdel)
++                *_dbg << "remove" << Position(s->_excl.x, s->_excl.xm);
++            else
++                *_dbg << "exclude" << json::flat << json::array
++                    << s->_excl.x << s->_excl.xm 
++                    << s->_excl.sm << s->_excl.smx << s->_excl.c
++                    << json::close;
++            *_dbg << json::close;
++        }
++    }
++}
++
++#endif
++
+diff --git a/gfx/graphite2/src/Justifier.cpp b/gfx/graphite2/src/Justifier.cpp
+--- a/gfx/graphite2/src/Justifier.cpp
++++ b/gfx/graphite2/src/Justifier.cpp
+@@ -26,17 +26,17 @@ of the License or (at your option) any l
+ */
+ 
+ #include "inc/Segment.h"
+ #include "graphite2/Font.h"
+ #include "inc/debug.h"
+ #include "inc/CharInfo.h"
+ #include "inc/Slot.h"
+ #include "inc/Main.h"
+-#include <math.h>
++#include <cmath>
+ 
+ using namespace graphite2;
+ 
+ class JustifyTotal {
+ public:
+     JustifyTotal() : m_numGlyphs(0), m_tStretch(0), m_tShrink(0), m_tStep(0), m_tWeight(0) {}
+     void accumulate(Slot *s, Segment *seg, int level);
+     int weight() const { return m_tWeight; }
+@@ -55,37 +55,44 @@ void JustifyTotal::accumulate(Slot *s, S
+ {
+     ++m_numGlyphs;
+     m_tStretch += s->getJustify(seg, level, 0);
+     m_tShrink += s->getJustify(seg, level, 1);
+     m_tStep += s->getJustify(seg, level, 2);
+     m_tWeight += s->getJustify(seg, level, 3);
+ }
+ 
+-float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags flags, Slot *pFirst, Slot *pLast)
++float Segment::justify(Slot *pSlot, const Font *font, float width, GR_MAYBE_UNUSED justFlags jflags, Slot *pFirst, Slot *pLast)
+ {
+     Slot *s, *end;
+     float currWidth = 0.0;
+     const float scale = font ? font->scale() : 1.0f;
+     Position res;
+ 
+     if (width < 0 && !(silf()->flags()))
+         return width;
+ 
++    if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
++    {
++        reverseSlots();
++        s = pFirst;
++        pFirst = pLast;
++        pLast = s;
++    }
+     if (!pFirst) pFirst = pSlot;
+     while (!pFirst->isBase()) pFirst = pFirst->attachedTo();
+     if (!pLast) pLast = last();
+     while (!pLast->isBase()) pLast = pLast->attachedTo();
+     const float base = pFirst->origin().x / scale;
+     width = width / scale;
+-    if ((flags & gr_justEndInline) == 0)
++    if ((jflags & gr_justEndInline) == 0)
+     {
+         do {
+             Rect bbox = theGlyphBBoxTemporary(pLast->glyph());
+-            if (bbox.bl.x != 0. || bbox.bl.y != 0. || bbox.tr.x != 0. || bbox.tr.y == 0.)
++            if (bbox.bl.x != 0.f || bbox.bl.y != 0.f || bbox.tr.x != 0.f || bbox.tr.y == 0.f)
+                 break;
+             pLast = pLast->prev();
+         } while (pLast != pFirst);
+     }
+ 
+     end = pLast->nextSibling();
+     pFirst = pFirst->nextSibling();
+ 
+@@ -111,28 +118,27 @@ float Segment::justify(Slot *pSlot, cons
+                 s->setJustify(this, 0, 3, 1);
+                 s->setJustify(this, 0, 2, 1);
+                 s->setJustify(this, 0, 0, -1);
+             }
+         }
+         ++numLevels;
+     }
+ 
+-    JustifyTotal *stats = new JustifyTotal[numLevels];
+-    if (!stats) return -1.0;
++    Vector<JustifyTotal> stats(numLevels);
+     for (s = pFirst; s != end; s = s->nextSibling())
+     {
+         float w = s->origin().x / scale + s->advance() - base;
+         if (w > currWidth) currWidth = w;
+         for (int j = 0; j < numLevels; ++j)
+             stats[j].accumulate(s, this, j);
+         s->just(0);
+     }
+ 
+-    for (int i = (width < 0.0) ? -1 : numLevels - 1; i >= 0; --i)
++    for (int i = (width < 0.0f) ? -1 : numLevels - 1; i >= 0; --i)
+     {
+         float diff;
+         float error = 0.;
+         float diffpw;
+         int tWeight = stats[i].weight();
+ 
+         do {
+             error = 0.;
+@@ -154,29 +160,29 @@ float Segment::justify(Slot *pSlot, cons
+                 }
+                 else
+                 {
+                     float max = uint16(s->getJustify(this, i, 1));
+                     if (i == 0) max += s->just();
+                     if (-pref > max) pref = -max;
+                     else tWeight += w;
+                 }
+-                int actual = step ? int(pref / step) * step : int(pref);
++                int actual = int(pref / step) * step;
+ 
+                 if (actual)
+                 {
+                     error += diffpw * w - actual;
+                     if (i == 0)
+                         s->just(s->just() + actual);
+                     else
+                         s->setJustify(this, i, 4, actual);
+                 }
+             }
+             currWidth += diff - error;
+-        } while (i == 0 && int(abs(error)) > 0 && tWeight);
++        } while (i == 0 && int(std::abs(error)) > 0 && tWeight);
+     }
+ 
+     Slot *oldFirst = m_first;
+     Slot *oldLast = m_last;
+     if (silf()->flags() & 1)
+     {
+         m_first = pSlot = addLineEnd(pSlot);
+         m_last = pLast = addLineEnd(end);
+@@ -192,41 +198,44 @@ float Segment::justify(Slot *pSlot, cons
+ #if !defined GRAPHITE2_NTRACING
+     json * const dbgout = m_face->logger();
+     if (dbgout)
+         *dbgout << json::object
+                     << "justifies"  << objectid(this)
+                     << "passes"     << json::array;
+ #endif
+ 
+-    if (m_silf->justificationPass() != m_silf->positionPass() && (width >= 0. || (silf()->flags() & 1)))
++    if (m_silf->justificationPass() != m_silf->positionPass() && (width >= 0.f || (silf()->flags() & 1)))
+         m_silf->runGraphite(this, m_silf->justificationPass(), m_silf->positionPass());
+ 
+ #if !defined GRAPHITE2_NTRACING
+     if (dbgout)
+     {
+         *dbgout     << json::item << json::close; // Close up the passes array
+-        positionSlots(NULL, pSlot, pLast);
++        positionSlots(NULL, pSlot, pLast, m_dir);
+         Slot *lEnd = pLast->nextSibling();
+         *dbgout << "output" << json::array;
+         for(Slot * t = pSlot; t != lEnd; t = t->next())
+             *dbgout     << dslot(this, t);
+         *dbgout         << json::close << json::close;
+     }
+ #endif
+ 
+-    res = positionSlots(font, pSlot, pLast);
++    res = positionSlots(font, pSlot, pLast, m_dir);
+ 
+     if (silf()->flags() & 1)
+     {
+         delLineEnd(m_first);
+         delLineEnd(m_last);
+     }
+     m_first = oldFirst;
+     m_last = oldLast;
++
++    if ((m_dir & 1) != m_silf->dir() && m_silf->bidiPass() != m_silf->numPasses())
++        reverseSlots();
+     return res.x;
+ }
+ 
+ Slot *Segment::addLineEnd(Slot *nSlot)
+ {
+     Slot *eSlot = newSlot();
+     if (!eSlot) return NULL;
+     const uint16 gid = silf()->endLineGlyphid();
+diff --git a/gfx/graphite2/src/Pass.cpp b/gfx/graphite2/src/Pass.cpp
+--- a/gfx/graphite2/src/Pass.cpp
++++ b/gfx/graphite2/src/Pass.cpp
+@@ -26,91 +26,120 @@ of the License or (at your option) any l
+ */
+ #include "inc/Main.h"
+ #include "inc/debug.h"
+ #include "inc/Endian.h"
+ #include "inc/Pass.h"
+ #include <cstring>
+ #include <cstdlib>
+ #include <cassert>
++#include <cmath>
+ #include "inc/Segment.h"
+ #include "inc/Code.h"
+ #include "inc/Rule.h"
+ #include "inc/Error.h"
++#include "inc/Collider.h"
+ 
+ using namespace graphite2;
+ using vm::Machine;
+ typedef Machine::Code  Code;
+ 
++enum KernCollison
++{
++    None       = 0,
++    CrossSpace = 1,
++    InWord     = 2,
++    reserved   = 3
++};
+ 
+ Pass::Pass()
+ : m_silf(0),
+   m_cols(0),
+   m_rules(0),
+   m_ruleMap(0),
+   m_startStates(0),
+   m_transitions(0),
+   m_states(0),
+-  m_flags(0),
++  m_codes(0),
++  m_progs(0),
++  m_numCollRuns(0),
++  m_kernColls(0),
+   m_iMaxLoop(0),
+   m_numGlyphs(0),
+   m_numRules(0),
+   m_numStates(0),
+   m_numTransition(0),
+   m_numSuccess(0),
++  m_successStart(0),
+   m_numColumns(0),
+   m_minPreCtxt(0),
+-  m_maxPreCtxt(0)
++  m_maxPreCtxt(0),
++  m_colThreshold(0),
++  m_isReverseDir(false)
+ {
+ }
+ 
+ Pass::~Pass()
+ {
+     free(m_cols);
+     free(m_startStates);
+     free(m_transitions);
+     free(m_states);
+     free(m_ruleMap);
+ 
+-    delete [] m_rules;
++    if (m_rules) delete [] m_rules;
++    if (m_codes) delete [] m_codes;
++    free(m_progs);
+ }
+ 
+-bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t subtable_base, GR_MAYBE_UNUSED Face & face, Error &e)
++bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t subtable_base,
++        GR_MAYBE_UNUSED Face & face, passtype pt, GR_MAYBE_UNUSED uint32 version, Error &e)
+ {
+-    const byte *                p = pass_start,
+-               * const pass_end   = p + pass_length;
++    const byte * p              = pass_start,
++               * const pass_end = p + pass_length;
+     size_t numRanges;
+ 
+     if (e.test(pass_length < 40, E_BADPASSLENGTH)) return face.error(e); 
+     // Read in basic values
+-    m_flags = be::read<byte>(p);
++    const byte flags = be::read<byte>(p);
++    if (e.test((flags & 0x1f) && 
++            (pt < PASS_TYPE_POSITIONING || !m_silf->aCollision() || !face.glyphs().hasBoxes()),
++            E_BADCOLLISIONPASS))
++        return face.error(e);
++    m_numCollRuns = flags & 0x7;
++    m_kernColls   = (flags >> 3) & 0x3;
++    m_isReverseDir = (flags >> 5) & 0x1;
+     m_iMaxLoop = be::read<byte>(p);
++    if (m_iMaxLoop < 1) m_iMaxLoop = 1;
+     be::skip<byte>(p,2); // skip maxContext & maxBackup
+     m_numRules = be::read<uint16>(p);
++    if (e.test(!m_numRules && m_numCollRuns == 0, E_BADEMPTYPASS)) return face.error(e);
+     be::skip<uint16>(p);   // fsmOffset - not sure why we would want this
+     const byte * const pcCode = pass_start + be::read<uint32>(p) - subtable_base,
+                * const rcCode = pass_start + be::read<uint32>(p) - subtable_base,
+                * const aCode  = pass_start + be::read<uint32>(p) - subtable_base;
+     be::skip<uint32>(p);
+     m_numStates = be::read<uint16>(p);
+     m_numTransition = be::read<uint16>(p);
+     m_numSuccess = be::read<uint16>(p);
+     m_numColumns = be::read<uint16>(p);
+     numRanges = be::read<uint16>(p);
+     be::skip<uint16>(p, 3); // skip searchRange, entrySelector & rangeShift.
+     assert(p - pass_start == 40);
+     // Perform some sanity checks.
+     if ( e.test(m_numTransition > m_numStates, E_BADNUMTRANS)
+             || e.test(m_numSuccess > m_numStates, E_BADNUMSUCCESS)
+             || e.test(m_numSuccess + m_numTransition < m_numStates, E_BADNUMSTATES)
+-            || e.test(numRanges == 0, E_NORANGES))
++            || e.test(m_numRules && numRanges == 0, E_NORANGES)
++            || e.test(m_numColumns > 0x7FFF, E_BADNUMCOLUMNS))
+         return face.error(e);
+ 
+     m_successStart = m_numStates - m_numSuccess;
+-    if (e.test(p + numRanges * 6 - 4 > pass_end, E_BADPASSLENGTH)) return face.error(e);
++    // test for beyond end - 1 to account for reading uint16
++    if (e.test(p + numRanges * 6 - 2 > pass_end, E_BADPASSLENGTH)) return face.error(e);
+     m_numGlyphs = be::peek<uint16>(p + numRanges * 6 - 4) + 1;
+     // Calculate the start of various arrays.
+     const byte * const ranges = p;
+     be::skip<uint16>(p, numRanges*3);
+     const byte * const o_rule_map = p;
+     be::skip<uint16>(p, m_numSuccess + 1);
+ 
+     // More sanity checks
+@@ -126,108 +155,141 @@ bool Pass::readPass(const byte * const p
+     m_maxPreCtxt = be::read<uint8>(p);
+     if (e.test(m_minPreCtxt > m_maxPreCtxt, E_BADCTXTLENBOUNDS)) return face.error(e);
+     const byte * const start_states = p;
+     be::skip<int16>(p, m_maxPreCtxt - m_minPreCtxt + 1);
+     const uint16 * const sort_keys = reinterpret_cast<const uint16 *>(p);
+     be::skip<uint16>(p, m_numRules);
+     const byte * const precontext = p;
+     be::skip<byte>(p, m_numRules);
+-    be::skip<byte>(p);     // skip reserved byte
+ 
+-    if (e.test(p + sizeof(uint16) > pass_end, E_BADCTXTLENS)) return face.error(e);
++    if (e.test(p + sizeof(uint16) + sizeof(uint8) > pass_end, E_BADCTXTLENS)) return face.error(e);
++    m_colThreshold = be::read<uint8>(p);
++    if (m_colThreshold == 0) m_colThreshold = 10;       // A default
+     const size_t pass_constraint_len = be::read<uint16>(p);
++
+     const uint16 * const o_constraint = reinterpret_cast<const uint16 *>(p);
+     be::skip<uint16>(p, m_numRules + 1);
+     const uint16 * const o_actions = reinterpret_cast<const uint16 *>(p);
+     be::skip<uint16>(p, m_numRules + 1);
+     const byte * const states = p;
++    if (e.test(p + 2u*m_numTransition*m_numColumns >= pass_end, E_BADPASSLENGTH)) return face.error(e);
+     be::skip<int16>(p, m_numTransition*m_numColumns);
+-    be::skip<byte>(p);          // skip reserved byte
+-    if (e.test(p != pcCode, E_BADPASSCCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)) return face.error(e);
++    be::skip<uint8>(p);
++    if (e.test(p != pcCode, E_BADPASSCCODEPTR)) return face.error(e);
+     be::skip<byte>(p, pass_constraint_len);
+-    if (e.test(p != rcCode, E_BADRULECCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)
++    if (e.test(p != rcCode, E_BADRULECCODEPTR)
+         || e.test(size_t(rcCode - pcCode) != pass_constraint_len, E_BADCCODELEN)) return face.error(e);
+     be::skip<byte>(p, be::peek<uint16>(o_constraint + m_numRules));
+-    if (e.test(p != aCode, E_BADACTIONCODEPTR) || e.test(p >= pass_end, E_BADPASSLENGTH)) return face.error(e);
++    if (e.test(p != aCode, E_BADACTIONCODEPTR)) return face.error(e);
+     be::skip<byte>(p, be::peek<uint16>(o_actions + m_numRules));
+ 
+     // We should be at the end or within the pass
+     if (e.test(p > pass_end, E_BADPASSLENGTH)) return face.error(e);
+ 
+     // Load the pass constraint if there is one.
+     if (pass_constraint_len)
+     {
+         face.error_context(face.error_context() + 1);
+         m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len, 
+-                                  precontext[0], be::peek<uint16>(sort_keys), *m_silf, face);
++                                  precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN);
+         if (e.test(!m_cPConstraint, E_OUTOFMEM)
+-                || e.test(m_cPConstraint.status(), m_cPConstraint.status() + E_CODEFAILURE))
++                || e.test(!m_cPConstraint, m_cPConstraint.status() + E_CODEFAILURE))
+             return face.error(e);
+         face.error_context(face.error_context() - 1);
+     }
+-    if (!readRanges(ranges, numRanges, e)) return face.error(e);
+-    if (!readRules(rule_map, numEntries,  precontext, sort_keys,
+-                   o_constraint, rcCode, o_actions, aCode, face, e)) return false;
++    if (m_numRules)
++    {
++        if (!readRanges(ranges, numRanges, e)) return face.error(e);
++        if (!readRules(rule_map, numEntries,  precontext, sort_keys,
++                   o_constraint, rcCode, o_actions, aCode, face, pt, e)) return false;
++    }
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::category _states_cat(face.tele.states);
+ #endif
+-    return readStates(start_states, states, o_rule_map, face, e);
++    return m_numRules ? readStates(start_states, states, o_rule_map, face, e) : true;
+ }
+ 
+ 
+ bool Pass::readRules(const byte * rule_map, const size_t num_entries,
+                      const byte *precontext, const uint16 * sort_key,
+                      const uint16 * o_constraint, const byte *rc_data,
+                      const uint16 * o_action,     const byte * ac_data,
+-                     Face & face, Error &e)
++                     Face & face, passtype pt, Error &e)
+ {
+     const byte * const ac_data_end = ac_data + be::peek<uint16>(o_action + m_numRules);
+     const byte * const rc_data_end = rc_data + be::peek<uint16>(o_constraint + m_numRules);
+ 
+-    if (e.test(!(m_rules = new Rule [m_numRules]), E_OUTOFMEM)) return face.error(e);
+     precontext += m_numRules;
+     sort_key   += m_numRules;
+     o_constraint += m_numRules;
+     o_action += m_numRules;
+ 
+     // Load rules.
+     const byte * ac_begin = 0, * rc_begin = 0,
+                * ac_end = ac_data + be::peek<uint16>(o_action),
+                * rc_end = rc_data + be::peek<uint16>(o_constraint);
++
++    // Allocate pools
++    m_rules = new Rule [m_numRules];
++    m_codes = new Code [m_numRules*2];
++    const size_t prog_pool_sz = vm::Machine::Code::estimateCodeDataOut(ac_end - ac_data + rc_end - rc_data);
++    m_progs = gralloc<byte>(prog_pool_sz);
++    byte * prog_pool_free = m_progs,
++         * prog_pool_end  = m_progs + prog_pool_sz;
++    if (e.test(!(m_rules && m_codes && m_progs), E_OUTOFMEM)) return face.error(e);
++
+     Rule * r = m_rules + m_numRules - 1;
+     for (size_t n = m_numRules; n; --n, --r, ac_end = ac_begin, rc_end = rc_begin)
+     {
+         face.error_context((face.error_context() & 0xFFFF00) + EC_ARULE + ((n - 1) << 24));
+         r->preContext = *--precontext;
+         r->sort       = be::peek<uint16>(--sort_key);
+ #ifndef NDEBUG
+         r->rule_idx   = n - 1;
+ #endif
+         if (r->sort > 63 || r->preContext >= r->sort || r->preContext > m_maxPreCtxt || r->preContext < m_minPreCtxt)
+             return false;
+         ac_begin      = ac_data + be::peek<uint16>(--o_action);
+         --o_constraint;
+         rc_begin      = be::peek<uint16>(o_constraint) ? rc_data + be::peek<uint16>(o_constraint) : rc_end;
+ 
+         if (ac_begin > ac_end || ac_begin > ac_data_end || ac_end > ac_data_end
+-                || rc_begin > rc_end || rc_begin > rc_data_end || rc_end > rc_data_end)
++                || rc_begin > rc_end || rc_begin > rc_data_end || rc_end > rc_data_end
++                || vm::Machine::Code::estimateCodeDataOut(ac_end - ac_begin + rc_end - rc_begin) > size_t(prog_pool_end - prog_pool_free))
+             return false;
+-        r->action     = new vm::Machine::Code(false, ac_begin, ac_end, r->preContext, r->sort, *m_silf, face);
+-        r->constraint = new vm::Machine::Code(true,  rc_begin, rc_end, r->preContext, r->sort, *m_silf, face);
++        r->action     = new (m_codes+n*2-2) vm::Machine::Code(false, ac_begin, ac_end, r->preContext, r->sort, *m_silf, face, pt, &prog_pool_free);
++        r->constraint = new (m_codes+n*2-1) vm::Machine::Code(true,  rc_begin, rc_end, r->preContext, r->sort, *m_silf, face, pt, &prog_pool_free);
+ 
+         if (e.test(!r->action || !r->constraint, E_OUTOFMEM)
+                 || e.test(r->action->status() != Code::loaded, r->action->status() + E_CODEFAILURE)
+                 || e.test(r->constraint->status() != Code::loaded, r->constraint->status() + E_CODEFAILURE)
+                 || e.test(!r->constraint->immutable(), E_MUTABLECCODE))
+             return face.error(e);
+     }
+ 
++    byte * moved_progs = static_cast<byte *>(realloc(m_progs, prog_pool_free - m_progs));
++    if (e.test(!moved_progs, E_OUTOFMEM))
++    {
++        if (prog_pool_free - m_progs == 0) m_progs = 0;
++        return face.error(e);
++    }
++
++    if (moved_progs != m_progs)
++    {
++        for (Code * c = m_codes, * const ce = c + m_numRules*2; c != ce; ++c)
++        {
++            c->externalProgramMoved(moved_progs - m_progs);
++        }
++        m_progs = moved_progs;
++    }
++
+     // Load the rule entries map
+     face.error_context((face.error_context() & 0xFFFF00) + EC_APASS);
++    //TODO: Coverty: 1315804: FORWARD_NULL
+     RuleEntry * re = m_ruleMap = gralloc<RuleEntry>(num_entries);
+     if (e.test(!re, E_OUTOFMEM)) return face.error(e);
+     for (size_t n = num_entries; n; --n, ++re)
+     {
+         const ptrdiff_t rn = be::read<uint16>(rule_map);
+         if (e.test(rn >= m_numRules, E_BADRULENUM))  return face.error(e);
+         re->rule = m_rules + rn;
+     }
+@@ -320,43 +382,69 @@ bool Pass::readRanges(const byte * range
+ 
+         if (e.test(ci != ci_end, E_BADRANGE))
+             return false;
+     }
+     return true;
+ }
+ 
+ 
+-void Pass::runGraphite(Machine & m, FiniteStateMachine & fsm) const
++bool Pass::runGraphite(vm::Machine & m, FiniteStateMachine & fsm, bool reverse) const
+ {
+     Slot *s = m.slotMap().segment.first();
+-    if (!s || !testPassConstraint(m)) return;
+-    Slot *currHigh = s->next();
++    if (!s || !testPassConstraint(m)) return true;
++    if (reverse)
++    {
++        m.slotMap().segment.reverseSlots();
++        s = m.slotMap().segment.first();
++    }
++    if (m_numRules)
++    {
++        Slot *currHigh = s->next();
+ 
+ #if !defined GRAPHITE2_NTRACING
+-    if (fsm.dbgout)  *fsm.dbgout << "rules" << json::array;
+-    json::closer rules_array_closer(fsm.dbgout);
++        if (fsm.dbgout)  *fsm.dbgout << "rules" << json::array;
++        json::closer rules_array_closer(fsm.dbgout);
+ #endif
+ 
+-    m.slotMap().highwater(currHigh);
+-    int lc = m_iMaxLoop;
+-    do
++        m.slotMap().highwater(currHigh);
++        int lc = m_iMaxLoop;
++        do
++        {
++            findNDoRule(s, m, fsm);
++            if (s && (s == m.slotMap().highwater() || m.slotMap().highpassed() || --lc == 0)) {
++                if (!lc)
++                    s = m.slotMap().highwater();
++                lc = m_iMaxLoop;
++                if (s)
++                    m.slotMap().highwater(s->next());
++            }
++        } while (s);
++    }
++    //TODO: Use enums for flags
++    const bool collisions = m_numCollRuns || m_kernColls;
++
++    if (!collisions || !m.slotMap().segment.hasCollisionInfo())
++        return true;
++
++    if (m_numCollRuns)
+     {
+-        findNDoRule(s, m, fsm);
+-        if (s && (m.slotMap().highpassed() || s == m.slotMap().highwater() || --lc == 0)) {
+-            if (!lc)
+-            {
+-//              if (dbgout) *dbgout << json::item << json::flat << rule_event(-1, s, 1);
+-                s = m.slotMap().highwater();
+-            }
+-            lc = m_iMaxLoop;
+-            if (s)
+-                m.slotMap().highwater(s->next());
++        if (!(m.slotMap().segment.flags() & Segment::SEG_INITCOLLISIONS))
++        {
++            m.slotMap().segment.positionSlots(0, 0, 0, m.slotMap().dir(), true);
++//            m.slotMap().segment.flags(m.slotMap().segment.flags() | Segment::SEG_INITCOLLISIONS);
+         }
+-    } while (s);
++        if (!collisionShift(&m.slotMap().segment, m.slotMap().dir(), fsm.dbgout))
++            return false;
++    }
++    if ((m_kernColls) && !collisionKern(&m.slotMap().segment, m.slotMap().dir(), fsm.dbgout))
++        return false;
++    if (collisions && !collisionFinish(&m.slotMap().segment, fsm.dbgout))
++        return false;
++    return true;
+ }
+ 
+ bool Pass::runFSM(FiniteStateMachine& fsm, Slot * slot) const
+ {
+     fsm.reset(slot, m_maxPreCtxt);
+     if (fsm.slots.context() < m_minPreCtxt)
+         return false;
+ 
+@@ -419,18 +507,18 @@ void Pass::findNDoRule(Slot * & slot, Ma
+         {
+             if (fsm.rules.size() != 0)
+             {
+                 *fsm.dbgout << json::item << json::object;
+                 dumpRuleEventConsidered(fsm, *r);
+                 if (r != re)
+                 {
+                     const int adv = doAction(r->rule->action, slot, m);
+-                    dumpRuleEventOutput(fsm, *r->rule, slot);
+-                    if (r->rule->action->deletes()) fsm.slots.collectGarbage();
++                    dumpRuleEventOutput(fsm, m, *r->rule, slot);
++                    if (r->rule->action->deletes()) fsm.slots.collectGarbage(slot);
+                     adjustSlot(adv, slot, fsm.slots);
+                     *fsm.dbgout << "cursor" << objectid(dslot(&fsm.slots.segment, slot))
+                             << json::close; // Close RuelEvent object
+ 
+                     return;
+                 }
+                 else
+                 {
+@@ -442,47 +530,49 @@ void Pass::findNDoRule(Slot * & slot, Ma
+             }
+         }
+         else
+ #endif
+         {
+             if (r != re)
+             {
+                 const int adv = doAction(r->rule->action, slot, m);
+-                if (r->rule->action->deletes()) fsm.slots.collectGarbage();
++                if (r->rule->action->deletes()) fsm.slots.collectGarbage(slot);
+                 adjustSlot(adv, slot, fsm.slots);
+                 return;
+             }
+         }
+     }
+ 
+     slot = slot->next();
++    return;
+ }
+ 
+ #if !defined GRAPHITE2_NTRACING
+ 
+ void Pass::dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const
+ {
+     *fsm.dbgout << "considered" << json::array;
+     for (const RuleEntry *r = fsm.rules.begin(); r != &re; ++r)
+     {
+-        if (r->rule->preContext > fsm.slots.context())  continue;
+-    *fsm.dbgout << json::flat << json::object
+-                    << "id"     << r->rule - m_rules
++        if (r->rule->preContext > fsm.slots.context())
++            continue;
++        *fsm.dbgout << json::flat << json::object
++                    << "id" << r->rule - m_rules
+                     << "failed" << true
+                     << "input" << json::flat << json::object
+                         << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, -r->rule->preContext)))
+                         << "length" << r->rule->sort
+                         << json::close  // close "input"
+                     << json::close; // close Rule object
+     }
+ }
+ 
+ 
+-void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * const last_slot) const
++void Pass::dumpRuleEventOutput(const FiniteStateMachine & fsm, Machine & m, const Rule & r, Slot * const last_slot) const
+ {
+     *fsm.dbgout     << json::item << json::flat << json::object
+                         << "id"     << &r - m_rules
+                         << "failed" << false
+                         << "input" << json::flat << json::object
+                             << "start" << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, 0)))
+                             << "length" << r.sort - r.preContext
+                             << json::close // close "input"
+@@ -490,17 +580,17 @@ void Pass::dumpRuleEventOutput(const Fin
+                 << json::close // close considered array
+                 << "output" << json::object
+                     << "range" << json::flat << json::object
+                         << "start"  << objectid(dslot(&fsm.slots.segment, input_slot(fsm.slots, 0)))
+                         << "end"    << objectid(dslot(&fsm.slots.segment, last_slot))
+                     << json::close // close "input"
+                     << "slots"  << json::array;
+     const Position rsb_prepos = last_slot ? last_slot->origin() : fsm.slots.segment.advance();
+-    fsm.slots.segment.positionSlots(0);
++    fsm.slots.segment.positionSlots(0, 0, 0, m.slotMap().dir());
+ 
+     for(Slot * slot = output_slot(fsm.slots, 0); slot != last_slot; slot = slot->next())
+         *fsm.dbgout     << dslot(&fsm.slots.segment, slot);
+     *fsm.dbgout         << json::close  // close "slots"
+                     << "postshift"  << (last_slot ? last_slot->origin() : fsm.slots.segment.advance()) - rsb_prepos
+                 << json::close;         // close "output" object
+ 
+ }
+@@ -546,22 +636,26 @@ bool Pass::testConstraint(const Rule & r
+         if (!ret || m.status() != Machine::finished)
+             return false;
+     }
+ 
+     return true;
+ }
+ 
+ 
+-void SlotMap::collectGarbage()
++void SlotMap::collectGarbage(Slot * &aSlot)
+ {
+     for(Slot **s = begin(), *const *const se = end() - 1; s != se; ++s) {
+         Slot *& slot = *s;
+         if(slot->isDeleted() || slot->isCopied())
++        {
++            if (slot == aSlot)
++                aSlot = slot->prev() ? slot->prev() : slot->next();
+             segment.freeSlot(slot);
++        }
+     }
+ }
+ 
+ 
+ 
+ int Pass::doAction(const Code *codeptr, Slot * & slot_out, vm::Machine & m) const
+ {
+     assert(codeptr);
+@@ -581,40 +675,412 @@ int Pass::doAction(const Code *codeptr, 
+ 
+     slot_out = *map;
+     return ret;
+ }
+ 
+ 
+ void Pass::adjustSlot(int delta, Slot * & slot_out, SlotMap & smap) const
+ {
+-    if (delta < 0)
++    if (!slot_out)
+     {
+-        if (!slot_out)
++        if (smap.highpassed() || slot_out == smap.highwater())
+         {
+             slot_out = smap.segment.last();
+             ++delta;
+-            if (smap.highpassed() && !smap.highwater())
++            if (!smap.highwater())
+                 smap.highpassed(false);
+         }
++        else
++        {
++            slot_out = smap.segment.first();
++            --delta;
++        }
++    }
++    if (delta < 0)
++    {
+         while (++delta <= 0 && slot_out)
+         {
+             if (smap.highpassed() && smap.highwater() == slot_out)
+                 smap.highpassed(false);
+             slot_out = slot_out->prev();
+         }
+     }
+     else if (delta > 0)
+     {
+-        if (!slot_out)
+-        {
+-            slot_out = smap.segment.first();
+-            --delta;
+-        }
+         while (--delta >= 0 && slot_out)
+         {
+             slot_out = slot_out->next();
+             if (slot_out == smap.highwater() && slot_out)
+                 smap.highpassed(true);
+         }
+     }
+ }
+ 
++bool Pass::collisionShift(Segment *seg, int dir, json * const dbgout) const
++{
++    ShiftCollider shiftcoll(dbgout);
++    // bool isfirst = true;
++    bool hasCollisions = false;
++    Slot *start = seg->first();      // turn on collision fixing for the first slot
++    Slot *end = NULL;
++    bool moved = false;
++
++#if !defined GRAPHITE2_NTRACING
++    if (dbgout)
++        *dbgout << "collisions" << json::array
++            << json::flat << json::object << "num-loops" << m_numCollRuns << json::close;
++#endif
++
++    while (start)
++    {
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)  *dbgout << json::object << "phase" << "1" << "moves" << json::array;
++#endif
++        hasCollisions = false;
++        end = NULL;
++        // phase 1 : position shiftable glyphs, ignoring kernable glyphs
++        for (Slot *s = start; s; s = s->next())
++        {
++            const SlotCollision * c = seg->collisionInfo(s);
++            if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_KERN)) == SlotCollision::COLL_FIX
++                      && !resolveCollisions(seg, s, start, shiftcoll, false, dir, moved, hasCollisions, dbgout))
++                return false;
++            if (s != start && (c->flags() & SlotCollision::COLL_END))
++            {
++                end = s->next();
++                break;
++            }
++        }
++
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)
++            *dbgout << json::close << json::close; // phase-1
++#endif
++
++        // phase 2 : loop until happy. 
++        for (int i = 0; i < m_numCollRuns - 1; ++i)
++        {
++            if (hasCollisions || moved)
++            {
++
++#if !defined GRAPHITE2_NTRACING
++                if (dbgout)
++                    *dbgout << json::object << "phase" << "2a" << "loop" << i << "moves" << json::array;
++#endif
++                // phase 2a : if any shiftable glyphs are in collision, iterate backwards,
++                // fixing them and ignoring other non-collided glyphs. Note that this handles ONLY
++                // glyphs that are actually in collision from phases 1 or 2b, and working backwards
++                // has the intended effect of breaking logjams.
++                if (hasCollisions)
++                {
++                    hasCollisions = false;
++                    #if 0
++                    moved = true;
++                    for (Slot *s = start; s != end; s = s->next())
++                    {
++                        SlotCollision * c = seg->collisionInfo(s);
++                        c->setShift(Position(0, 0));
++                    }
++                    #endif
++                    Slot *lend = end ? end->prev() : seg->last();
++                    Slot *lstart = start->prev();
++                    for (Slot *s = lend; s != lstart; s = s->prev())
++                    {
++                        SlotCollision * c = seg->collisionInfo(s);
++                        if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_KERN | SlotCollision::COLL_ISCOL))
++                                        == (SlotCollision::COLL_FIX | SlotCollision::COLL_ISCOL)) // ONLY if this glyph is still colliding
++                        {
++                            if (!resolveCollisions(seg, s, lend, shiftcoll, true, dir, moved, hasCollisions, dbgout))
++                                return false;
++                            c->setFlags(c->flags() | SlotCollision::COLL_TEMPLOCK);
++                        }
++                    }
++                }
++
++#if !defined GRAPHITE2_NTRACING
++                if (dbgout)
++                    *dbgout << json::close << json::close // phase 2a
++                        << json::object << "phase" << "2b" << "loop" << i << "moves" << json::array;
++#endif
++
++                // phase 2b : redo basic diacritic positioning pass for ALL glyphs. Each successive loop adjusts 
++                // glyphs from their current adjusted position, which has the effect of gradually minimizing the  
++                // resulting adjustment; ie, the final result will be gradually closer to the original location.  
++                // Also it allows more flexibility in the final adjustment, since it is moving along the  
++                // possible 8 vectors from successively different starting locations.
++                if (moved)
++                {
++                    moved = false;
++                    for (Slot *s = start; s != end; s = s->next())
++                    {
++                        SlotCollision * c = seg->collisionInfo(s);
++                        if (start && (c->flags() & (SlotCollision::COLL_FIX | SlotCollision::COLL_TEMPLOCK
++                                                        | SlotCollision::COLL_KERN)) == SlotCollision::COLL_FIX
++                                  && !resolveCollisions(seg, s, start, shiftcoll, false, dir, moved, hasCollisions, dbgout))
++                            return false;
++                        else if (c->flags() & SlotCollision::COLL_TEMPLOCK)
++                            c->setFlags(c->flags() & ~SlotCollision::COLL_TEMPLOCK);
++                    }
++                }
++        //      if (!hasCollisions) // no, don't leave yet because phase 2b will continue to improve things
++        //          break;
++#if !defined GRAPHITE2_NTRACING
++                if (dbgout)
++                    *dbgout << json::close << json::close; // phase 2
++#endif
++            }
++        }
++        if (!end)
++            break;
++        start = NULL;
++        for (Slot *s = end->prev(); s; s = s->next())
++        {
++            if (seg->collisionInfo(s)->flags() & SlotCollision::COLL_START)
++            {
++                start = s;
++                break;
++            }
++        }
++    }
++    return true;
++}
++
++bool Pass::collisionKern(Segment *seg, int dir, json * const dbgout) const
++{
++    KernCollider kerncoll(dbgout);
++    Slot *start = seg->first();
++    float ymin = 1e38f;
++    float ymax = -1e38f;
++    const GlyphCache &gc = seg->getFace()->glyphs();
++
++    // phase 3 : handle kerning of clusters
++#if !defined GRAPHITE2_NTRACING
++    if (dbgout)
++        *dbgout << json::object << "phase" << "3" << "moves" << json::array;
++#endif
++
++    for (Slot *s = seg->first(); s; s = s->next())
++    {
++        if (!gc.check(s->gid()))
++            return false;
++        const SlotCollision * c = seg->collisionInfo(s);
++        const Rect &bbox = seg->theGlyphBBoxTemporary(s->gid());
++        float y = s->origin().y + c->shift().y;
++        ymax = max(y + bbox.tr.y, ymax);
++        ymin = min(y + bbox.bl.y, ymin);
++        if (start && (c->flags() & (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
++                        == (SlotCollision::COLL_KERN | SlotCollision::COLL_FIX))
++            resolveKern(seg, s, start, kerncoll, dir, ymin, ymax, dbgout);
++        if (c->flags() & SlotCollision::COLL_END)
++            start = NULL;
++        if (c->flags() & SlotCollision::COLL_START)
++            start = s;
++    }
++
++#if !defined GRAPHITE2_NTRACING
++    if (dbgout)
++        *dbgout << json::close << json::close; // phase 3
++#endif
++    return true;
++}
++
++bool Pass::collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const
++{
++    for (Slot *s = seg->first(); s; s = s->next())
++    {
++        SlotCollision *c = seg->collisionInfo(s);
++        if (c->shift().x != 0 || c->shift().y != 0)
++        {
++            const Position newOffset = c->shift();
++            const Position nullPosition(0, 0);
++            c->setOffset(newOffset + c->offset());
++            c->setShift(nullPosition);
++        }
++    }
++//    seg->positionSlots();
++
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)
++            *dbgout << json::close;
++#endif
++    return true;
++}
++
++// Can slot s be kerned, or is it attached to something that can be kerned?
++static bool inKernCluster(Segment *seg, Slot *s)
++{
++    SlotCollision *c = seg->collisionInfo(s);
++    if (c->flags() & SlotCollision::COLL_KERN /** && c->flags() & SlotCollision::COLL_FIX **/ )
++        return true;
++    while (s->attachedTo())
++    {
++        s = s->attachedTo();
++        c = seg->collisionInfo(s);
++        if (c->flags() & SlotCollision::COLL_KERN /** && c->flags() & SlotCollision::COLL_FIX **/ )
++            return true;
++    }
++    return false;
++}
++
++// Fix collisions for the given slot.
++// Return true if everything was fixed, false if there are still collisions remaining.
++// isRev means be we are processing backwards.
++bool Pass::resolveCollisions(Segment *seg, Slot *slotFix, Slot *start,
++        ShiftCollider &coll, GR_MAYBE_UNUSED bool isRev, int dir, bool &moved, bool &hasCol,
++        json * const dbgout) const
++{
++    Slot * nbor;  // neighboring slot
++    SlotCollision *cFix = seg->collisionInfo(slotFix);
++    if (!coll.initSlot(seg, slotFix, cFix->limit(), cFix->margin(), cFix->marginWt(),
++            cFix->shift(), cFix->offset(), dir, dbgout))
++        return false;
++    bool collides = false;
++    // When we're processing forward, ignore kernable glyphs that preceed the target glyph.
++    // When processing backward, don't ignore these until we pass slotFix.
++    bool ignoreForKern = !isRev;
++    bool rtl = dir & 1;
++    Slot *base = slotFix;
++    while (base->attachedTo())
++        base = base->attachedTo();
++    Position zero(0., 0.);
++    
++    // Look for collisions with the neighboring glyphs.
++    for (nbor = start; nbor; nbor = isRev ? nbor->prev() : nbor->next())
++    {
++        SlotCollision *cNbor = seg->collisionInfo(nbor);
++        bool sameCluster = nbor->isChildOf(base);
++        if (nbor != slotFix         // don't process if this is the slot of interest
++                      && !(cNbor->flags() & SlotCollision::COLL_IGNORE)    // don't process if ignoring
++                      && (nbor == base || sameCluster       // process if in the same cluster as slotFix
++                            || !inKernCluster(seg, nbor)    // or this cluster is not to be kerned
++                            || (rtl ^ ignoreForKern))       // or it comes before(ltr) or after(rtl)
++                      && (!isRev    // if processing forwards then good to merge otherwise only:
++                            || !(cNbor->flags() & SlotCollision::COLL_FIX)     // merge in immovable stuff
++                            || ((cNbor->flags() & SlotCollision::COLL_KERN) && !sameCluster)     // ignore other kernable clusters
++                            || (cNbor->flags() & SlotCollision::COLL_ISCOL))   // test against other collided glyphs
++                      && !coll.mergeSlot(seg, nbor, cNbor->shift(), !ignoreForKern, sameCluster, collides, false, dbgout))
++            return false;
++        else if (nbor == slotFix)
++            // Switching sides of this glyph - if we were ignoring kernable stuff before, don't anymore.
++            ignoreForKern = !ignoreForKern;
++            
++        if (nbor != start && (cNbor->flags() & (isRev ? SlotCollision::COLL_START : SlotCollision::COLL_END)))
++            break;
++    }
++    bool isCol = false;
++    if (collides || cFix->shift().x != 0.f || cFix->shift().y != 0.f)
++    {
++        Position shift = coll.resolve(seg, isCol, dbgout);
++        // isCol has been set to true if a collision remains.
++        if (std::fabs(shift.x) < 1e38f && std::fabs(shift.y) < 1e38f)
++        {
++            if (sqr(shift.x-cFix->shift().x) + sqr(shift.y-cFix->shift().y) >= m_colThreshold * m_colThreshold)
++                moved = true;
++            cFix->setShift(shift);
++            if (slotFix->firstChild())
++            {
++                Rect bbox;
++                Position here = slotFix->origin() + shift;
++                float clusterMin = here.x;
++                slotFix->firstChild()->finalise(seg, NULL, here, bbox, 0, clusterMin, rtl, false);
++            }
++        }
++    }
++    else
++    {
++        // This glyph is not colliding with anything.
++#if !defined GRAPHITE2_NTRACING
++        if (dbgout)
++        {
++            *dbgout << json::object 
++                            << "missed" << objectid(dslot(seg, slotFix));
++            coll.outputJsonDbg(dbgout, seg, -1);
++            *dbgout << json::close;
++        }
++#endif
++    }
++
++    // Set the is-collision flag bit.
++    if (isCol)
++    { cFix->setFlags(cFix->flags() | SlotCollision::COLL_ISCOL | SlotCollision::COLL_KNOWN); }
++    else
++    { cFix->setFlags((cFix->flags() & ~SlotCollision::COLL_ISCOL) | SlotCollision::COLL_KNOWN); }
++    hasCol |= isCol;
++    return true;
++}
++
++float Pass::resolveKern(Segment *seg, Slot *slotFix, GR_MAYBE_UNUSED Slot *start, KernCollider &coll, int dir,
++    float &ymin, float &ymax, json *const dbgout) const
++{
++    Slot *nbor; // neighboring slot
++    float currSpace = 0.;
++    bool collides = false;
++    unsigned int space_count = 0;
++    Slot *base = slotFix;
++    while (base->attachedTo())
++        base = base->attachedTo();
++    SlotCollision *cFix = seg->collisionInfo(base);
++    const GlyphCache &gc = seg->getFace()->glyphs();
++
++    if (base != slotFix)
++    {
++        cFix->setFlags(cFix->flags() | SlotCollision::COLL_KERN | SlotCollision::COLL_FIX);
++        return 0;
++    }
++    bool seenEnd = (cFix->flags() & SlotCollision::COLL_END) != 0;
++    bool isInit = false;
++
++    for (nbor = slotFix->next(); nbor; nbor = nbor->next())
++    {
++        if (nbor->isChildOf(base))
++            continue;
++        if (!gc.check(nbor->gid()))
++            return 0.;
++        const Rect &bb = seg->theGlyphBBoxTemporary(nbor->gid());
++        SlotCollision *cNbor = seg->collisionInfo(nbor);
++        if (bb.bl.y == 0.f && bb.tr.y == 0.f)
++        {
++            if (m_kernColls == InWord)
++                break;
++            // Add space for a space glyph.
++            currSpace += nbor->advance();
++            ++space_count;
++        }
++        else
++        {
++            space_count = 0; 
++            float y = nbor->origin().y + cNbor->shift().y;
++            ymax = max(y + bb.tr.y, ymax);
++            ymin = min(y + bb.bl.y, ymin);
++            if (nbor != slotFix && !(cNbor->flags() & SlotCollision::COLL_IGNORE))
++            {
++                seenEnd = true;
++                if (!isInit)
++                {
++                    if (!coll.initSlot(seg, slotFix, cFix->limit(), cFix->margin(),
++                                    cFix->shift(), cFix->offset(), dir, ymin, ymax, dbgout))
++                        return 0.;
++                    isInit = true;
++                }
++                collides |= coll.mergeSlot(seg, nbor, cNbor->shift(), currSpace, dir, dbgout);
++            }
++        }
++        if (cNbor->flags() & SlotCollision::COLL_END)
++        {
++            if (seenEnd && space_count < 2)
++                break;
++            else
++                seenEnd = true;
++        }
++    }
++    if (collides)
++    {
++        Position mv = coll.resolve(seg, slotFix, dir, cFix->margin(), dbgout);
++        coll.shift(mv, dir);
++        Position delta = slotFix->advancePos() + mv - cFix->shift();
++        slotFix->advance(delta);
++        cFix->setShift(mv);
++        return mv.x;
++    }
++    return 0.;
++}
++
+diff --git a/gfx/graphite2/src/Position.cpp b/gfx/graphite2/src/Position.cpp
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/Position.cpp
+@@ -0,0 +1,98 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#include "inc/Position.h"
++#include <cmath>
++
++using namespace graphite2;
++
++bool Rect::hitTest(Rect &other)
++{
++    if (bl.x > other.tr.x) return false;
++    if (tr.x < other.bl.x) return false;
++    if (bl.y > other.tr.y) return false;
++    if (tr.y < other.bl.y) return false;
++    return true;
++}
++
++Position Rect::overlap(Position &offset, Rect &other, Position &othero)
++{
++    float ax = (bl.x + offset.x) - (other.tr.x + othero.x);
++    float ay = (bl.y + offset.y) - (other.tr.y + othero.y);
++    float bx = (other.bl.x + othero.x) - (tr.x + offset.x);
++    float by = (other.bl.y + othero.y) - (tr.y + offset.y);
++    return Position((ax > bx ? ax : bx), (ay > by ? ay : by));
++}
++
++float boundmin(float move, float lim1, float lim2, float &error)
++{
++    // error is always positive for easy comparison
++    if (move < lim1 && move < lim2)
++    { error = 0.; return move; }
++    else if (lim1 < lim2)
++    { error = std::fabs(move - lim1); return lim1; }
++    else
++    { error = std::fabs(move - lim2); return lim2; }
++}
++
++#if 0
++Position Rect::constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Position &other, Rect &obox, Rect &osdbox)
++{
++    // a = max, i = min, s = sum, d = diff
++    float eax, eay, eix, eiy, eas, eis, ead, eid;
++    float beste = INF;
++    Position res;
++    // calculate the movements in each direction and the error (amount of remaining overlap)
++    // first param is movement, second and third are movement over the constraining box
++    float ax = boundmin(obox.tr.x + other.x - box.bl.x - offset.x + 1, tr.x - offset.x, INF, &eax);
++    float ay = boundmin(obox.tr.y + other.y - box.bl.y - offset.y + 1, tr.y - offset.y, INF, &eay);
++    float ix = boundmin(obox.bl.x + other.x - box.tr.x - offset.x + 1, bl.x - offset.x, INF, &eix);
++    float iy = boundmin(obox.bl.y + other.y - box.tr.y - offset.y + 1, bl.y - offset.y, INF, &eiy);
++    float as = boundmin(ISQRT2 * (osdbox.tr.x + other.x + other.y - sdbox.bl.x - offset.x - offset.y) + 1, tr.x - offset.x, tr.y - offset.y, &eas);
++    float is = boundmin(ISQRT2 * (osdbox.bl.x + other.x + other.y - sdbox.tr.x - offset.x - offset.y) + 1, bl.x - offset.x, bl.y - offset.y, &eis);
++    float ad = boundmin(ISQRT2 * (osdbox.tr.y + other.x - other.y - sdbox.bl.y - offset.x + offset.y) + 1, tr.y - offset.y, tr.x - offset.x, &ead);
++    float id = boundmin(ISQRT2 * (osdbox.bl.y + other.x - other.y - sdbox.tr.y - offset.x + offset.y) + 1, bl.y - offset.y, bl.x - offset.x, &eid);
++
++    if (eax < beste)
++    { res = Position(ax, 0); beste = eax; }
++    if (eay < beste)
++    { res = Position(0, ay); beste = eay; }
++    if (eix < beste)
++    { res = Position(ix, 0); beste = eix; }
++    if (eiy < beste)
++    { res = Position(0, iy); beste = eiy; }
++    if (SQRT2 * (eas) < beste)
++    { res = Position(as, ad); beste = SQRT2 * (eas); }
++    if (SQRT2 * (eis) < beste)
++    { res = Position(is, is); beste = SQRT2 * (eis); }
++    if (SQRT2 * (ead) < beste)
++    { res = Position(ad, ad); beste = SQRT2 * (ead); }
++    if (SQRT2 * (eid) < beste)
++    { res = Position(id, id); beste = SQRT2 * (eid); }
++    return res;
++}
++#endif
++
+diff --git a/gfx/graphite2/src/SegCache.cpp b/gfx/graphite2/src/SegCache.cpp
+--- a/gfx/graphite2/src/SegCache.cpp
++++ b/gfx/graphite2/src/SegCache.cpp
+@@ -35,17 +35,17 @@ of the License or (at your option) any l
+ 
+ 
+ using namespace graphite2;
+ 
+ #ifndef GRAPHITE2_NSEGCACHE
+ 
+ SegCache::SegCache(const SegCacheStore * store, const Features & feats)
+ : m_prefixLength(ePrefixLength),
+-  m_maxCachedSegLength(eMaxSpliceSize),
++//  m_maxCachedSegLength(eMaxSpliceSize),
+   m_segmentCount(0),
+   m_features(feats),
+   m_totalAccessCount(0l), m_totalMisses(0l),
+   m_purgeFactor(1.0f / (ePurgeFactor * store->maxSegmentCount()))
+ {
+     m_prefixes.raw = grzeroalloc<void*>(store->maxCmapGid() + 2);
+     m_prefixes.range[SEG_CACHE_MIN_INDEX] = SEG_CACHE_UNSET_INDEX;
+     m_prefixes.range[SEG_CACHE_MAX_INDEX] = SEG_CACHE_UNSET_INDEX;
+@@ -79,17 +79,17 @@ SegCache::~SegCache()
+ {
+     assert(m_prefixes.raw == NULL);
+ }
+ 
+ SegCacheEntry* SegCache::cache(SegCacheStore * store, const uint16* cmapGlyphs, size_t length, Segment * seg, size_t charOffset)
+ {
+     uint16 pos = 0;
+     if (!length) return NULL;
+-    assert(length < m_maxCachedSegLength);
++//    assert(length < m_maxCachedSegLength);
+     SegCachePrefixArray pArray = m_prefixes;
+     while (pos + 1 < m_prefixLength)
+     {
+         uint16 gid = (pos < length)? cmapGlyphs[pos] : 0;
+         if (!pArray.array[gid].raw)
+         {
+             pArray.array[gid].raw = grzeroalloc<void*>(store->maxCmapGid() + 2);
+             if (!pArray.array[gid].raw)
+diff --git a/gfx/graphite2/src/Segment.cpp b/gfx/graphite2/src/Segment.cpp
+--- a/gfx/graphite2/src/Segment.cpp
++++ b/gfx/graphite2/src/Segment.cpp
+@@ -31,48 +31,53 @@ of the License or (at your option) any l
+ #include "inc/bits.h"
+ #include "inc/Segment.h"
+ #include "graphite2/Font.h"
+ #include "inc/CharInfo.h"
+ #include "inc/debug.h"
+ #include "inc/Slot.h"
+ #include "inc/Main.h"
+ #include "inc/CmapCache.h"
+-#include "inc/Bidi.h"
++#include "inc/Collider.h"
+ #include "graphite2/Segment.h"
+ 
+ 
+ using namespace graphite2;
+ 
+ Segment::Segment(unsigned int numchars, const Face* face, uint32 script, int textDir)
+ : m_freeSlots(NULL),
+   m_freeJustifies(NULL),
+   m_charinfo(new CharInfo[numchars]),
++  m_collisions(NULL),
+   m_face(face),
+   m_silf(face->chooseSilf(script)),
+   m_first(NULL),
+   m_last(NULL),
+   m_bufSize(numchars + 10),
+   m_numGlyphs(numchars),
+   m_numCharinfo(numchars),
+   m_passBits(m_silf->aPassBits() ? -1 : 0),
+   m_defaultOriginal(0),
+-  m_dir(textDir)
++  m_dir(textDir),
++  m_flags(((m_silf->flags() & 0x20) != 0) << 1)
+ {
+     freeSlot(newSlot());
+     m_bufSize = log_binary(numchars)+1;
+ }
+ 
+ Segment::~Segment()
+ {
+     for (SlotRope::iterator i = m_slots.begin(); i != m_slots.end(); ++i)
+         free(*i);
+-    for (AttributeRope::iterator j = m_userAttrs.begin(); j != m_userAttrs.end(); ++j)
+-        free(*j);
++    for (AttributeRope::iterator i = m_userAttrs.begin(); i != m_userAttrs.end(); ++i)
++        free(*i);
++    for (JustifyRope::iterator i = m_justifies.begin(); i != m_justifies.end(); ++i)
++        free(*i);
+     delete[] m_charinfo;
++    free(m_collisions);
+ }
+ 
+ #ifndef GRAPHITE2_NSEGCACHE
+ SegmentScopeState Segment::setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength)
+ {
+     SegmentScopeState state;
+     state.numGlyphsOutsideScope = m_numGlyphs - subLength;
+     state.realFirstSlot = m_first;
+@@ -159,28 +164,35 @@ void Segment::appendSlot(int id, int cid
+         m_passBits &= theGlyph->attrs()[m_silf->aPassBits()] 
+                     | (m_silf->numPasses() > 16 ? (theGlyph->attrs()[m_silf->aPassBits() + 1] << 16) : 0);
+ }
+ 
+ Slot *Segment::newSlot()
+ {
+     if (!m_freeSlots)
+     {
++        // check that the segment doesn't grow indefinintely
++        if (m_numGlyphs > m_numCharinfo * MAX_SEG_GROWTH_FACTOR)
++            return NULL;
+         int numUser = m_silf->numUser();
+ #if !defined GRAPHITE2_NTRACING
+         if (m_face->logger()) ++numUser;
+ #endif
+         Slot *newSlots = grzeroalloc<Slot>(m_bufSize);
+-        int16 *newAttrs = grzeroalloc<int16>(numUser * m_bufSize);
+-        if (!newSlots || !newAttrs) return NULL;
++        int16 *newAttrs = grzeroalloc<int16>(m_bufSize * numUser);
++        if (!newSlots || !newAttrs)
++        {
++            free(newSlots);
++            free(newAttrs);
++            return NULL;
++        }
+         for (size_t i = 0; i < m_bufSize; i++)
+         {
++            ::new (newSlots + i) Slot(newAttrs + i * numUser);
+             newSlots[i].next(newSlots + i + 1);
+-            newSlots[i].userAttrs(newAttrs + i * numUser);
+-            newSlots[i].setBidiClass(-1);
+         }
+         newSlots[m_bufSize - 1].next(NULL);
+         newSlots[0].next(NULL);
+         m_slots.push_back(newSlots);
+         m_userAttrs.push_back(newAttrs);
+         m_freeSlots = (m_bufSize > 1)? newSlots + 1 : NULL;
+         return newSlots;
+     }
+@@ -197,17 +209,17 @@ void Segment::freeSlot(Slot *aSlot)
+     if (aSlot->attachedTo())
+         aSlot->attachedTo()->removeChild(aSlot);
+     while (aSlot->firstChild())
+     {
+         aSlot->firstChild()->attachTo(NULL);
+         aSlot->removeChild(aSlot->firstChild());
+     }
+     // reset the slot incase it is reused
+-    ::new (aSlot) Slot;
++    ::new (aSlot) Slot(aSlot->userAttrs());
+     memset(aSlot->userAttrs(), 0, m_silf->numUser() * sizeof(int16));
+     // Update generation counter for debug
+ #if !defined GRAPHITE2_NTRACING
+     if (m_face->logger())
+         ++aSlot->userAttrs()[m_silf->numUser()];
+ #endif
+     // update next pointer
+     if (!m_freeSlots)
+@@ -301,16 +313,71 @@ void Segment::splice(size_t offset, size
+         slot->set(*srcSlot, offset, m_silf->numUser(), m_silf->numJustLevels(), numChars);
+         if (srcSlot->attachedTo())  slot->attachTo(indexmap[srcSlot->attachedTo()->index()]);
+         if (srcSlot->nextSibling()) slot->m_sibling = indexmap[srcSlot->nextSibling()->index()];
+         if (srcSlot->firstChild())  slot->m_child = indexmap[srcSlot->firstChild()->index()];
+     }
+ }
+ #endif // GRAPHITE2_NSEGCACHE
+ 
++// reverse the slots but keep diacritics in their same position after their bases
++void Segment::reverseSlots()
++{
++    m_dir = m_dir ^ 64;                 // invert the reverse flag
++    if (m_first == m_last) return;      // skip 0 or 1 glyph runs
++
++    Slot *t = 0;
++    Slot *curr = m_first;
++    Slot *tlast;
++    Slot *tfirst;
++    Slot *out = 0;
++
++    while (curr && getSlotBidiClass(curr) == 16)
++        curr = curr->next();
++    if (!curr) return;
++    tfirst = curr->prev();
++    tlast = curr;
++
++    while (curr)
++    {
++        if (getSlotBidiClass(curr) == 16)
++        {
++            Slot *d = curr->next();
++            while (d && getSlotBidiClass(d) == 16)
++                d = d->next();
++
++            d = d ? d->prev() : m_last;
++            Slot *p = out->next();    // one after the diacritics. out can't be null
++            if (p)
++                p->prev(d);
++            else
++                tlast = d;
++            t = d->next();
++            d->next(p);
++            curr->prev(out);
++            out->next(curr);
++        }
++        else    // will always fire first time round the loop
++        {
++            if (out)
++                out->prev(curr);
++            t = curr->next();
++            curr->next(out);
++            out = curr;
++        }
++        curr = t;
++    }
++    out->prev(tfirst);
++    if (tfirst)
++        tfirst->next(out);
++    else
++        m_first = out;
++    m_last = tlast;
++}
++
+ void Segment::linkClusters(Slot *s, Slot * end)
+ {
+     end = end->next();
+ 
+     for (; s != end && !s->isBase(); s = s->next());
+     Slot * ls = s;
+ 
+     if (m_dir & 1)
+@@ -330,39 +397,47 @@ void Segment::linkClusters(Slot *s, Slot
+             if (!s->isBase())   continue;
+ 
+             ls->sibling(s);
+             ls = s;
+         }
+     }
+ }
+ 
+-Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd)
++Position Segment::positionSlots(const Font *font, Slot * iStart, Slot * iEnd, bool isRtl, bool isFinal)
+ {
+     Position currpos(0., 0.);
+     float clusterMin = 0.;
+     Rect bbox;
+ 
++    if (currdir() != isRtl)
++    {
++        Slot *temp;
++        reverseSlots();
++        temp = iStart;
++        iStart = iEnd;
++        iEnd = temp;
++    }
+     if (!iStart)    iStart = m_first;
+     if (!iEnd)      iEnd   = m_last;
+ 
+-    if (m_dir & 1)
++    if (isRtl)
+     {
+         for (Slot * s = iEnd, * const end = iStart->prev(); s && s != end; s = s->prev())
+         {
+             if (s->isBase())
+-                currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x);
++                currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
+         }
+     }
+     else
+     {
+         for (Slot * s = iStart, * const end = iEnd->next(); s && s != end; s = s->next())
+         {
+             if (s->isBase())
+-                currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x);
++                currpos = s->finalise(this, font, currpos, bbox, 0, clusterMin = currpos.x, isRtl, isFinal);
+         }
+     }
+     return currpos;
+ }
+ 
+ 
+ void Segment::associateChars(int offset, int numChars)
+ {
+@@ -429,66 +504,28 @@ bool Segment::read_text(const Face *face
+     {
+     case gr_utf8:   process_utf_data(*this, *face, addFeatures(*pFeats), utf8::const_iterator(pStart), nChars); break;
+     case gr_utf16:  process_utf_data(*this, *face, addFeatures(*pFeats), utf16::const_iterator(pStart), nChars); break;
+     case gr_utf32:  process_utf_data(*this, *face, addFeatures(*pFeats), utf32::const_iterator(pStart), nChars); break;
+     }
+     return true;
+ }
+ 
+-void Segment::prepare_pos(const Font * /*font*/)
++void Segment::doMirror(uint16 aMirror)
+ {
+-    // copy key changeable metrics into slot (if any);
+-}
+-
+-Slot *process_bidi(Slot *start, int level, int prelevel, int &nextLevel, int dirover, int isol, int &cisol, int &isolerr, int &embederr, int init, Segment *seg, uint8 aMirror, BracketPairStack &stack);
+-void resolveImplicit(Slot *s, Segment *seg, uint8 aMirror);
+-void resolveWhitespace(int baseLevel, Slot *s);
+-Slot *resolveOrder(Slot * & s, const bool reordered, const int level = 0);
+-
+-void Segment::bidiPass(uint8 aBidi, int paradir, uint8 aMirror)
+-{
+-    if (slotCount() == 0)
+-        return;
+-
+-    Slot *s;
+-    int baseLevel = paradir ? 1 : 0;
+-    unsigned int bmask = 0;
+-    unsigned int ssize = 0;
+-    for (s = first(); s; s = s->next())
++    Slot * s;
++    for (s = m_first; s; s = s->next())
+     {
+-        if (s->getBidiClass() == -1)
+-        {
+-            unsigned int bAttr = glyphAttr(s->gid(), aBidi);
+-            s->setBidiClass((bAttr <= 22) * bAttr);
+-        }
+-        bmask |= (1 << s->getBidiClass());
+-        s->setBidiLevel(baseLevel);
+-        if (glyphAttr(s->gid(), aMirror) && s->getBidiClass() == 21)
+-            ++ssize;
+-    }
+-
+-    BracketPairStack bstack(ssize);
+-    if (bmask & (paradir ? 0x2E7892 : 0x2E789C))
+-    {
+-        // O(8N) algorithm, with no working data beyond what is needed for processParens
+-        int nextLevel = paradir;
+-        int e, i, c;
+-        process_bidi(first(), baseLevel, paradir, nextLevel, 0, 0, c = 0, i = 0, e = 0, 1, this, aMirror, bstack);
+-        resolveImplicit(first(), this, aMirror);
+-        resolveWhitespace(baseLevel, last());
+-        s = resolveOrder(s = first(), baseLevel != 0);
+-        if (s)
+-        {
+-            first(s); last(s->prev());
+-            s->prev()->next(0); s->prev(0);
+-        }
+-    }
+-    else if (!(dir() & 4) && baseLevel && aMirror)
+-    {
+-        for (s = first(); s; s = s->next())
+-        {
+-            unsigned short g = glyphAttr(s->gid(), aMirror);
+-            if (g) s->setGlyph(this, g);
+-        }
++        unsigned short g = glyphAttr(s->gid(), aMirror);
++        if (g && (!(dir() & 4) || !glyphAttr(s->gid(), aMirror + 1)))
++            s->setGlyph(this, g);
+     }
+ }
+ 
++bool Segment::initCollisions()
++{
++    m_collisions = grzeroalloc<SlotCollision>(slotCount());
++    if (!m_collisions) return false;
++
++    for (Slot *p = m_first; p; p = p->next())
++        ::new (collisionInfo(p)) SlotCollision(this, p);
++    return true;
++}
+diff --git a/gfx/graphite2/src/Silf.cpp b/gfx/graphite2/src/Silf.cpp
+--- a/gfx/graphite2/src/Silf.cpp
++++ b/gfx/graphite2/src/Silf.cpp
+@@ -46,23 +46,25 @@ Silf::Silf() throw()
+   m_justs(0),
+   m_numPasses(0),
+   m_numJusts(0),
+   m_sPass(0),
+   m_pPass(0),
+   m_jPass(0),
+   m_bPass(0),
+   m_flags(0),
++  m_dir(0),
+   m_aPseudo(0),
+   m_aBreak(0),
+   m_aUser(0),
+   m_aBidi(0),
+   m_aMirror(0),
+   m_aPassBits(0),
+   m_iMaxComp(0),
++  m_aCollision(0),
+   m_aLig(0),
+   m_numPseudo(0),
+   m_nClass(0),
+   m_nLinear(0),
+   m_gEndLine(0)
+ {
+     memset(&m_silfinfo, 0, sizeof m_silfinfo);
+ }
+@@ -88,16 +90,20 @@ void Silf::releaseBuffers() throw()
+ 
+ 
+ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face, uint32 version)
+ {
+     const byte * p = silf_start,
+                * const silf_end = p + lSilf;
+     Error e;
+ 
++    if (e.test(version >= 0x00060000, E_BADSILFVERSION))
++    {
++        releaseBuffers(); return face.error(e);
++    }
+     if (version >= 0x00030000)
+     {
+         if (e.test(lSilf < 28, E_BADSIZE)) { releaseBuffers(); return face.error(e); }
+         be::skip<int32>(p);    // ruleVersion
+         be::skip<uint16>(p,2); // passOffset & pseudosOffset
+     }
+     else if (e.test(lSilf < 20, E_BADSIZE)) { releaseBuffers(); return face.error(e); }
+     const uint16 maxGlyph = be::read<uint16>(p);
+@@ -132,73 +138,88 @@ bool Silf::readGraphite(const byte * con
+         for (uint8 i = 0; i < m_numJusts; i++)
+         {
+             ::new(m_justs + i) Justinfo(p[0], p[1], p[2], p[3]);
+             be::skip<byte>(p,8);
+         }
+     }
+ 
+     if (e.test(p + sizeof(uint16) + sizeof(uint8)*8 >= silf_end, E_BADENDJUSTS)) { releaseBuffers(); return face.error(e); }
+-    m_aLig      = be::read<uint16>(p);
+-    m_aUser     = be::read<uint8>(p);
+-    m_iMaxComp  = be::read<uint8>(p);
+-    be::skip<byte>(p,5);                        // direction and 4 reserved bytes
++    m_aLig       = be::read<uint16>(p);
++    m_aUser      = be::read<uint8>(p);
++    m_iMaxComp   = be::read<uint8>(p);
++    m_dir        = be::read<uint8>(p) - 1;
++    m_aCollision = be::read<uint8>(p);
++    be::skip<byte>(p,3);
+     be::skip<uint16>(p, be::read<uint8>(p));    // don't need critical features yet
+     be::skip<byte>(p);                          // reserved
+     if (e.test(p >= silf_end, E_BADCRITFEATURES))   { releaseBuffers(); return face.error(e); }
+     be::skip<uint32>(p, be::read<uint8>(p));    // don't use scriptTag array.
+     if (e.test(p + sizeof(uint16) + sizeof(uint32) >= silf_end, E_BADSCRIPTTAGS)) { releaseBuffers(); return face.error(e); }
+     m_gEndLine  = be::read<uint16>(p);          // lbGID
+     const byte * o_passes = p,
+                * const passes_start = silf_start + be::read<uint32>(p);
+ 
+     const size_t num_attrs = face.glyphs().numAttrs();
+     if (e.test(m_aPseudo   >= num_attrs, E_BADAPSEUDO)
+         || e.test(m_aBreak >= num_attrs, E_BADABREAK)
+         || e.test(m_aBidi  >= num_attrs, E_BADABIDI)
+         || e.test(m_aMirror>= num_attrs, E_BADAMIRROR)
++        || e.test(m_aCollision && m_aCollision >= num_attrs - 5, E_BADACOLLISION)
+         || e.test(m_numPasses > 128, E_BADNUMPASSES) || e.test(passes_start >= silf_end, E_BADPASSESSTART)
+         || e.test(m_pPass < m_sPass, E_BADPASSBOUND) || e.test(m_pPass > m_numPasses, E_BADPPASS) || e.test(m_sPass > m_numPasses, E_BADSPASS)
+         || e.test(m_jPass < m_pPass, E_BADJPASSBOUND) || e.test(m_jPass > m_numPasses, E_BADJPASS)
+         || e.test((m_bPass != 0xFF && (m_bPass < m_jPass || m_bPass > m_numPasses)), E_BADBPASS)
+         || e.test(m_aLig > 127, E_BADALIG))
+     {
+         releaseBuffers();
+         return face.error(e);
+     }
+     be::skip<uint32>(p, m_numPasses);
+     if (e.test(p + sizeof(uint16) >= passes_start, E_BADPASSESSTART)) { releaseBuffers(); return face.error(e); }
+     m_numPseudo = be::read<uint16>(p);
+     be::skip<uint16>(p, 3); // searchPseudo, pseudoSelector, pseudoShift
+-    if (e.test(p + m_numPseudo*(sizeof(uint32) + sizeof(uint16)) >= passes_start, E_BADNUMPSEUDO))
++    m_pseudos = new Pseudo[m_numPseudo];
++    if (e.test(p + m_numPseudo*(sizeof(uint32) + sizeof(uint16)) >= passes_start, E_BADNUMPSEUDO)
++        || e.test(!m_pseudos, E_OUTOFMEM))
+     {
+         releaseBuffers(); return face.error(e);
+     }
+-    m_pseudos = new Pseudo[m_numPseudo];
+     for (int i = 0; i < m_numPseudo; i++)
+     {
+         m_pseudos[i].uid = be::read<uint32>(p);
+         m_pseudos[i].gid = be::read<uint16>(p);
+     }
+ 
+     const size_t clen = readClassMap(p, passes_start - p, version, e);
+-    if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)) { releaseBuffers(); return face.error(e); }
++    m_passes = new Pass[m_numPasses];
++    if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)
++          || e.test(!m_passes, E_OUTOFMEM))
++    { releaseBuffers(); return face.error(e); }
+ 
+-    m_passes = new Pass[m_numPasses];
+     for (size_t i = 0; i < m_numPasses; ++i)
+     {
+         const byte * const pass_start = silf_start + be::read<uint32>(o_passes),
+                    * const pass_end = silf_start + be::peek<uint32>(o_passes);
+         face.error_context((face.error_context() & 0xFF00) + EC_ASILF + (i << 16));
+-        if (e.test(pass_start > pass_end, E_BADPASSSTART) || e.test(pass_end > silf_end, E_BADPASSEND)) {
++        if (e.test(pass_start > pass_end, E_BADPASSSTART) 
++                || e.test(pass_start < passes_start, E_BADPASSSTART)
++                || e.test(pass_end > silf_end, E_BADPASSEND)) {
+             releaseBuffers(); return face.error(e);
+         }
+ 
++        enum passtype pt = PASS_TYPE_UNKNOWN;
++        if (i >= m_jPass) pt = PASS_TYPE_JUSTIFICATION;
++        else if (i >= m_pPass) pt = PASS_TYPE_POSITIONING;
++        else if (i >= m_sPass) pt = PASS_TYPE_SUBSTITUTE;
++        else pt = PASS_TYPE_LINEBREAK;
++
+         m_passes[i].init(this);
+-        if (!m_passes[i].readPass(pass_start, pass_end - pass_start, pass_start - silf_start, face, e))
++        if (!m_passes[i].readPass(pass_start, pass_end - pass_start, pass_start - silf_start, face, pt,
++            version, e))
+         {
+             releaseBuffers();
+             return false;
+         }
+     }
+ 
+     // fill in gr_faceinfo
+     m_silfinfo.upem = face.glyphs().unitsPerEm();
+@@ -246,35 +267,38 @@ size_t Silf::readClassMap(const byte *p,
+     uint32 max_off;
+     if (version >= 0x00040000)
+         max_off = readClassOffsets<uint32>(p, data_len, e);
+     else
+         max_off = readClassOffsets<uint16>(p, data_len, e);
+ 
+     if (max_off == ERROROFFSET) return ERROROFFSET;
+ 
++    if (e.test((int)max_off < m_nLinear + (m_nClass - m_nLinear) * 6, E_CLASSESTOOBIG))
++        return ERROROFFSET;
++
+     // Check the linear offsets are sane, these must be monotonically increasing.
+     for (const uint32 *o = m_classOffsets, * const o_end = o + m_nLinear; o != o_end; ++o)
+         if (e.test(o[0] > o[1], E_BADCLASSOFFSET))
+             return ERROROFFSET;
+ 
+     // Fortunately the class data is all uint16s so we can decode these now
+     m_classData = gralloc<uint16>(max_off);
+     if (e.test(!m_classData, E_OUTOFMEM)) return ERROROFFSET;
+     for (uint16 *d = m_classData, * const d_end = d + max_off; d != d_end; ++d)
+         *d = be::read<uint16>(p);
+ 
+     // Check the lookup class invariants for each non-linear class
+     for (const uint32 *o = m_classOffsets + m_nLinear, * const o_end = m_classOffsets + m_nClass; o != o_end; ++o)
+     {
+         const uint16 * lookup = m_classData + *o;
+-        if (e.test(*o > max_off - 4, E_HIGHCLASSOFFSET)                        // LookupClass doesn't stretch over max_off
++        if (e.test(*o + 4 > max_off, E_HIGHCLASSOFFSET)                        // LookupClass doesn't stretch over max_off
+          || e.test(lookup[0] == 0                                                   // A LookupClass with no looks is a suspicious thing ...
+-                    || lookup[0] > (max_off - *o - 4)/2                             // numIDs lookup pairs fits within (start of LookupClass' lookups array, max_off]
+-                    || lookup[3] != lookup[0] - lookup[1], E_BADCLASSLOOKUPINFO))   // rangeShift:   numIDs  - searchRange
++                    || lookup[0] * 2 + *o + 4 > max_off                             // numIDs lookup pairs fits within (start of LookupClass' lookups array, max_off]
++                    || lookup[3] + lookup[1] != lookup[0], E_BADCLASSLOOKUPINFO))   // rangeShift:   numIDs  - searchRange
+             return ERROROFFSET;
+     }
+ 
+     return max_off;
+ }
+ 
+ uint16 Silf::findPseudo(uint32 uid) const
+ {
+@@ -285,17 +309,17 @@ uint16 Silf::findPseudo(uint32 uid) cons
+ 
+ uint16 Silf::findClassIndex(uint16 cid, uint16 gid) const
+ {
+     if (cid > m_nClass) return -1;
+ 
+     const uint16 * cls = m_classData + m_classOffsets[cid];
+     if (cid < m_nLinear)        // output class being used for input, shouldn't happen
+     {
+-        for (unsigned int i = 0, n = m_classOffsets[cid + 1]; i < n; ++i, ++cls)
++        for (unsigned int i = 0, n = m_classOffsets[cid + 1] - m_classOffsets[cid]; i < n; ++i, ++cls)
+             if (*cls == gid) return i;
+         return -1;
+     }
+     else
+     {
+         const uint16 *  min = cls + 4,      // lookups array
+                      *  max = min + cls[0]*2; // lookups aray is numIDs (cls[0]) uint16 pairs long
+         do
+@@ -326,90 +350,82 @@ uint16 Silf::getClassGlyph(uint16 cid, u
+     }
+     return 0;
+ }
+ 
+ 
+ bool Silf::runGraphite(Segment *seg, uint8 firstPass, uint8 lastPass, int dobidi) const
+ {
+     assert(seg != 0);
+-    SlotMap            map(*seg);
++    SlotMap            map(*seg, m_dir);
+     FiniteStateMachine fsm(map, seg->getFace()->logger());
+     vm::Machine        m(map);
+     unsigned int       initSize = seg->slotCount();
+     uint8              lbidi = m_bPass;
+ #if !defined GRAPHITE2_NTRACING
+     json * const dbgout = seg->getFace()->logger();
+ #endif
+ 
+     if (lastPass == 0)
+     {
+         if (firstPass == lastPass && lbidi == 0xFF)
+             return true;
+         lastPass = m_numPasses;
+     }
+-    if (firstPass <= lbidi && lastPass >= lbidi && dobidi)
++    if ((firstPass < lbidi || (dobidi && firstPass == lbidi)) && (lastPass >= lbidi || (dobidi && lastPass + 1 == lbidi)))
+         lastPass++;
+     else
+         lbidi = 0xFF;
+ 
+     for (size_t i = firstPass; i < lastPass; ++i)
+     {
+         // bidi and mirroring
+         if (i == lbidi)
+         {
+ #if !defined GRAPHITE2_NTRACING
+             if (dbgout)
+             {
+                 *dbgout << json::item << json::object
+                             << "id"     << -1
+                             << "slots"  << json::array;
+-                seg->positionSlots(0);
++                seg->positionSlots(0, 0, 0, m_dir);
+                 for(Slot * s = seg->first(); s; s = s->next())
+                     *dbgout     << dslot(seg, s);
+                 *dbgout         << json::close
+                             << "rules"  << json::array << json::close
+                             << json::close;
+             }
+ #endif
+-
+-            if (!(seg->dir() & 2))
+-                seg->bidiPass(m_aBidi, seg->dir() & 1, m_aMirror);
+-            else if (m_aMirror)
+-            {
+-                Slot * s;
+-                for (s = seg->first(); s; s = s->next())
+-                {
+-                    unsigned short g = seg->glyphAttr(s->gid(), m_aMirror);
+-                    if (g && (!(seg->dir() & 4) || !seg->glyphAttr(s->gid(), m_aMirror + 1)))
+-                        s->setGlyph(seg, g);
+-                }
+-            }
++            if (seg->currdir() != (m_dir & 1))
++                seg->reverseSlots();
++            if (m_aMirror && (seg->dir() & 3) == 3)
++                seg->doMirror(m_aMirror);
+         --i;
++        lbidi = lastPass;
+         --lastPass;
+-        lbidi = 0xFF;
+         continue;
+         }
+ 
+ #if !defined GRAPHITE2_NTRACING
+         if (dbgout)
+         {
+             *dbgout << json::item << json::object
+                         << "id"     << i+1
+                         << "slots"  << json::array;
+-            seg->positionSlots(0);
++            seg->positionSlots(0, 0, 0, m_dir);
+             for(Slot * s = seg->first(); s; s = s->next())
+                 *dbgout     << dslot(seg, s);
+             *dbgout         << json::close;
+         }
+ #endif
+ 
+         // test whether to reorder, prepare for positioning
+-        if (i >= 32 || (seg->passBits() & (1 << i)) == 0)
+-            m_passes[i].runGraphite(m, fsm);
++        bool reverse = (lbidi == 0xFF) && (seg->currdir() != ((m_dir & 1) ^ m_passes[i].reverseDir()));
++        if ((i >= 32 || (seg->passBits() & (1 << i)) == 0 || m_passes[i].collisionLoops())
++                && !m_passes[i].runGraphite(m, fsm, reverse))
++            return false;
+         // only subsitution passes can change segment length, cached subsegments are short for their text
+         if (m.status() != vm::Machine::finished
+-            || (i < m_pPass && (seg->slotCount() > initSize * MAX_SEG_GROWTH_FACTOR
+-            || (seg->slotCount() && seg->slotCount() * MAX_SEG_GROWTH_FACTOR < initSize))))
++            || (seg->slotCount() && seg->slotCount() * MAX_SEG_GROWTH_FACTOR < initSize))
+             return false;
+     }
+     return true;
+ }
+diff --git a/gfx/graphite2/src/Slot.cpp b/gfx/graphite2/src/Slot.cpp
+--- a/gfx/graphite2/src/Slot.cpp
++++ b/gfx/graphite2/src/Slot.cpp
+@@ -24,34 +24,34 @@ Mozilla Public License (http://mozilla.o
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ #include "inc/Segment.h"
+ #include "inc/Slot.h"
+ #include "inc/Silf.h"
+ #include "inc/CharInfo.h"
+ #include "inc/Rule.h"
++#include "inc/Collider.h"
+ 
+ 
+ using namespace graphite2;
+ 
+-Slot::Slot() :
++Slot::Slot(int16 *user_attrs) :
+     m_next(NULL), m_prev(NULL),
+     m_glyphid(0), m_realglyphid(0), m_original(0), m_before(0), m_after(0),
+     m_index(0), m_parent(NULL), m_child(NULL), m_sibling(NULL),
+     m_position(0, 0), m_shift(0, 0), m_advance(0, 0),
+     m_attach(0, 0), m_with(0, 0), m_just(0.),
+-    m_flags(0), m_attLevel(0), m_bidiCls(-1), m_bidiLevel(0), m_justs(NULL)
+-    // Do not set m_userAttr since it is set *before* new is called since this
+-    // is used as a positional new to reset the GrSlot
++    m_flags(0), m_attLevel(0), m_bidiCls(-1), m_bidiLevel(0), 
++    m_userAttr(user_attrs), m_justs(NULL)
+ {
+ }
+ 
+ // take care, this does not copy any of the GrSlot pointer fields
+-void Slot::set(const Slot & orig, int charOffset, size_t numUserAttr, size_t justLevels, size_t numChars)
++void Slot::set(const Slot & orig, int charOffset, size_t sizeAttr, size_t justLevels, size_t numChars)
+ {
+     // leave m_next and m_prev unchanged
+     m_glyphid = orig.m_glyphid;
+     m_realglyphid = orig.m_realglyphid;
+     m_original = orig.m_original + charOffset;
+     if (charOffset + int(orig.m_before) < 0)
+         m_before = 0;
+     else
+@@ -68,95 +68,104 @@ void Slot::set(const Slot & orig, int ch
+     m_advance = orig.m_advance;
+     m_attach = orig.m_attach;
+     m_with = orig.m_with;
+     m_flags = orig.m_flags;
+     m_attLevel = orig.m_attLevel;
+     m_bidiCls = orig.m_bidiCls;
+     m_bidiLevel = orig.m_bidiLevel;
+     if (m_userAttr && orig.m_userAttr)
+-        memcpy(m_userAttr, orig.m_userAttr, numUserAttr * sizeof(*m_userAttr));
++        memcpy(m_userAttr, orig.m_userAttr, sizeAttr * sizeof(*m_userAttr));
+     if (m_justs && orig.m_justs)
+         memcpy(m_justs, orig.m_justs, SlotJustify::size_of(justLevels));
+ }
+ 
+ void Slot::update(int /*numGrSlots*/, int numCharInfo, Position &relpos)
+ {
+     m_before += numCharInfo;
+     m_after += numCharInfo;
+     m_position = m_position + relpos;
+ }
+ 
+-Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin)
++Position Slot::finalise(const Segment *seg, const Font *font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal)
+ {
++    SlotCollision *coll = NULL;
+     if (attrLevel && m_attLevel > attrLevel) return Position(0, 0);
+-    float scale = 1.0;
+-    Position shift(m_shift.x * ((seg->dir() & 1) * -2 + 1) + m_just, m_shift.y);
++    float scale = font ? font->scale() : 1.0f;
++    Position shift(m_shift.x * (rtl * -2 + 1) + m_just, m_shift.y);
+     float tAdvance = m_advance.x + m_just;
++    if (isFinal && (coll = seg->collisionInfo(this)))
++    {
++        const Position &collshift = coll->offset();
++        if (!(coll->flags() & SlotCollision::COLL_KERN) || rtl)
++            shift = shift + collshift;
++    }
+     const GlyphFace * glyphFace = seg->getFace()->glyphs().glyphSafe(glyph());
+     if (font)
+     {
+         scale = font->scale();
+         shift *= scale;
+         if (font->isHinted() && glyphFace)
+-            tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(m_glyphid);
++            tAdvance = (m_advance.x - glyphFace->theAdvance().x + m_just) * scale + font->advance(glyph());
+         else
+             tAdvance *= scale;
+     }    
+     Position res;
+ 
+     m_position = base + shift;
+     if (!m_parent)
+     {
+         res = base + Position(tAdvance, m_advance.y * scale);
+-        clusterMin = base.x;
++        clusterMin = m_position.x;
+     }
+     else
+     {
+         float tAdv;
+         m_position += (m_attach - m_with) * scale;
+-        tAdv = m_advance.x >= 0.5 ? m_position.x + tAdvance - shift.x : 0.f;
++        tAdv = m_advance.x >= 0.5f ? m_position.x + tAdvance - shift.x : 0.f;
+         res = Position(tAdv, 0);
+-        if ((m_advance.x >= 0.5 || m_position.x < 0) && m_position.x < clusterMin) clusterMin = m_position.x;
++        if ((m_advance.x >= 0.5f || m_position.x < 0) && m_position.x < clusterMin) clusterMin = m_position.x;
+     }
+ 
+     if (glyphFace)
+     {
+         Rect ourBbox = glyphFace->theBBox() * scale + m_position;
+         bbox = bbox.widen(ourBbox);
+     }
+ 
+     if (m_child && m_child != this && m_child->attachedTo() == this)
+     {
+-        Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin);
+-        if ((!m_parent || m_advance.x >= 0.5) && tRes.x > res.x) res = tRes;
++        Position tRes = m_child->finalise(seg, font, m_position, bbox, attrLevel, clusterMin, rtl, isFinal);
++        if ((!m_parent || m_advance.x >= 0.5f) && tRes.x > res.x) res = tRes;
+     }
+ 
+     if (m_parent && m_sibling && m_sibling != this && m_sibling->attachedTo() == m_parent)
+     {
+-        Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin);
++        Position tRes = m_sibling->finalise(seg, font, base, bbox, attrLevel, clusterMin, rtl, isFinal);
+         if (tRes.x > res.x) res = tRes;
+     }
+     
+     if (!m_parent && clusterMin < base.x)
+     {
+-        Position adj = Position(base.x - clusterMin, 0.);
++        Position adj = Position(m_position.x - clusterMin, 0.);
+         res += adj;
+         m_position += adj;
+         if (m_child) m_child->floodShift(adj);
+     }
+     return res;
+ }
+ 
+-int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel)
++int32 Slot::clusterMetric(const Segment *seg, uint8 metric, uint8 attrLevel, bool rtl)
+ {
+     Position base;
++    if (glyph() >= seg->getFace()->glyphs().numGlyphs())
++        return 0;
+     Rect bbox = seg->theGlyphBBoxTemporary(glyph());
+     float clusterMin = 0.;
+-    Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin);
++    Position res = finalise(seg, NULL, base, bbox, attrLevel, clusterMin, rtl, false);
+ 
+     switch (metrics(metric))
+     {
+     case kgmetLsb :
+         return static_cast<uint32>(bbox.bl.x);
+     case kgmetRsb :
+         return static_cast<uint32>(res.x - bbox.tr.x);
+     case kgmetBbTop :
+@@ -175,19 +184,20 @@ int32 Slot::clusterMetric(const Segment 
+         return static_cast<uint32>(res.x);
+     case kgmetAdvHeight :
+         return static_cast<uint32>(res.y);
+     default :
+         return 0;
+     }
+ }
+ 
++#define SLOTGETCOLATTR(x) { SlotCollision *c = seg->collisionInfo(this); return c ? int(c-> x) : 0; }
++
+ int Slot::getAttr(const Segment *seg, attrCode ind, uint8 subindex) const
+ {
+-    if (!this) return 0;
+     if (ind == gr_slatUserDefnV1)
+     {
+         ind = gr_slatUserDefn;
+         subindex = 0;
+     }
+     else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
+     {
+         int indx = ind - gr_slatJStretch;
+@@ -205,37 +215,66 @@ int Slot::getAttr(const Segment *seg, at
+     case gr_slatAttYOff :   return 0;
+     case gr_slatAttWithX :  return int(m_with.x);
+     case gr_slatAttWithY :  return int(m_with.y);
+     case gr_slatAttWithXOff:
+     case gr_slatAttWithYOff:return 0;
+     case gr_slatAttLevel :  return m_attLevel;
+     case gr_slatBreak :     return seg->charinfo(m_original)->breakWeight();
+     case gr_slatCompRef :   return 0;
+-    case gr_slatDir :       if (m_bidiCls == -1)
+-                                const_cast<Slot *>(this)->setBidiClass(seg->glyphAttr(gid(), seg->silf()->aBidi()));
+-                            return m_bidiCls;
++    case gr_slatDir :       return seg->dir() & 1;
+     case gr_slatInsert :    return isInsertBefore();
+     case gr_slatPosX :      return int(m_position.x); // but need to calculate it
+     case gr_slatPosY :      return int(m_position.y);
+     case gr_slatShiftX :    return int(m_shift.x);
+     case gr_slatShiftY :    return int(m_shift.y);
+     case gr_slatMeasureSol: return -1; // err what's this?
+     case gr_slatMeasureEol: return -1;
+     case gr_slatJWidth:     return int(m_just);
+     case gr_slatUserDefn :  return m_userAttr[subindex];
+     case gr_slatSegSplit :  return seg->charinfo(m_original)->flags() & 3;
+     case gr_slatBidiLevel:  return m_bidiLevel;
+-    default :               return 0;
++    case gr_slatColFlags :		{ SlotCollision *c = seg->collisionInfo(this); return c ? c->flags() : 0; }
++    case gr_slatColLimitblx :	SLOTGETCOLATTR(limit().bl.x)
++    case gr_slatColLimitbly :	SLOTGETCOLATTR(limit().bl.y)
++    case gr_slatColLimittrx :	SLOTGETCOLATTR(limit().tr.x)
++    case gr_slatColLimittry :	SLOTGETCOLATTR(limit().tr.y)
++    case gr_slatColShiftx :		SLOTGETCOLATTR(offset().x)
++    case gr_slatColShifty :		SLOTGETCOLATTR(offset().y)
++    case gr_slatColMargin :		SLOTGETCOLATTR(margin())
++    case gr_slatColMarginWt :	SLOTGETCOLATTR(marginWt())
++    case gr_slatColExclGlyph :	SLOTGETCOLATTR(exclGlyph())
++    case gr_slatColExclOffx :	SLOTGETCOLATTR(exclOffset().x)
++    case gr_slatColExclOffy :	SLOTGETCOLATTR(exclOffset().y)
++    case gr_slatSeqClass :		SLOTGETCOLATTR(seqClass())
++	case gr_slatSeqProxClass :	SLOTGETCOLATTR(seqProxClass())
++    case gr_slatSeqOrder :		SLOTGETCOLATTR(seqOrder())
++    case gr_slatSeqAboveXoff :	SLOTGETCOLATTR(seqAboveXoff())
++    case gr_slatSeqAboveWt :	SLOTGETCOLATTR(seqAboveWt())
++    case gr_slatSeqBelowXlim :	SLOTGETCOLATTR(seqBelowXlim())
++    case gr_slatSeqBelowWt :	SLOTGETCOLATTR(seqBelowWt())
++    case gr_slatSeqValignHt :	SLOTGETCOLATTR(seqValignHt())
++    case gr_slatSeqValignWt :	SLOTGETCOLATTR(seqValignWt())
++    default : return 0;
+     }
+ }
+ 
++#define SLOTCOLSETATTR(x) { \
++        SlotCollision *c = seg->collisionInfo(this); \
++        if (c) { c-> x ; c->setFlags(c->flags() & ~SlotCollision::COLL_KNOWN); } \
++        break; }
++#define SLOTCOLSETCOMPLEXATTR(t, y, x) { \
++        SlotCollision *c = seg->collisionInfo(this); \
++        if (c) { \
++        const t &s = c-> y; \
++        c-> x ; c->setFlags(c->flags() & ~SlotCollision::COLL_KNOWN); } \
++        break; }
++
+ void Slot::setAttr(Segment *seg, attrCode ind, uint8 subindex, int16 value, const SlotMap & map)
+ {
+-    if (!this) return;
+     if (ind == gr_slatUserDefnV1)
+     {
+         ind = gr_slatUserDefn;
+         subindex = 0;
+     }
+     else if (ind >= gr_slatJStretch && ind < gr_slatJStretch + 20 && ind != gr_slatJWidth)
+     {
+         int indx = ind - gr_slatJStretch;
+@@ -247,22 +286,22 @@ void Slot::setAttr(Segment *seg, attrCod
+     case gr_slatAdvX :  m_advance.x = value; break;
+     case gr_slatAdvY :  m_advance.y = value; break;
+     case gr_slatAttTo :
+     {
+         const uint16 idx = uint16(value);
+         if (idx < map.size() && map[idx])
+         {
+             Slot *other = map[idx];
+-            if (other == this) break;
++            if (other == this || other == m_parent) break;
+             if (m_parent) m_parent->removeChild(this);
+-            if (other->child(this))
++            if (!other->isChildOf(this) && other->child(this))
+             {
+                 attachTo(other);
+-                if (((seg->dir() & 1) != 0) ^ (idx > subindex))
++                if ((map.dir() != 0) ^ (idx > subindex))
+                     m_with = Position(advance(), 0);
+                 else        // normal match to previous root
+                     m_attach = Position(other->advance(), 0);
+             }
+         }
+         break;
+     }
+     case gr_slatAttX :          m_attach.x = value; break;
+@@ -275,29 +314,52 @@ void Slot::setAttr(Segment *seg, attrCod
+     case gr_slatAttWithYOff :   break;
+     case gr_slatAttLevel :
+         m_attLevel = byte(value);
+         break;
+     case gr_slatBreak :
+         seg->charinfo(m_original)->breakWeight(value);
+         break;
+     case gr_slatCompRef :   break;      // not sure what to do here
+-    case gr_slatDir :       m_bidiCls = value; break;
++    case gr_slatDir : break;
+     case gr_slatInsert :
+         markInsertBefore(value? true : false);
+         break;
+     case gr_slatPosX :      break; // can't set these here
+     case gr_slatPosY :      break;
+     case gr_slatShiftX :    m_shift.x = value; break;
+     case gr_slatShiftY :    m_shift.y = value; break;
+     case gr_slatMeasureSol :    break;
+     case gr_slatMeasureEol :    break;
+     case gr_slatJWidth :    just(value); break;
+     case gr_slatSegSplit :  seg->charinfo(m_original)->addflags(value & 3); break;
+     case gr_slatUserDefn :  m_userAttr[subindex] = value; break;
++    case gr_slatColFlags :  {
++        SlotCollision *c = seg->collisionInfo(this);
++        if (c)
++            c->setFlags(value);
++        break; }
++    case gr_slatColLimitblx :	SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(Position(value, s.bl.y), s.tr)))
++    case gr_slatColLimitbly :	SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(Position(s.bl.x, value), s.tr)))
++    case gr_slatColLimittrx :	SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(s.bl, Position(value, s.tr.y))))
++    case gr_slatColLimittry :	SLOTCOLSETCOMPLEXATTR(Rect, limit(), setLimit(Rect(s.bl, Position(s.tr.x, value))))
++    case gr_slatColMargin :		SLOTCOLSETATTR(setMargin(value))
++    case gr_slatColMarginWt :	SLOTCOLSETATTR(setMarginWt(value))
++    case gr_slatColExclGlyph :	SLOTCOLSETATTR(setExclGlyph(value))
++    case gr_slatColExclOffx :	SLOTCOLSETCOMPLEXATTR(Position, exclOffset(), setExclOffset(Position(value, s.y)))
++    case gr_slatColExclOffy :	SLOTCOLSETCOMPLEXATTR(Position, exclOffset(), setExclOffset(Position(s.x, value)))
++    case gr_slatSeqClass :		SLOTCOLSETATTR(setSeqClass(value))
++	case gr_slatSeqProxClass :	SLOTCOLSETATTR(setSeqProxClass(value))
++    case gr_slatSeqOrder :		SLOTCOLSETATTR(setSeqOrder(value))
++    case gr_slatSeqAboveXoff :	SLOTCOLSETATTR(setSeqAboveXoff(value))
++    case gr_slatSeqAboveWt :	SLOTCOLSETATTR(setSeqAboveWt(value))
++    case gr_slatSeqBelowXlim :	SLOTCOLSETATTR(setSeqBelowXlim(value))
++    case gr_slatSeqBelowWt :	SLOTCOLSETATTR(setSeqBelowWt(value))
++    case gr_slatSeqValignHt :	SLOTCOLSETATTR(setSeqValignHt(value))
++    case gr_slatSeqValignWt :	SLOTCOLSETATTR(setSeqValignWt(value))
+     default :
+         break;
+     }
+ }
+ 
+ int Slot::getJustify(const Segment *seg, uint8 level, uint8 subindex) const
+ {
+     if (level && level >= seg->silf()->numJustLevels()) return 0;
+@@ -369,46 +431,54 @@ bool Slot::removeChild(Slot *ap)
+ }
+ 
+ bool Slot::removeSibling(Slot *ap)
+ {
+     if (this == ap || !m_sibling) return false;
+     else if (ap == m_sibling)
+     {
+         m_sibling = m_sibling->nextSibling();
++        ap->sibling(NULL);
+         return true;
+     }
+     else
+         return m_sibling->removeSibling(ap);
+     return true;
+ }
+ 
+ void Slot::setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph)
+ {
+     m_glyphid = glyphid;
++    m_bidiCls = -1;
+     if (!theGlyph)
+     {
+         theGlyph = seg->getFace()->glyphs().glyphSafe(glyphid);
+         if (!theGlyph)
+         {
+             m_realglyphid = 0;
+             m_advance = Position(0.,0.);
+             return;
+         }
+     }
+     m_realglyphid = theGlyph->attrs()[seg->silf()->aPseudo()];
++    if (m_realglyphid > seg->getFace()->glyphs().numGlyphs())
++        m_realglyphid = 0;
+     const GlyphFace *aGlyph = theGlyph;
+     if (m_realglyphid)
+     {
+         aGlyph = seg->getFace()->glyphs().glyphSafe(m_realglyphid);
+         if (!aGlyph) aGlyph = theGlyph;
+     }
+     m_advance = Position(aGlyph->theAdvance().x, 0.);
+     if (seg->silf()->aPassBits())
++    {
+         seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()]);
++        if (seg->silf()->numPasses() > 16)
++            seg->mergePassBits(theGlyph->attrs()[seg->silf()->aPassBits()+1] << 16);
++    }
+ }
+ 
+ void Slot::floodShift(Position adj)
+ {
+     m_position += adj;
+     if (m_child) m_child->floodShift(adj);
+     if (m_sibling) m_sibling->floodShift(adj);
+ }
+@@ -420,8 +490,35 @@ void SlotJustify::LoadSlot(const Slot *s
+         Justinfo *justs = seg->silf()->justAttrs() + i;
+         int16 *v = values + i * NUMJUSTPARAMS;
+         v[0] = seg->glyphAttr(s->gid(), justs->attrStretch());
+         v[1] = seg->glyphAttr(s->gid(), justs->attrShrink());
+         v[2] = seg->glyphAttr(s->gid(), justs->attrStep());
+         v[3] = seg->glyphAttr(s->gid(), justs->attrWeight());
+     }
+ }
++
++Slot * Slot::nextInCluster(const Slot *s) const
++{
++    Slot *base;
++    if (s->firstChild())
++        return s->firstChild();
++    else if (s->nextSibling())
++        return s->nextSibling();
++    while ((base = s->attachedTo()))
++    {
++        // if (base->firstChild() == s && base->nextSibling())
++        if (base->nextSibling())
++            return base->nextSibling();
++        s = base;
++    }
++    return NULL;
++}
++
++bool Slot::isChildOf(const Slot *base) const
++{
++    if (m_parent == base)
++        return true;
++    else if (!m_parent)
++        return false;
++    else
++        return m_parent->isChildOf(base);
++}
+diff --git a/gfx/graphite2/src/Sparse.cpp b/gfx/graphite2/src/Sparse.cpp
+--- a/gfx/graphite2/src/Sparse.cpp
++++ b/gfx/graphite2/src/Sparse.cpp
+@@ -25,17 +25,17 @@ License, as published by the Free Softwa
+ of the License or (at your option) any later version.
+ */
+ #include <cassert>
+ #include "inc/Sparse.h"
+ #include "inc/bits.h"
+ 
+ using namespace graphite2;
+ 
+-sparse::chunk sparse::empty_chunk = {0,0};
++const sparse::chunk sparse::empty_chunk = {0,0};
+ 
+ sparse::~sparse() throw()
+ {
+     if (m_array.map == &empty_chunk) return;
+     free(m_array.values);
+ }
+ 
+ 
+diff --git a/gfx/graphite2/src/TtfUtil.cpp b/gfx/graphite2/src/TtfUtil.cpp
+--- a/gfx/graphite2/src/TtfUtil.cpp
++++ b/gfx/graphite2/src/TtfUtil.cpp
+@@ -57,18 +57,20 @@ Description
+     Forward declarations
+ ***********************************************************************************************/
+ 
+ /***********************************************************************************************
+     Local Constants and static variables
+ ***********************************************************************************************/
+ namespace 
+ {
++#ifdef ALL_TTFUTILS
+     // max number of components allowed in composite glyphs
+     const int kMaxGlyphComponents = 8;
++#endif
+ 
+     template <int R, typename T>
+     inline float fixed_to_float(const T f) {
+         return float(f)/float(2^R);
+     }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Table of standard Postscript glyph names. From Martin Hosken. Disagress with ttfdump.exe
+@@ -222,69 +224,79 @@ bool GetTableInfo(const Tag TableTag, co
+ /*----------------------------------------------------------------------------------------------
+     Check the specified table. Tests depend on the table type.
+     Return true if successful, false otherwise.
+ ----------------------------------------------------------------------------------------------*/
+ bool CheckTable(const Tag TableId, const void * pTable, size_t lTableSize)
+ {
+     using namespace Sfnt;
+     
+-    if (pTable == 0) return false;
++    if (pTable == 0 || lTableSize < 4) return false;
+ 
+     switch(TableId)
+     {
+     case Tag::cmap: // cmap
+     {
+         const Sfnt::CharacterCodeMap * const pCmap 
+             = reinterpret_cast<const Sfnt::CharacterCodeMap *>(pTable);
++        if (lTableSize < sizeof(Sfnt::CharacterCodeMap))
++            return false;
+         return be::swap(pCmap->version) == 0;
+     }
+ 
+     case Tag::head: // head
+     {
+         const Sfnt::FontHeader * const pHead 
+             = reinterpret_cast<const Sfnt::FontHeader *>(pTable);
++        if (lTableSize < sizeof(Sfnt::FontHeader))
++            return false;
+         bool r = be::swap(pHead->version) == OneFix
+             && be::swap(pHead->magic_number) == FontHeader::MagicNumber
+             && be::swap(pHead->glyph_data_format)
+                     == FontHeader::GlypDataFormat 
+             && (be::swap(pHead->index_to_loc_format)
+                     == FontHeader::ShortIndexLocFormat 
+                 || be::swap(pHead->index_to_loc_format)
+                     == FontHeader::LongIndexLocFormat) 
+             && sizeof(FontHeader) <= lTableSize;
+         return r;
+     }
+ 
+     case Tag::post: // post
+     {
+         const Sfnt::PostScriptGlyphName * const pPost 
+             = reinterpret_cast<const Sfnt::PostScriptGlyphName *>(pTable);
++        if (lTableSize < sizeof(Sfnt::PostScriptGlyphName))
++            return false;
+         const fixed format = be::swap(pPost->format);
+         bool r = format == PostScriptGlyphName::Format1 
+             || format == PostScriptGlyphName::Format2 
+             || format == PostScriptGlyphName::Format3 
+             || format == PostScriptGlyphName::Format25;
+         return r;
+     }
+ 
+     case Tag::hhea: // hhea
+     {
+         const Sfnt::HorizontalHeader * pHhea = 
+             reinterpret_cast<const Sfnt::HorizontalHeader *>(pTable);
++        if (lTableSize < sizeof(Sfnt::HorizontalHeader))
++            return false;
+         bool r = be::swap(pHhea->version) == OneFix
+             && be::swap(pHhea->metric_data_format) == 0
+             && sizeof (Sfnt::HorizontalHeader) <= lTableSize;
+         return r;
+     }
+ 
+     case Tag::maxp: // maxp
+     {
+         const Sfnt::MaximumProfile * pMaxp = 
+             reinterpret_cast<const Sfnt::MaximumProfile *>(pTable);
++        if (lTableSize < sizeof(Sfnt::MaximumProfile))
++            return false;
+         bool r = be::swap(pMaxp->version) == OneFix
+             && sizeof(Sfnt::MaximumProfile) <= lTableSize;
+         return r;
+     }
+ 
+     case Tag::OS_2: // OS/2
+     {
+         const Sfnt::Compatibility * pOs2 
+@@ -319,16 +331,18 @@ bool CheckTable(const Tag TableId, const
+             return false;
+         break;
+     }
+ 
+     case Tag::name:
+     {
+         const Sfnt::FontNames * pName 
+             = reinterpret_cast<const Sfnt::FontNames *>(pTable);
++        if (lTableSize < sizeof(Sfnt::FontNames))
++            return false;
+         return be::swap(pName->format) == 0;
+     }
+ 
+     default:
+         break;
+     }
+ 
+     return true;
+@@ -791,27 +805,27 @@ bool HorMetrics(gid16 nGlyphId, const vo
+         reinterpret_cast<const Sfnt::HorizontalMetric *>(pHmtx);
+ 
+     const Sfnt::HorizontalHeader * phhea = 
+         reinterpret_cast<const Sfnt::HorizontalHeader *>(pHhea);
+ 
+     size_t cLongHorMetrics = be::swap(phhea->num_long_hor_metrics);
+     if (nGlyphId < cLongHorMetrics) 
+     {   // glyph id is acceptable
+-        if (nGlyphId * sizeof(Sfnt::HorizontalMetric) >= lHmtxSize) return false;
++        if ((nGlyphId + 1) * sizeof(Sfnt::HorizontalMetric) > lHmtxSize) return false;
+         nAdvWid = be::swap(phmtx[nGlyphId].advance_width);
+         nLsb = be::swap(phmtx[nGlyphId].left_side_bearing);
+     }
+     else
+     {
+         // guard against bad glyph id
+         size_t lLsbOffset = sizeof(Sfnt::HorizontalMetric) * cLongHorMetrics +
+             sizeof(int16) * (nGlyphId - cLongHorMetrics); // offset in bytes
+         // We test like this as LsbOffset is an offset not a length.
+-        if (lLsbOffset > lHmtxSize - sizeof(int16))
++        if (lLsbOffset >= lHmtxSize - sizeof(int16) || cLongHorMetrics == 0)
+         {
+             nLsb = 0;
+             return false;
+         }
+         nAdvWid = be::swap(phmtx[cLongHorMetrics - 1].advance_width);
+         nLsb = be::peek<int16>(reinterpret_cast<const byte *>(phmtx) + lLsbOffset);
+     }
+ 
+@@ -833,31 +847,33 @@ const void * FindCmapSubtable(const void
+     {
+         if (be::swap(pTable->encoding[i].platform_id) == nPlatformId &&
+                 (nEncodingId == -1 || be::swap(pTable->encoding[i].platform_specific_id) == nEncodingId))
+         {
+             uint32 offset = be::swap(pTable->encoding[i].offset);
+             const uint8 * pRtn = reinterpret_cast<const uint8 *>(pCmap) + offset;
+             if (length)
+             {
+-                if (offset > length) return NULL;
++                if (offset > length - 2) return NULL;
+                 uint16 format = be::read<uint16>(pRtn);
+                 if (format == 4)
+                 {
++                    if (offset > length - 4) return NULL;
+                     uint16 subTableLength = be::peek<uint16>(pRtn);
+                     if (i + 1 == csuPlatforms)
+                     {
+                         if (subTableLength > length - offset)
+                             return NULL;
+                     }
+                     else if (subTableLength > be::swap(pTable->encoding[i+1].offset))
+                         return NULL;
+                 }
+                 if (format == 12)
+                 {
++                    if (offset > length - 6) return NULL;
+                     uint32 subTableLength = be::peek<uint32>(pRtn);
+                     if (i + 1 == csuPlatforms)
+                     {
+                         if (subTableLength > length - offset)
+                             return NULL;
+                     }
+                     else if (subTableLength > be::swap(pTable->encoding[i+1].offset))
+                         return NULL;
+@@ -868,48 +884,80 @@ const void * FindCmapSubtable(const void
+     }
+ 
+     return 0;
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Check the Microsoft Unicode subtable for expected values
+ ----------------------------------------------------------------------------------------------*/
+-bool CheckCmapSubtable4(const void * pCmapSubtable4)
++bool CheckCmapSubtable4(const void * pCmapSubtable4, size_t table_len /*, unsigned int maxgid*/)
+ {
+     if (!pCmapSubtable4) return false;
+     const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable4);
+-    // Bob H says ome freeware TT fonts have version 1 (eg, CALIGULA.TTF) 
++    // Bob H say some freeware TT fonts have version 1 (eg, CALIGULA.TTF) 
+     // so don't check subtable version. 21 Mar 2002 spec changes version to language.
+     if (be::swap(pTable->format) != 4) return false;
+     const Sfnt::CmapSubTableFormat4 * pTable4 = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtable4);
+     uint16 length = be::swap(pTable4->length);
++    if (length > table_len)
++        return false;
+     if (length < sizeof(Sfnt::CmapSubTableFormat4))
+         return false;
+     uint16 nRanges = be::swap(pTable4->seg_count_x2) >> 1;
+     if (length < sizeof(Sfnt::CmapSubTableFormat4) + 4 * nRanges * sizeof(uint16))
+         return false;
+     // check last range is properly terminated
+     uint16 chEnd = be::peek<uint16>(pTable4->end_code + nRanges - 1);
+-    return (chEnd == 0xFFFF);
++    if (chEnd != 0xFFFF)
++        return false;
++#if 0
++    int lastend = -1;
++    for (int i = 0; i < nRanges; ++i)
++    {
++        uint16 end = be::peek<uint16>(pTable4->end_code + i);
++        uint16 start = be::peek<uint16>(pTable4->end_code + nRanges + 1 + i);
++        int16 delta = be::peek<int16>(pTable4->end_code + 2*nRanges + 1 + i);
++        uint16 offset = be::peek<uint16>(pTable4->end_code + 3*nRanges + 1 + i);
++        if (lastend >= end || lastend >= start)
++            return false;
++        if (offset)
++        {
++            const uint16 *gstart = pTable4->end_code + 3*nRanges + 1 + i + (offset >> 1);
++            const uint16 *gend = gstart + end - start;
++            if ((char *)gend >= (char *)pCmapSubtable4 + length)
++                return false;
++            while (gstart <= gend)
++            {
++                uint16 g = be::peek<uint16>(gstart++);
++                if (g && ((g + delta) & 0xFFFF) > maxgid)
++                    return false;
++            }
++        }
++        else if (((delta + end) & 0xFFFF) > maxgid)
++            return false;
++        lastend = end;
++    }
++#endif
++    return true;
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Return the Glyph ID for the given Unicode ID in the Microsoft Unicode subtable.
+     (Actually this code only depends on subtable being format 4.)
+     Return 0 if the Unicode ID is not in the subtable.
+ ----------------------------------------------------------------------------------------------*/
+ gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey)
+ {
+     const Sfnt::CmapSubTableFormat4 * pTable = reinterpret_cast<const Sfnt::CmapSubTableFormat4 *>(pCmapSubtabel4);
+ 
+     uint16 nSeg = be::swap(pTable->seg_count_x2) >> 1;
+   
+     uint16 n;
+-        const uint16 * pLeft, * pMid;
++    const uint16 * pLeft, * pMid;
+     uint16 cMid, chStart, chEnd;
+ 
+     if (rangeKey)
+     {
+         pMid = &(pTable->end_code[rangeKey]);
+         chEnd = be::peek<uint16>(pMid);
+     }
+     else
+@@ -1027,29 +1075,41 @@ unsigned int CmapSubtable4NextCodepoint(
+     if (pRangeKey)
+         *pRangeKey = iRange + 1;
+     return be::peek<uint16>(pStartCode + iRange + 1);
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Check the Microsoft UCS-4 subtable for expected values.
+ ----------------------------------------------------------------------------------------------*/
+-bool CheckCmapSubtable12(const void *pCmapSubtable12)
++bool CheckCmapSubtable12(const void *pCmapSubtable12, size_t table_len /*, unsigned int maxgid*/)
+ {
+     if (!pCmapSubtable12)  return false;
+     const Sfnt::CmapSubTable * pTable = reinterpret_cast<const Sfnt::CmapSubTable *>(pCmapSubtable12);
+     if (be::swap(pTable->format) != 12)
+         return false;
+     const Sfnt::CmapSubTableFormat12 * pTable12 = reinterpret_cast<const Sfnt::CmapSubTableFormat12 *>(pCmapSubtable12);
+     uint32 length = be::swap(pTable12->length);
++    if (length > table_len)
++        return false;
+     if (length < sizeof(Sfnt::CmapSubTableFormat12))
+         return false;
+-    
+-    return (length == (sizeof(Sfnt::CmapSubTableFormat12) + (be::swap(pTable12->num_groups) - 1)
+-        * sizeof(uint32) * 3));
++    uint32 num_groups = be::swap(pTable12->num_groups);
++    if (length != (sizeof(Sfnt::CmapSubTableFormat12) + (num_groups - 1) * sizeof(uint32) * 3))
++        return false;
++#if 0
++    for (unsigned int i = 0; i < num_groups; ++i)
++    {
++        if (be::swap(pTable12->group[i].end_char_code)  - be::swap(pTable12->group[i].start_char_code) + be::swap(pTable12->group[i].start_glyph_id) > maxgid)
++            return false;
++        if (i > 0 && be::swap(pTable12->group[i].start_char_code) <= be::swap(pTable12->group[i-1].end_char_code))
++            return false;
++    }
++#endif
++    return true;
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Return the Glyph ID for the given Unicode ID in the Microsoft UCS-4 subtable.
+     (Actually this code only depends on subtable being format 12.)
+     Return 0 if the Unicode ID is not in the subtable.
+ ----------------------------------------------------------------------------------------------*/
+ gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey)
+@@ -1140,49 +1200,53 @@ unsigned int CmapSubtable12NextCodepoint
+     Technically this method should return an unsigned long but it is unlikely the offset will
+         exceed 2^31.
+ ----------------------------------------------------------------------------------------------*/
+ size_t LocaLookup(gid16 nGlyphId, 
+         const void * pLoca, size_t lLocaSize, 
+         const void * pHead) // throw (std::out_of_range)
+ {
+     const Sfnt::FontHeader * pTable = reinterpret_cast<const Sfnt::FontHeader *>(pHead);
++    size_t res = -2;
+ 
+     // CheckTable verifies the index_to_loc_format is valid
+     if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::ShortIndexLocFormat)
+     { // loca entries are two bytes and have been divided by two
+-        if (nGlyphId < (lLocaSize >> 1) - 1) // allow sentinel value to be accessed
++        if (lLocaSize > 1 && nGlyphId + 1u < lLocaSize >> 1) // allow sentinel value to be accessed
+         {
+             const uint16 * pShortTable = reinterpret_cast<const uint16 *>(pLoca);
+-            return (be::peek<uint16>(pShortTable + nGlyphId) << 1);
++            res = be::peek<uint16>(pShortTable + nGlyphId) << 1;
++            if (res == static_cast<size_t>(be::peek<uint16>(pShortTable + nGlyphId + 1) << 1))
++                return -1;
+         }
+     }
+-    
+-    if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat)
++    else if (be::swap(pTable->index_to_loc_format) == Sfnt::FontHeader::LongIndexLocFormat)
+     { // loca entries are four bytes
+-        if (nGlyphId < (lLocaSize >> 2) - 1)
++        if (lLocaSize > 3 && nGlyphId + 1u < lLocaSize >> 2)
+         {
+             const uint32 * pLongTable = reinterpret_cast<const uint32 *>(pLoca);
+-            return be::peek<uint32>(pLongTable + nGlyphId);
++            res = be::peek<uint32>(pLongTable + nGlyphId);
++            if (res == static_cast<size_t>(be::peek<uint32>(pLongTable + nGlyphId + 1)))
++                return -1;
+         }
+     }
+ 
+     // only get here if glyph id was bad
+-    return -1;
++    return res;
+     //throw std::out_of_range("glyph id out of range for font");
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Return a pointer into the glyf table based on the given offset (from LocaLookup).
+     Return NULL on error.
+ ----------------------------------------------------------------------------------------------*/
+ void * GlyfLookup(const void * pGlyf, size_t nGlyfOffset, size_t nTableLen)
+ {
+     const uint8 * pByte = reinterpret_cast<const uint8 *>(pGlyf);
+-        if (nGlyfOffset == size_t(-1) || nGlyfOffset >= nTableLen)
++        if (nGlyfOffset + pByte < pByte || nGlyfOffset + sizeof(Sfnt::Glyph) >= nTableLen)
+             return NULL;
+     return const_cast<uint8 *>(pByte + nGlyfOffset);
+ }
+ 
+ /*----------------------------------------------------------------------------------------------
+     Get the bounding box coordinates for a simple glyf entry (non-composite).
+     Return true if successful, false otherwise.
+ ----------------------------------------------------------------------------------------------*/
+@@ -1784,17 +1848,16 @@ bool GlyfContourEndPoints(gid16 nGlyphId
+     cnPoints - count of points from largest end point obtained from GlyfContourEndPoints
+     prgnX & prgnY - should point to buffers large enough to hold cnPoints integers
+         The ranges are parallel so that coordinates for point(n) are found at offset n in 
+         both ranges. These points are in absolute coordinates.
+     prgfOnCurve - should point to a buffer a large enough to hold cnPoints bytes (bool)
+         This range is parallel to the prgnX & prgnY
+     Return true if successful, false otherwise. On false, all points may be INT_MIN
+         False may indicate a white space glyph, a multi-level composite, or a corrupt font
+-    // TODO: doesn't support composite glyphs whose components are themselves components
+         It's not clear from the TTF spec when the transforms should be applied. Should the 
+         transform be done before or after attachment point calcs? (current code - before) 
+         Should the transform be applied to other offsets? (currently - no; however commented 
+         out code is in place so that if CompoundGlyph::UnscaledOffset on the MS rasterizer is 
+         clear (typical) then yes, and if CompoundGlyph::ScaledOffset on the Apple rasterizer is 
+         clear (typical?) then no). See GetComponentTransform.
+         It's also unclear where point numbering with attachment poinst starts 
+         (currently - first point number is relative to whole glyph, second point number is 
+diff --git a/gfx/graphite2/src/call_machine.cpp b/gfx/graphite2/src/call_machine.cpp
+--- a/gfx/graphite2/src/call_machine.cpp
++++ b/gfx/graphite2/src/call_machine.cpp
+@@ -65,57 +65,60 @@ using namespace graphite2;
+ using namespace vm;
+ 
+ struct regbank  {
+     slotref         is;
+     slotref *       map;
+     SlotMap       & smap;
+     slotref * const map_base;
+     const instr * & ip;
++    uint8           direction;
+     int8            flags;
+ };
+ 
+ typedef bool        (* ip_t)(registers);
+ 
+ // Pull in the opcode definitions
+ // We pull these into a private namespace so these otherwise common names dont
+ // pollute the toplevel namespace.
+ namespace {
+ #define smap    reg.smap
+ #define seg     smap.segment
+ #define is      reg.is
+ #define ip      reg.ip
+ #define map     reg.map
+ #define mapb    reg.map_base
+ #define flags   reg.flags
++#define dir     reg.direction
+ 
+ #include "inc/opcodes.h"
+ 
+ #undef smap
+ #undef seg
+ #undef is
+ #undef ip
+ #undef map
+ #undef mapb
+ #undef flags
++#undef dir
+ }
+ 
+ Machine::stack_t  Machine::run(const instr   * program,
+                                const byte    * data,
+                                slotref     * & map)
+ 
+ {
+     assert(program != 0);
+ 
+     // Declare virtual machine registers
+     const instr   * ip = program-1;
+     const byte    * dp = data;
+     stack_t       * sp = _stack + Machine::STACK_GUARD,
+             * const sb = sp;
+-    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, 0};
++    regbank         reg = {*map, map, _map, _map.begin()+_map.context(), ip, _map.dir(), 0};
+ 
+     // Run the program        
+     while ((reinterpret_cast<ip_t>(*++ip))(dp, sp, sb, reg)) {}
+     const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
+ 
+     check_final_stack(sp);
+     map = reg.map;
+     *map = reg.is;
+diff --git a/gfx/graphite2/src/direct_machine.cpp b/gfx/graphite2/src/direct_machine.cpp
+--- a/gfx/graphite2/src/direct_machine.cpp
++++ b/gfx/graphite2/src/direct_machine.cpp
+@@ -56,16 +56,17 @@ using namespace vm;
+ 
+ namespace {
+ 
+ const void * direct_run(const bool          get_table_mode,
+                         const instr       * program,
+                         const byte        * data,
+                         Machine::stack_t  * stack,
+                         slotref         * & __map,
++                        uint8                _dir,
+                         SlotMap           * __smap=0)
+ {
+     // We need to define and return to opcode table from within this function 
+     // other inorder to take the addresses of the instruction bodies.
+     #include "inc/opcode_table.h"
+     if (get_table_mode)
+         return opcode_table;
+ 
+@@ -74,16 +75,17 @@ const void * direct_run(const bool      
+     const byte        * dp = data;
+     Machine::stack_t  * sp = stack + Machine::STACK_GUARD,
+                 * const sb = sp;
+     SlotMap         & smap = *__smap;
+     Segment          & seg = smap.segment;
+     slotref             is = *__map,
+                      * map = __map,
+               * const mapb = smap.begin()+smap.context();
++    uint8            dir = _dir;
+     int8             flags = 0;
+     
+     // start the program
+     goto **ip;
+ 
+     // Pull in the opcode definitions
+     #include "inc/opcodes.h"
+     
+@@ -104,14 +106,14 @@ const opcode_t * Machine::getOpcodeTable
+ 
+ Machine::stack_t  Machine::run(const instr   * program,
+                                const byte    * data,
+                                slotref     * & is)
+ {
+     assert(program != 0);
+     
+     const stack_t *sp = static_cast<const stack_t *>(
+-                direct_run(false, program, data, _stack, is, &_map));
++                direct_run(false, program, data, _stack, is, _map.dir(), &_map));
+     const stack_t ret = sp == _stack+STACK_GUARD+1 ? *sp-- : 0;
+     check_final_stack(sp);
+     return ret;
+ }
+ 
+diff --git a/gfx/graphite2/src/files.mk b/gfx/graphite2/src/files.mk
+--- a/gfx/graphite2/src/files.mk
++++ b/gfx/graphite2/src/files.mk
+@@ -42,29 +42,32 @@
+     $($(_NS)_BASE)/src/gr_char_info.cpp \
+     $($(_NS)_BASE)/src/gr_face.cpp \
+     $($(_NS)_BASE)/src/gr_features.cpp \
+     $($(_NS)_BASE)/src/gr_font.cpp \
+     $($(_NS)_BASE)/src/gr_logging.cpp \
+     $($(_NS)_BASE)/src/gr_segment.cpp \
+     $($(_NS)_BASE)/src/gr_slot.cpp \
+     $($(_NS)_BASE)/src/json.cpp \
+-    $($(_NS)_BASE)/src/Bidi.cpp \
+     $($(_NS)_BASE)/src/CachedFace.cpp \
+     $($(_NS)_BASE)/src/CmapCache.cpp \
+     $($(_NS)_BASE)/src/Code.cpp \
++    $($(_NS)_BASE)/src/Collider.cpp \
++    $($(_NS)_BASE)/src/Decompressor.cpp \
+     $($(_NS)_BASE)/src/Face.cpp \
+     $($(_NS)_BASE)/src/FeatureMap.cpp \
+     $($(_NS)_BASE)/src/FileFace.cpp \
+     $($(_NS)_BASE)/src/Font.cpp \
+     $($(_NS)_BASE)/src/GlyphCache.cpp \
+     $($(_NS)_BASE)/src/GlyphFace.cpp \
++    $($(_NS)_BASE)/src/Intervals.cpp \
+     $($(_NS)_BASE)/src/Justifier.cpp \
+     $($(_NS)_BASE)/src/NameTable.cpp \
+     $($(_NS)_BASE)/src/Pass.cpp \
++    $($(_NS)_BASE)/src/Position.cpp \
+     $($(_NS)_BASE)/src/SegCache.cpp \
+     $($(_NS)_BASE)/src/SegCacheEntry.cpp \
+     $($(_NS)_BASE)/src/SegCacheStore.cpp \
+     $($(_NS)_BASE)/src/Segment.cpp \
+     $($(_NS)_BASE)/src/Silf.cpp \
+     $($(_NS)_BASE)/src/Slot.cpp \
+     $($(_NS)_BASE)/src/Sparse.cpp \
+     $($(_NS)_BASE)/src/TtfUtil.cpp \
+@@ -73,25 +76,29 @@
+ $(_NS)_PRIVATE_HEADERS = \
+     $($(_NS)_BASE)/src/inc/bits.h \
+     $($(_NS)_BASE)/src/inc/debug.h \
+     $($(_NS)_BASE)/src/inc/json.h \
+     $($(_NS)_BASE)/src/inc/CachedFace.h \
+     $($(_NS)_BASE)/src/inc/CharInfo.h \
+     $($(_NS)_BASE)/src/inc/CmapCache.h \
+     $($(_NS)_BASE)/src/inc/Code.h \
++    $($(_NS)_BASE)/src/inc/Collider.h \
++    $($(_NS)_BASE)/src/inc/Compression.h \
++    $($(_NS)_BASE)/src/inc/Decompressor.h \
+     $($(_NS)_BASE)/src/inc/Endian.h \
+     $($(_NS)_BASE)/src/inc/Error.h \
+     $($(_NS)_BASE)/src/inc/Face.h \
+     $($(_NS)_BASE)/src/inc/FeatureMap.h \
+     $($(_NS)_BASE)/src/inc/FeatureVal.h \
+     $($(_NS)_BASE)/src/inc/FileFace.h \
+     $($(_NS)_BASE)/src/inc/Font.h \
+     $($(_NS)_BASE)/src/inc/GlyphCache.h \
+     $($(_NS)_BASE)/src/inc/GlyphFace.h \
++    $($(_NS)_BASE)/src/inc/Intervals.h \
+     $($(_NS)_BASE)/src/inc/List.h \
+     $($(_NS)_BASE)/src/inc/locale2lcid.h \
+     $($(_NS)_BASE)/src/inc/Machine.h \
+     $($(_NS)_BASE)/src/inc/Main.h \
+     $($(_NS)_BASE)/src/inc/NameTable.h \
+     $($(_NS)_BASE)/src/inc/opcode_table.h \
+     $($(_NS)_BASE)/src/inc/opcodes.h \
+     $($(_NS)_BASE)/src/inc/Pass.h \
+diff --git a/gfx/graphite2/src/gr_face.cpp b/gfx/graphite2/src/gr_face.cpp
+--- a/gfx/graphite2/src/gr_face.cpp
++++ b/gfx/graphite2/src/gr_face.cpp
+@@ -41,17 +41,17 @@ extern json *global_log;
+ 
+ namespace
+ {
+     bool load_face(Face & face, unsigned int options)
+     {
+ #ifdef GRAPHITE2_TELEMETRY
+         telemetry::category _misc_cat(face.tele.misc);
+ #endif
+-        Face::Table silf(face, Tag::Silf);
++        Face::Table silf(face, Tag::Silf, 0x00050000);
+         if (silf)   options &= ~gr_face_dumbRendering;
+         else if (!(options &  gr_face_dumbRendering))
+             return false;
+ 
+         if (!face.readGlyphs(options))
+             return false;
+ 
+         if (silf)
+diff --git a/gfx/graphite2/src/gr_logging.cpp b/gfx/graphite2/src/gr_logging.cpp
+--- a/gfx/graphite2/src/gr_logging.cpp
++++ b/gfx/graphite2/src/gr_logging.cpp
+@@ -19,24 +19,25 @@
+     Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
+     internet at http://www.fsf.org/licenses/lgpl.html.
+ 
+ Alternatively, the contents of this file may be used under the terms of the
+ Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+-#include <stdio.h>
++#include <cstdio>
+ 
+ #include "graphite2/Log.h"
+ #include "inc/debug.h"
+ #include "inc/CharInfo.h"
+ #include "inc/Slot.h"
+ #include "inc/Segment.h"
+ #include "inc/json.h"
++#include "inc/Collider.h"
+ 
+ #if defined _WIN32
+ #include "windows.h"
+ #endif
+ 
+ using namespace graphite2;
+ 
+ #if !defined GRAPHITE2_NTRACING
+@@ -179,16 +180,17 @@ json & graphite2::operator << (json & j,
+ 
+ 
+ json & graphite2::operator << (json & j, const dslot & ds) throw()
+ {
+     assert(ds.first);
+     assert(ds.second);
+     const Segment & seg = *ds.first;
+     const Slot & s = *ds.second;
++    const SlotCollision *cslot = seg.collisionInfo(ds.second);
+ 
+     j << json::object
+         << "id"             << objectid(ds)
+         << "gid"            << s.gid()
+         << "charinfo" << json::flat << json::object
+             << "original"       << s.original()
+             << "before"         << s.before()
+             << "after"          << s.after()
+@@ -215,16 +217,38 @@ json & graphite2::operator << (json & j,
+         j   << json::close;
+     if (s.firstChild())
+     {
+         j   << "children" << json::flat << json::array;
+         for (const Slot *c = s.firstChild(); c; c = c->nextSibling())
+             j   << objectid(dslot(&seg, c));
+         j       << json::close;
+     }
++    if (cslot)
++    {
++		// Note: the reason for using Positions to lump together related attributes is to make the 
++		// JSON output slightly more compact.
++        j << "collision" << json::flat << json::object
++//              << "shift" << cslot->shift() -- not used pass level, only within the collision routine itself
++              << "offset" << cslot->offset()
++              << "limit" << cslot->limit()
++              << "flags" << cslot->flags()
++              << "margin" << Position(cslot->margin(), cslot->marginWt())
++              << "exclude" << cslot->exclGlyph()
++              << "excludeoffset" << cslot->exclOffset();
++		if (cslot->seqOrder() != 0)
++		{
++			j << "seqclass" << Position(cslot->seqClass(), cslot->seqProxClass())
++				<< "seqorder" << cslot->seqOrder()
++				<< "seqabove" << Position(cslot->seqAboveXoff(), cslot->seqAboveWt())
++				<< "seqbelow" << Position(cslot->seqBelowXlim(), cslot->seqBelowWt())
++				<< "seqvalign" << Position(cslot->seqValignHt(), cslot->seqValignWt());
++		}
++        j << json::close;
++    }
+     return j << json::close;
+ }
+ 
+ 
+ graphite2::objectid::objectid(const dslot & ds) throw()
+ {
+     const Slot * const p = ds.second;
+     uint32 s = reinterpret_cast<size_t>(p);
+diff --git a/gfx/graphite2/src/gr_segment.cpp b/gfx/graphite2/src/gr_segment.cpp
+--- a/gfx/graphite2/src/gr_segment.cpp
++++ b/gfx/graphite2/src/gr_segment.cpp
+@@ -43,21 +43,17 @@ namespace
+       Segment* pRes=new Segment(nChars, face, script, dir);
+ 
+       
+       if (!pRes->read_text(face, pFeats, enc, pStart, nChars) || !pRes->runGraphite())
+       {
+         delete pRes;
+         return NULL;
+       }
+-      // run the line break passes
+-      // run the substitution passes
+-      pRes->prepare_pos(font);
+-      // run the positioning passes
+-      pRes->finalise(font);
++      pRes->finalise(font, true);
+ 
+       return static_cast<gr_segment*>(pRes);
+   }
+ 
+ 
+ }
+ 
+ 
+diff --git a/gfx/graphite2/src/gr_slot.cpp b/gfx/graphite2/src/gr_slot.cpp
+--- a/gfx/graphite2/src/gr_slot.cpp
++++ b/gfx/graphite2/src/gr_slot.cpp
+@@ -98,21 +98,21 @@ float gr_slot_advance_X(const gr_slot* p
+         if (face && font->isHinted())
+             res = (res - face->glyphs().glyph(p->gid())->theAdvance().x) * scale + font->advance(p->gid());
+         else
+             res = res * scale;
+     }
+     return res;
+ }
+ 
+-float gr_slot_advance_Y(const gr_slot *p/*not NULL*/, const gr_face *face, const gr_font *font)
++float gr_slot_advance_Y(const gr_slot *p/*not NULL*/, GR_MAYBE_UNUSED const gr_face *face, const gr_font *font)
+ {
+     assert(p);
+     float res = p->advancePos().y;
+-    if (font && (face || !face))
++    if (font)
+         return res * font->scale();
+     else
+         return res;
+ }
+         
+ int gr_slot_before(const gr_slot* p/*not NULL*/)
+ {
+     assert(p);
+diff --git a/gfx/graphite2/src/inc/Code.h b/gfx/graphite2/src/inc/Code.h
+--- a/gfx/graphite2/src/inc/Code.h
++++ b/gfx/graphite2/src/inc/Code.h
+@@ -36,32 +36,41 @@ of the License or (at your option) any l
+ #include "inc/Main.h"
+ #include "inc/Machine.h"
+ 
+ namespace graphite2 {
+ 
+ class Silf;
+ class Face;
+ 
++enum passtype {
++    PASS_TYPE_UNKNOWN = 0,
++    PASS_TYPE_LINEBREAK,
++    PASS_TYPE_SUBSTITUTE,
++    PASS_TYPE_POSITIONING,
++    PASS_TYPE_JUSTIFICATION
++};
++
+ namespace vm {
+ 
+ class Machine::Code
+ {
+ public:
+     enum status_t 
+     {
+         loaded,
+         alloc_failed, 
+         invalid_opcode, 
+         unimplemented_opcode_used,
+         out_of_range_data,
+         jump_past_end,
+         arguments_exhausted,
+         missing_return,
+-        nested_context_item
++        nested_context_item,
++        underfull_stack
+     };
+ 
+ private:
+     class decoder;
+ 
+     instr *     _code;
+     byte  *     _data;
+     size_t      _data_size,
+@@ -72,40 +81,51 @@ private:
+                 _modify,
+                 _delete;
+     mutable bool _own;
+ 
+     void release_buffers() throw ();
+     void failure(const status_t) throw();
+ 
+ public:
++    static size_t estimateCodeDataOut(size_t num_bytecodes);
++
+     Code() throw();
+     Code(bool is_constraint, const byte * bytecode_begin, const byte * const bytecode_end,
+-         uint8 pre_context, uint16 rule_length, const Silf &, const Face &);
++         uint8 pre_context, uint16 rule_length, const Silf &, const Face &,
++         enum passtype pt, byte * * const _out = 0);
+     Code(const Machine::Code &) throw();
+     ~Code() throw();
+     
+     Code & operator=(const Code &rhs) throw();
+-    operator bool () const throw();
+-    status_t      status() const throw();
+-    bool          constraint() const throw();
+-    size_t        dataSize() const throw();
+-    size_t        instructionCount() const throw();
+-    bool          immutable() const throw();
+-    bool          deletes() const throw();
+-    size_t        maxRef() const throw();
++    operator bool () const throw()                  { return _code && status() == loaded; }
++    status_t      status() const throw()            { return _status; }
++    bool          constraint() const throw()        { return _constraint; }
++    size_t        dataSize() const throw()          { return _data_size; }
++    size_t        instructionCount() const throw()  { return _instr_count; }
++    bool          immutable() const throw()         { return !(_delete || _modify); }
++    bool          deletes() const throw()           { return _delete; }
++    size_t        maxRef() const throw()            { return _max_ref; }
++    void          externalProgramMoved(ptrdiff_t) throw();
+ 
+     int32 run(Machine &m, slotref * & map) const;
+     
+     CLASS_NEW_DELETE;
+ };
+ 
++inline
++size_t  Machine::Code::estimateCodeDataOut(size_t n_bc)
++{
++    return n_bc * (sizeof(instr)+sizeof(byte));
++}
++
++
+ inline Machine::Code::Code() throw()
+ : _code(0), _data(0), _data_size(0), _instr_count(0), _max_ref(0),
+-  _status(loaded), _constraint(false), _modify(false),_delete(false),
++  _status(loaded), _constraint(false), _modify(false), _delete(false),
+   _own(false)
+ {
+ }
+ 
+ inline Machine::Code::Code(const Machine::Code &obj) throw ()
+  :  _code(obj._code), 
+     _data(obj._data), 
+     _data_size(obj._data_size), 
+@@ -131,45 +151,19 @@ inline Machine::Code & Machine::Code::op
+     _constraint  = rhs._constraint;
+     _modify      = rhs._modify;
+     _delete      = rhs._delete;
+     _own         = rhs._own; 
+     rhs._own = false;
+     return *this;
+ }
+ 
+-inline Machine::Code::operator bool () const throw () {
+-    return _code && status() == loaded;
+-}
+-
+-inline Machine::Code::status_t Machine::Code::status() const throw() {
+-    return _status;
+-}
+-
+-inline bool Machine::Code::constraint() const throw() {
+-    return _constraint;
+-}
+-
+-inline size_t Machine::Code::dataSize() const throw() {
+-    return _data_size;
+-}
+-
+-inline size_t Machine::Code::instructionCount() const throw() {
+-    return _instr_count;
+-}
+-
+-inline bool Machine::Code::immutable() const throw()
++inline void Machine::Code::externalProgramMoved(ptrdiff_t dist) throw()
+ {
+-  return !(_delete || _modify);
+-}
+-
+-inline bool Machine::Code::deletes() const throw()
+-{
+-  return _delete;
+-}
+-
+-inline size_t Machine::Code::maxRef() const throw()
+-{
+-    return _max_ref;
++    if (_code && !_own)
++    {
++        _code += dist / sizeof(instr);
++        _data += dist;
++    }
+ }
+ 
+ } // namespace vm
+ } // namespace graphite2
+diff --git a/gfx/graphite2/src/inc/Collider.h b/gfx/graphite2/src/inc/Collider.h
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/inc/Collider.h
+@@ -0,0 +1,242 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#pragma once
++
++#include "inc/List.h"
++#include "inc/Position.h"
++#include "inc/Intervals.h"
++#include "inc/debug.h"
++
++namespace graphite2 {
++
++class json;
++class Slot;
++class Segment;
++
++#define SLOTCOLSETUINTPROP(x, y) uint16 x() const { return _ ##x; } void y (uint16 v) { _ ##x = v; }
++#define SLOTCOLSETINTPROP(x, y) int16 x() const { return _ ##x; } void y (int16 v) { _ ##x = v; }
++#define SLOTCOLSETPOSITIONPROP(x, y) const Position &x() const { return _ ##x; } void y (const Position &v) { _ ##x = v; }
++
++// Slot attributes related to collision-fixing
++class SlotCollision
++{
++public:
++    enum {
++    //  COLL_TESTONLY = 0,  // default - test other glyphs for collision with this one, but don't move this one
++        COLL_FIX = 1,       // fix collisions involving this glyph
++        COLL_IGNORE = 2,    // ignore this glyph altogether
++        COLL_START = 4,     // start of range of possible collisions
++        COLL_END = 8,       // end of range of possible collisions
++        COLL_KERN = 16,     // collisions with this glyph are fixed by adding kerning space after it
++        COLL_ISCOL = 32,    // this glyph has a collision
++        COLL_KNOWN = 64,    // we've figured out what's happening with this glyph
++        COLL_TEMPLOCK = 128,    // Lock glyphs that have been given priority positioning
++        ////COLL_JUMPABLE = 128,    // moving glyphs may jump this stationary glyph in any direction - DELETE
++        ////COLL_OVERLAP = 256,    // use maxoverlap to restrict - DELETE
++    };
++    
++    // Behavior for the collision.order attribute. To GDL this is an enum, to us it's a bitfield, with only 1 bit set
++    // Allows for easier inversion.
++    enum {
++        SEQ_ORDER_LEFTDOWN = 1,
++        SEQ_ORDER_RIGHTUP = 2,
++        SEQ_ORDER_NOABOVE = 4,
++        SEQ_ORDER_NOBELOW = 8,
++        SEQ_ORDER_NOLEFT = 16,
++        SEQ_ORDER_NORIGHT = 32
++    };
++    
++    SlotCollision(Segment *seg, Slot *slot);
++    void initFromSlot(Segment *seg, Slot *slot);
++    
++    const Rect &limit() const { return _limit; }
++    void setLimit(const Rect &r) { _limit = r; }
++    SLOTCOLSETPOSITIONPROP(shift, setShift)
++    SLOTCOLSETPOSITIONPROP(offset, setOffset)
++    SLOTCOLSETPOSITIONPROP(exclOffset, setExclOffset)
++    SLOTCOLSETUINTPROP(margin, setMargin)
++    SLOTCOLSETUINTPROP(marginWt, setMarginWt)
++    SLOTCOLSETUINTPROP(flags, setFlags)
++    SLOTCOLSETUINTPROP(exclGlyph, setExclGlyph)
++    SLOTCOLSETUINTPROP(seqClass, setSeqClass)
++    SLOTCOLSETUINTPROP(seqProxClass, setSeqProxClass)
++    SLOTCOLSETUINTPROP(seqOrder, setSeqOrder)
++    SLOTCOLSETINTPROP(seqAboveXoff, setSeqAboveXoff)
++    SLOTCOLSETUINTPROP(seqAboveWt, setSeqAboveWt)
++    SLOTCOLSETINTPROP(seqBelowXlim, setSeqBelowXlim)
++    SLOTCOLSETUINTPROP(seqBelowWt, setSeqBelowWt)
++    SLOTCOLSETUINTPROP(seqValignHt, setSeqValignHt)
++    SLOTCOLSETUINTPROP(seqValignWt, setSeqValignWt)
++
++    float getKern(int dir) const;
++    
++private:
++    Rect        _limit;
++    Position    _shift;     // adjustment within the given pass
++    Position    _offset;    // total adjustment for collisions
++    Position    _exclOffset;
++    uint16		_margin;
++    uint16		_marginWt;
++    uint16		_flags;
++    uint16		_exclGlyph;
++    uint16		_seqClass;
++	uint16		_seqProxClass;
++    uint16		_seqOrder;
++    int16		_seqAboveXoff;
++    uint16		_seqAboveWt;
++    int16		_seqBelowXlim;
++    uint16		_seqBelowWt;
++    uint16		_seqValignHt;
++    uint16		_seqValignWt;
++	
++};  // end of class SlotColllision
++
++struct BBox;
++struct SlantBox;
++
++class ShiftCollider
++{
++public:
++    typedef std::pair<float, float> fpair;
++    typedef Vector<fpair> vfpairs;
++    typedef vfpairs::iterator ivfpairs;
++
++    ShiftCollider(json *dbgout);
++    ~ShiftCollider() throw() { };
++
++    bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint,
++                float margin, float marginMin, const Position &currShift,
++                const Position &currOffset, int dir, GR_MAYBE_UNUSED json * const dbgout);
++    bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, bool isAfter, 
++                bool sameCluster, bool &hasCol, bool isExclusion, GR_MAYBE_UNUSED json * const dbgout);
++    Position resolve(Segment *seg, bool &isCol, GR_MAYBE_UNUSED json * const dbgout);
++    void addBox_slope(bool isx, const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, float weight, float m, bool minright, int mode);
++    void removeBox(const Rect &box, const BBox &bb, const SlantBox &sb, const Position &org, int mode);
++    const Position &origin() const { return _origin; }
++
++#if !defined GRAPHITE2_NTRACING
++	void outputJsonDbg(json * const dbgout, Segment *seg, int axis);
++	void outputJsonDbgStartSlot(json * const dbgout, Segment *seg);
++	void outputJsonDbgEndSlot(json * const dbgout, Position resultPos, int bestAxis, bool isCol);
++	void outputJsonDbgOneVector(json * const dbgout, Segment *seg, int axis, float tleft, float bestCost, float bestVal);
++	void outputJsonDbgRawRanges(json * const dbgout, int axis);
++	void outputJsonDbgRemovals(json * const dbgout, int axis, Segment *seg);
++#endif
++
++    CLASS_NEW_DELETE;
++
++protected:
++    Zones _ranges[4];   // possible movements in 4 directions (horizontally, vertically, diagonally);
++    Slot *  _target;    // the glyph to fix
++    Rect    _limit;
++    Position _currShift;
++    Position _currOffset;
++    Position _origin;   // Base for all relative calculations
++    float   _margin;
++	float	_marginWt;
++    float   _len[4];
++    uint16  _seqClass;
++	uint16	_seqProxClass;
++    uint16  _seqOrder;
++    
++	//bool _scraping[4];
++
++};	// end of class ShiftCollider
++
++inline
++ShiftCollider::ShiftCollider(GR_MAYBE_UNUSED json *dbgout)
++: _target(0),
++  _margin(0.0),
++  _marginWt(0.0),
++  _seqClass(0),
++  _seqProxClass(0),
++  _seqOrder(0)
++{
++#if !defined GRAPHITE2_NTRACING
++    for (int i = 0; i < 4; ++i)
++        _ranges[i].setdebug(dbgout);
++#endif
++}
++
++class KernCollider
++{
++public:
++    KernCollider(json *dbg);
++    ~KernCollider() throw() { };
++    bool initSlot(Segment *seg, Slot *aSlot, const Rect &constraint, float margin,
++            const Position &currShift, const Position &offsetPrev, int dir,
++            float ymin, float ymax, json * const dbgout);
++    bool mergeSlot(Segment *seg, Slot *slot, const Position &currShift, float currSpace, int dir, json * const dbgout);
++    Position resolve(Segment *seg, Slot *slot, int dir, float margin, json * const dbgout);
++    void shift(const Position &mv, int dir);
++
++    CLASS_NEW_DELETE;
++
++private:
++    Slot *  _target;        // the glyph to fix
++    Rect    _limit;
++    float   _margin;
++    Position _offsetPrev;   // kern from a previous pass
++    Position _currShift;    // NOT USED??
++    float _miny;	        // y-coordinates offset by global slot position
++    float _maxy;
++    Vector<float> _edges;   // edges of horizontal slices
++    float _sliceWidth;      // width of each slice
++    float _mingap;
++    float _xbound;        // max or min edge
++
++#if !defined GRAPHITE2_NTRACING    
++    // Debugging
++    Segment * _seg;
++    Vector<float> _nearEdges; // closest potential collision in each slice
++    Vector<Slot*> _slotNear;
++#endif
++};	// end of class KernCollider
++
++
++inline
++float sqr(float x) {
++    return x * x;
++}
++
++inline
++KernCollider::KernCollider(GR_MAYBE_UNUSED json *dbg)
++: _target(0),
++  _margin(0.0f),
++  _miny(-1e38f),
++  _maxy(1e38f),
++  _sliceWidth(0.0f),
++  _mingap(0.0f),
++  _xbound(0.0)
++{
++#if !defined GRAPHITE2_NTRACING
++    _seg = 0;
++#endif
++};
++
++};  // end of namespace graphite2
++
+diff --git a/gfx/graphite2/src/inc/Compression.h b/gfx/graphite2/src/inc/Compression.h
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/inc/Compression.h
+@@ -0,0 +1,103 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2015, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++
++#pragma once
++
++#include <cassert>
++#include <cstddef>
++#include <cstring>
++
++namespace
++{
++
++#if defined(_MSC_VER)
++typedef unsigned __int8 u8;
++typedef unsigned __int16 u16;
++typedef unsigned __int32 u32;
++typedef unsigned __int64 u64;
++#else
++#include <stdint.h>
++typedef uint8_t u8;
++typedef uint16_t u16;
++typedef uint32_t u32;
++typedef uint64_t u64;
++#endif
++
++ptrdiff_t const     MINMATCH  = 4;
++
++template<int S>
++inline 
++void unaligned_copy(void * d, void const * s) {
++  ::memcpy(d, s, S);
++}
++
++inline
++size_t align(size_t p) {
++    return (p + sizeof(unsigned long)-1) & ~(sizeof(unsigned long)-1);
++}
++
++inline 
++u8 * safe_copy(u8 * d, u8 const * s, size_t n) {
++    while (n--) *d++ = *s++;
++    return d;
++}
++
++inline
++u8 * overrun_copy(u8 * d, u8 const * s, size_t n) {
++    size_t const WS = sizeof(unsigned long);
++    u8 const * e = s + n;
++    do 
++    {
++        unaligned_copy<WS>(d, s);
++        d += WS;
++        s += WS;
++    }
++    while (s < e);
++    d-=(s-e);
++    
++    return d;
++}
++
++
++inline
++u8 * fast_copy(u8 * d, u8 const * s, size_t n) {
++    size_t const WS = sizeof(unsigned long);
++    size_t wn = n/WS;
++    while (wn--) 
++    {
++        unaligned_copy<WS>(d, s);
++        d += WS;
++        s += WS;
++    }
++    n &= WS-1;
++    return safe_copy(d, s, n);
++}
++
++
++} // end of anonymous namespace
++
++
+diff --git a/gfx/graphite2/src/inc/Decompressor.h b/gfx/graphite2/src/inc/Decompressor.h
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/inc/Decompressor.h
+@@ -0,0 +1,56 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2015, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++
++#pragma once
++
++#include <cstddef>
++
++namespace lz4
++{
++
++// decompress an LZ4 block
++// Parameters:
++//      @in         -   Input buffer containing an LZ4 block.
++//      @in_size    -   Size of the input LZ4 block in bytes.
++//      @out        -   Output buffer to hold decompressed results.
++//      @out_size   -   The size of the buffer pointed to by @out.
++// Invariants:
++//      @in         -   This buffer must be at least 1 machine word in length,
++//                      regardless of the actual LZ4 block size.
++//      @in_size    -   This must be at least 4 and must also be <= to the
++//                      allocated buffer @in.
++//      @out        -   This must be bigger than the input buffer and at least
++//                      13 bytes.
++//      @out_size   -   Must always be big enough to hold the expected size.
++// Return:
++//      -1          -  Decompression failed.
++//      size        -  Actual number of bytes decompressed.
++int decompress(void const *in, size_t in_size, void *out, size_t out_size);
++
++} // end of namespace shrinker
++
++
+diff --git a/gfx/graphite2/src/inc/Error.h b/gfx/graphite2/src/inc/Error.h
+--- a/gfx/graphite2/src/inc/Error.h
++++ b/gfx/graphite2/src/inc/Error.h
+@@ -106,22 +106,30 @@ enum errors {
+     E_BADRULECCODEPTR = 45, // The rule constraint code position does not align with where the forward reference says it should be
+     E_BADCCODELEN = 46,     // Bad rule/pass constraint code length
+     E_BADACTIONCODEPTR = 47,    // The action code position does not align with where the forward reference says it should be
+     E_MUTABLECCODE = 48,    // Constraint code edits slots. It shouldn't.
+     E_BADSTATE = 49,        // Bad state transition referencing an illegal state
+     E_BADRULEMAPPING = 50,  // The structure of the rule mapping is bad
+     E_BADRANGE = 51,        // Bad column range structure including a glyph in more than one column
+     E_BADRULENUM = 52,      // A reference to a rule is out of range (too high)
++    E_BADACOLLISION = 53,   // Bad Silf table collision attribute number (too high)
++    E_BADEMPTYPASS = 54,    // Can't have empty passes (no rules) except for collision passes
++    E_BADSILFVERSION = 55,  // The Silf table has a bad version (probably too high)
++    E_BADCOLLISIONPASS = 56,    // Collision flags set on a non positioning pass
++    E_BADNUMCOLUMNS = 57,   // Arbitrarily limit number of columns in fsm
+ // Code errors
+     E_CODEFAILURE = 60,     // Base code error. The following subcodes must align with Machine::Code::status_t in Code.h
+-        E_CODEALLOC = 61,       // Out of memory
+-        E_INVALIDOPCODE = 62,   // Invalid op code
+-        E_UNIMPOPCODE = 63,     // Unimplemented op code encountered
+-        E_OUTOFRANGECODE = 64,  // Code argument out of range
+-        E_BADJUMPCODE = 65,     // Code jumps past end of op codes
+-        E_CODEBADARGS = 66,     // Code arguments exhausted
+-        E_CODENORETURN = 67,    // Missing return type op code at end of code
+-        E_CODENESTEDCTXT = 68   // Nested context encountered in code
++    E_CODEALLOC = 61,       // Out of memory
++    E_INVALIDOPCODE = 62,   // Invalid op code
++    E_UNIMPOPCODE = 63,     // Unimplemented op code encountered
++    E_OUTOFRANGECODE = 64,  // Code argument out of range
++    E_BADJUMPCODE = 65,     // Code jumps past end of op codes
++    E_CODEBADARGS = 66,     // Code arguments exhausted
++    E_CODENORETURN = 67,    // Missing return type op code at end of code
++    E_CODENESTEDCTXT = 68,   // Nested context encountered in code
++// Compression errors
++    E_BADSCHEME = 69,
++    E_SHRINKERFAILED = 70,
+ };
+ 
+ }
+ 
+diff --git a/gfx/graphite2/src/inc/Face.h b/gfx/graphite2/src/inc/Face.h
+--- a/gfx/graphite2/src/inc/Face.h
++++ b/gfx/graphite2/src/inc/Face.h
+@@ -21,33 +21,34 @@
+ 
+ Alternatively, the contents of this file may be used under the terms of the
+ Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ #pragma once
+ 
+-#include <stdio.h>
++#include <cstdio>
+ 
+ #include "graphite2/Font.h"
+ 
+ #include "inc/Main.h"
+ #include "inc/FeatureMap.h"
+ #include "inc/TtfUtil.h"
+ #include "inc/Silf.h"
+ #include "inc/Error.h"
+ 
+ namespace graphite2 {
+ 
+ class Cmap;
+ class FileFace;
+ class GlyphCache;
+ class NameTable;
+ class json;
++class Font;
+ 
+ 
+ using TtfUtil::Tag;
+ 
+ // These are the actual tags, as distinct from the consecutive IDs in TtfUtil.h
+ 
+ class Face
+ {
+@@ -165,47 +166,51 @@ json * Face::logger() const throw()
+ 
+ 
+ 
+ class Face::Table
+ {
+     const Face *            _f;
+     mutable const byte *    _p;
+     uint32                  _sz;
++    bool                    _compressed;
++
++    Error decompress();
++
++    void releaseBuffers();
+ 
+ public:
+     Table() throw();
+-    Table(const Face & face, const Tag n) throw();
++    Table(const Face & face, const Tag n, uint32 version=0xffffffff) throw();
+     Table(const Table & rhs) throw();
+     ~Table() throw();
+ 
+     operator const byte * () const throw();
+ 
+     Table & operator = (const Table & rhs) throw();
+     size_t  size() const throw();
+ };
+ 
+ inline
+ Face::Table::Table() throw()
+-: _f(0), _p(0), _sz(0)
++: _f(0), _p(0), _sz(0), _compressed(false)
+ {
+ }
+ 
+ inline
+ Face::Table::Table(const Table & rhs) throw()
+-: _f(rhs._f), _p(rhs._p), _sz(rhs._sz)
++: _f(rhs._f), _p(rhs._p), _sz(rhs._sz), _compressed(rhs._compressed)
+ {
+     rhs._p = 0;
+ }
+ 
+ inline
+ Face::Table::~Table() throw()
+ {
+-    if (_p && _f->m_ops.release_table)
+-        (*_f->m_ops.release_table)(_f->m_appFaceHandle, _p);
++    releaseBuffers();
+ }
+ 
+ inline
+ Face::Table::operator const byte * () const throw()
+ {
+     return _p;
+ }
+ 
+diff --git a/gfx/graphite2/src/inc/FeatureMap.h b/gfx/graphite2/src/inc/FeatureMap.h
+--- a/gfx/graphite2/src/inc/FeatureMap.h
++++ b/gfx/graphite2/src/inc/FeatureMap.h
+@@ -51,17 +51,17 @@ private:
+ };
+ 
+ class FeatureRef
+ {
+     typedef uint32      chunk_t;
+     static const uint8  SIZEOF_CHUNK = sizeof(chunk_t)*8;
+ 
+ public:
+-    FeatureRef() : m_nameValues(0) {}
++    FeatureRef();
+     FeatureRef(const Face & face, unsigned short & bits_offset, uint32 max_val,
+                uint32 name, uint16 uiName, uint16 flags,
+                FeatureSetting *settings, uint16 num_set) throw();
+     ~FeatureRef() throw();
+ 
+     bool applyValToFeature(uint32 val, Features& pDest) const; //defined in GrFaceImp.h
+     void maskFeature(Features & pDest) const {
+     if (m_index < pDest.size())                 //defensive
+@@ -94,16 +94,26 @@ private:
+     byte    m_bits,             // how many bits to shift the value into place
+             m_index;            // index into the array to find the ulong to mask
+ 
+ private:        //unimplemented
+     FeatureRef& operator=(const FeatureRef&);
+ };
+ 
+ 
++inline
++FeatureRef::FeatureRef()
++: m_pFace(0), m_nameValues(0),
++  m_mask(0), m_max(0), m_id(0),
++  m_nameid(0), m_flags(0), m_numSet(0),
++  m_bits(0), m_index(0)
++{
++}
++
++
+ class NameAndFeatureRef
+ {
+   public:
+     NameAndFeatureRef(uint32 name = 0) : m_name(name) , m_pFRef(NULL){}
+     NameAndFeatureRef(const FeatureRef* p/*not NULL*/) : m_name(p->getId()), m_pFRef(p) {}
+ 
+     bool operator<(const NameAndFeatureRef& rhs) const //orders by m_name
+         {   return m_name<rhs.m_name; }
+@@ -112,35 +122,34 @@ class NameAndFeatureRef
+  
+     uint32 m_name;
+     const FeatureRef* m_pFRef;
+ };
+ 
+ class FeatureMap
+ {
+ public:
+-    FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL),
+-        m_defaultFeatures(NULL) {}
+-    ~FeatureMap() { delete [] m_feats; delete[] m_pNamedFeats; delete m_defaultFeatures; }
++    FeatureMap() : m_numFeats(0), m_feats(NULL), m_pNamedFeats(NULL) {}
++    ~FeatureMap() { delete [] m_feats; delete[] m_pNamedFeats; }
+ 
+     bool readFeats(const Face & face);
+     const FeatureRef *findFeatureRef(uint32 name) const;
+     FeatureRef *feature(uint16 index) const { return m_feats + index; }
+     //GrFeatureRef *featureRef(byte index) { return index < m_numFeats ? m_feats + index : NULL; }
+     const FeatureRef *featureRef(byte index) const { return index < m_numFeats ? m_feats + index : NULL; }
+     FeatureVal* cloneFeatures(uint32 langname/*0 means default*/) const;      //call destroy_Features when done.
+     uint16 numFeats() const { return m_numFeats; };
+     CLASS_NEW_DELETE
+ private:
+ friend class SillMap;
+     uint16 m_numFeats;
+ 
+     FeatureRef *m_feats;
+     NameAndFeatureRef* m_pNamedFeats;   //owned
+-    FeatureVal* m_defaultFeatures;        //owned
++    FeatureVal m_defaultFeatures;        //owned
+     
+ private:        //defensive on m_feats, m_pNamedFeats, and m_defaultFeatures
+     FeatureMap(const FeatureMap&);
+     FeatureMap& operator=(const FeatureMap&);
+ };
+ 
+ 
+ class SillMap
+diff --git a/gfx/graphite2/src/inc/FileFace.h b/gfx/graphite2/src/inc/FileFace.h
+--- a/gfx/graphite2/src/inc/FileFace.h
++++ b/gfx/graphite2/src/inc/FileFace.h
+@@ -27,17 +27,17 @@ of the License or (at your option) any l
+ #pragma once
+ 
+ //#include "inc/FeatureMap.h"
+ //#include "inc/GlyphsCache.h"
+ //#include "inc/Silf.h"
+ 
+ #ifndef GRAPHITE2_NFILEFACE
+ 
+-#include <stdio.h>
++#include <cstdio>
+ #include <cassert>
+ 
+ #include "graphite2/Font.h"
+ 
+ #include "inc/Main.h"
+ #include "inc/TtfTypes.h"
+ #include "inc/TtfUtil.h"
+ 
+diff --git a/gfx/graphite2/src/inc/GlyphCache.h b/gfx/graphite2/src/inc/GlyphCache.h
+--- a/gfx/graphite2/src/inc/GlyphCache.h
++++ b/gfx/graphite2/src/inc/GlyphCache.h
+@@ -24,24 +24,73 @@ Mozilla Public License (http://mozilla.o
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ #pragma once
+ 
+ 
+ #include "graphite2/Font.h"
+ #include "inc/Main.h"
++#include "inc/Position.h"
++#include "inc/GlyphFace.h"
+ 
+ namespace graphite2 {
+ 
+ class Face;
+ class FeatureVal;
+-class GlyphFace;
+ class Segment;
+ 
++
++struct SlantBox
++{
++    static const SlantBox empty;
++
++//    SlantBox(float psi = 0., float pdi = 0., float psa = 0., float pda = 0.) : si(psi), di(pdi), sa(psa), da(pda) {};
++    float width() const { return sa - si; }
++    float height() const { return da - di; }
++    float si; // min
++    float di; // min
++    float sa; // max
++    float da; // max
++};
++
++
++struct BBox
++{
++    BBox(float pxi = 0, float pyi = 0., float pxa = 0., float pya = 0.) : xi(pxi), yi(pyi), xa(pxa), ya(pya) {};
++    float width() const { return xa - xi; }
++    float height() const { return ya - yi; }
++    float xi; // min
++    float yi; // min
++    float xa; // max
++    float ya; // max
++};
++
++
++class GlyphBox
++{
++    GlyphBox(const GlyphBox &);
++    GlyphBox & operator = (const GlyphBox &);
++
++public:
++    GlyphBox(uint8 numsubs, unsigned short bitmap, Rect *slanted) : _num(numsubs), _bitmap(bitmap), _slant(*slanted) {}; 
++
++    void addSubBox(int subindex, int boundary, Rect *val) { _subs[subindex * 2 + boundary] = *val; }
++    Rect &subVal(int subindex, int boundary) { return _subs[subindex * 2 + boundary]; }
++    const Rect &slant() const { return _slant; }
++    uint8 num() const { return _num; }
++    const Rect *subs() const { return _subs; }
++
++private:
++    uint8   _num;
++    unsigned short  _bitmap;
++    Rect    _slant;
++    Rect    _subs[1];
++};
++
+ class GlyphCache
+ {
+     class Loader;
+ 
+     GlyphCache(const GlyphCache&);
+     GlyphCache& operator=(const GlyphCache&);
+ 
+ public:
+@@ -49,22 +98,34 @@ public:
+     ~GlyphCache();
+ 
+     unsigned short  numGlyphs() const throw();
+     unsigned short  numAttrs() const throw();
+     unsigned short  unitsPerEm() const throw();
+ 
+     const GlyphFace *glyph(unsigned short glyphid) const;      //result may be changed by subsequent call with a different glyphid
+     const GlyphFace *glyphSafe(unsigned short glyphid) const;
++    float            getBoundingMetric(unsigned short glyphid, uint8 metric) const;
++    uint8            numSubBounds(unsigned short glyphid) const;
++    float            getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const;
++    const Rect &     slant(unsigned short glyphid) const { return _boxes[glyphid] ? _boxes[glyphid]->slant() : _empty_slant_box; }
++    const SlantBox & getBoundingSlantBox(unsigned short glyphid) const;
++    const BBox &     getBoundingBBox(unsigned short glyphid) const;
++    const SlantBox & getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const;
++    const BBox &     getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const;
++    bool             check(unsigned short glyphid) const;
++    bool             hasBoxes() const { return _boxes != 0; }
+ 
+     CLASS_NEW_DELETE;
+     
+ private:
++    const Rect            _empty_slant_box;
+     const Loader        * _glyph_loader;
+     const GlyphFace *   * _glyphs;
++    GlyphBox        *   * _boxes;
+     unsigned short        _num_glyphs,
+                           _num_attrs,
+                           _upem;
+ };
+ 
+ inline
+ unsigned short GlyphCache::numGlyphs() const throw()
+ {
+@@ -79,14 +140,84 @@ unsigned short GlyphCache::numAttrs() co
+ 
+ inline
+ unsigned short  GlyphCache::unitsPerEm() const throw()
+ {
+     return _upem;
+ }
+ 
+ inline
++bool GlyphCache::check(unsigned short glyphid) const
++{
++    return _boxes && glyphid < _num_glyphs;
++}
++
++inline
+ const GlyphFace *GlyphCache::glyphSafe(unsigned short glyphid) const
+ {
+     return glyphid < _num_glyphs ? glyph(glyphid) : NULL;
+ }
+ 
++inline
++float GlyphCache::getBoundingMetric(unsigned short glyphid, uint8 metric) const
++{
++    if (glyphid >= _num_glyphs) return 0.;
++    switch (metric) {
++        case 0: return (float)(glyph(glyphid)->theBBox().bl.x);                          // x_min
++        case 1: return (float)(glyph(glyphid)->theBBox().bl.y);                          // y_min
++        case 2: return (float)(glyph(glyphid)->theBBox().tr.x);                          // x_max
++        case 3: return (float)(glyph(glyphid)->theBBox().tr.y);                          // y_max
++        case 4: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.x : 0.f);    // sum_min
++        case 5: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().bl.y : 0.f);    // diff_min
++        case 6: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.x : 0.f);    // sum_max
++        case 7: return (float)(_boxes[glyphid] ? _boxes[glyphid]->slant().tr.y : 0.f);    // diff_max
++        default: return 0.;
++    }
++}
++
++inline const SlantBox &GlyphCache::getBoundingSlantBox(unsigned short glyphid) const
++{
++    return _boxes[glyphid] ? *(SlantBox *)(&(_boxes[glyphid]->slant())) : SlantBox::empty;
++}
++
++inline const BBox &GlyphCache::getBoundingBBox(unsigned short glyphid) const
++{
++    return *(BBox *)(&(glyph(glyphid)->theBBox()));
++}
++
++inline
++float GlyphCache::getSubBoundingMetric(unsigned short glyphid, uint8 subindex, uint8 metric) const
++{
++    GlyphBox *b = _boxes[glyphid];
++    if (b == NULL || subindex >= b->num()) return 0;
++
++    switch (metric) {
++        case 0: return b->subVal(subindex, 0).bl.x;
++        case 1: return b->subVal(subindex, 0).bl.y;
++        case 2: return b->subVal(subindex, 0).tr.x;
++        case 3: return b->subVal(subindex, 0).tr.y;
++        case 4: return b->subVal(subindex, 1).bl.x;
++        case 5: return b->subVal(subindex, 1).bl.y;
++        case 6: return b->subVal(subindex, 1).tr.x;
++        case 7: return b->subVal(subindex, 1).tr.y;
++        default: return 0.;
++    }
++}
++
++inline const SlantBox &GlyphCache::getSubBoundingSlantBox(unsigned short glyphid, uint8 subindex) const
++{
++    GlyphBox *b = _boxes[glyphid];
++    return *(SlantBox *)(b->subs() + 2 * subindex + 1);
++}
++
++inline const BBox &GlyphCache::getSubBoundingBBox(unsigned short glyphid, uint8 subindex) const
++{
++    GlyphBox *b = _boxes[glyphid];
++    return *(BBox *)(b->subs() + 2 * subindex);
++}
++
++inline
++uint8 GlyphCache::numSubBounds(unsigned short glyphid) const
++{
++    return _boxes[glyphid] ? _boxes[glyphid]->num() : 0;
++}
++
+ } // namespace graphite2
+diff --git a/gfx/graphite2/src/inc/Intervals.h b/gfx/graphite2/src/inc/Intervals.h
+new file mode 100644
+--- /dev/null
++++ b/gfx/graphite2/src/inc/Intervals.h
+@@ -0,0 +1,234 @@
++/*  GRAPHITE2 LICENSING
++
++    Copyright 2010, SIL International
++    All rights reserved.
++
++    This library is free software; you can redistribute it and/or modify
++    it under the terms of the GNU Lesser General Public License as published
++    by the Free Software Foundation; either version 2.1 of License, or
++    (at your option) any later version.
++
++    This program is distributed in the hope that it will be useful,
++    but WITHOUT ANY WARRANTY; without even the implied warranty of
++    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++    Lesser General Public License for more details.
++
++    You should also have received a copy of the GNU Lesser General Public
++    License along with this library in the file named "LICENSE".
++    If not, write to the Free Software Foundation, 51 Franklin Street, 
++    Suite 500, Boston, MA 02110-1335, USA or visit their web page on the 
++    internet at http://www.fsf.org/licenses/lgpl.html.
++
++Alternatively, the contents of this file may be used under the terms of the
++Mozilla Public License (http://mozilla.org/MPL) or the GNU General Public
++License, as published by the Free Software Foundation, either version 2
++of the License or (at your option) any later version.
++*/
++#pragma once
++
++#include <utility>
++
++#include "inc/Main.h"
++#include "inc/List.h"
++#include "inc/json.h"
++#include "inc/Position.h"
++
++// An IntervalSet represents the possible movement of a given glyph in a given direction
++// (horizontally, vertically, or diagonally).
++// A vector is needed to represent disjoint ranges, eg, -300..-150, 20..200, 500..750.
++// Each pair represents the min/max of a sub-range.
++
++namespace graphite2 {
++
++class Segment;
++
++enum zones_t {SD, XY};
++
++class Zones
++{
++    struct Exclusion
++    {
++        template<zones_t O>
++        static Exclusion weighted(float xmin, float xmax, float f, float a0,
++                float m, float xi, float ai, float c, bool nega);
++
++        float   x,  // x position
++                xm, // xmax position
++                c,  // constant + sum(MiXi^2)
++                sm, // sum(Mi)
++                smx; // sum(MiXi)
++        bool    open;
++
++        Exclusion(float x, float w, float smi, float smxi, float c);
++        Exclusion & operator += (Exclusion const & rhs);
++        uint8 outcode(float p) const;
++
++        Exclusion   split_at(float p);
++        void        left_trim(float p);
++
++        bool        track_cost(float & cost, float & x, float origin) const;
++
++    private:
++        float test_position(float origin) const;
++        float cost(float x) const;
++     };
++
++    typedef Vector<Exclusion>                   exclusions;
++
++    typedef exclusions::iterator                iterator;
++    typedef Exclusion *                         pointer;
++    typedef Exclusion &                         reference;
++    typedef std::reverse_iterator<iterator>     reverse_iterator;
++
++public:
++    typedef exclusions::const_iterator              const_iterator;
++    typedef Exclusion const *                       const_pointer;
++    typedef Exclusion const &                       const_reference;
++    typedef std::reverse_iterator<const_iterator>   const_reverse_iterator;
++
++#if !defined GRAPHITE2_NTRACING
++    struct Debug
++    {
++        Exclusion       _excl;
++        bool            _isdel;
++        Vector<void *>  _env;
++
++        Debug(Exclusion *e, bool isdel, json *dbg) : _excl(*e), _isdel(isdel), _env(dbg->getenvs()) { };
++    };
++
++    typedef Vector<Debug>                       debugs;
++    typedef debugs::const_iterator                    idebugs;
++    void addDebug(Exclusion *e);
++    void removeDebug(float pos, float posm);
++    void setdebug(json *dbgout) { _dbg = dbgout; }
++    idebugs dbgs_begin() const { return _dbgs.begin(); }
++    idebugs dbgs_end() const { return _dbgs.end(); }
++    void jsonDbgOut(Segment *seg) const;
++    Position position() const { return Position(_pos, _posm); }
++#endif
++
++    Zones();
++    template<zones_t O>
++    void initialise(float xmin, float xmax, float margin_len, float margin_weight, float ao);
++
++    void exclude(float xmin, float xmax);
++    void exclude_with_margins(float xmin, float xmax, int axis);
++
++    template<zones_t O>
++    void weighted(float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
++    void weightedAxis(int axis, float xmin, float xmax, float f, float a0, float mi, float xi, float ai, float c, bool nega);
++
++    float closest( float origin, float &cost) const;
++
++    const_iterator begin() const { return _exclusions.begin(); }
++    const_iterator end() const { return _exclusions.end(); }
++
++private:
++    exclusions  _exclusions;
++#if !defined GRAPHITE2_NTRACING
++    json      * _dbg;
++    debugs      _dbgs;
++#endif
++    float       _margin_len,
++                _margin_weight,
++                _pos,
++                _posm;
++
++    void            insert(Exclusion e);
++    void            remove(float x, float xm);
++    const_iterator  find_exclusion_under(float x) const;
++};
++
++
++inline
++Zones::Zones()
++: _margin_len(0), _margin_weight(0), _pos(0), _posm(0)
++{
++#if !defined GRAPHITE2_NTRACING
++    _dbg = 0;
++#endif
++    _exclusions.reserve(8);
++}
++
++inline
++Zones::Exclusion::Exclusion(float x_, float xm_, float smi, float smxi, float c_)
++: x(x_), xm(xm_), c(c_), sm(smi), smx(smxi), open(false)
++{ }
++
++template<zones_t O>
++inline
++void Zones::initialise(float xmin, float xmax, float margin_len,
++        float margin_weight, float a0)
++{
++    _margin_len = margin_len;
++    _margin_weight = margin_weight;
++    _pos = xmin;
++    _posm = xmax;
++    _exclusions.clear();
++    _exclusions.push_back(Exclusion::weighted<O>(xmin, xmax, 1, a0, 0, 0, 0, 0, false));
++    _exclusions.front().open = true;
++#if !defined GRAPHITE2_NTRACING
++    _dbgs.clear();
++#endif
++}
++
++inline
++void Zones::exclude(float xmin, float xmax) {
++    remove(xmin, xmax);
++}
++
++template<zones_t O>
++inline
++void Zones::weighted(float xmin, float xmax, float f, float a0,
++        float m, float xi, float ai, float c, bool nega) {
++    insert(Exclusion::weighted<O>(xmin, xmax, f, a0, m, xi, ai, c, nega));
++}
++
++inline
++void Zones::weightedAxis(int axis, float xmin, float xmax, float f, float a0,
++        float m, float xi, float ai, float c, bool nega) {
++    if (axis < 2)
++        weighted<XY>(xmin, xmax, f, a0, m, xi, ai, c, nega);
++    else
++        weighted<SD>(xmin, xmax, f, a0, m, xi, ai, c, nega);
++}
++
++#if !defined GRAPHITE2_NTRACING
++inline
++void Zones::addDebug(Exclusion *e) {
++    if (_dbg)
++        _dbgs.push_back(Debug(e, false, _dbg));
++}
++
++inline
++void Zones::removeDebug(float pos, float posm) {
++    if (_dbg)
++    {
++        Exclusion e(pos, posm, 0, 0, 0);
++        _dbgs.push_back(Debug(&e, true, _dbg));
++    }
++}
++#endif
++
++template<>
++inline
++Zones::Exclusion Zones::Exclusion::weighted<XY>(float xmin, float xmax, float f, float a0,
++        float m, float xi, GR_MAYBE_UNUSED float ai, float c, GR_MAYBE_UNUSED bool nega) {
++    return Exclusion(xmin, xmax,
++            m + f,
++            m * xi, 
++            m * xi * xi + f * a0 * a0 + c);
++}
++
++template<>
++inline
++Zones::Exclusion Zones::Exclusion::weighted<SD>(float xmin, float xmax, float f, float a0,
++        float m, float xi, float ai,float c, bool nega) {
++    float xia = nega ? xi - ai : xi + ai;
++    return Exclusion(xmin, xmax, 
++            0.25f * (m + 2.f * f), 
++            0.25f * m * xia, 
++            0.25f * (m * xia * xia + 2.f * f * a0 * a0) + c);
++}
++
++} // end of namespace graphite2
+diff --git a/gfx/graphite2/src/inc/List.h b/gfx/graphite2/src/inc/List.h
+--- a/gfx/graphite2/src/inc/List.h
++++ b/gfx/graphite2/src/inc/List.h
+@@ -65,29 +65,30 @@ public:
+     iterator            end()           { return m_last; }
+     const_iterator      end() const     { return m_last; }
+     
+     bool                empty() const   { return m_first == m_last; }
+     size_t              size() const    { return m_last - m_first; }
+     size_t              capacity() const{ return m_end - m_first; }
+     
+     void                reserve(size_t n);
++    void                resize(size_t n, const T & v = T());
+     
+     reference           front()         { assert(size() > 0); return *begin(); }
+     const_reference     front() const   { assert(size() > 0); return *begin(); }
+     reference           back()          { assert(size() > 0); return *(end()-1); }
+     const_reference     back() const    { assert(size() > 0); return *(end()-1); }
+     
+     Vector<T>         & operator = (const Vector<T> & rhs) { assign(rhs.begin(), rhs.end()); return *this; }
+     reference           operator [] (size_t n)          { assert(size() > n); return m_first[n]; }
+     const_reference     operator [] (size_t n) const    { assert(size() > n); return m_first[n]; }
+     
+     void                assign(size_t n, const T& u)    { clear(); insert(begin(), n, u); }
+     void                assign(const_iterator first, const_iterator last)      { clear(); insert(begin(), first, last); }
+-    iterator            insert(iterator p, const T & x) { p = _insert_default(p, 1); *p = x; return p; }
++    iterator            insert(iterator p, const T & x) { p = _insert_default(p, 1); new (p) T(x); return p; }
+     void                insert(iterator p, size_t n, const T & x);
+     void                insert(iterator p, const_iterator first, const_iterator last);
+     void                pop_back()              { assert(size() > 0); --m_last; }
+     void                push_back(const T &v)   { if (m_last == m_end) reserve(size()+1); new (m_last++) T(v); }
+ 
+     void                clear()                 { erase(begin(), end()); }
+     iterator            erase(iterator p)       { return erase(p, p+1); }
+     iterator            erase(iterator first, iterator last);
+@@ -99,28 +100,37 @@ private:
+ template <typename T>
+ inline 
+ void Vector<T>::reserve(size_t n)
+ {
+     if (n > capacity()) 
+     {
+         const ptrdiff_t sz = size();
+         m_first = static_cast<T*>(realloc(m_first, n*sizeof(T)));
++        if (!m_first)   std::abort();
+         m_last  = m_first + sz;
+         m_end   = m_first + n;
+     }
+ }
+ 
++template <typename T>
++inline
++void Vector<T>::resize(size_t n, const T & v) {
++    const ptrdiff_t d = n-size();
++    if (d < 0)      erase(end()+d, end());
++    else if (d > 0) insert(end(), d, v);
++}
++
+ template<typename T> 
+ inline 
+ typename Vector<T>::iterator Vector<T>::_insert_default(iterator p, size_t n)
+ {
+     assert(begin() <= p && p <= end());
+     const ptrdiff_t i = p - begin();
+-    reserve((size() + n + 7) >> 3 << 3);
++    reserve(((size() + n + 7) >> 3) << 3);
+     p = begin() + i;
+     // Move tail if there is one
+     if (p != end()) memmove(p + n, p, distance(p,end())*sizeof(T));
+     m_last += n;
+     return p;
+ }
+ 
+ template<typename T> 
+diff --git a/gfx/graphite2/src/inc/Machine.h b/gfx/graphite2/src/inc/Machine.h
+--- a/gfx/graphite2/src/inc/Machine.h
++++ b/gfx/graphite2/src/inc/Machine.h
+@@ -105,17 +105,19 @@ enum opcode {
+ 
+     PUSH_IGLYPH_ATTR,    // not implemented
+ 
+     POP_RET,                        RET_ZERO,           RET_TRUE,
+     IATTR_SET,                      IATTR_ADD,          IATTR_SUB,
+     PUSH_PROC_STATE,                PUSH_VERSION,
+     PUT_SUBS,                       PUT_SUBS2,          PUT_SUBS3,
+     PUT_GLYPH,                      PUSH_GLYPH_ATTR,    PUSH_ATT_TO_GLYPH_ATTR,
+-    MAX_OPCODE,
++    BITOR,                          BITAND,             BITNOT,
++    BITSET,                         SET_FEAT,
++    MAX_OPCODE,                     
+     // private opcodes for internal use only, comes after all other on disk opcodes
+     TEMP_COPY = MAX_OPCODE
+ };
+ 
+ struct opcode_t 
+ {
+     instr           impl[2];
+     uint8           param_sz;
+@@ -143,17 +145,17 @@ public:
+ 
+     Machine(SlotMap &) throw();
+     static const opcode_t *   getOpcodeTable() throw();
+ 
+     CLASS_NEW_DELETE;
+ 
+     SlotMap   & slotMap() const throw();
+     status_t    status() const throw();
+-    operator bool () const throw();
++//    operator bool () const throw();
+ 
+ private:
+     void    check_final_stack(const stack_t * const sp);
+     stack_t run(const instr * program, const byte * data,
+                 slotref * & map) HOT;
+ 
+     SlotMap       & _map;
+     stack_t         _stack[STACK_MAX + 2*STACK_GUARD];
+diff --git a/gfx/graphite2/src/inc/Main.h b/gfx/graphite2/src/inc/Main.h
+--- a/gfx/graphite2/src/inc/Main.h
++++ b/gfx/graphite2/src/inc/Main.h
+@@ -80,25 +80,25 @@ struct telemetry  {};
+ // typesafe wrapper around malloc for simple types
+ // use free(pointer) to deallocate
+ 
+ template <typename T> T * gralloc(size_t n)
+ {
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::count_bytes(sizeof(T) * n);
+ #endif
+-    return reinterpret_cast<T*>(malloc(sizeof(T) * n));
++    return static_cast<T*>(malloc(sizeof(T) * n));
+ }
+ 
+ template <typename T> T * grzeroalloc(size_t n)
+ {
+ #ifdef GRAPHITE2_TELEMETRY
+     telemetry::count_bytes(sizeof(T) * n);
+ #endif
+-    return reinterpret_cast<T*>(calloc(n, sizeof(T)));
++    return static_cast<T*>(calloc(n, sizeof(T)));
+ }
+ 
+ template <typename T>
+ inline T min(const T a, const T b)
+ {
+     return a < b ? a : b;
+ }
+ 
+@@ -115,13 +115,32 @@ inline T max(const T a, const T b)
+     void * operator new   (size_t, void * p) throw() { return p; } \
+     void * operator new[] (size_t size) {return gralloc<byte>(size);} \
+     void * operator new[] (size_t, void * p) throw() { return p; } \
+     void operator delete   (void * p) throw() { free(p);} \
+     void operator delete   (void *, void *) throw() {} \
+     void operator delete[] (void * p)throw() { free(p); } \
+     void operator delete[] (void *, void *) throw() {}
+ 
+-#ifdef __GNUC__
++#if defined(__GNUC__)  || defined(__clang__)
+ #define GR_MAYBE_UNUSED __attribute__((unused))
+ #else
+ #define GR_MAYBE_UNUSED
+ #endif
++
++#if defined(__clang__) && __cplusplus >= 201103L
++   /* clang's fallthrough annotations are only available starting in C++11. */
++    #define GR_FALLTHROUGH [[clang::fallthrough]]
++#elif defined(_MSC_VER)
++   /*
++    * MSVC's __fallthrough annotations are checked by /analyze (Code Analysis):
++    * https://msdn.microsoft.com/en-us/library/ms235402%28VS.80%29.aspx
++    */
++    #include <sal.h>
++    #define GR_FALLTHROUGH __fallthrough
++#else
++    #define GR_FALLTHROUGH /* fallthrough */
++#endif
++
++#ifdef _MSC_VER
++#pragma warning(disable: 4800)
++#pragma warning(disable: 4355)
++#endif
+diff --git a/gfx/graphite2/src/inc/Pass.h b/gfx/graphite2/src/inc/Pass.h
+--- a/gfx/graphite2/src/inc/Pass.h
++++ b/gfx/graphite2/src/inc/Pass.h
+@@ -34,65 +34,85 @@ namespace graphite2 {
+ class Segment;
+ class Face;
+ class Silf;
+ struct Rule;
+ struct RuleEntry;
+ struct State;
+ class FiniteStateMachine;
+ class Error;
++class ShiftCollider;
++class KernCollider;
++class json;
++
++enum passtype;
+ 
+ class Pass
+ {   
+ public:
+     Pass();
+     ~Pass();
+     
+-    bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face, Error &e);
+-    void runGraphite(vm::Machine & m, FiniteStateMachine & fsm) const;
++    bool readPass(const byte * pPass, size_t pass_length, size_t subtable_base, Face & face,
++        enum passtype pt, uint32 version, Error &e);
++    bool runGraphite(vm::Machine & m, FiniteStateMachine & fsm, bool reverse) const;
+     void init(Silf *silf) { m_silf = silf; }
+-    byte spaceContextuals() const { return (m_flags & 0x0E) >> 1; }
++    byte collisionLoops() const { return m_numCollRuns; }
++    bool reverseDir() const { return m_isReverseDir; }
+ 
+     CLASS_NEW_DELETE
+ private:
+     void    findNDoRule(Slot* & iSlot, vm::Machine &, FiniteStateMachine& fsm) const;
+     int     doAction(const vm::Machine::Code* codeptr, Slot * & slot_out, vm::Machine &) const;
+     bool    testPassConstraint(vm::Machine & m) const;
+     bool    testConstraint(const Rule & r, vm::Machine &) const;
+     bool    readRules(const byte * rule_map, const size_t num_entries,
+                      const byte *precontext, const uint16 * sort_key,
+                      const uint16 * o_constraint, const byte *constraint_data, 
+                      const uint16 * o_action, const byte * action_data,
+-                     Face &, Error &e);
++                     Face &, enum passtype pt, Error &e);
+     bool    readStates(const byte * starts, const byte * states, const byte * o_rule_map, Face &, Error &e);
+     bool    readRanges(const byte * ranges, size_t num_ranges, Error &e);
+     uint16  glyphToCol(const uint16 gid) const;
+     bool    runFSM(FiniteStateMachine & fsm, Slot * slot) const;
+     void    dumpRuleEventConsidered(const FiniteStateMachine & fsm, const RuleEntry & re) const;
+-    void    dumpRuleEventOutput(const FiniteStateMachine & fsm, const Rule & r, Slot * os) const;
++    void    dumpRuleEventOutput(const FiniteStateMachine & fsm, vm::Machine & m, const Rule & r, Slot * os) const;
+     void    adjustSlot(int delta, Slot * & slot_out, SlotMap &) const;
+-    const Silf* m_silf;
+-    uint16    * m_cols;
+-    Rule      * m_rules; // rules
+-    RuleEntry * m_ruleMap;
+-    uint16    * m_startStates; // prectxt length
+-    uint16    * m_transitions;
+-    State     * m_states;
+-    
+-    byte   m_flags;
++    bool    collisionShift(Segment *seg, int dir, json * const dbgout) const;
++    bool    collisionKern(Segment *seg, int dir, json * const dbgout) const;
++    bool    collisionFinish(Segment *seg, GR_MAYBE_UNUSED json * const dbgout) const;
++    bool    resolveCollisions(Segment *seg, Slot *slot, Slot *start, ShiftCollider &coll, bool isRev,
++                     int dir, bool &moved, bool &hasCol, json * const dbgout) const;
++    float   resolveKern(Segment *seg, Slot *slot, Slot *start, KernCollider &coll, int dir,
++                     float &ymin, float &ymax, json *const dbgout) const;
++
++    const Silf        * m_silf;
++    uint16            * m_cols;
++    Rule              * m_rules; // rules
++    RuleEntry         * m_ruleMap;
++    uint16            * m_startStates; // prectxt length
++    uint16            * m_transitions;
++    State             * m_states;
++    vm::Machine::Code * m_codes;
++    byte              * m_progs;
++
++    byte   m_numCollRuns;
++    byte   m_kernColls;
+     byte   m_iMaxLoop;
+     uint16 m_numGlyphs;
+     uint16 m_numRules;
+     uint16 m_numStates;
+     uint16 m_numTransition;
+     uint16 m_numSuccess;
+     uint16 m_successStart;
+     uint16 m_numColumns;
+     byte m_minPreCtxt;
+     byte m_maxPreCtxt;
++    byte m_colThreshold;
++    bool m_isReverseDir;
+     vm::Machine::Code m_cPConstraint;
+     
+ private:        //defensive
+     Pass(const Pass&);
+     Pass& operator=(const Pass&);
+ };
+ 
+ } // namespace graphite2
+diff --git a/gfx/graphite2/src/inc/Position.h b/gfx/graphite2/src/inc/Position.h
+--- a/gfx/graphite2/src/inc/Position.h
++++ b/gfx/graphite2/src/inc/Position.h
+@@ -45,15 +45,24 @@ public:
+ 
+ class Rect
+ {
+ public :
+     Rect() {}
+     Rect(const Position& botLeft, const Position& topRight): bl(botLeft), tr(topRight) {}
+     Rect widen(const Rect& other) { return Rect(Position(bl.x > other.bl.x ? other.bl.x : bl.x, bl.y > other.bl.y ? other.bl.y : bl.y), Position(tr.x > other.tr.x ? tr.x : other.tr.x, tr.y > other.tr.y ? tr.y : other.tr.y)); }
+     Rect operator + (const Position &a) const { return Rect(Position(bl.x + a.x, bl.y + a.y), Position(tr.x + a.x, tr.y + a.y)); }
++    Rect operator - (const Position &a) const { return Rect(Position(bl.x - a.x, bl.y - a.y), Position(tr.x - a.x, tr.y - a.y)); }
+     Rect operator * (float m) const { return Rect(Position(bl.x, bl.y) * m, Position(tr.x, tr.y) * m); }
++    float width() const { return tr.x - bl.x; }
++    float height() const { return tr.y - bl.y; }
++
++    bool hitTest(Rect &other);
++
++    // returns Position(overlapx, overlapy) where overlap<0 if overlapping else positive)
++    Position overlap(Position &offset, Rect &other, Position &otherOffset);
++    //Position constrainedAvoid(Position &offset, Rect &box, Rect &sdbox, Position &other, Rect &obox, Rect &osdbox);
+ 
+     Position bl;
+     Position tr;
+ };
+ 
+ } // namespace graphite2
+diff --git a/gfx/graphite2/src/inc/Rule.h b/gfx/graphite2/src/inc/Rule.h
+--- a/gfx/graphite2/src/inc/Rule.h
++++ b/gfx/graphite2/src/inc/Rule.h
+@@ -36,30 +36,36 @@ struct Rule {
+   const vm::Machine::Code * constraint, 
+                  * action;
+   unsigned short   sort;
+   byte             preContext;
+ #ifndef NDEBUG
+   uint16           rule_idx;
+ #endif
+ 
+-  Rule() : constraint(0), action(0), sort(0), preContext(0) {}
+-  ~Rule();
++  Rule();
++  ~Rule() {}
+ 
+   CLASS_NEW_DELETE;
+ 
+ private:
+   Rule(const Rule &);
+   Rule & operator = (const Rule &);
+ };
+ 
+-inline Rule::~Rule()
++inline
++Rule::Rule()
++: constraint(0),
++  action(0),
++  sort(0),
++  preContext(0)
+ {
+-  delete constraint;
+-  delete action;
++#ifndef NDEBUG
++  rule_idx = 0;
++#endif
+ }
+ 
+ 
+ struct RuleEntry
+ {
+   const Rule   * rule;
+ 
+   inline
+@@ -91,40 +97,43 @@ bool State::empty() const
+     return rules_end == rules;
+ }
+ 
+ 
+ class SlotMap
+ {
+ public:
+   enum {MAX_SLOTS=64};
+-  SlotMap(Segment & seg);
++  SlotMap(Segment & seg, uint8 direction);
+   
+   Slot       * * begin();
+   Slot       * * end();
+   size_t         size() const;
+   unsigned short context() const;
+   void           reset(Slot &, unsigned short);
+   
+   Slot * const & operator[](int n) const;
+   Slot       * & operator [] (int);
+   void           pushSlot(Slot * const slot);
+-  void           collectGarbage();
++  void           collectGarbage(Slot *& aSlot);
+ 
+   Slot         * highwater() { return m_highwater; }
+   void           highwater(Slot *s) { m_highwater = s; m_highpassed = false; }
+   bool           highpassed() const { return m_highpassed; }
+   void           highpassed(bool v) { m_highpassed = v; }
+ 
++  uint8          dir() const { return m_dir; }
++
+   Segment &    segment;
+ private:
+   Slot         * m_slot_map[MAX_SLOTS+1];
+   unsigned short m_size;
+   unsigned short m_precontext;
+   Slot         * m_highwater;
++  uint8          m_dir;
+   bool           m_highpassed;
+ };
+ 
+ 
+ class FiniteStateMachine
+ {
+ public:
+   enum {MAX_RULES=128};
+@@ -228,18 +237,18 @@ void FiniteStateMachine::Rules::accumula
+       return;
+     }
+   }
+   while (rre != rrend && out != lrend) { *out++ = *rre++; }
+   m_end = out;
+ }
+ 
+ inline
+-SlotMap::SlotMap(Segment & seg)
+-: segment(seg), m_size(0), m_precontext(0), m_highwater(0), m_highpassed(false)
++SlotMap::SlotMap(Segment & seg, uint8 direction)
++: segment(seg), m_size(0), m_precontext(0), m_highwater(0), m_dir(direction), m_highpassed(false)
+ {
+     m_slot_map[0] = 0;
+ }
+ 
+ inline
+ Slot * * SlotMap::begin()
+ {
+   return &m_slot_map[1]; // allow map to go 1 before slot_map when inserting
+diff --git a/gfx/graphite2/src/inc/SegCache.h b/gfx/graphite2/src/inc/SegCache.h
+--- a/gfx/graphite2/src/inc/SegCache.h
++++ b/gfx/graphite2/src/inc/SegCache.h
+@@ -258,17 +258,17 @@ public:
+ 
+     CLASS_NEW_DELETE
+ private:
+     void freeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level);
+     void purgeLevel(SegCacheStore * store, SegCachePrefixArray prefixes, size_t level,
+                     unsigned long long minAccessCount, unsigned long long oldAccessTime);
+ 
+     uint16 m_prefixLength;
+-    uint16 m_maxCachedSegLength;
++//    uint16 m_maxCachedSegLength;
+     size_t m_segmentCount;
+     SegCachePrefixArray m_prefixes;
+     Features m_features;
+     mutable unsigned long long m_totalAccessCount;
+     mutable unsigned long long m_totalMisses;
+     float m_purgeFactor;
+ };
+ 
+diff --git a/gfx/graphite2/src/inc/Segment.h b/gfx/graphite2/src/inc/Segment.h
+--- a/gfx/graphite2/src/inc/Segment.h
++++ b/gfx/graphite2/src/inc/Segment.h
+@@ -30,29 +30,28 @@ of the License or (at your option) any l
+ 
+ #include <cassert>
+ 
+ #include "inc/CharInfo.h"
+ #include "inc/Face.h"
+ #include "inc/FeatureVal.h"
+ #include "inc/GlyphCache.h"
+ #include "inc/GlyphFace.h"
+-//#include "inc/Silf.h"
+ #include "inc/Slot.h"
+ #include "inc/Position.h"
+ #include "inc/List.h"
+-#include "inc/Bidi.h"
++#include "inc/Collider.h"
+ 
+ #define MAX_SEG_GROWTH_FACTOR  256
+ 
+ namespace graphite2 {
+ 
+ typedef Vector<Features>        FeatureList;
+ typedef Vector<Slot *>          SlotRope;
+-typedef Vector<int16 *>        AttributeRope;
++typedef Vector<int16 *>         AttributeRope;
+ typedef Vector<SlotJustify *>   JustifyRope;
+ 
+ #ifndef GRAPHITE2_NSEGCACHE
+ class SegmentScopeState;
+ #endif
+ class Font;
+ class Segment;
+ class Silf;
+@@ -81,119 +80,151 @@ private:
+ 
+ class Segment
+ {
+     // Prevent copying of any kind.
+     Segment(const Segment&);
+     Segment& operator=(const Segment&);
+ 
+ public:
++
++    enum {
++        SEG_INITCOLLISIONS = 1,
++        SEG_HASCOLLISIONS = 2
++    };
++
+     unsigned int slotCount() const { return m_numGlyphs; }      //one slot per glyph
+     void extendLength(int num) { m_numGlyphs += num; }
+     Position advance() const { return m_advance; }
+     bool runGraphite() { if (m_silf) return m_face->runGraphite(this, m_silf); else return true;};
+     void chooseSilf(uint32 script) { m_silf = m_face->chooseSilf(script); }
+     const Silf *silf() const { return m_silf; }
+     unsigned int charInfoCount() const { return m_numCharinfo; }
+     const CharInfo *charinfo(unsigned int index) const { return index < m_numCharinfo ? m_charinfo + index : NULL; }
+     CharInfo *charinfo(unsigned int index) { return index < m_numCharinfo ? m_charinfo + index : NULL; }
+-    int8 dir() const { return m_dir; }
+ 
+     Segment(unsigned int numchars, const Face* face, uint32 script, int dir);
+     ~Segment();
+ #ifndef GRAPHITE2_NSEGCACHE
+     SegmentScopeState setScope(Slot * firstSlot, Slot * lastSlot, size_t subLength);
+     void removeScope(SegmentScopeState & state);
+     void append(const Segment &other);
+     void splice(size_t offset, size_t length, Slot * const startSlot,
+             Slot * endSlot, const Slot * srcSlot,
+             const size_t numGlyphs);
+ #endif
++    uint8 flags() const { return m_flags; }
++    void flags(uint8 f) { m_flags = f; }
+     Slot *first() { return m_first; }
+     void first(Slot *p) { m_first = p; }
+     Slot *last() { return m_last; }
+     void last(Slot *p) { m_last = p; }
+     void appendSlot(int i, int cid, int gid, int fid, size_t coffset);
+     Slot *newSlot();
+     void freeSlot(Slot *);
+     SlotJustify *newJustify();
+     void freeJustify(SlotJustify *aJustify);
+-    Position positionSlots(const Font *font, Slot *first=0, Slot *last=0);
++    Position positionSlots(const Font *font=0, Slot *first=0, Slot *last=0, bool isRtl = false, bool isFinal = true);
+     void associateChars(int offset, int num);
+     void linkClusters(Slot *first, Slot *last);
+     uint16 getClassGlyph(uint16 cid, uint16 offset) const { return m_silf->getClassGlyph(cid, offset); }
+     uint16 findClassIndex(uint16 cid, uint16 gid) const { return m_silf->findClassIndex(cid, gid); }
+     int addFeatures(const Features& feats) { m_feats.push_back(feats); return m_feats.size() - 1; }
+     uint32 getFeature(int index, uint8 findex) const { const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); if (!pFR) return 0; else return pFR->getFeatureVal(m_feats[index]); }
++    void setFeature(int index, uint8 findex, uint32 val) {
++        const FeatureRef* pFR=m_face->theSill().theFeatureMap().featureRef(findex); 
++        if (pFR)
++        {
++            if (val > pFR->maxVal()) val = pFR->maxVal();
++            pFR->applyValToFeature(val, m_feats[index]);
++        } }
++    int8 dir() const { return m_dir; }
+     void dir(int8 val) { m_dir = val; }
++    bool currdir() const { return ((m_dir >> 6) ^ m_dir) & 1; }
+     unsigned int passBits() const { return m_passBits; }
+     void mergePassBits(const unsigned int val) { m_passBits &= val; }
+     int16 glyphAttr(uint16 gid, uint16 gattr) const { const GlyphFace * p = m_face->glyphs().glyphSafe(gid); return p ? p->attrs()[gattr] : 0; }
+-    int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const;
++    int32 getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const;
+     float glyphAdvance(uint16 gid) const { return m_face->glyphs().glyph(gid)->theAdvance().x; }
+     const Rect &theGlyphBBoxTemporary(uint16 gid) const { return m_face->glyphs().glyph(gid)->theBBox(); }   //warning value may become invalid when another glyph is accessed
+     Slot *findRoot(Slot *is) const { return is->attachedTo() ? findRoot(is->attachedTo()) : is; }
+     int numAttrs() const { return m_silf->numUser(); }
+     int defaultOriginal() const { return m_defaultOriginal; }
+     const Face * getFace() const { return m_face; }
+     const Features & getFeatures(unsigned int /*charIndex*/) { assert(m_feats.size() == 1); return m_feats[0]; }
+-    void bidiPass(uint8 aBidi, int paradir, uint8 aMirror);
++    void bidiPass(int paradir, uint8 aMirror);
++    int8 getSlotBidiClass(Slot *s) const;
++    void doMirror(uint16 aMirror);
+     Slot *addLineEnd(Slot *nSlot);
+     void delLineEnd(Slot *s);
+     bool hasJustification() const { return m_justifies.size() != 0; }
++    void reverseSlots();
+ 
+     bool isWhitespace(const int cid) const;
+-
++    bool hasCollisionInfo() const { return (m_flags & SEG_HASCOLLISIONS); }
++    SlotCollision *collisionInfo(const Slot *s) const { return m_collisions ? m_collisions + s->index() : 0; }
+     CLASS_NEW_DELETE
+ 
+ public:       //only used by: GrSegment* makeAndInitialize(const GrFont *font, const GrFace *face, uint32 script, const FeaturesHandle& pFeats/*must not be IsNull*/, encform enc, const void* pStart, size_t nChars, int dir);
+     bool read_text(const Face *face, const Features* pFeats/*must not be NULL*/, gr_encform enc, const void*pStart, size_t nChars);
+-    void prepare_pos(const Font *font);
+-    void finalise(const Font *font);
++    void finalise(const Font *font, bool reverse=false);
+     float justify(Slot *pSlot, const Font *font, float width, enum justFlags flags, Slot *pFirst, Slot *pLast);
++    bool initCollisions();
+   
+ private:
+     Position        m_advance;          // whole segment advance
+     SlotRope        m_slots;            // Vector of slot buffers
+     AttributeRope   m_userAttrs;        // Vector of userAttrs buffers
+     JustifyRope     m_justifies;        // Slot justification info buffers
+     FeatureList     m_feats;            // feature settings referenced by charinfos in this segment
+     Slot          * m_freeSlots;        // linked list of free slots
+     SlotJustify   * m_freeJustifies;    // Slot justification blocks free list
+     CharInfo      * m_charinfo;         // character info, one per input character
++    SlotCollision * m_collisions;
+     const Face    * m_face;             // GrFace
+     const Silf    * m_silf;
+     Slot          * m_first;            // first slot in segment
+     Slot          * m_last;             // last slot in segment
+     unsigned int    m_bufSize,          // how big a buffer to create when need more slots
+                     m_numGlyphs,
+                     m_numCharinfo,      // size of the array and number of input characters
+                     m_passBits;         // if bit set then skip pass
+     int             m_defaultOriginal;  // number of whitespace chars in the string
+     int8            m_dir;
++    uint8           m_flags;            // General purpose flags
+ };
+ 
+-
++inline
++int8 Segment::getSlotBidiClass(Slot *s) const
++{
++    int8 res = s->getBidiClass();
++    if (res != -1) return res;
++    res = int8(glyphAttr(s->gid(), m_silf->aBidi()));
++    s->setBidiClass(res);
++    return res;
++}
+ 
+ inline
+-void Segment::finalise(const Font *font)
++void Segment::finalise(const Font *font, bool reverse)
+ {
+     if (!m_first) return;
+ 
+-    m_advance = positionSlots(font);
+-    associateChars(0, m_numCharinfo);
++    m_advance = positionSlots(font, m_first, m_last, m_silf->dir(), true);
++    //associateChars(0, m_numCharinfo);
++    if (reverse && currdir() != (m_dir & 1))
++        reverseSlots();
+     linkClusters(m_first, m_last);
+ }
+ 
+ inline
+-int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel) const {
++int32 Segment::getGlyphMetric(Slot *iSlot, uint8 metric, uint8 attrLevel, bool rtl) const {
+     if (attrLevel > 0)
+     {
+         Slot *is = findRoot(iSlot);
+-        return is->clusterMetric(this, metric, attrLevel);
++        return is->clusterMetric(this, metric, attrLevel, rtl);
+     }
+     else
+         return m_face->getGlyphMetric(iSlot->gid(), metric);
+ }
+ 
+ inline
+ bool Segment::isWhitespace(const int cid) const
+ {
+@@ -206,68 +237,12 @@ bool Segment::isWhitespace(const int cid
+          + (cid >= 0x2000) * (cid <= 0x200A)
+          + (cid == 0x2028)
+          + (cid == 0x2029)
+          + (cid == 0x202F)
+          + (cid == 0x205F)
+          + (cid == 0x3000)) != 0;
+ }
+ 
+-//inline
+-//bool Segment::isWhitespace(const int cid) const
+-//{
+-//    switch (cid >> 8)
+-//    {
+-//        case 0x00:
+-//            switch (cid)
+-//            {
+-//            case 0x09:
+-//            case 0x0A:
+-//            case 0x0B:
+-//            case 0x0C:
+-//            case 0x0D:
+-//            case 0x20:
+-//                return true;
+-//            default:
+-//                break;
+-//            }
+-//            break;
+-//        case 0x16:
+-//            return cid == 0x1680;
+-//            break;
+-//        case 0x18:
+-//            return cid == 0x180E;
+-//            break;
+-//        case 0x20:
+-//            switch (cid)
+-//            {
+-//            case 0x00:
+-//            case 0x01:
+-//            case 0x02:
+-//            case 0x03:
+-//            case 0x04:
+-//            case 0x05:
+-//            case 0x06:
+-//            case 0x07:
+-//            case 0x08:
+-//            case 0x09:
+-//            case 0x0A:
+-//            case 0x28:
+-//            case 0x29:
+-//            case 0x2F:
+-//            case 0x5F:
+-//                return true
+-//            default:
+-//                break;
+-//            }
+-//            break;
+-//        case 0x30:
+-//            return cid == 0x3000;
+-//            break;
+-//    }
+-//
+-//    return false;
+-//}
+-
+ } // namespace graphite2
+ 
+ struct gr_segment : public graphite2::Segment {};
+ 
+diff --git a/gfx/graphite2/src/inc/Silf.h b/gfx/graphite2/src/inc/Silf.h
+--- a/gfx/graphite2/src/inc/Silf.h
++++ b/gfx/graphite2/src/inc/Silf.h
+@@ -80,24 +80,26 @@ public:
+     uint16 getClassGlyph(uint16 cid, unsigned int index) const;
+     uint16 findPseudo(uint32 uid) const;
+     uint8 numUser() const { return m_aUser; }
+     uint8 aPseudo() const { return m_aPseudo; }
+     uint8 aBreak() const { return m_aBreak; }
+     uint8 aMirror() const {return m_aMirror; }
+     uint8 aPassBits() const { return m_aPassBits; }
+     uint8 aBidi() const { return m_aBidi; }
++    uint8 aCollision() const { return m_aCollision; }
+     uint8 substitutionPass() const { return m_sPass; }
+     uint8 positionPass() const { return m_pPass; }
+     uint8 justificationPass() const { return m_jPass; }
+     uint8 bidiPass() const { return m_bPass; }
+     uint8 numPasses() const { return m_numPasses; }
+     uint8 maxCompPerLig() const { return m_iMaxComp; }
+     uint16 numClasses() const { return m_nClass; }
+     byte  flags() const { return m_flags; }
++    byte  dir() const { return m_dir; }
+     uint8 numJustLevels() const { return m_numJusts; }
+     Justinfo *justAttrs() const { return m_justs; }
+     uint16 endLineGlyphid() const { return m_gEndLine; }
+     const gr_faceinfo *silfInfo() const { return &m_silfinfo; }
+ 
+     CLASS_NEW_DELETE;
+ 
+ private:
+@@ -107,23 +109,20 @@ private:
+     Pass          * m_passes;
+     Pseudo        * m_pseudos;
+     uint32        * m_classOffsets;
+     uint16        * m_classData;
+     Justinfo      * m_justs;
+     uint8           m_numPasses;
+     uint8           m_numJusts;
+     uint8           m_sPass, m_pPass, m_jPass, m_bPass,
+-                    m_flags;
++                    m_flags, m_dir;
+ 
+-    uint8   m_aPseudo, m_aBreak, m_aUser, m_aBidi, m_aMirror, m_aPassBits,
+-            m_iMaxComp;
+-    uint16  m_aLig,
+-            m_numPseudo,
+-            m_nClass,
+-            m_nLinear,
+-            m_gEndLine;
++    uint8       m_aPseudo, m_aBreak, m_aUser, m_aBidi, m_aMirror, m_aPassBits,
++                m_iMaxComp, m_aCollision;
++    uint16      m_aLig, m_numPseudo, m_nClass, m_nLinear,
++                m_gEndLine;
+     gr_faceinfo m_silfinfo;
+     
+     void releaseBuffers() throw();
+ };
+ 
+ } // namespace graphite2
+diff --git a/gfx/graphite2/src/inc/Slot.h b/gfx/graphite2/src/inc/Slot.h
+--- a/gfx/graphite2/src/inc/Slot.h
++++ b/gfx/graphite2/src/inc/Slot.h
+@@ -27,25 +27,23 @@ of the License or (at your option) any l
+ #pragma once
+ 
+ #include "graphite2/Types.h"
+ #include "graphite2/Segment.h"
+ #include "inc/Main.h"
+ #include "inc/Font.h"
+ #include "inc/Position.h"
+ 
+-
+-
+ namespace graphite2 {
+ 
+ typedef gr_attrCode attrCode;
+ 
+ class GlyphFace;
++class SegCacheEntry;
+ class Segment;
+-class SegCacheEntry;
+ 
+ struct SlotJustify
+ {
+     static const int NUMJUSTPARAMS = 5;
+ 
+     SlotJustify(const SlotJustify &);
+     SlotJustify & operator = (const SlotJustify &);
+ 
+@@ -70,73 +68,79 @@ class Slot
+     };
+ 
+ public:
+     struct iterator;
+ 
+     unsigned short gid() const { return m_glyphid; }
+     Position origin() const { return m_position; }
+     float advance() const { return m_advance.x; }
++    void advance(Position &val) { m_advance = val; }
+     Position advancePos() const { return m_advance; }
+     int before() const { return m_before; }
+     int after() const { return m_after; }
+     uint32 index() const { return m_index; }
+     void index(uint32 val) { m_index = val; }
+ 
+-    Slot();
++    Slot(int16 *m_userAttr = NULL);
+     void set(const Slot & slot, int charOffset, size_t numUserAttr, size_t justLevels, size_t numChars);
+     Slot *next() const { return m_next; }
+     void next(Slot *s) { m_next = s; }
+     Slot *prev() const { return m_prev; }
+     void prev(Slot *s) { m_prev = s; }
+     uint16 glyph() const { return m_realglyphid ? m_realglyphid : m_glyphid; }
+     void setGlyph(Segment *seg, uint16 glyphid, const GlyphFace * theGlyph = NULL);
+     void setRealGid(uint16 realGid) { m_realglyphid = realGid; }
+     void adjKern(const Position &pos) { m_shift = m_shift + pos; m_advance = m_advance + pos; }
+     void origin(const Position &pos) { m_position = pos + m_shift; }
+     void originate(int ind) { m_original = ind; }
+     int original() const { return m_original; }
+     void before(int ind) { m_before = ind; }
+     void after(int ind) { m_after = ind; }
+     bool isBase() const { return (!m_parent); }
+     void update(int numSlots, int numCharInfo, Position &relpos);
+-    Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin);
++    Position finalise(const Segment* seg, const Font* font, Position & base, Rect & bbox, uint8 attrLevel, float & clusterMin, bool rtl, bool isFinal);
+     bool isDeleted() const { return (m_flags & DELETED) ? true : false; }
+     void markDeleted(bool state) { if (state) m_flags |= DELETED; else m_flags &= ~DELETED; }
+     bool isCopied() const { return (m_flags & COPIED) ? true : false; }
+     void markCopied(bool state) { if (state) m_flags |= COPIED; else m_flags &= ~COPIED; }
+     bool isPositioned() const { return (m_flags & POSITIONED) ? true : false; }
+     void markPositioned(bool state) { if (state) m_flags |= POSITIONED; else m_flags &= ~POSITIONED; }
+     bool isInsertBefore() const { return !(m_flags & INSERTED); }
+     uint8 getBidiLevel() const { return m_bidiLevel; }
+     void setBidiLevel(uint8 level) { m_bidiLevel = level; }
++    int8 getBidiClass(const Segment *seg);
+     int8 getBidiClass() const { return m_bidiCls; }
+     void setBidiClass(int8 cls) { m_bidiCls = cls; }
+     int16 *userAttrs() const { return m_userAttr; }
+     void userAttrs(int16 *p) { m_userAttr = p; }
+     void markInsertBefore(bool state) { if (!state) m_flags |= INSERTED; else m_flags &= ~INSERTED; }
+     void setAttr(Segment* seg, attrCode ind, uint8 subindex, int16 val, const SlotMap & map);
+     int getAttr(const Segment *seg, attrCode ind, uint8 subindex) const;
+     int getJustify(const Segment *seg, uint8 level, uint8 subindex) const;
+     void setJustify(Segment *seg, uint8 level, uint8 subindex, int16 value);
+     bool isLocalJustify() const { return m_justs != NULL; };
+     void attachTo(Slot *ap) { m_parent = ap; }
+     Slot *attachedTo() const { return m_parent; }
+     Position attachOffset() const { return m_attach - m_with; }
+     Slot* firstChild() const { return m_child; }
++    void firstChild(Slot *ap) { m_child = ap; }
+     bool child(Slot *ap);
+     Slot* nextSibling() const { return m_sibling; }
++    void nextSibling(Slot *ap) { m_sibling = ap; }
+     bool sibling(Slot *ap);
+     bool removeChild(Slot *ap);
+     bool removeSibling(Slot *ap);
+-    int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel);
++    int32 clusterMetric(const Segment* seg, uint8 metric, uint8 attrLevel, bool rtl);
+     void positionShift(Position a) { m_position += a; }
+     void floodShift(Position adj);
+     float just() const { return m_just; }
+     void just(float j) { m_just = j; }
++    Slot *nextInCluster(const Slot *s) const;
++    bool isChildOf(const Slot *base) const;
+ 
+     CLASS_NEW_DELETE
+ 
+ private:
+     Slot *m_next;           // linked list of slots
+     Slot *m_prev;
+     unsigned short m_glyphid;        // glyph id
+     uint16 m_realglyphid;
+diff --git a/gfx/graphite2/src/inc/Sparse.h b/gfx/graphite2/src/inc/Sparse.h
+--- a/gfx/graphite2/src/inc/Sparse.h
++++ b/gfx/graphite2/src/inc/Sparse.h
+@@ -51,17 +51,17 @@ private:
+     static const unsigned char  SIZEOF_CHUNK = (sizeof(mask_t) - sizeof(key_type))*8;
+ 
+     struct chunk
+     {
+         mask_t          mask:SIZEOF_CHUNK;
+         key_type        offset;
+     };
+ 
+-    static chunk  empty_chunk;
++    static const chunk  empty_chunk;
+     sparse(const sparse &);
+     sparse & operator = (const sparse &);
+ 
+ public:
+     template<typename I>
+     sparse(I first, const I last);
+     sparse() throw();
+     ~sparse() throw();
+@@ -83,17 +83,17 @@ private:
+     }           m_array;
+     key_type    m_nchunks;
+ };
+ 
+ 
+ inline
+ sparse::sparse() throw() : m_nchunks(0)
+ {
+-    m_array.map = &empty_chunk;
++    m_array.map = const_cast<graphite2::sparse::chunk *>(&empty_chunk);
+ }
+ 
+ 
+ template <typename I>
+ sparse::sparse(I attr, const I last)
+ : m_nchunks(0)
+ {
+     m_array.map = 0;
+@@ -108,30 +108,31 @@ sparse::sparse(I attr, const I last)
+         if (v.first <= lastkey) { m_nchunks = 0; return; }
+ 
+         lastkey = v.first;
+         const key_type k = v.first / SIZEOF_CHUNK;
+         if (k >= m_nchunks) m_nchunks = k+1;
+     }
+     if (m_nchunks == 0)
+     {
+-        m_array.map=&empty_chunk;
++        m_array.map=const_cast<graphite2::sparse::chunk *>(&empty_chunk);
+         return;
+     }
+ 
+     m_array.values = grzeroalloc<mapped_type>((m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)
+                                                  / sizeof(mapped_type)
+                                                  + n_values);
+ 
+     if (m_array.values == 0)
+     {
+         free(m_array.values); m_array.map=0;
+         return;
+     }
+ 
++    // coverity[forward_null : FALSE] Since m_array is union and m_array.values is not NULL
+     chunk * ci = m_array.map;
+     ci->offset = (m_nchunks*sizeof(chunk) + sizeof(mapped_type)-1)/sizeof(mapped_type);
+     mapped_type * vi = m_array.values + ci->offset;
+     for (; attr != last; ++attr, ++vi)
+     {
+         const typename std::iterator_traits<I>::value_type v = *attr;
+         if (v.second == 0)  { --vi; continue; }
+ 
+diff --git a/gfx/graphite2/src/inc/TtfUtil.h b/gfx/graphite2/src/inc/TtfUtil.h
+--- a/gfx/graphite2/src/inc/TtfUtil.h
++++ b/gfx/graphite2/src/inc/TtfUtil.h
+@@ -132,21 +132,21 @@ public:
+     int GetLangsForNames(const void * pName, int nPlatformId, int nEncodingId,
+         int *nameIdList, int cNameIds, short *langIdList);
+     void SwapWString(void * pWStr, size_t nSize = 0); // throw (std::invalid_argument);
+ #endif
+ 
+     ////////////////////////////////// cmap lookup tools 
+     const void * FindCmapSubtable(const void * pCmap, int nPlatformId = 3, 
+         int nEncodingId = 1, size_t length = 0);
+-    bool CheckCmapSubtable4(const void * pCmap31);
++    bool CheckCmapSubtable4(const void * pCmap31, size_t table_len /*, unsigned int maxgid*/);
+     gid16 CmapSubtable4Lookup(const void * pCmapSubtabel4, unsigned int nUnicodeId, int rangeKey = 0);
+     unsigned int CmapSubtable4NextCodepoint(const void *pCmap31, unsigned int nUnicodeId,
+         int * pRangeKey = 0);
+-    bool CheckCmapSubtable12(const void *pCmap310);
++    bool CheckCmapSubtable12(const void *pCmap310, size_t table_len /*, unsigned int maxgid*/);
+     gid16 CmapSubtable12Lookup(const void * pCmap310, unsigned int uUnicodeId, int rangeKey = 0);
+     unsigned int CmapSubtable12NextCodepoint(const void *pCmap310, unsigned int nUnicodeId,
+         int * pRangeKey = 0);
+ 
+     ///////////////////////////////// horizontal metric data for a glyph
+     bool HorMetrics(gid16 nGlyphId, const void * pHmtx, size_t lHmtxSize, 
+         const void * pHhea, int & nLsb, unsigned int & nAdvWid);
+ 
+diff --git a/gfx/graphite2/src/inc/UtfCodec.h b/gfx/graphite2/src/inc/UtfCodec.h
+--- a/gfx/graphite2/src/inc/UtfCodec.h
++++ b/gfx/graphite2/src/inc/UtfCodec.h
+@@ -126,19 +126,22 @@ public:
+     static uchar_t get(const codeunit_t * cp, int8 & l) throw()
+     {
+         const int8 seq_sz = sz_lut[*cp >> 4];
+         uchar_t u = *cp & mask_lut[seq_sz];
+         l = 1;
+         bool toolong = false;
+ 
+         switch(seq_sz) {
+-            case 4:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong  = (u < 0x10); // no break
+-            case 3:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x20); // no break
+-            case 2:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x80); // no break
++            case 4:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong  = (u < 0x10); GR_FALLTHROUGH;
++                // no break
++            case 3:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x20); GR_FALLTHROUGH;
++                // no break
++            case 2:     u <<= 6; u |= *++cp & 0x3F; if (*cp >> 6 != 2) break; ++l; toolong |= (u < 0x80); GR_FALLTHROUGH;
++                // no break
+             case 1:     break;
+             case 0:     l = -1; return 0xFFFD;
+         }
+ 
+         if (l != seq_sz || toolong)
+         {
+             l = -l;
+             return 0xFFFD;
+diff --git a/gfx/graphite2/src/inc/bits.h b/gfx/graphite2/src/inc/bits.h
+--- a/gfx/graphite2/src/inc/bits.h
++++ b/gfx/graphite2/src/inc/bits.h
+@@ -24,25 +24,73 @@ Mozilla Public License (http://mozilla.o
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ #pragma once
+ 
+ namespace graphite2
+ {
+ 
++
++#if defined GRAPHITE2_BUILTINS && (defined __GNUC__ || defined __clang__)
++
+ template<typename T>
+ inline unsigned int bit_set_count(T v)
+ {
+-    v = v - ((v >> 1) & T(~T(0)/3));                           // temp
+-    v = (v & T(~T(0)/15*3)) + ((v >> 2) & T(~T(0)/15*3));      // temp
+-    v = (v + (v >> 4)) & T(~T(0)/255*15);                      // temp
+-    return (T)(v * T(~T(0)/255)) >> (sizeof(T)-1)*8;           // count
++    return __builtin_popcount(v);
+ }
+ 
++template<>
++inline unsigned int bit_set_count(int16 v)
++{
++    return __builtin_popcount(static_cast<uint16>(v));
++}
++
++template<>
++inline unsigned int bit_set_count(int8 v)
++{
++    return __builtin_popcount(static_cast<uint8>(v));
++}
++
++template<>
++inline unsigned int bit_set_count(unsigned long v)
++{
++    return __builtin_popcountl(v);
++}
++
++template<>
++inline unsigned int bit_set_count(signed long v)
++{
++    return __builtin_popcountl(v);
++}
++
++template<>
++inline unsigned int bit_set_count(unsigned long long v)
++{
++    return __builtin_popcountll(v);
++}
++
++template<>
++inline unsigned int bit_set_count(signed long long v)
++{
++    return __builtin_popcountll(v);
++}
++#else
++
++template<typename T>
++inline unsigned int bit_set_count(T v)
++{
++    v = v - ((v >> 1) & T(~(0UL)/3));                           // temp
++    v = (v & T(~(0UL)/15*3)) + ((v >> 2) & T(~(0UL)/15*3));     // temp
++    v = (v + (v >> 4)) & T(~(0UL)/255*15);                      // temp
++    return (T)(v * T(~(0UL)/255)) >> (sizeof(T)-1)*8;           // count
++}
++
++#endif
++
+ 
+ template<int S>
+ inline unsigned long _mask_over_val(unsigned long v)
+ {
+     v = _mask_over_val<S/2>(v);
+     v |= v >> S*4;
+     return v;
+ }
+@@ -82,9 +130,17 @@ inline T has_zero(const T x)
+ 
+ template<typename T>
+ inline T zero_bytes(const T x, unsigned char n)
+ {
+     const T t = T(~T(0)/255*n);
+     return T((has_zero(x^t) >> 7)*n);
+ }
+ 
++#if 0
++inline float float_round(float x, uint32 m)
++{
++    *reinterpret_cast<unsigned int *>(&x) &= m;
++    return *reinterpret_cast<float *>(&x);
+ }
++#endif
++
++}
+diff --git a/gfx/graphite2/src/inc/debug.h b/gfx/graphite2/src/inc/debug.h
+--- a/gfx/graphite2/src/inc/debug.h
++++ b/gfx/graphite2/src/inc/debug.h
+@@ -49,31 +49,39 @@ struct objectid
+ {
+     char name[16];
+     objectid(const dslot &) throw();
+     objectid(const Segment * const p) throw();
+ };
+ 
+ 
+ json & operator << (json & j, const Position &) throw();
++json & operator << (json & j, const Rect &) throw();
+ json & operator << (json & j, const CharInfo &) throw();
+ json & operator << (json & j, const dslot &) throw();
+ json & operator << (json & j, const objectid &) throw();
+ json & operator << (json & j, const telemetry &) throw();
+ 
+ 
+ 
+ inline
+ json & operator << (json & j, const Position & p) throw()
+ {
+     return j << json::flat << json::array << p.x << p.y << json::close;
+ }
+ 
+ 
+ inline
++json & operator << (json & j, const Rect & p) throw()
++{
++    return j << json::flat << json::array << p.bl.x << p.bl.y << p.tr.x << p.tr.y << json::close;
++}
++
++
++inline
+ json & operator << (json & j, const objectid & sid) throw()
+ {
+     return j << sid.name;
+ }
+ 
+ 
+ } // namespace graphite2
+ 
+diff --git a/gfx/graphite2/src/inc/json.h b/gfx/graphite2/src/inc/json.h
+--- a/gfx/graphite2/src/inc/json.h
++++ b/gfx/graphite2/src/inc/json.h
+@@ -24,19 +24,21 @@ Mozilla Public License (http://mozilla.o
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ // JSON pretty printer for graphite font debug output logging.
+ // Created on: 15 Dec 2011
+ //     Author: Tim Eves
+ 
+ #pragma once
++
+ #include "inc/Main.h"
+ #include <cassert>
+-#include <stdio.h>
++#include <cstdio>
++#include "inc/List.h"
+ 
+ namespace graphite2 {
+ 
+ class json
+ {
+     // Prevent copying
+     json(const json &);
+     json & operator = (const json &);
+@@ -44,31 +46,36 @@ class json
+     typedef void (*_context_t)(json &);
+     class _null_t {};
+ 
+     FILE * const    _stream;
+     char            _contexts[128], // context stack
+                   * _context,       // current context (top of stack)
+                   * _flatten;       // if !0 points to context above which
+                                     //  pretty printed output should occur.
++    Vector<void *>  _env;
+ 
+     void context(const char current) throw();
+     void indent(const int d=0) throw();
+     void push_context(const char, const char) throw();
+     void pop_context() throw();
+ 
+ public:
+     class closer;
+ 
+     typedef const char *    string;
+     typedef double          number;
+     typedef long signed int integer;
+     typedef bool            boolean;
+     static const _null_t    null;
+ 
++    void setenv(unsigned int index, void *val) { _env.reserve(index + 1); if (index >= _env.size()) _env.insert(_env.end(), _env.size() - index + 1, 0); _env[index] = val; }
++    void *getenv(unsigned int index) const { return _env[index]; }
++    const Vector<void *> &getenvs() const { return _env; }
++
+     static void flat(json &) throw();
+     static void close(json &) throw();
+     static void object(json &) throw();
+     static void array(json &) throw();
+     static void item(json &) throw();
+ 
+     json(FILE * stream) throw();
+     ~json() throw ();
+diff --git a/gfx/graphite2/src/inc/opcode_table.h b/gfx/graphite2/src/inc/opcode_table.h
+--- a/gfx/graphite2/src/inc/opcode_table.h
++++ b/gfx/graphite2/src/inc/opcode_table.h
+@@ -38,17 +38,17 @@ of the License or (at your option) any l
+ //      sattrnum - 0 .. 29 (gr_slatJWidth) , 55 (gr_slatUserDefn)
+ //      attrid - 0 .. silf.numUser() where sattrnum == 55; 0..silf.m_iMaxComp where sattrnum == 15 otherwise 0
+ //      gattrnum - 0 .. face->getGlyphFaceCache->numAttrs()
+ //      gmetric - 0 .. 11 (kgmetDescent)
+ //      featidx - 0 .. face.numFeatures()
+ //      level - any byte
+ static const opcode_t opcode_table[] = 
+ {
+-    {{do2(nop)},                                    0,  "NOP"},
++    {{do2(nop)},                                    0, "NOP"},
+ 
+     {{do2(push_byte)},                              1, "PUSH_BYTE"},                // number
+     {{do2(push_byte_u)},                            1, "PUSH_BYTE_U"},              // number
+     {{do2(push_short)},                             2, "PUSH_SHORT"},               // number number
+     {{do2(push_short_u)},                           2, "PUSH_SHORT_U"},             // number number
+     {{do2(push_long)},                              4, "PUSH_LONG"},                // number number number number
+ 
+     {{do2(add)},                                    0, "ADD"},
+@@ -109,12 +109,17 @@ static const opcode_t opcode_table[] =
+     {{do2(push_proc_state)},                        1, "PUSH_PROC_STATE"},          // dummy
+     {{do2(push_version)},                           0, "PUSH_VERSION"},
+     {{do_(put_subs), NILOP},                        5, "PUT_SUBS"},                 // slot input_class input_class output_class output_class
+     {{NILOP,NILOP},                                 0, "PUT_SUBS2"},
+     {{NILOP,NILOP},                                 0, "PUT_SUBS3"},
+     {{do_(put_glyph), NILOP},                       2, "PUT_GLYPH"},                // output_class output_class
+     {{do2(push_glyph_attr)},                        3, "PUSH_GLYPH_ATTR"},          // gattrnum gattrnum slot
+     {{do2(push_att_to_glyph_attr)},                 3, "PUSH_ATT_TO_GLYPH_ATTR"},   // gattrnum gattrnum slot
++    {{do2(bor)},                                    0, "BITOR"},
++    {{do2(band)},                                   0, "BITAND"},
++    {{do2(bnot)},                                   0, "BITNOT"},   // 0x40
++    {{do2(setbits)},                                4, "BITSET"},
++    {{do2(set_feat)},                               2, "SET_FEAT"},
+     // private opcodes for internal use only, comes after all other on disk opcodes.
+     {{do_(temp_copy), NILOP},                       0, "TEMP_COPY"}
+ };
+ 
+diff --git a/gfx/graphite2/src/inc/opcodes.h b/gfx/graphite2/src/inc/opcodes.h
+--- a/gfx/graphite2/src/inc/opcodes.h
++++ b/gfx/graphite2/src/inc/opcodes.h
+@@ -56,16 +56,17 @@ of the License or (at your option) any l
+ //                    pushed.
+ //        seg       = A reference to the Segment this code is running over.
+ //        is        = The current slot index
+ //        isb       = The original base slot index at the start of this rule
+ //        isf       = The first positioned slot
+ //        isl       = The last positioned slot
+ //        ip        = The current instruction pointer
+ //        endPos    = Position of advance of last cluster
++//        dir       = writing system directionality of the font
+      
+ 
+ // #define NOT_IMPLEMENTED     assert(false)
+ #define NOT_IMPLEMENTED
+ 
+ #define binop(op)           const int32 a = pop(); *sp = int32(*sp) op a
+ #define use_params(n)       dp += n
+ 
+@@ -236,30 +237,34 @@ STARTOP(put_subs_8bit_obs)
+         index = seg.findClassIndex(input_class, slot->gid());
+         is->setGlyph(&seg, seg.getClassGlyph(output_class, index));
+     }
+ ENDOP
+ 
+ STARTOP(put_copy)
+     declare_params(1);
+     const int  slot_ref = int8(*param);
+-    if (is && (slot_ref ||is != *map))
++    if (is)
+     {
+-        int16 *tempUserAttrs = is->userAttrs();
+         slotref ref = slotat(slot_ref);
+-        if (ref)
++        if (ref && ref != is)
+         {
+-            memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
++            int16 *tempUserAttrs = is->userAttrs();
++            if (is->attachedTo() || is->firstChild()) DIE
+             Slot *prev = is->prev();
+             Slot *next = is->next();
+-            memcpy(is, slotat(slot_ref), sizeof(Slot));
++            memcpy(tempUserAttrs, ref->userAttrs(), seg.numAttrs() * sizeof(uint16));
++            memcpy(is, ref, sizeof(Slot));
++            is->firstChild(NULL);
++            is->nextSibling(NULL);
+             is->userAttrs(tempUserAttrs);
+             is->next(next);
+             is->prev(prev);
+-            is->sibling(NULL);
++            if (is->attachedTo())
++                is->attachedTo()->child(is);
+         }
+         is->markCopied(false);
+         is->markDeleted(false);
+     }
+ ENDOP
+ 
+ STARTOP(insert)
+     Slot *newSlot = seg.newSlot();
+@@ -304,24 +309,26 @@ STARTOP(insert)
+     {
+         newSlot->originate(newSlot->prev()->original());
+         newSlot->after(newSlot->prev()->after());
+     }
+     else
+     {
+         newSlot->originate(seg.defaultOriginal());
+     }
++    if (is == smap.highwater())
++        smap.highpassed(false);
+     is = newSlot;
+     seg.extendLength(1);
+     if (map != &smap[-1]) 
+         --map;
+ ENDOP
+ 
+ STARTOP(delete_)
+-    if (!is) DIE
++    if (!is || is->isDeleted()) DIE
+     is->markDeleted(true);
+     if (is->prev())
+         is->prev()->next(is->next());
+     else
+         seg.first(is->next());
+     
+     if (is->next())
+         is->next()->prev(is->prev());
+@@ -380,30 +387,30 @@ STARTOP(attr_set)
+ ENDOP
+ 
+ STARTOP(attr_add)
+     declare_params(1);
+     const attrCode      slat = attrCode(uint8(*param));
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, 0);
+     is->setAttr(&seg, slat, 0, val + res, smap);
+ ENDOP
+ 
+ STARTOP(attr_sub)
+     declare_params(1);
+     const attrCode      slat = attrCode(uint8(*param));
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, 0);
+     is->setAttr(&seg, slat, 0, res - val, smap);
+ ENDOP
+ 
+ STARTOP(attr_set_slot)
+     declare_params(1);
+@@ -422,17 +429,17 @@ STARTOP(iattr_set_slot)
+ ENDOP
+ 
+ STARTOP(push_slot_attr)
+     declare_params(2);
+     const attrCode      slat     = attrCode(uint8(param[0]));
+     const int           slot_ref = int8(param[1]);
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     slotref slot = slotat(slot_ref);
+     if (slot)
+     {
+         int res = slot->getAttr(&seg, slat, 0);
+         push(res);
+     }
+@@ -449,17 +456,17 @@ ENDOP
+ 
+ STARTOP(push_glyph_metric)
+     declare_params(3);
+     const unsigned int  glyph_attr  = uint8(param[0]);
+     const int           slot_ref    = int8(param[1]);
+     const signed int    attr_level  = uint8(param[2]);
+     slotref slot = slotat(slot_ref);
+     if (slot)
+-        push(seg.getGlyphMetric(slot, glyph_attr, attr_level));
++        push(seg.getGlyphMetric(slot, glyph_attr, attr_level, dir));
+ ENDOP
+ 
+ STARTOP(push_feat)
+     declare_params(2);
+     const unsigned int  feat        = uint8(param[0]);
+     const int           slot_ref    = int8(param[1]);
+     slotref slot = slotat(slot_ref);
+     if (slot)
+@@ -487,28 +494,28 @@ STARTOP(push_att_to_glyph_metric)
+     const unsigned int  glyph_attr  = uint8(param[0]);
+     const int           slot_ref    = int8(param[1]);
+     const signed int    attr_level  = uint8(param[2]);
+     slotref slot = slotat(slot_ref);
+     if (slot)
+     {
+         slotref att = slot->attachedTo();
+         if (att) slot = att;
+-        push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level)));
++        push(int32(seg.getGlyphMetric(slot, glyph_attr, attr_level, dir)));
+     }
+ ENDOP
+ 
+ STARTOP(push_islot_attr)
+     declare_params(3);
+     const attrCode  slat     = attrCode(uint8(param[0]));
+     const int           slot_ref = int8(param[1]),
+                         idx      = uint8(param[2]);
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     slotref slot = slotat(slot_ref);
+     if (slot)
+     {
+         int res = slot->getAttr(&seg, slat, idx);
+         push(res);
+     }
+@@ -543,31 +550,31 @@ ENDOP
+ 
+ STARTOP(iattr_add)
+     declare_params(2);
+     const attrCode      slat = attrCode(uint8(param[0]));
+     const size_t        idx  = uint8(param[1]);
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, idx);
+     is->setAttr(&seg, slat, idx, val + res, smap);
+ ENDOP
+ 
+ STARTOP(iattr_sub)
+     declare_params(2);
+     const attrCode      slat = attrCode(uint8(param[0]));
+     const size_t        idx  = uint8(param[1]);
+     const          int  val  = int(pop());
+     if ((slat == gr_slatPosX || slat == gr_slatPosY) && (flags & POSITIONED) == 0)
+     {
+-        seg.positionSlots(0, *smap.begin(), *(smap.end()-1));
++        seg.positionSlots(0, *smap.begin(), *(smap.end()-1), dir);
+         flags |= POSITIONED;
+     }
+     int res = is->getAttr(&seg, slat, idx);
+     is->setAttr(&seg, slat, idx, res - val, smap);
+ ENDOP
+ 
+ STARTOP(push_proc_state)
+     use_params(1);
+@@ -631,16 +638,50 @@ STARTOP(push_att_to_glyph_attr)
+         slotref att = slot->attachedTo();
+         if (att) slot = att;
+         push(int32(seg.glyphAttr(slot->gid(), glyph_attr)));
+     }
+ ENDOP
+ 
+ STARTOP(temp_copy)
+     slotref newSlot = seg.newSlot();
+-    if (!newSlot) DIE;
++    if (!newSlot || !is) DIE;
+     int16 *tempUserAttrs = newSlot->userAttrs();
+     memcpy(newSlot, is, sizeof(Slot));
+     memcpy(tempUserAttrs, is->userAttrs(), seg.numAttrs() * sizeof(uint16));
+     newSlot->userAttrs(tempUserAttrs);
+     newSlot->markCopied(true);
+     *map = newSlot;
+ ENDOP
++
++STARTOP(band)
++    binop(&);
++ENDOP
++
++STARTOP(bor)
++    binop(|);
++ENDOP
++
++STARTOP(bnot)
++    *sp = ~*sp;
++ENDOP
++
++STARTOP(setbits)
++    declare_params(4);
++    const uint16 m  = uint16(param[0]) << 8
++                    | uint8(param[1]);
++    const uint16 v  = uint16(param[2]) << 8
++                    | uint8(param[3]);
++    *sp = ((*sp) & ~m) | v;
++ENDOP
++
++STARTOP(set_feat)
++    declare_params(2);
++    const unsigned int  feat        = uint8(param[0]);
++    const int           slot_ref    = int8(param[1]);
++    slotref slot = slotat(slot_ref);
++    if (slot)
++    {
++        uint8 fid = seg.charinfo(slot->original())->fid();
++        seg.setFeature(fid, feat, pop());
++    }
++ENDOP
++
+diff --git a/gfx/graphite2/src/json.cpp b/gfx/graphite2/src/json.cpp
+--- a/gfx/graphite2/src/json.cpp
++++ b/gfx/graphite2/src/json.cpp
+@@ -24,17 +24,18 @@ Mozilla Public License (http://mozilla.o
+ License, as published by the Free Software Foundation, either version 2
+ of the License or (at your option) any later version.
+ */
+ // JSON debug logging
+ // Author: Tim Eves
+ 
+ #if !defined GRAPHITE2_NTRACING
+ 
+-#include <stdio.h>
++#include <cstdio>
++#include <limits>
+ #include "inc/json.h"
+ 
+ using namespace graphite2;
+ 
+ namespace
+ {
+     enum
+     {
+@@ -111,16 +112,29 @@ json & json::operator << (json::string s
+     const char ctxt = _context[-1] == obj ? *_context == member ? seq : member : seq;
+     context(ctxt);
+     fprintf(_stream, "\"%s\"", s);
+     if (ctxt == member) fputc(' ', _stream);
+ 
+     return *this;
+ }
+ 
+-json & json::operator << (json::number f) throw()   { context(seq); fprintf(_stream, "%g", f); return *this; }
++json & json::operator << (json::number f) throw()
++{ 
++    context(seq); 
++    if (std::numeric_limits<json::number>::infinity() == f)
++        fputs("Infinity", _stream);
++    else if (-std::numeric_limits<json::number>::infinity() == f)
++        fputs("-Infinity", _stream);
++    else if (std::numeric_limits<json::number>::quiet_NaN() == f ||
++            std::numeric_limits<json::number>::signaling_NaN() == f)
++        fputs("NaN", _stream);
++    else
++        fprintf(_stream, "%g", f); 
++    return *this; 
++}
+ json & json::operator << (json::integer d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
+ json & json::operator << (long unsigned d) throw()  { context(seq); fprintf(_stream, "%ld", d); return *this; }
+ json & json::operator << (json::boolean b) throw()  { context(seq); fputs(b ? "true" : "false", _stream); return *this; }
+ json & json::operator << (json::_null_t) throw()    { context(seq); fputs("null",_stream); return *this; }
+ 
+ #endif
+ 
+diff --git a/gfx/graphite2/src/moz.build b/gfx/graphite2/src/moz.build
+--- a/gfx/graphite2/src/moz.build
++++ b/gfx/graphite2/src/moz.build
+@@ -18,37 +18,40 @@ if CONFIG['GNU_CC']:
+     ]
+ else:
+     UNIFIED_SOURCES += [
+         'call_machine.cpp'
+     ]
+ 
+ # This should contain all of the _SOURCES from files.mk, except *_machine.cpp
+ UNIFIED_SOURCES += [
+-    'Bidi.cpp',
+     'CachedFace.cpp',
+     'CmapCache.cpp',
+     'Code.cpp',
++    'Collider.cpp',
++    'Decompressor.cpp',
+     'Face.cpp',
+     'FeatureMap.cpp',
+     'FileFace.cpp',
+     'Font.cpp',
+     'GlyphCache.cpp',
+     'GlyphFace.cpp',
+     'gr_char_info.cpp',
+     'gr_face.cpp',
+     'gr_features.cpp',
+     'gr_font.cpp',
+     'gr_logging.cpp',
+     'gr_segment.cpp',
+     'gr_slot.cpp',
++    'Intervals.cpp',
+     'json.cpp',
+     'Justifier.cpp',
+     'NameTable.cpp',
+     'Pass.cpp',
++    'Position.cpp',
+     'SegCache.cpp',
+     'SegCacheEntry.cpp',
+     'SegCacheStore.cpp',
+     'Segment.cpp',
+     'Silf.cpp',
+     'Slot.cpp',
+     'Sparse.cpp',
+     'TtfUtil.cpp',
+
diff --git a/gnu/packages/patches/libsndfile-CVE-2014-9496.patch b/gnu/packages/patches/libsndfile-CVE-2014-9496.patch
deleted file mode 100644
index 87d42955fb..0000000000
--- a/gnu/packages/patches/libsndfile-CVE-2014-9496.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-Copied from Fedora.
-
-http://pkgs.fedoraproject.org/cgit/libsndfile.git/plain/libsndfile-1.0.25-cve2014_9496.patch
-
-diff -up libsndfile-1.0.25/src/sd2.c.cve2014_9496 libsndfile-1.0.25/src/sd2.c
---- libsndfile-1.0.25/src/sd2.c.cve2014_9496	2011-01-19 11:10:36.000000000 +0100
-+++ libsndfile-1.0.25/src/sd2.c	2015-01-13 17:00:35.920285526 +0100
-@@ -395,6 +395,21 @@ read_marker (const unsigned char * data,
- 		return 0x666 ;
- } /* read_marker */
- 
-+static inline int
-+read_rsrc_marker (const SD2_RSRC *prsrc, int offset)
-+{	const unsigned char * data = prsrc->rsrc_data ;
-+
-+	if (offset < 0 || offset + 3 >= prsrc->rsrc_len)
-+		return 0 ;
-+
-+	if (CPU_IS_BIG_ENDIAN)
-+		return (((uint32_t) data [offset]) << 24) + (data [offset + 1] << 16) + (data [offset + 2] << 8) + data [offset + 3] ;
-+	if (CPU_IS_LITTLE_ENDIAN)
-+		return data [offset] + (data [offset + 1] << 8) + (data [offset + 2] << 16) + (((uint32_t) data [offset + 3]) << 24) ;
-+
-+	return 0 ;
-+} /* read_rsrc_marker */
-+
- static void
- read_str (const unsigned char * data, int offset, char * buffer, int buffer_len)
- {	int k ;
-@@ -496,6 +511,11 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
- 
- 	rsrc.type_offset = rsrc.map_offset + 30 ;
- 
-+	if (rsrc.map_offset + 28 > rsrc.rsrc_len)
-+	{       psf_log_printf (psf, "Bad map offset.\n") ;
-+		goto parse_rsrc_fork_cleanup ;
-+		} ;
-+
- 	rsrc.type_count = read_short (rsrc.rsrc_data, rsrc.map_offset + 28) + 1 ;
- 	if (rsrc.type_count < 1)
- 	{	psf_log_printf (psf, "Bad type count.\n") ;
-@@ -512,7 +532,12 @@ sd2_parse_rsrc_fork (SF_PRIVATE *psf)
- 
- 	rsrc.str_index = -1 ;
- 	for (k = 0 ; k < rsrc.type_count ; k ++)
--	{	marker = read_marker (rsrc.rsrc_data, rsrc.type_offset + k * 8) ;
-+	{	if (rsrc.type_offset + k * 8 > rsrc.rsrc_len)
-+		{	psf_log_printf (psf, "Bad rsrc marker.\n") ;
-+			goto parse_rsrc_fork_cleanup ;
-+			} ;
-+
-+		marker = read_rsrc_marker (&rsrc, rsrc.type_offset + k * 8) ;
- 
- 		if (marker == STR_MARKER)
- 		{	rsrc.str_index = k ;
diff --git a/gnu/packages/patches/libsndfile-CVE-2015-7805.patch b/gnu/packages/patches/libsndfile-CVE-2015-7805.patch
deleted file mode 100644
index d617f81e5c..0000000000
--- a/gnu/packages/patches/libsndfile-CVE-2015-7805.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-Slightly modified to apply cleanly to libsndfile-1.0.25.
-
-From d2a87385c1ca1d72918e9a2875d24f202a5093e8 Mon Sep 17 00:00:00 2001
-From: Erik de Castro Lopo <erikd@mega-nerd.com>
-Date: Sat, 7 Feb 2015 15:45:10 +1100
-Subject: [PATCH] src/common.c : Fix a header parsing bug.
-
-When the file header is bigger that SF_HEADER_LEN, the code would seek
-instead of reading causing file parse errors.
-
-The current header parsing and writing code *badly* needs a re-write.
----
- src/common.c | 27 +++++++++++----------------
- 1 file changed, 11 insertions(+), 16 deletions(-)
-
-diff --git a/src/common.c b/src/common.c
-index dd4edb7..c6b88cc 100644
---- a/src/common.c
-+++ b/src/common.c
-@@ -1,5 +1,5 @@
- /*
--** Copyright (C) 1999-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
-+** Copyright (C) 1999-2015 Erik de Castro Lopo <erikd@mega-nerd.com>
- **
- ** This program is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU Lesser General Public License as published by
-@@ -800,21 +800,16 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes)
- {	int count = 0 ;
- 
- 	if (psf->headindex >= SIGNED_SIZEOF (psf->header))
--	{	memset (ptr, 0, SIGNED_SIZEOF (psf->header) - psf->headindex) ;
--
--		/* This is the best that we can do. */
--		psf_fseek (psf, bytes, SEEK_CUR) ;
--		return bytes ;
--		} ;
-+		return psf_fread (ptr, 1, bytes, psf) ;
- 
- 	if (psf->headindex + bytes > SIGNED_SIZEOF (psf->header))
- 	{	int most ;
- 
- 		most = SIGNED_SIZEOF (psf->header) - psf->headindex ;
- 		psf_fread (psf->header + psf->headend, 1, most, psf) ;
--		memset ((char *) ptr + most, 0, bytes - most) ;
--
--		psf_fseek (psf, bytes - most, SEEK_CUR) ;
-+		memcpy (ptr, psf->header + psf->headend, most) ;
-+		psf->headend = psf->headindex += most ;
-+		psf_fread ((char *) ptr + most, bytes - most, 1, psf) ;
- 		return bytes ;
- 		} ;
- 
-@@ -822,7 +817,7 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes)
- 	{	count = psf_fread (psf->header + psf->headend, 1, bytes - (psf->headend - psf->headindex), psf) ;
- 		if (count != bytes - (int) (psf->headend - psf->headindex))
- 		{	psf_log_printf (psf, "Error : psf_fread returned short count.\n") ;
--			return 0 ;
-+			return count ;
- 			} ;
- 		psf->headend += count ;
- 		} ;
-@@ -836,7 +831,6 @@ header_read (SF_PRIVATE *psf, void *ptr, int bytes)
- static void
- header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
- {
--
- 	switch (whence)
- 	{	case SEEK_SET :
- 			if (position > SIGNED_SIZEOF (psf->header))
-@@ -885,8 +879,7 @@ header_seek (SF_PRIVATE *psf, sf_count_t position, int whence)
- 
- static int
- header_gets (SF_PRIVATE *psf, char *ptr, int bufsize)
--{
--	int		k ;
-+{	int		k ;
- 
- 	for (k = 0 ; k < bufsize - 1 ; k++)
- 	{	if (psf->headindex < psf->headend)
-@@ -1073,8 +1066,10 @@ psf_binheader_readf (SF_PRIVATE *psf, char const *format, ...)
- 			case 'j' :
- 					/* Get the seek position first. */
- 					count = va_arg (argptr, size_t) ;
--					header_seek (psf, count, SEEK_CUR) ;
--					byte_count += count ;
-+					if (count)
-+					{	header_seek (psf, count, SEEK_CUR) ;
-+						byte_count += count ;
-+						} ;
- 					break ;
- 
- 			default :
--- 
-2.6.3
-
diff --git a/gnu/packages/patches/libssh-0.6.5-CVE-2016-0739.patch b/gnu/packages/patches/libssh-0.6.5-CVE-2016-0739.patch
new file mode 100644
index 0000000000..a5fdd7ffff
--- /dev/null
+++ b/gnu/packages/patches/libssh-0.6.5-CVE-2016-0739.patch
@@ -0,0 +1,77 @@
+Fix CVE-2016-0739 (Weak Diffie-Hellman secret generation in
+dh_generate_x() and dh_generate_y()).
+
+"Due to a byte/bit confusion, the DH secret was too short. This file was
+completely reworked and will be commited in a future version."
+Source:
+https://git.libssh.org/projects/libssh.git/commit/?id=f8d0026c65fc8a55748ae481758e2cf376c26c86
+
+This patch was created by upstream for libssh-0.7.3, but applied without
+modification to libssh-0.6.3 by Debian. In Guix, we apply it without
+modification to libssh-0.6.5.
+
+References:
+https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-0739
+https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-0739
+https://security-tracker.debian.org/tracker/CVE-2016-0739
+
+---
+ src/dh.c | 22 +++++++++++++++++-----
+ 1 file changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/src/dh.c b/src/dh.c
+index e489a1d..d27b66e 100644
+--- a/src/dh.c
++++ b/src/dh.c
+@@ -227,15 +227,21 @@ void ssh_crypto_finalize(void) {
+ }
+ 
+ int dh_generate_x(ssh_session session) {
++  int keysize;
++  if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
++    keysize = 1023;
++  } else {
++    keysize = 2047;
++  }
+   session->next_crypto->x = bignum_new();
+   if (session->next_crypto->x == NULL) {
+     return -1;
+   }
+ 
+ #ifdef HAVE_LIBGCRYPT
+-  bignum_rand(session->next_crypto->x, 128);
++  bignum_rand(session->next_crypto->x, keysize);
+ #elif defined HAVE_LIBCRYPTO
+-  bignum_rand(session->next_crypto->x, 128, 0, -1);
++  bignum_rand(session->next_crypto->x, keysize, -1, 0);
+ #endif
+ 
+   /* not harder than this */
+@@ -248,15 +254,21 @@ int dh_generate_x(ssh_session session) {
+ 
+ /* used by server */
+ int dh_generate_y(ssh_session session) {
+-    session->next_crypto->y = bignum_new();
++  int keysize;
++  if (session->next_crypto->kex_type == SSH_KEX_DH_GROUP1_SHA1) {
++    keysize = 1023;
++  } else {
++    keysize = 2047;
++  }
++  session->next_crypto->y = bignum_new();
+   if (session->next_crypto->y == NULL) {
+     return -1;
+   }
+ 
+ #ifdef HAVE_LIBGCRYPT
+-  bignum_rand(session->next_crypto->y, 128);
++  bignum_rand(session->next_crypto->y, keysize);
+ #elif defined HAVE_LIBCRYPTO
+-  bignum_rand(session->next_crypto->y, 128, 0, -1);
++  bignum_rand(session->next_crypto->y, keysize, -1, 0);
+ #endif
+ 
+   /* not harder than this */
+-- 
+cgit v0.12
+
diff --git a/gnu/packages/patches/libssh-CVE-2014-0017.patch b/gnu/packages/patches/libssh-CVE-2014-0017.patch
deleted file mode 100644
index 94d8cc33d2..0000000000
--- a/gnu/packages/patches/libssh-CVE-2014-0017.patch
+++ /dev/null
@@ -1,89 +0,0 @@
-Patch from libssh 0.6, with bind.c hunk adjusted for 0.5.5.
-
-From e99246246b4061f7e71463f8806b9dcad65affa0 Mon Sep 17 00:00:00 2001
-From: Aris Adamantiadis <aris@0xbadc0de.be>
-Date: Wed, 05 Feb 2014 20:24:12 +0000
-Subject: security: fix for vulnerability CVE-2014-0017
-
-When accepting a new connection, a forking server based on libssh forks
-and the child process handles the request. The RAND_bytes() function of
-openssl doesn't reset its state after the fork, but simply adds the
-current process id (getpid) to the PRNG state, which is not guaranteed
-to be unique.
-This can cause several children to end up with same PRNG state which is
-a security issue.
----
-diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
-index 7374a88..e8ff32c 100644
---- a/include/libssh/wrapper.h
-+++ b/include/libssh/wrapper.h
-@@ -70,5 +70,6 @@ int crypt_set_algorithms_server(ssh_session session);
- struct ssh_crypto_struct *crypto_new(void);
- void crypto_free(struct ssh_crypto_struct *crypto);
- 
-+void ssh_reseed(void);
- 
- #endif /* WRAPPER_H_ */
-diff --git a/src/bind.c b/src/bind.c
-index 8d82d0d..03d3403 100644
---- a/src/bind.c
-+++ b/src/bind.c
-@@ -375,6 +375,8 @@ int ssh_bind_accept(ssh_bind sshbind, ss
-   session->dsa_key = dsa;
-   session->rsa_key = rsa;
- 
-+  /* force PRNG to change state in case we fork after ssh_bind_accept */
-+  ssh_reseed();
-   return SSH_OK;
- }
- 
-diff --git a/src/libcrypto.c b/src/libcrypto.c
-index bb1d96a..d8cc795 100644
---- a/src/libcrypto.c
-+++ b/src/libcrypto.c
-@@ -23,6 +23,7 @@
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-+#include <sys/time.h>
- 
- #include "libssh/priv.h"
- #include "libssh/session.h"
-@@ -38,6 +39,8 @@
- #include <openssl/rsa.h>
- #include <openssl/hmac.h>
- #include <openssl/opensslv.h>
-+#include <openssl/rand.h>
-+
- #ifdef HAVE_OPENSSL_AES_H
- #define HAS_AES
- #include <openssl/aes.h>
-@@ -74,6 +77,12 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
-     return 0;
- }
- 
-+void ssh_reseed(void){
-+    struct timeval tv;
-+    gettimeofday(&tv, NULL);
-+    RAND_add(&tv, sizeof(tv), 0.0);
-+}
-+
- SHACTX sha1_init(void) {
-   SHACTX c = malloc(sizeof(*c));
-   if (c == NULL) {
-diff --git a/src/libgcrypt.c b/src/libgcrypt.c
-index 899bccd..4617901 100644
---- a/src/libgcrypt.c
-+++ b/src/libgcrypt.c
-@@ -45,6 +45,9 @@ static int alloc_key(struct ssh_cipher_struct *cipher) {
-     return 0;
- }
- 
-+void ssh_reseed(void){
-+	}
-+
- SHACTX sha1_init(void) {
-   SHACTX ctx = NULL;
-   gcry_md_open(&ctx, GCRY_MD_SHA1, 0);
---
-cgit v0.9.1
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch
deleted file mode 100644
index 0f5603e228..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt1.patch
+++ /dev/null
@@ -1,569 +0,0 @@
-Copied from Debian.
-
-From b813d5811432faed844a2dfd3daecde914978f2c Mon Sep 17 00:00:00 2001
-From: Nicolas Williams <nico@twosigma.com>
-Date: Mon, 14 Sep 2015 12:27:52 -0400
-Subject: Fix SPNEGO context aliasing bugs [CVE-2015-2695]
-
-The SPNEGO mechanism currently replaces its context handle with the
-mechanism context handle upon establishment, under the assumption that
-most GSS functions are only called after context establishment.  This
-assumption is incorrect, and can lead to aliasing violations for some
-programs.  Maintain the SPNEGO context structure after context
-establishment and refer to it in all GSS methods.  Add initiate and
-opened flags to the SPNEGO context structure for use in
-gss_inquire_context() prior to context establishment.
-
-CVE-2015-2695:
-
-In MIT krb5 1.5 and later, applications which call
-gss_inquire_context() on a partially-established SPNEGO context can
-cause the GSS-API library to read from a pointer using the wrong type,
-generally causing a process crash.  This bug may go unnoticed, because
-the most common SPNEGO authentication scenario establishes the context
-after just one call to gss_accept_sec_context().  Java server
-applications using the native JGSS provider are vulnerable to this
-bug.  A carefully crafted SPNEGO packet might allow the
-gss_inquire_context() call to succeed with attacker-determined
-results, but applications should not make access control decisions
-based on gss_inquire_context() results prior to context establishment.
-
-    CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C
-
-[ghudson@mit.edu: several bugfixes, style changes, and edge-case
-behavior changes; commit message and CVE description]
-
-ticket: 8244
-target_version: 1.14
-tags: pullup
-
-(cherry picked from commit b51b33f2bc5d1497ddf5bd107f791c101695000d)
-Patch-Category: upstream
----
- src/lib/gssapi/spnego/gssapiP_spnego.h |   2 +
- src/lib/gssapi/spnego/spnego_mech.c    | 254 ++++++++++++++++++++++++---------
- 2 files changed, 192 insertions(+), 64 deletions(-)
-
-diff --git a/src/lib/gssapi/spnego/gssapiP_spnego.h b/src/lib/gssapi/spnego/gssapiP_spnego.h
-index bc23f56..8e05736 100644
---- a/src/lib/gssapi/spnego/gssapiP_spnego.h
-+++ b/src/lib/gssapi/spnego/gssapiP_spnego.h
-@@ -102,6 +102,8 @@ typedef struct {
- 	int firstpass;
- 	int mech_complete;
- 	int nego_done;
-+	int initiate;
-+	int opened;
- 	OM_uint32 ctx_flags;
- 	gss_name_t internal_name;
- 	gss_OID actual_mech;
-diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
-index 6e39c37..a1072b0 100644
---- a/src/lib/gssapi/spnego/spnego_mech.c
-+++ b/src/lib/gssapi/spnego/spnego_mech.c
-@@ -104,7 +104,7 @@ static OM_uint32 get_negotiable_mechs(OM_uint32 *, spnego_gss_cred_id_t,
- 				      gss_cred_usage_t, gss_OID_set *);
- static void release_spnego_ctx(spnego_gss_ctx_id_t *);
- static void check_spnego_options(spnego_gss_ctx_id_t);
--static spnego_gss_ctx_id_t create_spnego_ctx(void);
-+static spnego_gss_ctx_id_t create_spnego_ctx(int);
- static int put_mech_set(gss_OID_set mechSet, gss_buffer_t buf);
- static int put_input_token(unsigned char **, gss_buffer_t, unsigned int);
- static int put_mech_oid(unsigned char **, gss_OID_const, unsigned int);
-@@ -442,7 +442,7 @@ check_spnego_options(spnego_gss_ctx_id_t spnego_ctx)
- }
- 
- static spnego_gss_ctx_id_t
--create_spnego_ctx(void)
-+create_spnego_ctx(int initiate)
- {
- 	spnego_gss_ctx_id_t spnego_ctx = NULL;
- 	spnego_ctx = (spnego_gss_ctx_id_t)
-@@ -465,6 +465,8 @@ create_spnego_ctx(void)
- 	spnego_ctx->mic_rcvd = 0;
- 	spnego_ctx->mech_complete = 0;
- 	spnego_ctx->nego_done = 0;
-+	spnego_ctx->opened = 0;
-+	spnego_ctx->initiate = initiate;
- 	spnego_ctx->internal_name = GSS_C_NO_NAME;
- 	spnego_ctx->actual_mech = GSS_C_NO_OID;
- 
-@@ -630,7 +632,7 @@ init_ctx_new(OM_uint32 *minor_status,
- 	OM_uint32 ret;
- 	spnego_gss_ctx_id_t sc = NULL;
- 
--	sc = create_spnego_ctx();
-+	sc = create_spnego_ctx(1);
- 	if (sc == NULL)
- 		return GSS_S_FAILURE;
- 
-@@ -647,10 +649,7 @@ init_ctx_new(OM_uint32 *minor_status,
- 		ret = GSS_S_FAILURE;
- 		goto cleanup;
- 	}
--	/*
--	 * The actual context is not yet determined, set the output
--	 * context handle to refer to the spnego context itself.
--	 */
-+
- 	sc->ctx_handle = GSS_C_NO_CONTEXT;
- 	*ctx = (gss_ctx_id_t)sc;
- 	sc = NULL;
-@@ -1091,16 +1090,11 @@ cleanup:
- 	}
- 	gss_release_buffer(&tmpmin, &mechtok_out);
- 	if (ret == GSS_S_COMPLETE) {
--		/*
--		 * Now, switch the output context to refer to the
--		 * negotiated mechanism's context.
--		 */
--		*context_handle = (gss_ctx_id_t)spnego_ctx->ctx_handle;
-+		spnego_ctx->opened = 1;
- 		if (actual_mech != NULL)
- 			*actual_mech = spnego_ctx->actual_mech;
- 		if (ret_flags != NULL)
- 			*ret_flags = spnego_ctx->ctx_flags;
--		release_spnego_ctx(&spnego_ctx);
- 	} else if (ret != GSS_S_CONTINUE_NEEDED) {
- 		if (spnego_ctx != NULL) {
- 			gss_delete_sec_context(&tmpmin,
-@@ -1344,7 +1338,7 @@ acc_ctx_hints(OM_uint32 *minor_status,
- 	if (ret != GSS_S_COMPLETE)
- 		goto cleanup;
- 
--	sc = create_spnego_ctx();
-+	sc = create_spnego_ctx(0);
- 	if (sc == NULL) {
- 		ret = GSS_S_FAILURE;
- 		goto cleanup;
-@@ -1426,7 +1420,7 @@ acc_ctx_new(OM_uint32 *minor_status,
- 		gss_release_buffer(&tmpmin, &sc->DER_mechTypes);
- 		assert(mech_wanted != GSS_C_NO_OID);
- 	} else
--		sc = create_spnego_ctx();
-+		sc = create_spnego_ctx(0);
- 	if (sc == NULL) {
- 		ret = GSS_S_FAILURE;
- 		*return_token = NO_TOKEN_SEND;
-@@ -1809,13 +1803,12 @@ cleanup:
- 			ret = GSS_S_FAILURE;
- 	}
- 	if (ret == GSS_S_COMPLETE) {
--		*context_handle = (gss_ctx_id_t)sc->ctx_handle;
-+		sc->opened = 1;
- 		if (sc->internal_name != GSS_C_NO_NAME &&
- 		    src_name != NULL) {
- 			*src_name = sc->internal_name;
- 			sc->internal_name = GSS_C_NO_NAME;
- 		}
--		release_spnego_ctx(&sc);
- 	} else if (ret != GSS_S_CONTINUE_NEEDED) {
- 		if (sc != NULL) {
- 			gss_delete_sec_context(&tmpmin, &sc->ctx_handle,
-@@ -2128,8 +2121,13 @@ spnego_gss_unwrap(
- 		gss_qop_t *qop_state)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_unwrap(minor_status,
--			context_handle,
-+			sc->ctx_handle,
- 			input_message_buffer,
- 			output_message_buffer,
- 			conf_state,
-@@ -2149,8 +2147,13 @@ spnego_gss_wrap(
- 		gss_buffer_t output_message_buffer)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_wrap(minor_status,
--		    context_handle,
-+		    sc->ctx_handle,
- 		    conf_req_flag,
- 		    qop_req,
- 		    input_message_buffer,
-@@ -2167,8 +2170,14 @@ spnego_gss_process_context_token(
- 				const gss_buffer_t token_buffer)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	/* SPNEGO doesn't have its own context tokens. */
-+	if (!sc->opened)
-+		return (GSS_S_DEFECTIVE_TOKEN);
-+
- 	ret = gss_process_context_token(minor_status,
--					context_handle,
-+					sc->ctx_handle,
- 					token_buffer);
- 
- 	return (ret);
-@@ -2192,19 +2201,9 @@ spnego_gss_delete_sec_context(
- 	if (*ctx == NULL)
- 		return (GSS_S_COMPLETE);
- 
--	/*
--	 * If this is still an SPNEGO mech, release it locally.
--	 */
--	if ((*ctx)->magic_num == SPNEGO_MAGIC_ID) {
--		(void) gss_delete_sec_context(minor_status,
--				    &(*ctx)->ctx_handle,
--				    output_token);
--		(void) release_spnego_ctx(ctx);
--	} else {
--		ret = gss_delete_sec_context(minor_status,
--				    context_handle,
--				    output_token);
--	}
-+	(void) gss_delete_sec_context(minor_status, &(*ctx)->ctx_handle,
-+				      output_token);
-+	(void) release_spnego_ctx(ctx);
- 
- 	return (ret);
- }
-@@ -2216,8 +2215,13 @@ spnego_gss_context_time(
- 			OM_uint32	*time_rec)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_context_time(minor_status,
--			    context_handle,
-+			    sc->ctx_handle,
- 			    time_rec);
- 	return (ret);
- }
-@@ -2229,9 +2233,20 @@ spnego_gss_export_sec_context(
- 			    gss_buffer_t interprocess_token)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = *(spnego_gss_ctx_id_t *)context_handle;
-+
-+	/* We don't currently support exporting partially established
-+	 * contexts. */
-+	if (!sc->opened)
-+		return GSS_S_UNAVAILABLE;
-+
- 	ret = gss_export_sec_context(minor_status,
--				    context_handle,
-+				    &sc->ctx_handle,
- 				    interprocess_token);
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT) {
-+		release_spnego_ctx(&sc);
-+		*context_handle = GSS_C_NO_CONTEXT;
-+	}
- 	return (ret);
- }
- 
-@@ -2241,11 +2256,12 @@ spnego_gss_import_sec_context(
- 	const gss_buffer_t	interprocess_token,
- 	gss_ctx_id_t		*context_handle)
- {
--	OM_uint32 ret;
--	ret = gss_import_sec_context(minor_status,
--				    interprocess_token,
--				    context_handle);
--	return (ret);
-+	/*
-+	 * Until we implement partial context exports, there are no SPNEGO
-+	 * exported context tokens, only tokens for underlying mechs.  So just
-+	 * return an error for now.
-+	 */
-+	return GSS_S_UNAVAILABLE;
- }
- #endif /* LEAN_CLIENT */
- 
-@@ -2262,16 +2278,48 @@ spnego_gss_inquire_context(
- 			int		*opened)
- {
- 	OM_uint32 ret = GSS_S_COMPLETE;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (src_name != NULL)
-+		*src_name = GSS_C_NO_NAME;
-+	if (targ_name != NULL)
-+		*targ_name = GSS_C_NO_NAME;
-+	if (lifetime_rec != NULL)
-+		*lifetime_rec = 0;
-+	if (mech_type != NULL)
-+		*mech_type = (gss_OID)gss_mech_spnego;
-+	if (ctx_flags != NULL)
-+		*ctx_flags = 0;
-+	if (locally_initiated != NULL)
-+		*locally_initiated = sc->initiate;
-+	if (opened != NULL)
-+		*opened = sc->opened;
-+
-+	if (sc->ctx_handle != GSS_C_NO_CONTEXT) {
-+		ret = gss_inquire_context(minor_status, sc->ctx_handle,
-+					  src_name, targ_name, lifetime_rec,
-+					  mech_type, ctx_flags, NULL, NULL);
-+	}
- 
--	ret = gss_inquire_context(minor_status,
--				context_handle,
--				src_name,
--				targ_name,
--				lifetime_rec,
--				mech_type,
--				ctx_flags,
--				locally_initiated,
--				opened);
-+	if (!sc->opened) {
-+		/*
-+		 * We are still doing SPNEGO negotiation, so report SPNEGO as
-+		 * the OID.  After negotiation is complete we will report the
-+		 * underlying mechanism OID.
-+		 */
-+		if (mech_type != NULL)
-+			*mech_type = (gss_OID)gss_mech_spnego;
-+
-+		/*
-+		 * Remove flags we don't support with partially-established
-+		 * contexts.  (Change this to keep GSS_C_TRANS_FLAG if we add
-+		 * support for exporting partial SPNEGO contexts.)
-+		 */
-+		if (ctx_flags != NULL) {
-+			*ctx_flags &= ~GSS_C_PROT_READY_FLAG;
-+			*ctx_flags &= ~GSS_C_TRANS_FLAG;
-+		}
-+	}
- 
- 	return (ret);
- }
-@@ -2286,8 +2334,13 @@ spnego_gss_wrap_size_limit(
- 	OM_uint32	*max_input_size)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_wrap_size_limit(minor_status,
--				context_handle,
-+				sc->ctx_handle,
- 				conf_req_flag,
- 				qop_req,
- 				req_output_size,
-@@ -2304,8 +2357,13 @@ spnego_gss_get_mic(
- 		gss_buffer_t message_token)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_get_mic(minor_status,
--		    context_handle,
-+		    sc->ctx_handle,
- 		    qop_req,
- 		    message_buffer,
- 		    message_token);
-@@ -2321,8 +2379,13 @@ spnego_gss_verify_mic(
- 		gss_qop_t *qop_state)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_verify_mic(minor_status,
--			    context_handle,
-+			    sc->ctx_handle,
- 			    msg_buffer,
- 			    token_buffer,
- 			    qop_state);
-@@ -2337,8 +2400,14 @@ spnego_gss_inquire_sec_context_by_oid(
- 		gss_buffer_set_t *data_set)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	/* There are no SPNEGO-specific OIDs for this function. */
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_UNAVAILABLE);
-+
- 	ret = gss_inquire_sec_context_by_oid(minor_status,
--			    context_handle,
-+			    sc->ctx_handle,
- 			    desired_object,
- 			    data_set);
- 	return (ret);
-@@ -2407,8 +2476,15 @@ spnego_gss_set_sec_context_option(
- 		const gss_buffer_t value)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)*context_handle;
-+
-+	/* There are no SPNEGO-specific OIDs for this function, and we cannot
-+	 * construct an empty SPNEGO context with it. */
-+	if (sc == NULL || sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_UNAVAILABLE);
-+
- 	ret = gss_set_sec_context_option(minor_status,
--			    context_handle,
-+			    &sc->ctx_handle,
- 			    desired_object,
- 			    value);
- 	return (ret);
-@@ -2425,8 +2501,13 @@ spnego_gss_wrap_aead(OM_uint32 *minor_status,
- 		     gss_buffer_t output_message_buffer)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_wrap_aead(minor_status,
--			    context_handle,
-+			    sc->ctx_handle,
- 			    conf_req_flag,
- 			    qop_req,
- 			    input_assoc_buffer,
-@@ -2447,8 +2528,13 @@ spnego_gss_unwrap_aead(OM_uint32 *minor_status,
- 		       gss_qop_t *qop_state)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_unwrap_aead(minor_status,
--			      context_handle,
-+			      sc->ctx_handle,
- 			      input_message_buffer,
- 			      input_assoc_buffer,
- 			      output_payload_buffer,
-@@ -2467,8 +2553,13 @@ spnego_gss_wrap_iov(OM_uint32 *minor_status,
- 		    int iov_count)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_wrap_iov(minor_status,
--			   context_handle,
-+			   sc->ctx_handle,
- 			   conf_req_flag,
- 			   qop_req,
- 			   conf_state,
-@@ -2486,8 +2577,13 @@ spnego_gss_unwrap_iov(OM_uint32 *minor_status,
- 		      int iov_count)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_unwrap_iov(minor_status,
--			     context_handle,
-+			     sc->ctx_handle,
- 			     conf_state,
- 			     qop_state,
- 			     iov,
-@@ -2505,8 +2601,13 @@ spnego_gss_wrap_iov_length(OM_uint32 *minor_status,
- 			   int iov_count)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_wrap_iov_length(minor_status,
--				  context_handle,
-+				  sc->ctx_handle,
- 				  conf_req_flag,
- 				  qop_req,
- 				  conf_state,
-@@ -2523,8 +2624,13 @@ spnego_gss_complete_auth_token(
- 		gss_buffer_t input_message_buffer)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_UNAVAILABLE);
-+
- 	ret = gss_complete_auth_token(minor_status,
--				      context_handle,
-+				      sc->ctx_handle,
- 				      input_message_buffer);
- 	return (ret);
- }
-@@ -2776,8 +2882,13 @@ spnego_gss_pseudo_random(OM_uint32 *minor_status,
- 			 gss_buffer_t prf_out)
- {
- 	OM_uint32 ret;
-+	spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context;
-+
-+	if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+		return (GSS_S_NO_CONTEXT);
-+
- 	ret = gss_pseudo_random(minor_status,
--				context,
-+				sc->ctx_handle,
- 				prf_key,
- 				prf_in,
- 				desired_output_len,
-@@ -2918,7 +3029,12 @@ spnego_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
- 		       gss_qop_t qop_req, gss_iov_buffer_desc *iov,
- 		       int iov_count)
- {
--    return gss_get_mic_iov(minor_status, context_handle, qop_req, iov,
-+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+	    return (GSS_S_NO_CONTEXT);
-+
-+    return gss_get_mic_iov(minor_status, sc->ctx_handle, qop_req, iov,
- 			   iov_count);
- }
- 
-@@ -2927,7 +3043,12 @@ spnego_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
- 			  gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
- 			  int iov_count)
- {
--    return gss_verify_mic_iov(minor_status, context_handle, qop_state, iov,
-+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+	    return (GSS_S_NO_CONTEXT);
-+
-+    return gss_verify_mic_iov(minor_status, sc->ctx_handle, qop_state, iov,
- 			      iov_count);
- }
- 
-@@ -2936,7 +3057,12 @@ spnego_gss_get_mic_iov_length(OM_uint32 *minor_status,
- 			      gss_ctx_id_t context_handle, gss_qop_t qop_req,
- 			      gss_iov_buffer_desc *iov, int iov_count)
- {
--    return gss_get_mic_iov_length(minor_status, context_handle, qop_req, iov,
-+    spnego_gss_ctx_id_t sc = (spnego_gss_ctx_id_t)context_handle;
-+
-+    if (sc->ctx_handle == GSS_C_NO_CONTEXT)
-+	    return (GSS_S_NO_CONTEXT);
-+
-+    return gss_get_mic_iov_length(minor_status, sc->ctx_handle, qop_req, iov,
- 				  iov_count);
- }
- 
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch
deleted file mode 100644
index aa9fcfa0dd..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2695-pt2.patch
+++ /dev/null
@@ -1,65 +0,0 @@
-Copied from Debian.
-
-From 18c512ebdcc5cacc777e9dbcc6817f83c301ad93 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Wed, 4 Nov 2015 21:29:10 -0500
-Subject: Fix SPNEGO context import
-
-The patches for CVE-2015-2695 did not implement a SPNEGO
-gss_import_sec_context() function, under the erroneous belief than an
-exported SPNEGO context would be tagged with the underlying context
-mechanism.  Implement it now to allow SPNEGO contexts to be
-successfully exported and imported after establishment.
-
-ticket: 8273
-(cherry picked from commit fbb565f913c52eba9bea82f1694aba7a8c90e93d)
-
-Patch-Category: upstream
----
- src/lib/gssapi/spnego/spnego_mech.c | 33 +++++++++++++++++++++++++++------
- 1 file changed, 27 insertions(+), 6 deletions(-)
-
-diff --git a/src/lib/gssapi/spnego/spnego_mech.c b/src/lib/gssapi/spnego/spnego_mech.c
-index a1072b0..02284a1 100644
---- a/src/lib/gssapi/spnego/spnego_mech.c
-+++ b/src/lib/gssapi/spnego/spnego_mech.c
-@@ -2256,12 +2256,33 @@ spnego_gss_import_sec_context(
- 	const gss_buffer_t	interprocess_token,
- 	gss_ctx_id_t		*context_handle)
- {
--	/*
--	 * Until we implement partial context exports, there are no SPNEGO
--	 * exported context tokens, only tokens for underlying mechs.  So just
--	 * return an error for now.
--	 */
--	return GSS_S_UNAVAILABLE;
-+	OM_uint32 ret, tmpmin;
-+	gss_ctx_id_t mctx;
-+	spnego_gss_ctx_id_t sc;
-+	int initiate, opened;
-+
-+	ret = gss_import_sec_context(minor_status, interprocess_token, &mctx);
-+	if (ret != GSS_S_COMPLETE)
-+		return ret;
-+
-+	ret = gss_inquire_context(&tmpmin, mctx, NULL, NULL, NULL, NULL, NULL,
-+				  &initiate, &opened);
-+	if (ret != GSS_S_COMPLETE || !opened) {
-+		/* We don't currently support importing partially established
-+		 * contexts. */
-+		(void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER);
-+		return GSS_S_FAILURE;
-+	}
-+
-+	sc = create_spnego_ctx(initiate);
-+	if (sc == NULL) {
-+		(void) gss_delete_sec_context(&tmpmin, &mctx, GSS_C_NO_BUFFER);
-+		return GSS_S_FAILURE;
-+	}
-+	sc->ctx_handle = mctx;
-+	sc->opened = 1;
-+	*context_handle = (gss_ctx_id_t)sc;
-+	return GSS_S_COMPLETE;
- }
- #endif /* LEAN_CLIENT */
- 
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch
deleted file mode 100644
index 7b4b1d71ab..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2696.patch
+++ /dev/null
@@ -1,736 +0,0 @@
-Copied from Debian.
-
-From ebea85358bc72ec20c53130d83acb93f95853b76 Mon Sep 17 00:00:00 2001
-From: Nicolas Williams <nico@twosigma.com>
-Date: Mon, 14 Sep 2015 12:28:36 -0400
-Subject: Fix IAKERB context aliasing bugs [CVE-2015-2696]
-
-The IAKERB mechanism currently replaces its context handle with the
-krb5 mechanism handle upon establishment, under the assumption that
-most GSS functions are only called after context establishment.  This
-assumption is incorrect, and can lead to aliasing violations for some
-programs.  Maintain the IAKERB context structure after context
-establishment and add new IAKERB entry points to refer to it with that
-type.  Add initiate and established flags to the IAKERB context
-structure for use in gss_inquire_context() prior to context
-establishment.
-
-CVE-2015-2696:
-
-In MIT krb5 1.9 and later, applications which call
-gss_inquire_context() on a partially-established IAKERB context can
-cause the GSS-API library to read from a pointer using the wrong type,
-generally causing a process crash.  Java server applications using the
-native JGSS provider are vulnerable to this bug.  A carefully crafted
-IAKERB packet might allow the gss_inquire_context() call to succeed
-with attacker-determined results, but applications should not make
-access control decisions based on gss_inquire_context() results prior
-to context establishment.
-
-    CVSSv2 Vector: AV:N/AC:M/Au:N/C:N/I:N/A:C/E:POC/RL:OF/RC:C
-
-[ghudson@mit.edu: several bugfixes, style changes, and edge-case
-behavior changes; commit message and CVE description]
-
-ticket: 8244
-target_version: 1.14
-tags: pullup
-
-(cherry picked from commit e04f0283516e80d2f93366e0d479d13c9b5c8c2a)
-Patch-Category: upstream
----
- src/lib/gssapi/krb5/gssapiP_krb5.h | 114 ++++++++++++
- src/lib/gssapi/krb5/gssapi_krb5.c  | 105 +++++++++--
- src/lib/gssapi/krb5/iakerb.c       | 351 +++++++++++++++++++++++++++++++++----
- 3 files changed, 529 insertions(+), 41 deletions(-)
-
-diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
-index a0e8625..05dc321 100644
---- a/src/lib/gssapi/krb5/gssapiP_krb5.h
-+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
-@@ -620,6 +620,21 @@ OM_uint32 KRB5_CALLCONV krb5_gss_accept_sec_context_ext
- );
- #endif /* LEAN_CLIENT */
- 
-+OM_uint32 KRB5_CALLCONV krb5_gss_inquire_sec_context_by_oid
-+(OM_uint32*,       /* minor_status */
-+ const gss_ctx_id_t,
-+ /* context_handle */
-+ const gss_OID,    /* desired_object */
-+ gss_buffer_set_t* /* data_set */
-+);
-+
-+OM_uint32 KRB5_CALLCONV krb5_gss_set_sec_context_option
-+(OM_uint32*,       /* minor_status */
-+ gss_ctx_id_t*,    /* context_handle */
-+ const gss_OID,    /* desired_object */
-+ const gss_buffer_t/* value */
-+);
-+
- OM_uint32 KRB5_CALLCONV krb5_gss_process_context_token
- (OM_uint32*,       /* minor_status */
-  gss_ctx_id_t,     /* context_handle */
-@@ -1301,6 +1316,105 @@ OM_uint32 KRB5_CALLCONV
- krb5_gss_import_cred(OM_uint32 *minor_status, gss_buffer_t token,
-                      gss_cred_id_t *cred_handle);
- 
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_process_context_token(OM_uint32 *minor_status,
-+                                 const gss_ctx_id_t context_handle,
-+                                 const gss_buffer_t token_buffer);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                        OM_uint32 *time_rec);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_inquire_context(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, gss_name_t *src_name,
-+                           gss_name_t *targ_name, OM_uint32 *lifetime_rec,
-+                           gss_OID *mech_type, OM_uint32 *ctx_flags,
-+                           int *locally_initiated, int *opened);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                   gss_qop_t qop_req, gss_buffer_t message_buffer,
-+                   gss_buffer_t message_token);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                       gss_qop_t qop_req, gss_iov_buffer_desc *iov,
-+                       int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status,
-+                              gss_ctx_id_t context_handle, gss_qop_t qop_req,
-+                              gss_iov_buffer_desc *iov, int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                      gss_buffer_t msg_buffer, gss_buffer_t token_buffer,
-+                      gss_qop_t *qop_state);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                          gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
-+                          int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                int conf_req_flag, gss_qop_t qop_req,
-+                gss_buffer_t input_message_buffer, int *conf_state,
-+                gss_buffer_t output_message_buffer);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                    int conf_req_flag, gss_qop_t qop_req, int *conf_state,
-+                    gss_iov_buffer_desc *iov, int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_iov_length(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, int conf_req_flag,
-+                           gss_qop_t qop_req, int *conf_state,
-+                           gss_iov_buffer_desc *iov, int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                  gss_buffer_t input_message_buffer,
-+                  gss_buffer_t output_message_buffer, int *conf_state,
-+                  gss_qop_t *qop_state);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                      int *conf_state, gss_qop_t *qop_state,
-+                      gss_iov_buffer_desc *iov, int iov_count);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_size_limit(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, int conf_req_flag,
-+                           gss_qop_t qop_req, OM_uint32 req_output_size,
-+                           OM_uint32 *max_input_size);
-+
-+#ifndef LEAN_CLIENT
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_export_sec_context(OM_uint32 *minor_status,
-+                              gss_ctx_id_t *context_handle,
-+                              gss_buffer_t interprocess_token);
-+#endif /* LEAN_CLIENT */
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status,
-+                                      const gss_ctx_id_t context_handle,
-+                                      const gss_OID desired_object,
-+                                      gss_buffer_set_t *data_set);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_set_sec_context_option(OM_uint32 *minor_status,
-+                                  gss_ctx_id_t *context_handle,
-+                                  const gss_OID desired_object,
-+                                  const gss_buffer_t value);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                         int prf_key, const gss_buffer_t prf_in,
-+                         ssize_t desired_output_len, gss_buffer_t prf_out);
-+
- /* Magic string to identify exported krb5 GSS credentials.  Increment this if
-  * the format changes. */
- #define CRED_EXPORT_MAGIC "K5C1"
-diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
-index 77b7fff..9a23656 100644
---- a/src/lib/gssapi/krb5/gssapi_krb5.c
-+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
-@@ -345,7 +345,7 @@ static struct {
-     }
- };
- 
--static OM_uint32 KRB5_CALLCONV
-+OM_uint32 KRB5_CALLCONV
- krb5_gss_inquire_sec_context_by_oid (OM_uint32 *minor_status,
-                                      const gss_ctx_id_t context_handle,
-                                      const gss_OID desired_object,
-@@ -459,7 +459,7 @@ static struct {
- };
- #endif
- 
--static OM_uint32 KRB5_CALLCONV
-+OM_uint32 KRB5_CALLCONV
- krb5_gss_set_sec_context_option (OM_uint32 *minor_status,
-                                  gss_ctx_id_t *context_handle,
-                                  const gss_OID desired_object,
-@@ -904,20 +904,103 @@ static struct gss_config krb5_mechanism = {
-     krb5_gss_get_mic_iov_length,
- };
- 
-+/* Functions which use security contexts or acquire creds are IAKERB-specific;
-+ * other functions can borrow from the krb5 mech. */
-+static struct gss_config iakerb_mechanism = {
-+    { GSS_MECH_KRB5_OID_LENGTH, GSS_MECH_KRB5_OID },
-+    NULL,
-+    iakerb_gss_acquire_cred,
-+    krb5_gss_release_cred,
-+    iakerb_gss_init_sec_context,
-+#ifdef LEAN_CLIENT
-+    NULL,
-+#else
-+    iakerb_gss_accept_sec_context,
-+#endif
-+    iakerb_gss_process_context_token,
-+    iakerb_gss_delete_sec_context,
-+    iakerb_gss_context_time,
-+    iakerb_gss_get_mic,
-+    iakerb_gss_verify_mic,
-+#if defined(IOV_SHIM_EXERCISE_WRAP) || defined(IOV_SHIM_EXERCISE)
-+    NULL,
-+#else
-+    iakerb_gss_wrap,
-+#endif
-+#if defined(IOV_SHIM_EXERCISE_UNWRAP) || defined(IOV_SHIM_EXERCISE)
-+    NULL,
-+#else
-+    iakerb_gss_unwrap,
-+#endif
-+    krb5_gss_display_status,
-+    krb5_gss_indicate_mechs,
-+    krb5_gss_compare_name,
-+    krb5_gss_display_name,
-+    krb5_gss_import_name,
-+    krb5_gss_release_name,
-+    krb5_gss_inquire_cred,
-+    NULL,                /* add_cred */
-+#ifdef LEAN_CLIENT
-+    NULL,
-+    NULL,
-+#else
-+    iakerb_gss_export_sec_context,
-+    NULL,
-+#endif
-+    krb5_gss_inquire_cred_by_mech,
-+    krb5_gss_inquire_names_for_mech,
-+    iakerb_gss_inquire_context,
-+    krb5_gss_internal_release_oid,
-+    iakerb_gss_wrap_size_limit,
-+    krb5_gss_localname,
-+    krb5_gss_authorize_localname,
-+    krb5_gss_export_name,
-+    krb5_gss_duplicate_name,
-+    krb5_gss_store_cred,
-+    iakerb_gss_inquire_sec_context_by_oid,
-+    krb5_gss_inquire_cred_by_oid,
-+    iakerb_gss_set_sec_context_option,
-+    krb5_gssspi_set_cred_option,
-+    krb5_gssspi_mech_invoke,
-+    NULL,                /* wrap_aead */
-+    NULL,                /* unwrap_aead */
-+    iakerb_gss_wrap_iov,
-+    iakerb_gss_unwrap_iov,
-+    iakerb_gss_wrap_iov_length,
-+    NULL,               /* complete_auth_token */
-+    NULL,               /* acquire_cred_impersonate_name */
-+    NULL,               /* add_cred_impersonate_name */
-+    NULL,               /* display_name_ext */
-+    krb5_gss_inquire_name,
-+    krb5_gss_get_name_attribute,
-+    krb5_gss_set_name_attribute,
-+    krb5_gss_delete_name_attribute,
-+    krb5_gss_export_name_composite,
-+    krb5_gss_map_name_to_any,
-+    krb5_gss_release_any_name_mapping,
-+    iakerb_gss_pseudo_random,
-+    NULL,               /* set_neg_mechs */
-+    krb5_gss_inquire_saslname_for_mech,
-+    krb5_gss_inquire_mech_for_saslname,
-+    krb5_gss_inquire_attrs_for_mech,
-+    krb5_gss_acquire_cred_from,
-+    krb5_gss_store_cred_into,
-+    iakerb_gss_acquire_cred_with_password,
-+    krb5_gss_export_cred,
-+    krb5_gss_import_cred,
-+    NULL,               /* import_sec_context_by_mech */
-+    NULL,               /* import_name_by_mech */
-+    NULL,               /* import_cred_by_mech */
-+    iakerb_gss_get_mic_iov,
-+    iakerb_gss_verify_mic_iov,
-+    iakerb_gss_get_mic_iov_length,
-+};
-+
- #ifdef _GSS_STATIC_LINK
- #include "mglueP.h"
- static int gss_iakerbmechglue_init(void)
- {
-     struct gss_mech_config mech_iakerb;
--    struct gss_config iakerb_mechanism = krb5_mechanism;
--
--    /* IAKERB mechanism mirrors krb5, but with different context SPIs */
--    iakerb_mechanism.gss_accept_sec_context = iakerb_gss_accept_sec_context;
--    iakerb_mechanism.gss_init_sec_context   = iakerb_gss_init_sec_context;
--    iakerb_mechanism.gss_delete_sec_context = iakerb_gss_delete_sec_context;
--    iakerb_mechanism.gss_acquire_cred       = iakerb_gss_acquire_cred;
--    iakerb_mechanism.gssspi_acquire_cred_with_password
--                                    = iakerb_gss_acquire_cred_with_password;
- 
-     memset(&mech_iakerb, 0, sizeof(mech_iakerb));
-     mech_iakerb.mech = &iakerb_mechanism;
-diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
-index f30de32..4662bd9 100644
---- a/src/lib/gssapi/krb5/iakerb.c
-+++ b/src/lib/gssapi/krb5/iakerb.c
-@@ -47,6 +47,8 @@ struct _iakerb_ctx_id_rec {
-     gss_ctx_id_t gssc;
-     krb5_data conv;                     /* conversation for checksumming */
-     unsigned int count;                 /* number of round trips */
-+    int initiate;
-+    int established;
-     krb5_get_init_creds_opt *gic_opts;
- };
- 
-@@ -695,7 +697,7 @@ cleanup:
-  * Allocate and initialise an IAKERB context
-  */
- static krb5_error_code
--iakerb_alloc_context(iakerb_ctx_id_t *pctx)
-+iakerb_alloc_context(iakerb_ctx_id_t *pctx, int initiate)
- {
-     iakerb_ctx_id_t ctx;
-     krb5_error_code code;
-@@ -709,6 +711,8 @@ iakerb_alloc_context(iakerb_ctx_id_t *pctx)
-     ctx->magic = KG_IAKERB_CONTEXT;
-     ctx->state = IAKERB_AS_REQ;
-     ctx->count = 0;
-+    ctx->initiate = initiate;
-+    ctx->established = 0;
- 
-     code = krb5_gss_init_context(&ctx->k5c);
-     if (code != 0)
-@@ -732,7 +736,7 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status,
-                               gss_ctx_id_t *context_handle,
-                               gss_buffer_t output_token)
- {
--    OM_uint32 major_status = GSS_S_COMPLETE;
-+    iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle;
- 
-     if (output_token != GSS_C_NO_BUFFER) {
-         output_token->length = 0;
-@@ -740,23 +744,10 @@ iakerb_gss_delete_sec_context(OM_uint32 *minor_status,
-     }
- 
-     *minor_status = 0;
-+    *context_handle = GSS_C_NO_CONTEXT;
-+    iakerb_release_context(iakerb_ctx);
- 
--    if (*context_handle != GSS_C_NO_CONTEXT) {
--        iakerb_ctx_id_t iakerb_ctx = (iakerb_ctx_id_t)*context_handle;
--
--        if (iakerb_ctx->magic == KG_IAKERB_CONTEXT) {
--            iakerb_release_context(iakerb_ctx);
--            *context_handle = GSS_C_NO_CONTEXT;
--        } else {
--            assert(iakerb_ctx->magic == KG_CONTEXT);
--
--            major_status = krb5_gss_delete_sec_context(minor_status,
--                                                       context_handle,
--                                                       output_token);
--        }
--    }
--
--    return major_status;
-+    return GSS_S_COMPLETE;
- }
- 
- static krb5_boolean
-@@ -802,7 +793,7 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status,
-     int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT);
- 
-     if (initialContextToken) {
--        code = iakerb_alloc_context(&ctx);
-+        code = iakerb_alloc_context(&ctx, 0);
-         if (code != 0)
-             goto cleanup;
- 
-@@ -854,11 +845,8 @@ iakerb_gss_accept_sec_context(OM_uint32 *minor_status,
-                                                        time_rec,
-                                                        delegated_cred_handle,
-                                                        &exts);
--        if (major_status == GSS_S_COMPLETE) {
--            *context_handle = ctx->gssc;
--            ctx->gssc = NULL;
--            iakerb_release_context(ctx);
--        }
-+        if (major_status == GSS_S_COMPLETE)
-+            ctx->established = 1;
-         if (mech_type != NULL)
-             *mech_type = (gss_OID)gss_mech_krb5;
-     }
-@@ -897,7 +885,7 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
-     int initialContextToken = (*context_handle == GSS_C_NO_CONTEXT);
- 
-     if (initialContextToken) {
--        code = iakerb_alloc_context(&ctx);
-+        code = iakerb_alloc_context(&ctx, 1);
-         if (code != 0) {
-             *minor_status = code;
-             goto cleanup;
-@@ -983,11 +971,8 @@ iakerb_gss_init_sec_context(OM_uint32 *minor_status,
-                                                      ret_flags,
-                                                      time_rec,
-                                                      &exts);
--        if (major_status == GSS_S_COMPLETE) {
--            *context_handle = ctx->gssc;
--            ctx->gssc = GSS_C_NO_CONTEXT;
--            iakerb_release_context(ctx);
--        }
-+        if (major_status == GSS_S_COMPLETE)
-+            ctx->established = 1;
-         if (actual_mech_type != NULL)
-             *actual_mech_type = (gss_OID)gss_mech_krb5;
-     } else {
-@@ -1010,3 +995,309 @@ cleanup:
- 
-     return major_status;
- }
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_unwrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                  gss_buffer_t input_message_buffer,
-+                  gss_buffer_t output_message_buffer, int *conf_state,
-+                  gss_qop_t *qop_state)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_unwrap(minor_status, ctx->gssc, input_message_buffer,
-+                           output_message_buffer, conf_state, qop_state);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                int conf_req_flag, gss_qop_t qop_req,
-+                gss_buffer_t input_message_buffer, int *conf_state,
-+                gss_buffer_t output_message_buffer)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_wrap(minor_status, ctx->gssc, conf_req_flag, qop_req,
-+                         input_message_buffer, conf_state,
-+                         output_message_buffer);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_process_context_token(OM_uint32 *minor_status,
-+                                 const gss_ctx_id_t context_handle,
-+                                 const gss_buffer_t token_buffer)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_DEFECTIVE_TOKEN;
-+
-+    return krb5_gss_process_context_token(minor_status, ctx->gssc,
-+                                          token_buffer);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_context_time(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                        OM_uint32 *time_rec)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_context_time(minor_status, ctx->gssc, time_rec);
-+}
-+
-+#ifndef LEAN_CLIENT
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_export_sec_context(OM_uint32 *minor_status,
-+                              gss_ctx_id_t *context_handle,
-+                              gss_buffer_t interprocess_token)
-+{
-+    OM_uint32 maj;
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    /* We don't currently support exporting partially established contexts. */
-+    if (!ctx->established)
-+        return GSS_S_UNAVAILABLE;
-+
-+    maj = krb5_gss_export_sec_context(minor_status, &ctx->gssc,
-+                                      interprocess_token);
-+    if (ctx->gssc == GSS_C_NO_CONTEXT) {
-+        iakerb_release_context(ctx);
-+        *context_handle = GSS_C_NO_CONTEXT;
-+    }
-+    return maj;
-+}
-+
-+/*
-+ * Until we implement partial context exports, there are no SPNEGO exported
-+ * context tokens, only tokens for the underlying krb5 context.  So we do not
-+ * need to implement an iakerb_gss_import_sec_context() yet; it would be
-+ * unreachable except via a manually constructed token.
-+ */
-+
-+#endif /* LEAN_CLIENT */
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_inquire_context(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, gss_name_t *src_name,
-+                           gss_name_t *targ_name, OM_uint32 *lifetime_rec,
-+                           gss_OID *mech_type, OM_uint32 *ctx_flags,
-+                           int *initiate, int *opened)
-+{
-+    OM_uint32 ret;
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (src_name != NULL)
-+        *src_name = GSS_C_NO_NAME;
-+    if (targ_name != NULL)
-+        *targ_name = GSS_C_NO_NAME;
-+    if (lifetime_rec != NULL)
-+        *lifetime_rec = 0;
-+    if (mech_type != NULL)
-+        *mech_type = (gss_OID)gss_mech_iakerb;
-+    if (ctx_flags != NULL)
-+        *ctx_flags = 0;
-+    if (initiate != NULL)
-+        *initiate = ctx->initiate;
-+    if (opened != NULL)
-+        *opened = ctx->established;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_COMPLETE;
-+
-+    ret = krb5_gss_inquire_context(minor_status, ctx->gssc, src_name,
-+                                   targ_name, lifetime_rec, mech_type,
-+                                   ctx_flags, initiate, opened);
-+
-+    if (!ctx->established) {
-+        /* Report IAKERB as the mech OID until the context is established. */
-+        if (mech_type != NULL)
-+            *mech_type = (gss_OID)gss_mech_iakerb;
-+
-+        /* We don't support exporting partially-established contexts. */
-+        if (ctx_flags != NULL)
-+            *ctx_flags &= ~GSS_C_TRANS_FLAG;
-+    }
-+
-+    return ret;
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_size_limit(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, int conf_req_flag,
-+                           gss_qop_t qop_req, OM_uint32 req_output_size,
-+                           OM_uint32 *max_input_size)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_wrap_size_limit(minor_status, ctx->gssc, conf_req_flag,
-+                                    qop_req, req_output_size, max_input_size);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                   gss_qop_t qop_req, gss_buffer_t message_buffer,
-+                   gss_buffer_t message_token)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_get_mic(minor_status, ctx->gssc, qop_req, message_buffer,
-+                            message_token);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_verify_mic(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                      gss_buffer_t msg_buffer, gss_buffer_t token_buffer,
-+                      gss_qop_t *qop_state)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_verify_mic(minor_status, ctx->gssc, msg_buffer,
-+                               token_buffer, qop_state);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_inquire_sec_context_by_oid(OM_uint32 *minor_status,
-+                                      const gss_ctx_id_t context_handle,
-+                                      const gss_OID desired_object,
-+                                      gss_buffer_set_t *data_set)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_UNAVAILABLE;
-+
-+    return krb5_gss_inquire_sec_context_by_oid(minor_status, ctx->gssc,
-+                                               desired_object, data_set);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_set_sec_context_option(OM_uint32 *minor_status,
-+                                  gss_ctx_id_t *context_handle,
-+                                  const gss_OID desired_object,
-+                                  const gss_buffer_t value)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle;
-+
-+    if (ctx == NULL || ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_UNAVAILABLE;
-+
-+    return krb5_gss_set_sec_context_option(minor_status, &ctx->gssc,
-+                                           desired_object, value);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                    int conf_req_flag, gss_qop_t qop_req, int *conf_state,
-+                    gss_iov_buffer_desc *iov, int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_wrap_iov(minor_status, ctx->gssc, conf_req_flag, qop_req,
-+                             conf_state, iov, iov_count);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_unwrap_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                      int *conf_state, gss_qop_t *qop_state,
-+                      gss_iov_buffer_desc *iov, int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_unwrap_iov(minor_status, ctx->gssc, conf_state, qop_state,
-+                               iov, iov_count);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_wrap_iov_length(OM_uint32 *minor_status,
-+                           gss_ctx_id_t context_handle, int conf_req_flag,
-+                           gss_qop_t qop_req, int *conf_state,
-+                           gss_iov_buffer_desc *iov, int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_wrap_iov_length(minor_status, ctx->gssc, conf_req_flag,
-+                                    qop_req, conf_state, iov, iov_count);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_pseudo_random(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                         int prf_key, const gss_buffer_t prf_in,
-+                         ssize_t desired_output_len, gss_buffer_t prf_out)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_pseudo_random(minor_status, ctx->gssc, prf_key, prf_in,
-+                                  desired_output_len, prf_out);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                       gss_qop_t qop_req, gss_iov_buffer_desc *iov,
-+                       int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_get_mic_iov(minor_status, ctx->gssc, qop_req, iov,
-+                                iov_count);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_verify_mic_iov(OM_uint32 *minor_status, gss_ctx_id_t context_handle,
-+                          gss_qop_t *qop_state, gss_iov_buffer_desc *iov,
-+                          int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_verify_mic_iov(minor_status, ctx->gssc, qop_state, iov,
-+                                   iov_count);
-+}
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_get_mic_iov_length(OM_uint32 *minor_status,
-+                              gss_ctx_id_t context_handle, gss_qop_t qop_req,
-+                              gss_iov_buffer_desc *iov, int iov_count)
-+{
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+
-+    if (ctx->gssc == GSS_C_NO_CONTEXT)
-+        return GSS_S_NO_CONTEXT;
-+
-+    return krb5_gss_get_mic_iov_length(minor_status, ctx->gssc, qop_req, iov,
-+                                       iov_count);
-+}
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch
deleted file mode 100644
index f65ce39623..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2697.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-Copied from Debian.
-
-From fcafb522a0509bfd6f4f6b57e4a1e93c0092eeb0 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Fri, 25 Sep 2015 12:51:47 -0400
-Subject: Fix build_principal memory bug [CVE-2015-2697]
-
-In build_principal_va(), use k5memdup0() instead of strdup() to make a
-copy of the realm, to ensure that we allocate the correct number of
-bytes and do not read past the end of the input string.  This bug
-affects krb5_build_principal(), krb5_build_principal_va(), and
-krb5_build_principal_alloc_va().  krb5_build_principal_ext() is not
-affected.
-
-CVE-2015-2697:
-
-In MIT krb5 1.7 and later, an authenticated attacker may be able to
-cause a KDC to crash using a TGS request with a large realm field
-beginning with a null byte.  If the KDC attempts to find a referral to
-answer the request, it constructs a principal name for lookup using
-krb5_build_principal() with the requested realm.  Due to a bug in this
-function, the null byte causes only one byte be allocated for the
-realm field of the constructed principal, far less than its length.
-Subsequent operations on the lookup principal may cause a read beyond
-the end of the mapped memory region, causing the KDC process to crash.
-
-CVSSv2: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C
-
-ticket: 8252 (new)
-target_version: 1.14
-tags: pullup
-
-(cherry picked from commit f0c094a1b745d91ef2f9a4eae2149aac026a5789)
-Patch-Category: upstream
----
- src/lib/krb5/krb/bld_princ.c | 6 ++----
- 1 file changed, 2 insertions(+), 4 deletions(-)
-
-diff --git a/src/lib/krb5/krb/bld_princ.c b/src/lib/krb5/krb/bld_princ.c
-index ab6fed8..8604268 100644
---- a/src/lib/krb5/krb/bld_princ.c
-+++ b/src/lib/krb5/krb/bld_princ.c
-@@ -40,10 +40,8 @@ build_principal_va(krb5_context context, krb5_principal princ,
-     data = malloc(size * sizeof(krb5_data));
-     if (!data) { retval = ENOMEM; }
- 
--    if (!retval) {
--        r = strdup(realm);
--        if (!r) { retval = ENOMEM; }
--    }
-+    if (!retval)
-+        r = k5memdup0(realm, rlen, &retval);
- 
-     while (!retval && (component = va_arg(ap, char *))) {
-         if (count == size) {
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch
deleted file mode 100644
index 67545e4c16..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt1.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-Copied from Debian.
-
-From 1a8bdc6d81dcd7dd8a4d42e8de6d2cacf1dd4408 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Tue, 27 Oct 2015 00:44:24 -0400
-Subject: Fix two IAKERB comments
-
-The comment explaining why there is no iakerb_gss_import_sec_context()
-erroneously referenced SPNEGO instead of IAKERB (noticed by Ben
-Kaduk).  The comment above iakerb_gss_delete_sec_context() is out of
-date after the last commit.
-
-(cherry picked from commit 92d6dd045dfc06cc03d20b327a6ee7a71e6bc24d)
-
-Patch-Category: upstream
----
- src/lib/gssapi/krb5/iakerb.c | 6 +-----
- 1 file changed, 1 insertion(+), 5 deletions(-)
-
-diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
-index 4662bd9..e25862d 100644
---- a/src/lib/gssapi/krb5/iakerb.c
-+++ b/src/lib/gssapi/krb5/iakerb.c
-@@ -727,10 +727,6 @@ cleanup:
-     return code;
- }
- 
--/*
-- * Delete an IAKERB context. This can also accept Kerberos context
-- * handles. The heuristic is similar to SPNEGO's delete_sec_context.
-- */
- OM_uint32 KRB5_CALLCONV
- iakerb_gss_delete_sec_context(OM_uint32 *minor_status,
-                               gss_ctx_id_t *context_handle,
-@@ -1077,7 +1073,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status,
- }
- 
- /*
-- * Until we implement partial context exports, there are no SPNEGO exported
-+ * Until we implement partial context exports, there are no IAKERB exported
-  * context tokens, only tokens for the underlying krb5 context.  So we do not
-  * need to implement an iakerb_gss_import_sec_context() yet; it would be
-  * unreachable except via a manually constructed token.
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch b/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch
deleted file mode 100644
index 8725cd4eed..0000000000
--- a/gnu/packages/patches/mit-krb5-CVE-2015-2698-pt2.patch
+++ /dev/null
@@ -1,132 +0,0 @@
-Copied from Debian.
-
-From 4b330d5be1f8048be4d079ac3cb38d60c0e99e69 Mon Sep 17 00:00:00 2001
-From: Greg Hudson <ghudson@mit.edu>
-Date: Wed, 4 Nov 2015 21:28:28 -0500
-Subject: Fix IAKERB context export/import [CVE-2015-2698]
-
-The patches for CVE-2015-2696 contained a regression in the newly
-added IAKERB iakerb_gss_export_sec_context() function, which could
-cause it to corrupt memory.  Fix the regression by properly
-dereferencing the context_handle pointer before casting it.
-
-Also, the patches did not implement an IAKERB gss_import_sec_context()
-function, under the erroneous belief than an exported IAKERB context
-would be tagged as a krb5 context.  Implement it now to allow IAKERB
-contexts to be successfully exported and imported after establishment.
-
-CVE-2015-2698:
-
-In any MIT krb5 release with the patches for CVE-2015-2696 applied, an
-application which calls gss_export_sec_context() may experience memory
-corruption if the context was established using the IAKERB mechanism.
-Historically, some vulnerabilities of this nature can be translated
-into remote code execution, though the necessary exploits must be
-tailored to the individual application and are usually quite
-complicated.
-
-    CVSSv2 Vector: AV:N/AC:H/Au:S/C:C/I:C/A:C/E:POC/RL:OF/RC:C
-
-ticket: 8273 (new)
-target_version: 1.14
-tags: pullup
-
-(cherry picked from commit d8b31c874c7d1039be7649362ef11c89f4e14c27)
-
-Patch-Category: upstream
----
- src/lib/gssapi/krb5/gssapiP_krb5.h |  5 +++++
- src/lib/gssapi/krb5/gssapi_krb5.c  |  2 +-
- src/lib/gssapi/krb5/iakerb.c       | 42 +++++++++++++++++++++++++++++++-------
- 3 files changed, 41 insertions(+), 8 deletions(-)
-
-diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
-index 05dc321..ac53662 100644
---- a/src/lib/gssapi/krb5/gssapiP_krb5.h
-+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
-@@ -1396,6 +1396,11 @@ OM_uint32 KRB5_CALLCONV
- iakerb_gss_export_sec_context(OM_uint32 *minor_status,
-                               gss_ctx_id_t *context_handle,
-                               gss_buffer_t interprocess_token);
-+
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_import_sec_context(OM_uint32 *minor_status,
-+                              const gss_buffer_t interprocess_token,
-+                              gss_ctx_id_t *context_handle);
- #endif /* LEAN_CLIENT */
- 
- OM_uint32 KRB5_CALLCONV
-diff --git a/src/lib/gssapi/krb5/gssapi_krb5.c b/src/lib/gssapi/krb5/gssapi_krb5.c
-index 9a23656..d7ba279 100644
---- a/src/lib/gssapi/krb5/gssapi_krb5.c
-+++ b/src/lib/gssapi/krb5/gssapi_krb5.c
-@@ -945,7 +945,7 @@ static struct gss_config iakerb_mechanism = {
-     NULL,
- #else
-     iakerb_gss_export_sec_context,
--    NULL,
-+    iakerb_gss_import_sec_context,
- #endif
-     krb5_gss_inquire_cred_by_mech,
-     krb5_gss_inquire_names_for_mech,
-diff --git a/src/lib/gssapi/krb5/iakerb.c b/src/lib/gssapi/krb5/iakerb.c
-index e25862d..32a341e 100644
---- a/src/lib/gssapi/krb5/iakerb.c
-+++ b/src/lib/gssapi/krb5/iakerb.c
-@@ -1057,7 +1057,7 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status,
-                               gss_buffer_t interprocess_token)
- {
-     OM_uint32 maj;
--    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)context_handle;
-+    iakerb_ctx_id_t ctx = (iakerb_ctx_id_t)*context_handle;
- 
-     /* We don't currently support exporting partially established contexts. */
-     if (!ctx->established)
-@@ -1072,13 +1072,41 @@ iakerb_gss_export_sec_context(OM_uint32 *minor_status,
-     return maj;
- }
- 
--/*
-- * Until we implement partial context exports, there are no IAKERB exported
-- * context tokens, only tokens for the underlying krb5 context.  So we do not
-- * need to implement an iakerb_gss_import_sec_context() yet; it would be
-- * unreachable except via a manually constructed token.
-- */
-+OM_uint32 KRB5_CALLCONV
-+iakerb_gss_import_sec_context(OM_uint32 *minor_status,
-+                              gss_buffer_t interprocess_token,
-+                              gss_ctx_id_t *context_handle)
-+{
-+    OM_uint32 maj, tmpmin;
-+    krb5_error_code code;
-+    gss_ctx_id_t gssc;
-+    krb5_gss_ctx_id_t kctx;
-+    iakerb_ctx_id_t ctx;
-+
-+    maj = krb5_gss_import_sec_context(minor_status, interprocess_token, &gssc);
-+    if (maj != GSS_S_COMPLETE)
-+        return maj;
-+    kctx = (krb5_gss_ctx_id_t)gssc;
-+
-+    if (!kctx->established) {
-+        /* We don't currently support importing partially established
-+         * contexts. */
-+        krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER);
-+        return GSS_S_FAILURE;
-+    }
- 
-+    code = iakerb_alloc_context(&ctx, kctx->initiate);
-+    if (code != 0) {
-+        krb5_gss_delete_sec_context(&tmpmin, &gssc, GSS_C_NO_BUFFER);
-+        *minor_status = code;
-+        return GSS_S_FAILURE;
-+    }
-+
-+    ctx->gssc = gssc;
-+    ctx->established = 1;
-+    *context_handle = (gss_ctx_id_t)ctx;
-+    return GSS_S_COMPLETE;
-+}
- #endif /* LEAN_CLIENT */
- 
- OM_uint32 KRB5_CALLCONV
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch
new file mode 100644
index 0000000000..a296d8cb1b
--- /dev/null
+++ b/gnu/packages/patches/mit-krb5-CVE-2015-8629.patch
@@ -0,0 +1,51 @@
+Copied from Fedora.
+http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8629.patch?h=f22
+
+From df17a1224a3406f57477bcd372c61e04c0e5a5bb Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Fri, 8 Jan 2016 12:45:25 -0500
+Subject: [PATCH 1/3] Verify decoded kadmin C strings [CVE-2015-8629]
+
+In xdr_nullstring(), check that the decoded string is terminated with
+a zero byte and does not contain any internal zero bytes.
+
+CVE-2015-8629:
+
+In all versions of MIT krb5, an authenticated attacker can cause
+kadmind to read beyond the end of allocated memory by sending a string
+without a terminating zero byte.  Information leakage may be possible
+for an attacker with permission to modify the database.
+
+    CVSSv2 Vector: AV:N/AC:H/Au:S/C:P/I:N/A:N/E:POC/RL:OF/RC:C
+
+ticket: 8341 (new)
+target_version: 1.14-next
+target_version: 1.13-next
+tags: pullup
+---
+ src/lib/kadm5/kadm_rpc_xdr.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
+index 2bef858..ba67084 100644
+--- a/src/lib/kadm5/kadm_rpc_xdr.c
++++ b/src/lib/kadm5/kadm_rpc_xdr.c
+@@ -64,7 +64,14 @@ bool_t xdr_nullstring(XDR *xdrs, char **objp)
+ 		    return FALSE;
+ 	       }
+ 	  }
+-	  return (xdr_opaque(xdrs, *objp, size));
++	  if (!xdr_opaque(xdrs, *objp, size))
++		  return FALSE;
++	  /* Check that the unmarshalled bytes are a C string. */
++	  if ((*objp)[size - 1] != '\0')
++		  return FALSE;
++	  if (memchr(*objp, '\0', size - 1) != NULL)
++		  return FALSE;
++	  return TRUE;
+ 
+      case XDR_ENCODE:
+ 	  if (size != 0)
+-- 
+2.7.0.rc3
+
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch
new file mode 100644
index 0000000000..c21d84b1e7
--- /dev/null
+++ b/gnu/packages/patches/mit-krb5-CVE-2015-8630.patch
@@ -0,0 +1,81 @@
+Copied from Fedora.
+http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8630.patch?h=f22
+
+From b863de7fbf080b15e347a736fdda0a82d42f4f6b Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Fri, 8 Jan 2016 12:52:28 -0500
+Subject: [PATCH 2/3] Check for null kadm5 policy name [CVE-2015-8630]
+
+In kadm5_create_principal_3() and kadm5_modify_principal(), check for
+entry->policy being null when KADM5_POLICY is included in the mask.
+
+CVE-2015-8630:
+
+In MIT krb5 1.12 and later, an authenticated attacker with permission
+to modify a principal entry can cause kadmind to dereference a null
+pointer by supplying a null policy value but including KADM5_POLICY in
+the mask.
+
+    CVSSv2 Vector: AV:N/AC:H/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C
+
+ticket: 8342 (new)
+target_version: 1.14-next
+target_version: 1.13-next
+tags: pullup
+---
+ src/lib/kadm5/srv/svr_principal.c | 12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c
+index 5b95fa3..1d4365c 100644
+--- a/src/lib/kadm5/srv/svr_principal.c
++++ b/src/lib/kadm5/srv/svr_principal.c
+@@ -395,6 +395,8 @@ kadm5_create_principal_3(void *server_handle,
+     /*
+      * Argument sanity checking, and opening up the DB
+      */
++    if (entry == NULL)
++        return EINVAL;
+     if(!(mask & KADM5_PRINCIPAL) || (mask & KADM5_MOD_NAME) ||
+        (mask & KADM5_MOD_TIME) || (mask & KADM5_LAST_PWD_CHANGE) ||
+        (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
+@@ -403,12 +405,12 @@ kadm5_create_principal_3(void *server_handle,
+         return KADM5_BAD_MASK;
+     if ((mask & KADM5_KEY_DATA) && entry->n_key_data != 0)
+         return KADM5_BAD_MASK;
++    if((mask & KADM5_POLICY) && entry->policy == NULL)
++        return KADM5_BAD_MASK;
+     if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR))
+         return KADM5_BAD_MASK;
+     if((mask & ~ALL_PRINC_MASK))
+         return KADM5_BAD_MASK;
+-    if (entry == NULL)
+-        return EINVAL;
+ 
+     /*
+      * Check to see if the principal exists
+@@ -643,6 +645,8 @@ kadm5_modify_principal(void *server_handle,
+ 
+     krb5_clear_error_message(handle->context);
+ 
++    if(entry == NULL)
++        return EINVAL;
+     if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) ||
+        (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) ||
+        (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) ||
+@@ -651,10 +655,10 @@ kadm5_modify_principal(void *server_handle,
+         return KADM5_BAD_MASK;
+     if((mask & ~ALL_PRINC_MASK))
+         return KADM5_BAD_MASK;
++    if((mask & KADM5_POLICY) && entry->policy == NULL)
++        return KADM5_BAD_MASK;
+     if((mask & KADM5_POLICY) && (mask & KADM5_POLICY_CLR))
+         return KADM5_BAD_MASK;
+-    if(entry == (kadm5_principal_ent_t) NULL)
+-        return EINVAL;
+     if (mask & KADM5_TL_DATA) {
+         tl_data_orig = entry->tl_data;
+         while (tl_data_orig) {
+-- 
+2.7.0.rc3
+
diff --git a/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch b/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch
new file mode 100644
index 0000000000..dd1eb2945c
--- /dev/null
+++ b/gnu/packages/patches/mit-krb5-CVE-2015-8631.patch
@@ -0,0 +1,576 @@
+Copied from Fedora.
+http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-CVE-2015-8631.patch?h=f22
+
+From 83ed75feba32e46f736fcce0d96a0445f29b96c2 Mon Sep 17 00:00:00 2001
+From: Greg Hudson <ghudson@mit.edu>
+Date: Fri, 8 Jan 2016 13:16:54 -0500
+Subject: [PATCH 3/3] Fix leaks in kadmin server stubs [CVE-2015-8631]
+
+In each kadmind server stub, initialize the client_name and
+server_name variables, and release them in the cleanup handler.  Many
+of the stubs will otherwise leak the client and server name if
+krb5_unparse_name() fails.  Also make sure to free the prime_arg
+variables in rename_principal_2_svc(), or we can leak the first one if
+unparsing the second one fails.  Discovered by Simo Sorce.
+
+CVE-2015-8631:
+
+In all versions of MIT krb5, an authenticated attacker can cause
+kadmind to leak memory by supplying a null principal name in a request
+which uses one.  Repeating these requests will eventually cause
+kadmind to exhaust all available memory.
+
+    CVSSv2 Vector: AV:N/AC:L/Au:S/C:N/I:N/A:C/E:POC/RL:OF/RC:C
+
+ticket: 8343 (new)
+target_version: 1.14-next
+target_version: 1.13-next
+tags: pullup
+---
+ src/kadmin/server/server_stubs.c | 151 ++++++++++++++++++++-------------------
+ 1 file changed, 77 insertions(+), 74 deletions(-)
+
+diff --git a/src/kadmin/server/server_stubs.c b/src/kadmin/server/server_stubs.c
+index 1879dc6..6ac797e 100644
+--- a/src/kadmin/server/server_stubs.c
++++ b/src/kadmin/server/server_stubs.c
+@@ -334,7 +334,8 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret          ret;
+     char                        *prime_arg;
+-    gss_buffer_desc             client_name, service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+     restriction_t               *rp;
+@@ -382,10 +383,10 @@ create_principal_2_svc(cprinc_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
+-    gss_release_buffer(&minor_stat, &client_name);
+-    gss_release_buffer(&minor_stat, &service_name);
+ 
+ exit_func:
++    gss_release_buffer(&minor_stat, &client_name);
++    gss_release_buffer(&minor_stat, &service_name);
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -395,7 +396,8 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret          ret;
+     char                        *prime_arg;
+-    gss_buffer_desc             client_name, service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+     restriction_t               *rp;
+@@ -444,10 +446,10 @@ create_principal3_2_svc(cprinc3_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
+-    gss_release_buffer(&minor_stat, &client_name);
+-    gss_release_buffer(&minor_stat, &service_name);
+ 
+ exit_func:
++    gss_release_buffer(&minor_stat, &client_name);
++    gss_release_buffer(&minor_stat, &service_name);
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -457,8 +459,8 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -501,10 +503,10 @@ delete_principal_2_svc(dprinc_arg *arg, struct svc_req *rqstp)
+ 
+     }
+     free(prime_arg);
+-    gss_release_buffer(&minor_stat, &client_name);
+-    gss_release_buffer(&minor_stat, &service_name);
+ 
+ exit_func:
++    gss_release_buffer(&minor_stat, &client_name);
++    gss_release_buffer(&minor_stat, &service_name);
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -514,8 +516,8 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     restriction_t                   *rp;
+@@ -559,9 +561,9 @@ modify_principal_2_svc(mprinc_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -570,10 +572,9 @@ generic_ret *
+ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret          ret;
+-    char                        *prime_arg1,
+-        *prime_arg2;
+-    gss_buffer_desc             client_name,
+-        service_name;
++    char                        *prime_arg1 = NULL, *prime_arg2 = NULL;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+     restriction_t               *rp;
+@@ -655,11 +656,11 @@ rename_principal_2_svc(rprinc_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+ 
+     }
++exit_func:
+     free(prime_arg1);
+     free(prime_arg2);
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -669,8 +670,8 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
+ {
+     static gprinc_ret               ret;
+     char                            *prime_arg, *funcname;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -719,9 +720,9 @@ get_principal_2_svc(gprinc_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -731,8 +732,8 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
+ {
+     static gprincs_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -777,9 +778,9 @@ get_princs_2_svc(gprincs_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+ 
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -789,8 +790,8 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -840,9 +841,9 @@ chpass_principal_2_svc(chpass_arg *arg, struct svc_req *rqstp)
+     }
+ 
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -852,8 +853,8 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -909,9 +910,9 @@ chpass_principal3_2_svc(chpass3_arg *arg, struct svc_req *rqstp)
+     }
+ 
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -921,8 +922,8 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -969,9 +970,9 @@ setv4key_principal_2_svc(setv4key_arg *arg, struct svc_req *rqstp)
+     }
+ 
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -981,8 +982,8 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1029,9 +1030,9 @@ setkey_principal_2_svc(setkey_arg *arg, struct svc_req *rqstp)
+     }
+ 
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1041,8 +1042,8 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1092,9 +1093,9 @@ setkey_principal3_2_svc(setkey3_arg *arg, struct svc_req *rqstp)
+     }
+ 
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1106,8 +1107,8 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
+     krb5_keyblock               *k;
+     int                         nkeys;
+     char                        *prime_arg, *funcname;
+-    gss_buffer_desc             client_name,
+-        service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+     const char                  *errmsg = NULL;
+@@ -1164,9 +1165,9 @@ chrand_principal_2_svc(chrand_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1178,8 +1179,8 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
+     krb5_keyblock               *k;
+     int                         nkeys;
+     char                        *prime_arg, *funcname;
+-    gss_buffer_desc             client_name,
+-        service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+     const char                  *errmsg = NULL;
+@@ -1241,9 +1242,9 @@ chrand_principal3_2_svc(chrand3_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1253,8 +1254,8 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1295,9 +1296,9 @@ create_policy_2_svc(cpol_arg *arg, struct svc_req *rqstp)
+         if (errmsg != NULL)
+             krb5_free_error_message(handle->context, errmsg);
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1307,8 +1308,8 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1347,9 +1348,9 @@ delete_policy_2_svc(dpol_arg *arg, struct svc_req *rqstp)
+         if (errmsg != NULL)
+             krb5_free_error_message(handle->context, errmsg);
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1359,8 +1360,8 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1400,9 +1401,9 @@ modify_policy_2_svc(mpol_arg *arg, struct svc_req *rqstp)
+         if (errmsg != NULL)
+             krb5_free_error_message(handle->context, errmsg);
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1413,8 +1414,8 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
+     static gpol_ret             ret;
+     kadm5_ret_t         ret2;
+     char                        *prime_arg, *funcname;
+-    gss_buffer_desc             client_name,
+-        service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_principal_ent_rec     caller_ent;
+     kadm5_server_handle_t       handle;
+@@ -1475,9 +1476,9 @@ get_policy_2_svc(gpol_arg *arg, struct svc_req *rqstp)
+         log_unauth(funcname, prime_arg,
+                    &client_name, &service_name, rqstp);
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ 
+@@ -1488,8 +1489,8 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
+ {
+     static gpols_ret                ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1531,9 +1532,9 @@ get_pols_2_svc(gpols_arg *arg, struct svc_req *rqstp)
+         if (errmsg != NULL)
+             krb5_free_error_message(handle->context, errmsg);
+     }
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1541,7 +1542,8 @@ exit_func:
+ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+ {
+     static getprivs_ret            ret;
+-    gss_buffer_desc                client_name, service_name;
++    gss_buffer_desc                client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                      minor_stat;
+     kadm5_server_handle_t          handle;
+     const char                     *errmsg = NULL;
+@@ -1571,9 +1573,9 @@ getprivs_ret * get_privs_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+     if (errmsg != NULL)
+         krb5_free_error_message(handle->context, errmsg);
+ 
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1583,7 +1585,8 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret          ret;
+     char                        *prime_arg, *funcname;
+-    gss_buffer_desc             client_name, service_name;
++    gss_buffer_desc             client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc             service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                   minor_stat;
+     kadm5_server_handle_t       handle;
+ 
+@@ -1629,9 +1632,9 @@ purgekeys_2_svc(purgekeys_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1641,8 +1644,8 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp)
+ {
+     static gstrings_ret             ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1688,9 +1691,9 @@ get_strings_2_svc(gstrings_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1700,8 +1703,8 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
+ {
+     static generic_ret              ret;
+     char                            *prime_arg;
+-    gss_buffer_desc                 client_name,
+-        service_name;
++    gss_buffer_desc                 client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc                 service_name = GSS_C_EMPTY_BUFFER;
+     OM_uint32                       minor_stat;
+     kadm5_server_handle_t           handle;
+     const char                      *errmsg = NULL;
+@@ -1744,9 +1747,9 @@ set_string_2_svc(sstring_arg *arg, struct svc_req *rqstp)
+             krb5_free_error_message(handle->context, errmsg);
+     }
+     free(prime_arg);
++exit_func:
+     gss_release_buffer(&minor_stat, &client_name);
+     gss_release_buffer(&minor_stat, &service_name);
+-exit_func:
+     free_server_handle(handle);
+     return &ret;
+ }
+@@ -1754,8 +1757,8 @@ exit_func:
+ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+ {
+     static generic_ret         ret;
+-    gss_buffer_desc            client_name,
+-        service_name;
++    gss_buffer_desc            client_name = GSS_C_EMPTY_BUFFER;
++    gss_buffer_desc            service_name = GSS_C_EMPTY_BUFFER;
+     kadm5_server_handle_t      handle;
+     OM_uint32                  minor_stat;
+     const char                 *errmsg = NULL;
+@@ -1797,10 +1800,10 @@ generic_ret *init_2_svc(krb5_ui_4 *arg, struct svc_req *rqstp)
+                      rqstp->rq_cred.oa_flavor);
+     if (errmsg != NULL)
+         krb5_free_error_message(NULL, errmsg);
+-    gss_release_buffer(&minor_stat, &client_name);
+-    gss_release_buffer(&minor_stat, &service_name);
+ 
+ exit_func:
++    gss_release_buffer(&minor_stat, &client_name);
++    gss_release_buffer(&minor_stat, &service_name);
+     return(&ret);
+ }
+ 
+-- 
+2.7.0.rc3
+
diff --git a/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch b/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch
new file mode 100644
index 0000000000..195db38d08
--- /dev/null
+++ b/gnu/packages/patches/mit-krb5-init-context-null-spnego.patch
@@ -0,0 +1,49 @@
+Copied from Fedora.
+http://pkgs.fedoraproject.org/cgit/rpms/krb5.git/tree/krb5-init_context_null_spnego.patch?h=f22
+
+From 3beb564cea3d219efcf71682b6576cad548c2d23 Mon Sep 17 00:00:00 2001
+From: Simo Sorce <simo@redhat.com>
+Date: Tue, 5 Jan 2016 12:11:59 -0500
+Subject: [PATCH] Check internal context on init context errors
+
+If the mechanism deletes the internal context handle on error, the
+mechglue must do the same with the union context, to avoid crashes if
+the application calls other functions with this invalid union context.
+
+[ghudson@mit.edu: edit commit message and code comment]
+
+ticket: 8337 (new)
+target_version: 1.14-next
+target_version: 1.13-next
+tags: pullup
+---
+ src/lib/gssapi/mechglue/g_init_sec_context.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/src/lib/gssapi/mechglue/g_init_sec_context.c b/src/lib/gssapi/mechglue/g_init_sec_context.c
+index aaae767..9f154b8 100644
+--- a/src/lib/gssapi/mechglue/g_init_sec_context.c
++++ b/src/lib/gssapi/mechglue/g_init_sec_context.c
+@@ -224,12 +224,15 @@ OM_uint32 *		time_rec;
+ 
+     if (status != GSS_S_COMPLETE && status != GSS_S_CONTINUE_NEEDED) {
+ 	/*
+-	 * the spec says (the preferred) method is to delete all
+-	 * context info on the first call to init, and on all
+-	 * subsequent calls make the caller responsible for
+-	 * calling gss_delete_sec_context
++	 * The spec says the preferred method is to delete all context info on
++	 * the first call to init, and on all subsequent calls make the caller
++	 * responsible for calling gss_delete_sec_context.  However, if the
++	 * mechanism decided to delete the internal context, we should also
++	 * delete the union context.
+ 	 */
+ 	map_error(minor_status, mech);
++	if (union_ctx_id->internal_ctx_id == GSS_C_NO_CONTEXT)
++	    *context_handle = GSS_C_NO_CONTEXT;
+ 	if (*context_handle == GSS_C_NO_CONTEXT) {
+ 	    free(union_ctx_id->mech_type->elements);
+ 	    free(union_ctx_id->mech_type);
+-- 
+2.6.4
+
diff --git a/gnu/packages/patches/ocaml-findlib-make-install.patch b/gnu/packages/patches/ocaml-findlib-make-install.patch
new file mode 100644
index 0000000000..238f9ca3ce
--- /dev/null
+++ b/gnu/packages/patches/ocaml-findlib-make-install.patch
@@ -0,0 +1,20 @@
+Ocaml wants to install its "core" libraries in OCAML_CORE_STDLIB.  That
+does not work in a store-based distribution.
+
+A solution was already provided by Nix
+
+    https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/ocaml/findlib/install_topfind.patch
+
+regenerated for Guix.
+
+--- findlib-1.5.3/src/findlib/Makefile	2014-09-16 13:21:46.000000000 +0200
++++ findlib-1.5.3/src/findlib/Makefile.new	2014-10-01 14:30:54.141082521 +0200
+@@ -89,7 +89,7 @@
+ install: all
+ 	mkdir -p "$(prefix)$(OCAML_SITELIB)/$(NAME)"
+ 	mkdir -p "$(prefix)$(OCAMLFIND_BIN)"
+-	test $(INSTALL_TOPFIND) -eq 0 || cp topfind "$(prefix)$(OCAML_CORE_STDLIB)"
++	test $(INSTALL_TOPFIND) -eq 0 || cp topfind "$(prefix)$(OCAML_SITELIB)"
+ 	files=`$(TOP)/tools/collect_files $(TOP)/Makefile.config findlib.cmi findlib.mli findlib.cma topfind.cmi topfind.mli fl_package_base.mli fl_package_base.cmi fl_metascanner.mli fl_metascanner.cmi fl_metatoken.cmi findlib_top.cma findlib.cmxa findlib.a findlib.cmxs findlib_dynload.cma findlib_dynload.cmxa findlib_dynload.a findlib_dynload.cmxs fl_dynload.mli fl_dynload.cmi META` && \
+ 	cp $$files "$(prefix)$(OCAML_SITELIB)/$(NAME)"
+ 	f="ocamlfind$(EXEC_SUFFIX)"; { test -f ocamlfind_opt$(EXEC_SUFFIX) && f="ocamlfind_opt$(EXEC_SUFFIX)"; }; \
diff --git a/gnu/packages/patches/python-paste-remove-timing-test.patch b/gnu/packages/patches/python-paste-remove-timing-test.patch
new file mode 100644
index 0000000000..6ab8d1a59c
--- /dev/null
+++ b/gnu/packages/patches/python-paste-remove-timing-test.patch
@@ -0,0 +1,16 @@
+Remove this test to verify that things were modified since a certain time.
+
+That assumption doesn't hold up when your environment doesn't have access to a
+real clock and thinks it's living in 1970 :)
+
+--- a/tests/test_fileapp.py    2015-04-23 13:48:37.000000000 -0700
++++ b/tests/test_fileapp.py	2016-02-22 19:20:08.332802417 -0800
+@@ -223,8 +223,6 @@
+                   status=304)
+     res = app.get('/', headers={'If-None-Match': 'asdf'},
+                   status=200)
+-    res = app.get('/', headers={'If-Modified-Since': 'Sat, 1 Jan 2005 12:00:00 GMT'},
+-                  status=200)
+     res = app.get('/', headers={'If-Modified-Since': last_mod + '; length=100'},
+                   status=304)
+     res = app.get('/', headers={'If-Modified-Since': 'invalid date'},
diff --git a/gnu/packages/patches/python-paste-remove-website-test.patch b/gnu/packages/patches/python-paste-remove-website-test.patch
new file mode 100644
index 0000000000..93417fbe75
--- /dev/null
+++ b/gnu/packages/patches/python-paste-remove-website-test.patch
@@ -0,0 +1,21 @@
+Remove the test to see if the Python Paste website is up.
+
+Obviously without network access there is no way for us to check this, and
+it's pretty strange to test a project's website when you really mean to test
+the project anyhow...
+
+--- a/tests/test_proxy.py	2016-02-22 19:13:04.040117767 -0800
++++ b/tests/test_proxy.py	2016-02-22 19:13:04.040117767 -0800
+@@ -1,12 +1,3 @@
+ from paste import proxy
+ from paste.fixture import TestApp
+
+-def test_paste_website():
+-    # Not the most robust test...
+-    # need to test things like POSTing to pages, and getting from pages
+-    # that don't set content-length.
+-    app = proxy.Proxy('http://pythonpaste.org')
+-    app = TestApp(app)
+-    res = app.get('/')
+-    assert 'documentation' in res
+-
diff --git a/gnu/packages/patches/qemu-CVE-2015-8619.patch b/gnu/packages/patches/qemu-CVE-2015-8619.patch
new file mode 100644
index 0000000000..5961343d1e
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2015-8619.patch
@@ -0,0 +1,119 @@
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Wed, 13 Jan 2016 09:09:58 +0100
+Subject: [PATCH] hmp: fix sendkey out of bounds write (CVE-2015-8619)
+
+When processing 'sendkey' command, hmp_sendkey routine null
+terminates the 'keyname_buf' array. This results in an OOB
+write issue, if 'keyname_len' was to fall outside of
+'keyname_buf' array.
+
+Since the keyname's length is known the keyname_buf can be
+removed altogether by adding a length parameter to
+index_from_key() and using it for the error output as well.
+
+Reported-by: Ling Liu <liuling-it@360.cn>
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Message-Id: <20160113080958.GA18934@olga>
+[Comparison with "<" dumbed down, test for junk after strtoul()
+tweaked]
+Signed-off-by: Markus Armbruster <armbru@redhat.com>
+
+(cherry picked from commit 64ffbe04eaafebf4045a3ace52a360c14959d196)
+---
+ hmp.c                | 18 ++++++++----------
+ include/ui/console.h |  2 +-
+ ui/input-legacy.c    |  5 +++--
+ 3 files changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/hmp.c b/hmp.c
+index 2140605..1904203 100644
+--- a/hmp.c
++++ b/hmp.c
+@@ -1734,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
+     int has_hold_time = qdict_haskey(qdict, "hold-time");
+     int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
+     Error *err = NULL;
+-    char keyname_buf[16];
+     char *separator;
+     int keyname_len;
+ 
+     while (1) {
+         separator = strchr(keys, '-');
+         keyname_len = separator ? separator - keys : strlen(keys);
+-        pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
+ 
+         /* Be compatible with old interface, convert user inputted "<" */
+-        if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
+-            pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
++        if (keys[0] == '<' && keyname_len == 1) {
++            keys = "less";
+             keyname_len = 4;
+         }
+-        keyname_buf[keyname_len] = 0;
+ 
+         keylist = g_malloc0(sizeof(*keylist));
+         keylist->value = g_malloc0(sizeof(*keylist->value));
+@@ -1761,16 +1758,17 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
+         }
+         tmp = keylist;
+ 
+-        if (strstart(keyname_buf, "0x", NULL)) {
++        if (strstart(keys, "0x", NULL)) {
+             char *endp;
+-            int value = strtoul(keyname_buf, &endp, 0);
+-            if (*endp != '\0') {
++            int value = strtoul(keys, &endp, 0);
++            assert(endp <= keys + keyname_len);
++            if (endp != keys + keyname_len) {
+                 goto err_out;
+             }
+             keylist->value->type = KEY_VALUE_KIND_NUMBER;
+             keylist->value->u.number = value;
+         } else {
+-            int idx = index_from_key(keyname_buf);
++            int idx = index_from_key(keys, keyname_len);
+             if (idx == Q_KEY_CODE_MAX) {
+                 goto err_out;
+             }
+@@ -1792,7 +1790,7 @@ out:
+     return;
+ 
+ err_out:
+-    monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
++    monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
+     goto out;
+ }
+ 
+diff --git a/include/ui/console.h b/include/ui/console.h
+index c249db4..5739bdd 100644
+--- a/include/ui/console.h
++++ b/include/ui/console.h
+@@ -433,7 +433,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
+ void curses_display_init(DisplayState *ds, int full_screen);
+ 
+ /* input.c */
+-int index_from_key(const char *key);
++int index_from_key(const char *key, size_t key_length);
+ 
+ /* gtk.c */
+ void early_gtk_display_init(int opengl);
+diff --git a/ui/input-legacy.c b/ui/input-legacy.c
+index e0a39f0..3f28bbc 100644
+--- a/ui/input-legacy.c
++++ b/ui/input-legacy.c
+@@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
+ static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
+     QTAILQ_HEAD_INITIALIZER(led_handlers);
+ 
+-int index_from_key(const char *key)
++int index_from_key(const char *key, size_t key_length)
+ {
+     int i;
+ 
+     for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
+-        if (!strcmp(key, QKeyCode_lookup[i])) {
++        if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
++            !QKeyCode_lookup[i][key_length]) {
+             break;
+         }
+     }
diff --git a/gnu/packages/patches/qemu-CVE-2016-1981.patch b/gnu/packages/patches/qemu-CVE-2016-1981.patch
new file mode 100644
index 0000000000..03e7b333c9
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2016-1981.patch
@@ -0,0 +1,95 @@
+From: Laszlo Ersek <lersek@redhat.com>
+Date: Tue, 19 Jan 2016 14:17:20 +0100
+Subject: [PATCH] e1000: eliminate infinite loops on out-of-bounds transfer
+ start
+
+The start_xmit() and e1000_receive_iov() functions implement DMA transfers
+iterating over a set of descriptors that the guest's e1000 driver
+prepares:
+
+- the TDLEN and RDLEN registers store the total size of the descriptor
+  area,
+
+- while the TDH and RDH registers store the offset (in whole tx / rx
+  descriptors) into the area where the transfer is supposed to start.
+
+Each time a descriptor is processed, the TDH and RDH register is bumped
+(as appropriate for the transfer direction).
+
+QEMU already contains logic to deal with bogus transfers submitted by the
+guest:
+
+- Normally, the transmit case wants to increase TDH from its initial value
+  to TDT. (TDT is allowed to be numerically smaller than the initial TDH
+  value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
+  that QEMU currently has here is a check against reaching the original
+  TDH value again -- a complete wraparound, which should never happen.
+
+- In the receive case RDH is increased from its initial value until
+  "total_size" bytes have been received; preferably in a single step, or
+  in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
+  RX descriptors are skipped without receiving data, while RDH is
+  incremented just the same. QEMU tries to prevent an infinite loop
+  (processing only null RX descriptors) by detecting whether RDH assumes
+  its original value during the loop. (Again, wrapping from RDLEN to 0 is
+  normal.)
+
+What both directions miss is that the guest could program TDLEN and RDLEN
+so low, and the initial TDH and RDH so high, that these registers will
+immediately be truncated to zero, and then never reassume their initial
+values in the loop -- a full wraparound will never occur.
+
+The condition that expresses this is:
+
+  xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
+
+i.e., TDH or RDH start out after the last whole rx or tx descriptor that
+fits into the TDLEN or RDLEN sized area.
+
+This condition could be checked before we enter the loops, but
+pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
+bogus DMA addresses, so we just extend the existing failsafes with the
+above condition.
+
+This is CVE-2016-1981.
+
+Cc: "Michael S. Tsirkin" <mst@redhat.com>
+Cc: Petr Matousek <pmatouse@redhat.com>
+Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
+Cc: Prasad Pandit <ppandit@redhat.com>
+Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
+Cc: Jason Wang <jasowang@redhat.com>
+Cc: qemu-stable@nongnu.org
+RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
+Signed-off-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+(cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc)
+---
+ hw/net/e1000.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/net/e1000.c b/hw/net/e1000.c
+index bec06e9..34d0823 100644
+--- a/hw/net/e1000.c
++++ b/hw/net/e1000.c
+@@ -908,7 +908,8 @@ start_xmit(E1000State *s)
+          * bogus values to TDT/TDLEN.
+          * there's nothing too intelligent we could do about this.
+          */
+-        if (s->mac_reg[TDH] == tdh_start) {
++        if (s->mac_reg[TDH] == tdh_start ||
++            tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
+             DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
+                    tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
+             break;
+@@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
+         if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
+             s->mac_reg[RDH] = 0;
+         /* see comment in start_xmit; same here */
+-        if (s->mac_reg[RDH] == rdh_start) {
++        if (s->mac_reg[RDH] == rdh_start ||
++            rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
+             DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
+                    rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
+             set_ics(s, 0, E1000_ICS_RXO);
diff --git a/gnu/packages/patches/qemu-CVE-2016-2197.patch b/gnu/packages/patches/qemu-CVE-2016-2197.patch
new file mode 100644
index 0000000000..d851e1ec75
--- /dev/null
+++ b/gnu/packages/patches/qemu-CVE-2016-2197.patch
@@ -0,0 +1,40 @@
+From: John Snow <jsnow@redhat.com>
+Date: Wed, 10 Feb 2016 13:29:40 -0500
+Subject: [PATCH] ahci: Do not unmap NULL addresses
+
+Definitely don't try to unmap a garbage address.
+
+Reported-by: Zuozhi fzz <zuozhi.fzz@alibaba-inc.com>
+Signed-off-by: John Snow <jsnow@redhat.com>
+Message-id: 1454103689-13042-2-git-send-email-jsnow@redhat.com
+(cherry picked from commit 99b4cb71069f109b79b27bc629fc0cf0886dbc4b)
+---
+ hw/ide/ahci.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
+index 17f1cbd..cdc9299 100644
+--- a/hw/ide/ahci.c
++++ b/hw/ide/ahci.c
+@@ -661,6 +661,10 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
+ 
+ static void ahci_unmap_fis_address(AHCIDevice *ad)
+ {
++    if (ad->res_fis == NULL) {
++        DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
++        return;
++    }
+     dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
+                      DMA_DIRECTION_FROM_DEVICE, 256);
+     ad->res_fis = NULL;
+@@ -677,6 +681,10 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
+ 
+ static void ahci_unmap_clb_address(AHCIDevice *ad)
+ {
++    if (ad->lst == NULL) {
++        DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
++        return;
++    }
+     dma_memory_unmap(ad->hba->as, ad->lst, 1024,
+                      DMA_DIRECTION_FROM_DEVICE, 1024);
+     ad->lst = NULL;
diff --git a/gnu/packages/patches/qemu-usb-ehci-oob-read.patch b/gnu/packages/patches/qemu-usb-ehci-oob-read.patch
new file mode 100644
index 0000000000..d63c0832b8
--- /dev/null
+++ b/gnu/packages/patches/qemu-usb-ehci-oob-read.patch
@@ -0,0 +1,49 @@
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Wed, 20 Jan 2016 01:26:46 +0530
+Subject: [PATCH] usb: check page select value while processing iTD
+
+While processing isochronous transfer descriptors(iTD), the page
+select(PG) field value could lead to an OOB read access. Add
+check to avoid it.
+
+Reported-by: Qinghao Tang <luodalongde@gmail.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+(cherry picked from commit 49d925ce50383a286278143c05511d30ec41a36e)
+---
+ hw/usb/hcd-ehci.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
+index d07f228..c40013e 100644
+--- a/hw/usb/hcd-ehci.c
++++ b/hw/usb/hcd-ehci.c
+@@ -1404,21 +1404,23 @@ static int ehci_process_itd(EHCIState *ehci,
+         if (itd->transact[i] & ITD_XACT_ACTIVE) {
+             pg   = get_field(itd->transact[i], ITD_XACT_PGSEL);
+             off  = itd->transact[i] & ITD_XACT_OFFSET_MASK;
+-            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
+-            ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
+             len  = get_field(itd->transact[i], ITD_XACT_LENGTH);
+ 
+             if (len > max * mult) {
+                 len = max * mult;
+             }
+-
+-            if (len > BUFF_SIZE) {
++            if (len > BUFF_SIZE || pg > 6) {
+                 return -1;
+             }
+ 
++            ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
+             qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
+             if (off + len > 4096) {
+                 /* transfer crosses page border */
++                if (pg == 6) {
++                    return -1;  /* avoid page pg + 1 */
++                }
++                ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
+                 uint32_t len2 = off + len - 4096;
+                 uint32_t len1 = len - len2;
+                 qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
diff --git a/gnu/packages/patches/slurm-configure-remove-nonfree-contribs.patch b/gnu/packages/patches/slurm-configure-remove-nonfree-contribs.patch
new file mode 100644
index 0000000000..b63d5bb018
--- /dev/null
+++ b/gnu/packages/patches/slurm-configure-remove-nonfree-contribs.patch
@@ -0,0 +1,43 @@
+From 53eda9102b969a4be2882cea4befee03591a7436 Mon Sep 17 00:00:00 2001
+From: Pjotr Prins <pjotr.public01@thebird.nl>
+Date: Fri, 12 Feb 2016 12:43:33 +0100
+Subject: [PATCH] Remove contribs
+
+---
+ configure.ac | 20 --------------------
+ 1 file changed, 20 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index fedf354..e010732 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -438,26 +438,6 @@ dnl All slurm Makefiles:
+ AC_CONFIG_FILES([Makefile
+ 		 config.xml
+ 		 auxdir/Makefile
+-		 contribs/Makefile
+-		 contribs/cray/Makefile
+-		 contribs/cray/csm/Makefile
+-		 contribs/lua/Makefile
+-		 contribs/mic/Makefile
+-		 contribs/pam/Makefile
+-		 contribs/pam_slurm_adopt/Makefile
+-		 contribs/perlapi/Makefile
+-		 contribs/perlapi/libslurm/Makefile
+-		 contribs/perlapi/libslurm/perl/Makefile.PL
+-		 contribs/perlapi/libslurmdb/Makefile
+-		 contribs/perlapi/libslurmdb/perl/Makefile.PL
+-		 contribs/torque/Makefile
+-		 contribs/phpext/Makefile
+-		 contribs/phpext/slurm_php/config.m4
+-		 contribs/sgather/Makefile
+-		 contribs/sgi/Makefile
+-		 contribs/sjobexit/Makefile
+-		 contribs/slurmdb-direct/Makefile
+-		 contribs/pmi2/Makefile
+ 		 doc/Makefile
+ 		 doc/man/Makefile
+ 		 doc/man/man1/Makefile
+-- 
+2.1.4
+
diff --git a/gnu/packages/patches/tclxml-3.2-install.patch b/gnu/packages/patches/tclxml-3.2-install.patch
new file mode 100644
index 0000000000..09d59925bf
--- /dev/null
+++ b/gnu/packages/patches/tclxml-3.2-install.patch
@@ -0,0 +1,17 @@
+Install everything in PREFIX, set EXTRA_PATH to find it there.
+
+--- ./Makefile.in~	2016-02-06 01:29:16.595090365 +0100
++++ ./Makefile.in	2016-02-06 09:29:04.286008931 +0100
+@@ -133,9 +133,9 @@
+ # require for testing here (like TCLX_LIBRARY).
+ #========================================================================
+
+-EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR)
++EXTRA_PATH	= $(top_builddir):$(TCL_BIN_DIR):$(libdir)
+ #EXTRA_PATH     = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR)
+-TCLLIBPATH      = $(top_builddir)
++TCLLIBPATH      = $(pkglibdir)
+ TCLSH_ENV	= TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` \
+ 		  @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \
+ 		  PATH="$(EXTRA_PATH):$(PATH)" \
+ 
\ No newline at end of file
diff --git a/gnu/packages/patches/xf86-video-mga-glibc-2.20.patch b/gnu/packages/patches/xf86-video-mga-glibc-2.20.patch
deleted file mode 100644
index 3b8277df80..0000000000
--- a/gnu/packages/patches/xf86-video-mga-glibc-2.20.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Fix test compilation with exa.h in configure when using glibc 2.20.
-Inspired by a patch by Peter Hutterer <peter.hutterer@who-t.net>.
-See <https://raw.githubusercontent.com/openembedded/oe-core/master/meta/recipes-graphics/xorg-driver/xf86-input-synaptics/always_include_xorg_server.h.patch>.
-
---- xf86-video-mga-1.6.3/configure.~1~	2013-12-04 21:10:25.000000000 -0500
-+++ xf86-video-mga-1.6.3/configure	2014-12-19 01:06:23.005774736 -0500
-@@ -18464,7 +18464,9 @@
- 
-     SAVE_CPPFLAGS="$CPPFLAGS"
-     CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
--    ac_fn_c_check_header_mongrel "$LINENO" "exa.h" "ac_cv_header_exa_h" "$ac_includes_default"
-+    ac_fn_c_check_header_mongrel "$LINENO" "exa.h" "ac_cv_header_exa_h" "$ac_includes_default
-+#include <xorg-server.h>
-+"
- if test "x$ac_cv_header_exa_h" = xyes; then :
-   have_exa_h="yes"
- else
diff --git a/gnu/packages/patches/xf86-video-r128-glibc-2.20.patch b/gnu/packages/patches/xf86-video-r128-glibc-2.20.patch
deleted file mode 100644
index 21a430ebc6..0000000000
--- a/gnu/packages/patches/xf86-video-r128-glibc-2.20.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-Fix test compilation with exa.h in configure when using glibc 2.20.
-Inspired by a patch by Peter Hutterer <peter.hutterer@who-t.net>.
-See <https://raw.githubusercontent.com/openembedded/oe-core/master/meta/recipes-graphics/xorg-driver/xf86-input-synaptics/always_include_xorg_server.h.patch>.
-
---- xf86-video-r128-6.9.2/configure.~1~	2013-10-02 14:38:15.000000000 -0400
-+++ xf86-video-r128-6.9.2/configure	2014-12-19 01:23:03.346735159 -0500
-@@ -18400,7 +18400,9 @@
- 
-         SAVE_CPPFLAGS="$CPPFLAGS"
-         CPPFLAGS="$CPPFLAGS $XORG_CFLAGS"
--        ac_fn_c_check_header_mongrel "$LINENO" "exa.h" "ac_cv_header_exa_h" "$ac_includes_default"
-+        ac_fn_c_check_header_mongrel "$LINENO" "exa.h" "ac_cv_header_exa_h" "$ac_includes_default
-+#include <xorg-server.h>
-+"
- if test "x$ac_cv_header_exa_h" = xyes; then :
-   have_exa_h="yes"
- else
diff --git a/gnu/packages/patches/xf86-video-siliconmotion-remove-mibstore.patch b/gnu/packages/patches/xf86-video-siliconmotion-remove-mibstore.patch
deleted file mode 100644
index 5fd9100609..0000000000
--- a/gnu/packages/patches/xf86-video-siliconmotion-remove-mibstore.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Removes references to mibstore.h and miInitializeBackingStore, which
-have been removed from xorg-server.  Zack Rusin <zackr@vmware.com>
-wrote: "It was a noop for at least 5 years and it has been removed."
-See: http://patches.openembedded.org/patch/46133/
-
---- xf86-video-siliconmotion-1.7.7/src/smi_driver.c.~1~	2012-07-17 00:53:21.000000000 -0400
-+++ xf86-video-siliconmotion-1.7.7/src/smi_driver.c	2014-12-19 01:30:16.708884086 -0500
-@@ -1750,8 +1750,6 @@
- 		   "Done writing mode.  Register dump:\n");
-     SMI_PrintRegs(pScrn);
- 
--    miInitializeBackingStore(pScreen);
--
- #ifdef HAVE_XMODES
-     xf86DiDGAInit(pScreen, (unsigned long)(pSmi->FBBase + pScrn->fbOffset));
- #endif
diff --git a/gnu/packages/patches/xf86-video-sis-fix-exa-crash.patch b/gnu/packages/patches/xf86-video-sis-fix-exa-crash.patch
deleted file mode 100644
index f5cd0b9a9e..0000000000
--- a/gnu/packages/patches/xf86-video-sis-fix-exa-crash.patch
+++ /dev/null
@@ -1,45 +0,0 @@
-Fix X server crash when sis driver is used with EXA acceleration.
-
-Source: http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/trusty/xserver-xorg-video-sis/trusty/revision/24/debian/patches/fix-exa-crash.diff
-
-The patch was originally proposed by nihui:
-https://bugs.launchpad.net/ubuntu/+source/xserver-xorg-video-sis/+bug/1066464/comments/13
-
---- a/src/sis310_accel.c
-+++ b/src/sis310_accel.c
-@@ -1874,7 +1874,7 @@
- {
- 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pDst->drawable.pScreen);
- 	SISPtr pSiS = SISPTR(pScrn);
--	unsigned char *dst = pDst->devPrivate.ptr;
-+	unsigned char *dst = ((unsigned char *) pSiS->FbBase) + exaGetPixmapOffset(pDst);
- 	int dst_pitch = exaGetPixmapPitch(pDst);
- 
- 	(pSiS->SyncAccel)(pScrn);
-@@ -1882,7 +1882,7 @@
- 	if(pDst->drawable.bitsPerPixel < 8)
- 	   return FALSE;
- 
--	dst += (x * pDst->drawable.bitsPerPixel / 8) + (y * src_pitch);
-+	dst += (x * pDst->drawable.bitsPerPixel / 8) + (y * dst_pitch);
- 	while(h--) {
- 	   SiSMemCopyToVideoRam(pSiS, dst, (unsigned char *)src,
- 				(w * pDst->drawable.bitsPerPixel / 8));
-@@ -1953,7 +1953,7 @@
- {
- 	ScrnInfoPtr pScrn = xf86ScreenToScrn(pSrc->drawable.pScreen);
- 	SISPtr pSiS = SISPTR(pScrn);
--	unsigned char *src = pSrc->devPrivate.ptr;
-+	unsigned char *src = ((unsigned char *) pSiS->FbBase) + exaGetPixmapOffset(pSrc);
- 	int src_pitch = exaGetPixmapPitch(pSrc);
- 	int size = src_pitch < dst_pitch ? src_pitch : dst_pitch;
- 
-@@ -1964,7 +1964,7 @@
- 
- 	src += (x * pSrc->drawable.bitsPerPixel / 8) + (y * src_pitch);
- 	while(h--) {
--	   SiSMemCopyFromVideoRam(pSiS, (unsigned char *)dst, src, size);
-+	   SiSMemCopyFromVideoRam(pSiS, (unsigned char *)dst, src, (w * pSrc->drawable.bitsPerPixel / 8));
- 	   src += src_pitch;
- 	   dst += dst_pitch;
- 	}
diff --git a/gnu/packages/patches/xf86-video-sis-update-api.patch b/gnu/packages/patches/xf86-video-sis-update-api.patch
deleted file mode 100644
index d8c5c07273..0000000000
--- a/gnu/packages/patches/xf86-video-sis-update-api.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-Update xf86-video-sis to the current xorg-server API.
-
-Copied from: http://pkgs.fedoraproject.org/cgit/xorg-x11-drv-sis.git/tree/sis-0.10.7-git.patch?id=2705859f0ddc7ee7a3b07f21b442ebeab5df1276
-Commit log: http://pkgs.fedoraproject.org/cgit/xorg-x11-drv-sis.git/log/sis-0.10.7-git.patch
-
-Patch by Adam Jackson <ajax@redhat.com>
-
-diff --git a/src/sis.h b/src/sis.h
-index 46fca2a..20e6134 100644
---- a/src/sis.h
-+++ b/src/sis.h
-@@ -75,7 +75,6 @@
- 
- #include "compiler.h"
- #include "xf86Pci.h"
--#include "xf86Priv.h"
- #include "xf86_OSproc.h"
- #if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 6
- #include "xf86Resources.h"
-diff --git a/src/sis_driver.c b/src/sis_driver.c
-index 61e8075..0fd83d7 100644
---- a/src/sis_driver.c
-+++ b/src/sis_driver.c
-@@ -57,7 +57,6 @@
- #include "fb.h"
- #include "micmap.h"
- #include "mipointer.h"
--#include "mibstore.h"
- #include "edid.h"
- 
- #define SIS_NEED_inSISREG
-@@ -94,6 +93,10 @@
- #include "dri.h"
- #endif
- 
-+#ifndef DEFAULT_DPI
-+#define DEFAULT_DPI 96
-+#endif
-+
- /*
-  * LookupWindow was removed with video abi 11.
-  */
-@@ -7344,7 +7347,11 @@ SISUnmapMem(ScrnInfoPtr pScrn)
-         if(pSiSEnt->MapCountIOBase) {
- 	    pSiSEnt->MapCountIOBase--;
- 	    if((pSiSEnt->MapCountIOBase == 0) || (pSiSEnt->forceUnmapIOBase)) {
-+#ifndef XSERVER_LIBPCIACCESS
- 		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBase, (pSiS->mmioSize * 1024));
-+#else
-+	        pci_device_unmap_range(pSiS->PciInfo, pSiSEnt->IOBase, (pSiS->mmioSize * 1024));
-+#endif
- 		pSiSEnt->IOBase = NULL;
- 		pSiSEnt->MapCountIOBase = 0;
- 		pSiSEnt->forceUnmapIOBase = FALSE;
-@@ -7355,7 +7362,11 @@ SISUnmapMem(ScrnInfoPtr pScrn)
- 	if(pSiSEnt->MapCountIOBaseDense) {
- 	    pSiSEnt->MapCountIOBaseDense--;
- 	    if((pSiSEnt->MapCountIOBaseDense == 0) || (pSiSEnt->forceUnmapIOBaseDense)) {
-+#ifndef XSERVER_LIBPCIACCESS
- 		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->IOBaseDense, (pSiS->mmioSize * 1024));
-+#else
-+		pci_device_unmap_range(pSiS->PciInfo, (pointer)pSiSEnt->IOBaseDense, (pSiS->mmioSize * 1024));
-+#endif
- 		pSiSEnt->IOBaseDense = NULL;
- 		pSiSEnt->MapCountIOBaseDense = 0;
- 		pSiSEnt->forceUnmapIOBaseDense = FALSE;
-@@ -7366,7 +7377,11 @@ SISUnmapMem(ScrnInfoPtr pScrn)
- 	if(pSiSEnt->MapCountFbBase) {
- 	    pSiSEnt->MapCountFbBase--;
- 	    if((pSiSEnt->MapCountFbBase == 0) || (pSiSEnt->forceUnmapFbBase)) {
-+#ifndef XSERVER_LIBPCIACCESS
- 		xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiSEnt->RealFbBase, pSiS->FbMapSize);
-+#else
-+		pci_device_unmap_range(pSiS->PciInfo, (pointer)pSiSEnt->RealFbBase, pSiS->FbMapSize);
-+#endif
- 		pSiSEnt->FbBase = pSiSEnt->RealFbBase = NULL;
- 		pSiSEnt->MapCountFbBase = 0;
- 		pSiSEnt->forceUnmapFbBase = FALSE;
-@@ -7376,13 +7391,25 @@ SISUnmapMem(ScrnInfoPtr pScrn)
- 	}
-     } else {
- #endif
-+#ifndef XSERVER_LIBPCIACCESS
- 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBase, (pSiS->mmioSize * 1024));
-+#else
-+	pci_device_unmap_range(pSiS->PciInfo, (pointer)pSiS->IOBase, (pSiS->mmioSize * 1024));
-+#endif
- 	pSiS->IOBase = NULL;
- #ifdef __alpha__
-+#ifndef XSERVER_LIBPCIACCESS
- 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->IOBaseDense, (pSiS->mmioSize * 1024));
-+#else
-+	pci_device_unmap_range(pSiS->PciInfo, (pointer)pSiS->IOBaseDense, (pSiS->mmioSize * 1024));
-+#endif
- 	pSiS->IOBaseDense = NULL;
- #endif
-+#ifndef XSERVER_LIBPCIACCESS
- 	xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pSiS->RealFbBase, pSiS->FbMapSize);
-+#else
-+	pci_device_unmap_range(pSiS->PciInfo, (pointer)pSiS->RealFbBase, pSiS->FbMapSize);
-+#endif
- 	pSiS->FbBase = pSiS->RealFbBase = NULL;
- #ifdef SISDUALHEAD
-     }
-@@ -8859,7 +8886,6 @@ SISScreenInit(SCREEN_INIT_ARGS_DECL)
-     }
-     pSiS->SiSFastVidCopyDone = TRUE;
- 
--    miInitializeBackingStore(pScreen);
-     xf86SetBackingStore(pScreen);
-     xf86SetSilkenMouse(pScreen);
- 
-@@ -9352,7 +9378,14 @@ SISMergedPointerMoved(SCRN_ARG_TYPE arg, int x, int y)
-      }
-      if(doit) {
- 	sigstate = xf86BlockSIGIO();
--#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 15
-+#if GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 18
-+        {
-+            double dx = x, dy = y;
-+            miPointerSetPosition(inputInfo.pointer, Absolute, &dx, &dy, NULL, NULL);
-+            x = (int)dx;
-+            y = (int)dy;
-+        }
-+#elif GET_ABI_MAJOR(ABI_XINPUT_VERSION) >= 15
-         {
-             double dx = x, dy = y;
-             miPointerSetPosition(inputInfo.pointer, Absolute, &dx, &dy);
diff --git a/gnu/packages/patches/xf86-video-tdfx-remove-mibstore.patch b/gnu/packages/patches/xf86-video-tdfx-remove-mibstore.patch
deleted file mode 100644
index 05e2154433..0000000000
--- a/gnu/packages/patches/xf86-video-tdfx-remove-mibstore.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-Removes references to mibstore.h and miInitializeBackingStore, which
-have been removed from xorg-server.  Zack Rusin <zackr@vmware.com>
-wrote: "It was a noop for at least 5 years and it has been removed."
-See: http://patches.openembedded.org/patch/46133/
-
---- xf86-video-tdfx-1.4.5/src/tdfx_driver.c.~1~	2012-07-17 01:21:16.000000000 -0400
-+++ xf86-video-tdfx-1.4.5/src/tdfx_driver.c	2014-12-19 01:36:42.762798424 -0500
-@@ -62,10 +62,6 @@
- 
- #include "compiler.h"
- 
--/* Drivers using the mi implementation of backing store need: */
--
--#include "mibstore.h"
--
- /* All drivers using the vgahw module need this */
- /* This driver needs to be modified to not use vgaHW for multihead operation */
- #include "vgaHW.h"
-@@ -2373,7 +2369,6 @@
-     }
-   }
- 
--  miInitializeBackingStore(pScreen);
-   xf86SetBackingStore(pScreen);
-   xf86SetSilkenMouse(pScreen);
- 
diff --git a/gnu/packages/patches/xf86-video-trident-remove-mibstore.patch b/gnu/packages/patches/xf86-video-trident-remove-mibstore.patch
deleted file mode 100644
index 74c89878e7..0000000000
--- a/gnu/packages/patches/xf86-video-trident-remove-mibstore.patch
+++ /dev/null
@@ -1,23 +0,0 @@
-Removes references to mibstore.h and miInitializeBackingStore, which
-have been removed from xorg-server.  Zack Rusin <zackr@vmware.com>
-wrote: "It was a noop for at least 5 years and it has been removed."
-See: http://patches.openembedded.org/patch/46133/
-
---- xf86-video-trident-1.3.6/src/trident_driver.c.~1~	2012-07-15 22:16:00.000000000 -0400
-+++ xf86-video-trident-1.3.6/src/trident_driver.c	2014-12-19 01:45:29.529410518 -0500
-@@ -56,7 +56,6 @@
- 
- #include "mipointer.h"
- 
--#include "mibstore.h"
- #include "shadow.h"
- #include "trident.h"
- #include "trident_regs.h"
-@@ -3037,7 +3036,6 @@
-     	TridentAccelInit(pScreen);
-     }
- 
--    miInitializeBackingStore(pScreen);
-     xf86SetBackingStore(pScreen);
- 
-     /* Initialise cursor functions */
diff --git a/gnu/packages/patches/xf86-video-vmware-glibc-2.20.patch b/gnu/packages/patches/xf86-video-vmware-glibc-2.20.patch
deleted file mode 100644
index 43d21d13ab..0000000000
--- a/gnu/packages/patches/xf86-video-vmware-glibc-2.20.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-Allow builds with glibc 2.20.
-Based on a patch by Peter Hutterer <peter.hutterer@who-t.net>.
-See <https://raw.githubusercontent.com/openembedded/oe-core/master/meta/recipes-graphics/xorg-driver/xf86-input-synaptics/always_include_xorg_server.h.patch>.
-
---- xf86-video-vmware-13.0.2/vmwgfx/vmwgfx_overlay.c.~1~	2014-03-20 09:15:03.000000000 -0400
-+++ xf86-video-vmware-13.0.2/vmwgfx/vmwgfx_overlay.c	2014-12-19 02:31:34.759122552 -0500
-@@ -35,6 +35,8 @@
-  */
- 
- 
-+#include <xorg-server.h>
-+
- #include "xf86xv.h"
- #include "fourcc.h"
- #define debug_printf(...)
diff --git a/gnu/packages/pdf.scm b/gnu/packages/pdf.scm
index 4b30bf09d5..a99fdd70ae 100644
--- a/gnu/packages/pdf.scm
+++ b/gnu/packages/pdf.scm
@@ -55,7 +55,7 @@
    (version "0.37.0")
    (source (origin
             (method url-fetch)
-            (uri (string-append "http://poppler.freedesktop.org/poppler-"
+            (uri (string-append "https://poppler.freedesktop.org/poppler-"
                                 version ".tar.xz"))
             (sha256 (base32
                      "1vjvd0md8y37hlq3lsj0l01a3v3mzm572rzpn1311frvmrg9r7xq"))))
diff --git a/gnu/packages/perl.scm b/gnu/packages/perl.scm
index 0e63aa943e..6ca62aa2ae 100644
--- a/gnu/packages/perl.scm
+++ b/gnu/packages/perl.scm
@@ -2758,9 +2758,9 @@ versa using either JSON::XS or JSON::PP.")
     (build-system perl-build-system)
     (native-inputs
      `(("perl-test-fatal" ,perl-test-fatal)
-       ("perl-test-requires", perl-test-requires)
-       ("perl-test-warnings", perl-test-warnings)
-       ("perl-test-without-module", perl-test-without-module)))
+       ("perl-test-requires" ,perl-test-requires)
+       ("perl-test-warnings" ,perl-test-warnings)
+       ("perl-test-without-module" ,perl-test-without-module)))
     (propagated-inputs
      `(("perl-namespace-clean" ,perl-namespace-clean)))
     (home-page "http://search.cpan.org/dist/JSON-Any")
@@ -6277,4 +6277,27 @@ really be high enough to warrant the use of a keyword, and the size so small
 such that being individual extensions would be wasteful.")
     (license (package-license perl))))
 
+(define-public perl-shell-command
+  (package
+    (name "perl-shell-command")
+    (version "0.06")
+    (source
+      (origin
+        (method url-fetch)
+        (uri (string-append
+               "mirror://cpan/authors/id/F/FL/FLORA/Shell-Command-"
+               version
+               ".tar.gz"))
+        (sha256
+          (base32
+            "1lgc2rb3b5a4lxvbq0cbg08qk0n2i88srxbsz93bwi3razpxxr7k"))))
+    (build-system perl-build-system)
+    (home-page
+      "http://search.cpan.org/dist/Shell-Command")
+    (synopsis
+      "Cross-platform functions emulating common shell commands")
+    (description
+      "Shell::Command is a thin wrapper around ExtUtils::Command.")
+    (license (package-license perl))))
+
 ;;; END: Core module overrides
diff --git a/gnu/packages/pkg-config.scm b/gnu/packages/pkg-config.scm
index 5923395dec..d7cc454e03 100644
--- a/gnu/packages/pkg-config.scm
+++ b/gnu/packages/pkg-config.scm
@@ -33,9 +33,17 @@
    (version "0.29")
    (source (origin
             (method url-fetch)
-            (uri (string-append
-                  "http://pkgconfig.freedesktop.org/releases/pkg-config-"
-                  version ".tar.gz"))
+            (uri (list
+                  (string-append
+                   "http://fossies.org/linux/misc/pkg-config-" version
+                   ".tar.gz")
+
+                  ;; FIXME: The following URL redirects to HTTPS, which
+                  ;; creates bootstrapping problems:
+                  ;; <http://bugs.gnu.org/22774>.
+                  (string-append
+                   "http://pkgconfig.freedesktop.org/releases/pkg-config-"
+                   version ".tar.gz")))
             (sha256
              (base32
               "0sq09a39wj4cxf8l2jvkq067g08ywfma4v6nhprnf351s82pfl68"))))
diff --git a/gnu/packages/polkit.scm b/gnu/packages/polkit.scm
index 4cafb45d92..4f21612804 100644
--- a/gnu/packages/polkit.scm
+++ b/gnu/packages/polkit.scm
@@ -2,6 +2,7 @@
 ;;; Copyright © 2014 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -42,7 +43,7 @@
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://www.freedesktop.org/software/polkit/releases/"
+                   "https://www.freedesktop.org/software/polkit/releases/"
                    name "-" version ".tar.gz"))
              (sha256
               (base32
@@ -139,11 +140,11 @@ for unprivileged applications.")
                "1ip78x20hjqvm08kxhp6gb8hf6k5n6sxyx6kk2yvvq53djzh7yv7"))))
     (build-system cmake-build-system)
     (inputs
-      `(("polkit" ,polkit)))
+     `(("polkit" ,polkit)))
     (propagated-inputs
-      `(("qt" ,qt-4))) ; according to the pkg-config files
+     `(("qt" ,qt))) ; qt-4 according to the pkg-config files
     (native-inputs
-      `(("pkg-config", pkg-config)))
+     `(("pkg-config" ,pkg-config)))
     (arguments
      `(#:configure-flags (list (string-append "-DCMAKE_INSTALL_RPATH="
                                               (assoc-ref %outputs "out")
diff --git a/gnu/packages/pulseaudio.scm b/gnu/packages/pulseaudio.scm
index fe976a92f4..8c37b2a3f1 100644
--- a/gnu/packages/pulseaudio.scm
+++ b/gnu/packages/pulseaudio.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015 Ludovic Courtès <ludo@gnu.org>
-;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2014, 2015, 2016 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -43,17 +44,14 @@
 (define libsndfile
   (package
     (name "libsndfile")
-    (version "1.0.25")
+    (version "1.0.26")
     (source (origin
              (method url-fetch)
              (uri (string-append "http://www.mega-nerd.com/libsndfile/files/libsndfile-"
                                  version ".tar.gz"))
              (sha256
               (base32
-               "10j8mbb65xkyl0kfy0hpzpmrp0jkr12c7mfycqipxgka6ayns0ar"))
-             (patches
-              (map search-patch '("libsndfile-CVE-2014-9496.patch"
-                                  "libsndfile-CVE-2015-7805.patch")))))
+               "14jhla289cj45946h0hq2an0a9g4wkwb3v4571bla6ixfvn20rfd"))))
     (build-system gnu-build-system)
     (inputs
      `(("libvorbis" ,libvorbis)
@@ -117,15 +115,15 @@ rates.")
 (define pulseaudio
   (package
     (name "pulseaudio")
-    (version "6.0")
+    (version "8.0")
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://freedesktop.org/software/pulseaudio/releases/pulseaudio-"
-                   version ".tar.xz"))
+                   "https://freedesktop.org/software/pulseaudio/releases/"
+                   name "-" version ".tar.xz"))
              (sha256
               (base32
-               "1xpnfxa0d8pgf6b4qdgnkcvrvdxbbbjd5ync19h0f5hbp3h401mm"))
+               "128rrlvrgb4ia3pbzipf5mi6nvrpm6zmxn5r3bynqiikhvify3k9"))
              (modules '((guix build utils)))
              (snippet
               ;; Disable console-kit support by default since it's deprecated
@@ -198,7 +196,7 @@ sound server.")
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://freedesktop.org/software/pulseaudio/pavucontrol/pavucontrol-"
+                   "https://freedesktop.org/software/pulseaudio/pavucontrol/pavucontrol-"
                    version
                    ".tar.xz"))
              (sha256
diff --git a/gnu/packages/pumpio.scm b/gnu/packages/pumpio.scm
index 27a1250ae9..821090790e 100644
--- a/gnu/packages/pumpio.scm
+++ b/gnu/packages/pumpio.scm
@@ -24,7 +24,6 @@
   #:use-module (guix git-download)
   #:use-module (guix build-system gnu)
   #:use-module (gnu packages aspell)
-  #:use-module (gnu packages kde)
   #:use-module (gnu packages qt)
   #:use-module (gnu packages web))
 
diff --git a/gnu/packages/python.scm b/gnu/packages/python.scm
index 987e1238ff..2e485a9aff 100644
--- a/gnu/packages/python.scm
+++ b/gnu/packages/python.scm
@@ -17,6 +17,7 @@
 ;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;; Copyright © 2015 Kyle Meyer <kyle@kyleam.com>
 ;;; Copyright © 2015 Chris Marusich <cmmarusich@gmail.com>
+;;; Copyright © 2016 Danny Milosavljevic <dannym+a@scratchpost.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -37,7 +38,7 @@
   #:use-module ((guix licenses)
                 #:select (asl2.0 bsd-4 bsd-3 bsd-2 non-copyleft cc0 x11 x11-style
                           gpl2 gpl2+ gpl3+ lgpl2.0+ lgpl2.1 lgpl2.1+ lgpl3+ agpl3+
-                          isc mpl2.0 psfl public-domain unlicense x11-style
+                          isc mpl2.0 psfl public-domain repoze unlicense x11-style
                           zpl2.1))
   #:use-module ((guix licenses) #:select (expat zlib) #:prefix license:)
   #:use-module (gnu packages)
@@ -320,8 +321,8 @@ data types.")
                   (lambda (old new)
                     (symlink (string-append python old)
                              (string-append bin "/" new)))
-                  `("python3", "pydoc3", "idle3")
-                  `("python",  "pydoc",  "idle"))))))
+                  `("python3" ,"pydoc3" ,"idle3")
+                  `("python"  ,"pydoc"  ,"idle"))))))
     (synopsis "Wrapper for the Python 3 commands")
     (description
      "This package provides wrappers for the commands of Python@tie{}3.x such
@@ -966,14 +967,13 @@ datetime module, available in Python 2.3+.")
 (define-public python-pandas
   (package
     (name "python-pandas")
-    (version "0.16.0")
+    (version "0.16.2")
     (source
      (origin
-      (method url-fetch)
-      (uri (string-append "https://pypi.python.org/packages/source/p/"
-                          "pandas/pandas-" version ".tar.gz"))
-      (sha256
-       (base32 "1wfrp8dx1zcsry6f09ndza6qm1yr7f163211f4l9vjlnhxpxw4s0"))))
+       (method url-fetch)
+       (uri (pypi-uri "pandas" version))
+       (sha256
+        (base32 "10agmrkps8bi5948vwpipfxds5kj1d076m9i0nhaxwqiw7gm6670"))))
     (build-system python-build-system)
     (arguments
      `(;; Three tests fail:
@@ -1301,18 +1301,15 @@ bug tracker.")
 (define-public python-enum34
   (package
     (name "python-enum34")
-    (version "1.0")
+    (version "1.1.0")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "https://pypi.python.org/packages/source/e/"
-                          "enum34/enum34-" version ".tar.gz"))
+      (uri (pypi-uri "enum34" version))
       (sha256
        (base32
-        "0dg6mpg9n4g9diyrbnbb5vd9d1qw9f265zwhknqy0mxh0cvmjjrq"))))
+        "0yx1m4564wxgbm4glb3457hi16xihd9w63rv13y2przkdir9dfgp"))))
     (build-system python-build-system)
-    (inputs
-     `(("python-setuptools" ,python-setuptools)))
     (arguments
      `(#:phases
        (alist-replace
@@ -1326,6 +1323,9 @@ bug tracker.")
 backported for previous versions of Python from 2.4 to 3.3.")
     (license bsd-3)))
 
+(define-public python2-enum34
+  (package-with-python2 python-enum34))
+
 (define-public python-parse-type
   (package
     (name "python-parse-type")
@@ -1342,8 +1342,7 @@ backported for previous versions of Python from 2.4 to 3.3.")
     (inputs
      `(("python-setuptools" ,python-setuptools)
        ("python-six" ,python-six)
-       ("python-parse" ,python-parse)
-       ("python-enum34" ,python-enum34))) ;required for python<3.4
+       ("python-parse" ,python-parse)))
     (arguments '(#:tests? #f))            ;TODO: tests require pytest
     (home-page "https://github.com/jenisys/parse_type")
     (synopsis "Extended parse module")
@@ -1655,6 +1654,42 @@ supports coverage of subprocesses.")
 (define-public python2-pytest-runner
   (package-with-python2 python-pytest-runner))
 
+(define-public python-pytest-xdist
+  (package
+    (name "python-pytest-xdist")
+    (version "1.14")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "pytest-xdist" version ".zip"))
+       (sha256
+        (base32
+         "08rn2l39ds60xshs4js787l84pfckksqklfq2wq9x8ig2aci2pja"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("unzip" ,unzip)
+       ("python-setuptools" ,python-setuptools)
+       ("python-setuptools-scm" ,python-setuptools-scm)))
+    (propagated-inputs
+     `(("python-execnet" ,python-execnet)
+       ("python-pytest" ,python-pytest)
+       ("python-py" ,python-py)))
+    (home-page
+     "https://github.com/pytest-dev/pytest-xdist")
+    (synopsis
+     "Plugin for py.test with distributed testing and loop-on-failing modes")
+    (description
+     "The pytest-xdist plugin extends py.test with some unique test execution
+modes: parallelization, running tests in boxed subprocesses, the ability
+to run tests repeatedly when failed, and the ability to run tests on multiple
+Python interpreters or platforms.  It uses rsync to copy the existing
+program code to a remote location, executes there, and then syncs the
+result back.")
+    (license license:expat)))
+
+(define-public python2-pytest-xdist
+  (package-with-python2 python-pytest-xdist))
+
 (define-public python-scripttest
   (package
     (name "python-scripttest")
@@ -1993,7 +2028,6 @@ backported from Python 2.7 for Python 2.4+.")
     (inputs
      `(("python-setuptools" ,python-setuptools)
        ("python-six" ,python-six)
-       ("python-enum43" ,python-enum34)
        ("python-parse" ,python-parse)
        ("python-parse-type" ,python-parse-type)))
     (arguments `(#:tests? #f))          ;TODO: tests require nose>=1.3 and
@@ -2107,14 +2141,14 @@ with sensible defaults out of the box.")
 (define-public python-wheel
   (package
     (name "python-wheel")
-    (version "0.26.0")
+    (version "0.29.0")
     (source
       (origin
         (method url-fetch)
         (uri (pypi-uri "wheel" version))
         (sha256
          (base32
-          "032k1ajijbqnv0z0k88bhf75mdimi18fcmm28mss90610lw3bbga"))))
+          "0j0n38hg1jvrmyy68f9ikvzq1gs9g0sx4ws7maf8wi3bwbbqmfqy"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-setuptools" ,python-setuptools)
@@ -2130,27 +2164,27 @@ packages will be properly installed with only the @code{Unpack} step and the
 unpacked archive preserves enough information to @code{Spread} (copy data and
 scripts to their final locations) at any later time.  Wheel files can be
 installed with a newer @code{pip} or with wheel's own command line utility.")
-    (license license:expat)))
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-wheel))))))
 
 (define-public python2-wheel
-  (let ((wheel (package-with-python2 python-wheel)))
+  (let ((wheel (package-with-python2
+                (strip-python2-variant python-wheel))))
     (package (inherit wheel)
-      (native-inputs
-       `(("python2-functools32" ,python2-functools32)
-         ("python2-jsonschema" ,python2-jsonschema)
-         ,@(alist-delete "python-jsonschema"
-                         (package-native-inputs wheel)))))))
+      (native-inputs `(("python2-functools32" ,python2-functools32)
+                        ,@(package-native-inputs wheel))))))
+
 
 (define-public python-requests
   (package
     (name "python-requests")
-    (version "2.8.1")
+    (version "2.9.1")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "requests" version))
              (sha256
               (base32
-               "0ny2nr1sqr4hcn3903ghmh7w2yni8shlfv240a8c9p6wyidqvzl4"))))
+               "0zsqrzlybf25xscgi7ja4s48y2abf9wvjkn47wh984qgs1fq2xy5"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-setuptools" ,python-setuptools)))
@@ -2179,12 +2213,7 @@ than Python’s urllib2 library.")
                "0gdr9dxm24amxpbyqpbh3lbwxc2i42hnqv50sigx568qssv3v2ir"))))))
 
 (define-public python2-requests
-  (let ((requests (package-with-python2 python-requests)))
-    (package (inherit requests)
-      (propagated-inputs
-       `(("python2-wheel" ,python2-wheel)
-         ,@(alist-delete "python-wheel"
-                         (package-propagated-inputs requests)))))))
+  (package-with-python2 python-requests))
 
 (define-public python-vcversioner
   (package
@@ -2231,10 +2260,12 @@ version numbers.")
     (synopsis "Implementation of JSON Schema for Python")
     (description
      "Jsonschema is an implementation of JSON Schema for Python.")
-    (license license:expat)))
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-jsonschema))))))
 
 (define-public python2-jsonschema
-  (let ((jsonschema (package-with-python2 python-jsonschema)))
+  (let ((jsonschema (package-with-python2
+                     (strip-python2-variant python-jsonschema))))
     (package (inherit jsonschema)
       (inputs
        `(("python2-functools32" ,python2-functools32)
@@ -2305,7 +2336,7 @@ somewhat intelligeble.")
     (build-system python-build-system)
     (native-inputs
      `(("python-setuptools" ,python-setuptools)
-       ("python-coverage", python-coverage)
+       ("python-coverage" ,python-coverage)
        ("python-nose" ,python-nose)
        ("python-mock" ,python-mock)))
     (inputs
@@ -2945,7 +2976,7 @@ writing C extensions for Python as easy as Python itself.")
 (define python-numpy-bootstrap
   (package
     (name "python-numpy-bootstrap")
-    (version "1.9.1")
+    (version "1.10.4")
     (source
      (origin
        (method url-fetch)
@@ -2953,7 +2984,7 @@ writing C extensions for Python as easy as Python itself.")
                            "/numpy-" version ".tar.gz"))
        (sha256
         (base32
-         "070ybfvpgfmiz2hs94x445hvkh9dh52nyi0m8jp5kdihgvhbnx80"))))
+         "1bjjhvncraka5s6i4lg644jrxij6bvycxy7an20gcz3a0m11iygp"))))
     (build-system python-build-system)
     (inputs
      `(("python-nose" ,python-nose)
@@ -3014,16 +3045,14 @@ capabilities.")
 (define-public python2-fastlmm
   (package
     (name "python2-fastlmm")
-    (version "0.2.14")
+    (version "0.2.21")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append
-             "https://pypi.python.org/packages/source/f/fastlmm"
-             "/fastlmm-" version ".zip"))
+       (uri (pypi-uri "fastlmm" version ".zip"))
        (sha256
         (base32
-         "023sydkrc3yxad2bycar02jfswwlh4199kafzhf2bssyx2c3xa0l"))))
+         "1q8c34rpmwkfy3r4d5172pzdkpfryj561897z9r3x22gq7813x1m"))))
     (build-system python-build-system)
     (arguments
      `(#:python ,python-2)) ; only Python 2.7 is supported
@@ -3371,16 +3400,14 @@ toolkits.")
 (define-public python2-pysnptools
   (package
     (name "python2-pysnptools")
-    (version "0.2.13")
+    (version "0.3.5")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append
-             "https://pypi.python.org/packages/source/p/pysnptools"
-             "/pysnptools-" version ".zip"))
+       (uri (pypi-uri "pysnptools" version ".zip"))
        (sha256
         (base32
-         "1rzf5qvwfvd2pp84b14pb2gdvxdk5avnj7rb41ac8gndpkr9g6ib"))))
+         "15f4j4w5q603i7mlphb5r6mb1mn33pqg81595fpjp158140yqx7b"))))
     (build-system python-build-system)
     (arguments
      `(#:python ,python-2)) ; only Python 2.7 is supported
@@ -3538,7 +3565,7 @@ routines such as routines for numerical integration and optimization.")
 (define-public python-sqlalchemy
   (package
     (name "python-sqlalchemy")
-    (version "0.9.7")
+    (version "1.0.12")
     (source
      (origin
       (method url-fetch)
@@ -3546,7 +3573,7 @@ routines such as routines for numerical integration and optimization.")
                           "SQLAlchemy/SQLAlchemy-" version ".tar.gz"))
       (sha256
        (base32
-        "059ayifj5l08v6vv56anhyibyllscn10dlzr2fcw68gz1hfjdzsz"))))
+        "1l8qclhd0s90w3pvwhi5mjxdwr5j7gw7cjka2fx6f2vqmq7f4yb6"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-cython" ,python-cython) ;for c extensions
@@ -3570,6 +3597,42 @@ simple and Pythonic domain language.")
 (define-public python2-sqlalchemy
   (package-with-python2 python-sqlalchemy))
 
+(define-public python-alembic
+  (package
+    (name "python-alembic")
+    (version "0.8.4")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "alembic" version))
+       (sha256
+        (base32
+         "0jk23a852l3ybv7gfz81xzslyrnqnpjds5x15zd234y9rh9gq1w5"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-mock" ,python-mock)
+       ("python-pytest-cov" ,python-pytest-cov)))
+    (propagated-inputs
+     `(("python-sqlalchemy" ,python-sqlalchemy)
+       ("python-mako" ,python-mako)
+       ("python-editor" ,python-editor)))
+    (home-page "http://bitbucket.org/zzzeek/alembic")
+    (synopsis
+     "Database migration tool for SQLAlchemy")
+    (description
+     "Alembic is a lightweight database migration tool for usage with the
+SQLAlchemy Database Toolkit for Python.")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-alembic))))))
+
+(define-public python2-alembic
+  (let ((alembic (package-with-python2
+                  (strip-python2-variant python-alembic))))
+    (package
+      (inherit alembic)
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ,@(package-native-inputs alembic))))))
+
 (define-public python-distutils-extra
   (package
     (name "python-distutils-extra")
@@ -3888,18 +3951,18 @@ PNG, PostScript, PDF, and SVG file output.")
 (define-public python-decorator
   (package
     (name "python-decorator")
-    (version "4.0.6")
+    (version "4.0.9")
     (source
      (origin
        (method url-fetch)
        (uri (pypi-uri "decorator" version))
        (sha256
-        (base32 "1710cwsbwr8fkiq59w2min7rwgdz7ly51yz8l8yh1zbpfxcm8qhw"))))
+        (base32 "1a5vwhflfd9sh3rfb40xlyipldgdzfff6brman57hqv3661jw0lh"))))
     (build-system python-build-system)
     (arguments '(#:tests? #f)) ; no test target
     (native-inputs
      `(("python-setuptools" ,python-setuptools)))
-    (home-page "http://pypi.python.org/pypi/decorator/")
+    (home-page "https://pypi.python.org/pypi/decorator/")
     (synopsis "Python module to simplify usage of decorators")
     (description
       "The aim of the decorator module is to simplify the usage of decorators
@@ -4141,15 +4204,14 @@ standard library.")
 (define-public python-traitlets
   (package
     (name "python-traitlets")
-    (version "4.0.0")
+    (version "4.1.0")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "https://pypi.python.org/packages/source/t/"
-                           "traitlets/traitlets-" version ".tar.gz"))
+       (uri (pypi-uri "traitlets" version))
        (sha256
         (base32
-         "0fr3w2xwb46c591dp7zw02bgf4d21mjy9g6rhwc9bwd4ji50n50b"))))
+         "0nxgj8jxlm1kqf8cx2x7vjid05zdgbxpqhjbdl46r8njlpgkh3j4"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
@@ -4159,7 +4221,8 @@ standard library.")
      `(("python-ipython-genutils" ,python-ipython-genutils)
        ("python-decorator" ,python-decorator)))
     (native-inputs
-     `(("python-nose" ,python-nose)))
+     `(("python-mock" ,python-mock)
+       ("python-nose" ,python-nose)))
     (home-page "http://ipython.org")
     (synopsis "Configuration system for Python applications")
     (description
@@ -4294,17 +4357,14 @@ computing.")
 (define-public python-isodate
   (package
     (name "python-isodate")
-    (version "0.5.1")
+    (version "0.5.4")
     (source
       (origin
         (method url-fetch)
-        (uri (string-append
-              "https://pypi.python.org/packages/source/i/isodate/isodate-"
-              version
-              ".tar.gz"))
+        (uri (pypi-uri "isodate" version))
         (sha256
           (base32
-            "1yqjn0is0p64cmk9xhq4hc6q06jk86d60kg2jws58d78q0qysami"))))
+            "0cafaiwixgpxwh9dsd28qb0dbzsj6xpxjdkyk30ns91ps10mq422"))))
     (build-system python-build-system)
     (inputs
       `(("python-setuptools" ,python-setuptools)))
@@ -4323,17 +4383,14 @@ ISO 8601 dates, time and duration.")
 (define-public python-html5lib
   (package
     (name "python-html5lib")
-    (version "1.0b3")
+    (version "1.0b8")
     (source
       (origin
         (method url-fetch)
-        (uri (string-append
-              "https://pypi.python.org/packages/source/h/html5lib/html5lib-"
-              version
-              ".tar.gz"))
+        (uri (pypi-uri "html5lib" version))
         (sha256
           (base32
-            "1l5i6xzckzx4hnh9qzv9q3kyhkgjx2hsi2k9srgci3qizjmvp6ln"))))
+            "1lknq5j3nh11xrl268ks76zaj0gyzh34v94n5vbf6dk8llzxdx0q"))))
     (build-system python-build-system)
     (propagated-inputs
       `(("python-six" ,python-six))) ; required to "import html5lib"
@@ -4395,7 +4452,7 @@ features useful for text console applications.")
      (origin
        (method url-fetch)
        (uri (string-append
-             "http://dbus.freedesktop.org/releases/dbus-python/dbus-python-"
+             "https://dbus.freedesktop.org/releases/dbus-python/dbus-python-"
              version ".tar.gz"))
        (sha256
         (base32 "1py62qir966lvdkngg0v8k1khsqxwk5m4s8nflpk1agk5f5nqb71"))))
@@ -4471,17 +4528,14 @@ translate the complete SQLite API into Python.")
 (define-public python-lxml
   (package
     (name "python-lxml")
-    (version "3.4.2")
+    (version "3.5.0")
     (source
       (origin
         (method url-fetch)
-        (uri (string-append
-              "https://pypi.python.org/packages/source/l/lxml/lxml-"
-              version
-              ".tar.gz"))
+        (uri (pypi-uri "lxml" version))
         (sha256
           (base32
-            "0pd23qz8vms1mgm41p96h4vac5y91igs4wr9640gnvxgk019kmf7"))))
+            "0y7m2s8ci6q642zl85y5axkj8z827l0vhjl532acb75hlkir77rl"))))
     (build-system python-build-system)
     (inputs
       `(("libxml2" ,libxml2)
@@ -4498,6 +4552,39 @@ libxml2 and libxslt.")
 (define-public python2-lxml
   (package-with-python2 python-lxml))
 
+;; beautifulsoup4 has a totally different namespace than 3.x,
+;; and pypi seems to put it under its own name, so I guess we should too
+(define-public python-beautifulsoup4
+  (package
+    (name "python-beautifulsoup4")
+    (version "4.4.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "beautifulsoup4" version))
+       (sha256
+        (base32
+         "1d36lc4pfkvl74fmzdib2nqnvknm0jddgf2n9yd7im150qyh3m47"))))
+    (build-system python-build-system)
+    (home-page
+     "http://www.crummy.com/software/BeautifulSoup/bs4/")
+    (synopsis
+     "Python screen-scraping library")
+    (description
+     "Beautiful Soup is a Python library designed for rapidly setting up
+screen-scraping projects.  It offers Pythonic idioms for navigating,
+searching, and modifying a parse tree, providing a toolkit for
+dissecting a document and extracting what you need.  It automatically
+converts incoming documents to Unicode and outgoing documents to UTF-8.")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-beautifulsoup4))))))
+
+(define-public python2-beautifulsoup4
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-beautifulsoup4)))
+    (native-inputs `(("python2-setuptools" ,python2-setuptools)))))
+
 (define-public python2-pil
   (package
     (name "python2-pil")
@@ -4658,15 +4745,13 @@ interfaces in an easy and portable manner.")
 (define-public python-networkx
   (package
     (name "python-networkx")
-    (version "1.9.1")
+    (version "1.11")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append
-             "https://pypi.python.org/packages/source/n/networkx/networkx-"
-             version ".tar.gz"))
+       (uri (pypi-uri "networkx" version))
        (sha256
-        (base32 "0n8wy0yq1kmdq4wh68mlhwhkndvwzx48lg41a1z0sxxms0wfp033"))))
+        (base32 "1f74s56xb4ggixiq0vxyfxsfk8p20c7a099lpcf60izv1php03hd"))))
     (build-system python-build-system)
     ;; python-decorator is needed at runtime
     (propagated-inputs
@@ -4965,17 +5050,14 @@ applications.")
 (define-public python-pep8
   (package
     (name "python-pep8")
-    (version "1.6.2")
+    (version "1.7.0")
     (source
       (origin
         (method url-fetch)
-        (uri (string-append
-               "https://pypi.python.org/packages/source/p/pep8/pep8-"
-               version
-               ".tar.gz"))
+        (uri (pypi-uri "pep8" version))
         (sha256
           (base32
-            "1zybkcdw1sx84dvkfss96nhykqg9bc0cdpwpl4k9wlxm61bf7dxq"))))
+            "002rkl4lsn6x2mxmf8ar00l0m8i3mzrc6pnzz77blyksmpsxa4x1"))))
     (build-system python-build-system)
     (inputs
       `(("python-setuptools" ,python-setuptools)))
@@ -5016,20 +5098,19 @@ PEP 8.")
 (define-public python-mccabe
   (package
     (name "python-mccabe")
-    (version "0.3.1")
+    (version "0.4.0")
     (source
       (origin
         (method url-fetch)
-        (uri (string-append
-               "https://pypi.python.org/packages/source/m/mccabe/mccabe-"
-               version
-               ".tar.gz"))
+        (uri (pypi-uri "mccabe" version))
         (sha256
           (base32
-            "05ix3vdv5hjk4irl97n2n3c4g1vqvz7dbmkzs13f3bx97bxsczjz"))))
+            "0yr08a36h8lqlif10l4xcikbbig7q8f41gqywir7rrvnv3mi4aws"))))
     (build-system python-build-system)
     (inputs
-      `(("python-setuptools" ,python-setuptools)))
+      `(("python-pytest" ,python-pytest)
+        ("python-pytest-runner" ,python-pytest-runner)
+        ("python-setuptools" ,python-setuptools)))
     (home-page "https://github.com/flintwork/mccabe")
     (synopsis "McCabe checker, plugin for flake8")
     (description
@@ -5049,7 +5130,8 @@ complexity of Python source code.")
         (uri (pypi-uri "mccabe" version))
         (sha256
           (base32
-            "0fi4a81kr5bcv5p4xgibqr595hyj5dafkqgsmfk96mfy8w71fajs"))))))
+            "0fi4a81kr5bcv5p4xgibqr595hyj5dafkqgsmfk96mfy8w71fajs"))))
+    (inputs `(("python-setuptools" ,python-setuptools)))))
 
 (define-public python2-mccabe-0.2.1
   (package-with-python2 python-mccabe-0.2.1))
@@ -5095,19 +5177,19 @@ complexity of Python source code.")
 (define-public python-flake8
   (package
     (name "python-flake8")
-    (version "2.5.1")
+    (version "2.5.4")
     (source
       (origin
         (method url-fetch)
         (uri (pypi-uri "flake8" version))
         (sha256
           (base32
-            "00sn2g5ydriv5anbipcrprpv797kh4q8rfa75w3fc7v7n14fv2j4"))))
+            "0bs9cz4fr99r2rwig1b8jwaadl1nan7kgpdzqwj0bwbckwbmh7nc"))))
     (build-system python-build-system)
     (inputs
       `(("python-setuptools" ,python-setuptools)
-        ("python-pep8" ,python-pep8-1.5.7)
-        ("python-pyflakes" ,python-pyflakes-0.8.1)
+        ("python-pep8" ,python-pep8)
+        ("python-pyflakes" ,python-pyflakes)
         ("python-mccabe" ,python-mccabe)
         ("python-mock" ,python-mock)
         ("python-nose" ,python-nose)))
@@ -5314,7 +5396,7 @@ from an XML-based format.")
 (define-public python-ly
   (package
     (name "python-ly")
-    (version "0.9.2")
+    (version "0.9.3")
     (source
      (origin
        (method url-fetch)
@@ -5323,7 +5405,7 @@ from an XML-based format.")
              version ".tar.gz"))
        (sha256
         (base32
-         "1bsjg4q9ihr8bfdclrcmb8yjcg8xm9dznh58f3zsyrkrjzwbhcd2"))))
+         "1y6ananq8fia4y4m5id6gvsrm68bzpzd1y46pfzvawic0wjg2l0l"))))
     (build-system python-build-system)
     (native-inputs
      `(("python-setuptools" ,python-setuptools)))
@@ -5790,7 +5872,6 @@ responses, rather than doing any computation.")
      `(("python-cffi" ,python-cffi)
        ("python-six" ,python-six)
        ("python-pyasn1" ,python-pyasn1)
-       ("python-enum34" ,python-enum34)
        ("python-idna" ,python-idna)
        ("python-iso8601" ,python-iso8601)))
     (native-inputs
@@ -5810,15 +5891,18 @@ library” for Python.  The package includes both high level recipes, and low
 level interfaces to common cryptographic algorithms such as symmetric ciphers,
 message digests and key derivation functions.")
     ;; Distributed under either BSD-3 or ASL2.0
-    (license (list bsd-3 asl2.0))))
+    (license (list bsd-3 asl2.0))
+    (properties `((python2-variant . ,(delay python2-cryptography))))))
 
 (define-public python2-cryptography
-  (let ((crypto (package-with-python2 python-cryptography)))
+  (let ((crypto (package-with-python2
+                 (strip-python2-variant python-cryptography))))
     (package (inherit crypto)
       (propagated-inputs
        `(("python2-ipaddress" ,python2-ipaddress)
          ("python2-backport-ssl-match-hostname"
           ,python2-backport-ssl-match-hostname)
+         ("python2-enum34" ,python2-enum34)
          ,@(package-propagated-inputs crypto))))))
 
 (define-public python-pyopenssl
@@ -5870,12 +5954,7 @@ library.")
     (license asl2.0)))
 
 (define-public python2-pyopenssl
-  (let ((pyopenssl (package-with-python2 python-pyopenssl)))
-    (package (inherit pyopenssl)
-      (propagated-inputs
-       `(("python2-cryptography" ,python2-cryptography)
-         ,@(alist-delete "python-cryptography"
-                         (package-propagated-inputs pyopenssl)))))))
+  (package-with-python2 python-pyopenssl))
 
 (define-public python-pip
   (package
@@ -6663,7 +6742,7 @@ of the SSL peer.")
          (replace 'check
            (lambda _ (zero?
                       (system*
-                       "python" "test_contextlib2.py", "-v")))))))
+                       "python" "test_contextlib2.py" "-v")))))))
     (home-page "http://contextlib2.readthedocs.org/")
     (synopsis "Tools for decorators and context managers")
     (description "This module is primarily a backport of the Python
@@ -6728,13 +6807,13 @@ WebSocket usage in Python programs.")
 (define-public python-atomicwrites
   (package
     (name "python-atomicwrites")
-    (version "0.1.8")
+    (version "0.1.9")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "atomicwrites" version))
              (sha256
               (base32
-               "13nwk0gw0yb61pnf5vxs3fvhav6q3zrf08x9ggc93bnk5fsssx1j"))))
+               "08s05h211r07vs66r4din3swrbzb344vli041fihpg34q3lcxpvw"))))
     (build-system python-build-system)
     (synopsis "Atomic file writes in Python")
     (description "Library for atomic file writes using platform dependent tools
@@ -6745,13 +6824,13 @@ for atomic filesystem operations.")
 (define-public python-requests-toolbelt
   (package
     (name "python-requests-toolbelt")
-    (version "0.5.0")
+    (version "0.6.0")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "requests-toolbelt" version))
              (sha256
               (base32
-               "1kbms1s52dhb98vbpaprr15b0ijdbqp500lpfsyjccpd8cjkyngk"))))
+               "07slish560haspn0hpwgy2izhk2snqq06s6acp8xzmhhz079qknc"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-requests" ,python-requests)))
@@ -6783,13 +6862,13 @@ applications.")
 (define-public python-click-log
   (package
     (name "python-click-log")
-    (version "0.1.1")
+    (version "0.1.3")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "click-log" version))
              (sha256
               (base32
-               "1z3jdwjmwax159zrnyx830xa968rfqrpkm04ad5xqyh0269ydiqb"))))
+               "0kdd1vminxpcfczxl2kkf285n0dr1gxh2cdbx1p6vkj7b7bci3gx"))))
     (build-system python-build-system)
     (propagated-inputs
      `(("python-click" ,python-click)))
@@ -6810,8 +6889,6 @@ applications.")
               (base32
                "1iks5701qnp3dlr3q1d9qm68y2plp2m029irhpz92a44psfkjf1f"))))
     (build-system python-build-system)
-    (native-inputs
-     `(("unzip" ,unzip)))
     (propagated-inputs
      `(("python-pytest" ,python-pytest)))
     (synopsis "Namespace control and lazy-import mechanism")
@@ -6819,7 +6896,15 @@ applications.")
 package and greatly reduce the number of imports for your users.  It is a small
 pure Python module that works on virtually all Python versions.")
     (home-page "https://bitbucket.org/hpk42/apipkg")
-    (license license:expat)))
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-apipkg))))))
+
+(define-public python2-apipkg
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-apipkg)))
+    (native-inputs
+     `(("python2-setuptools" ,python2-setuptools)))))
 
 (define-public python-execnet
   (package
@@ -6847,7 +6932,17 @@ minimal and fast API targetting the following uses:
 @item write scripts to administer multiple environments
 @end enumerate")
     (home-page "http://codespeak.net/execnet/")
-    (license license:expat)))
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-execnet))))))
+
+(define-public python2-execnet
+  (let ((execnet (package-with-python2
+                  (strip-python2-variant python-execnet))))
+    (package
+      (inherit execnet)
+      (native-inputs
+       `(("python2-setuptools" ,python2-setuptools)
+         ,@(package-native-inputs execnet))))))
 
 ;;; The software provided by this package was integrated into pytest 2.8.
 (define-public python-pytest-cache
@@ -6872,13 +6967,13 @@ the last py.test invocation.")
 (define-public python-pytest-localserver
   (package
     (name "python-pytest-localserver")
-    (version "0.3.4")
+    (version "0.3.5")
     (source (origin
              (method url-fetch)
-             (uri (pypi-uri "pytest-localserver" version ".zip"))
+             (uri (pypi-uri "pytest-localserver" version))
              (sha256
               (base32
-               "050q505a7gnsz7vqidw0w5dvxjb2flzi7z734agpjzmsl85c2bcx"))))
+               "0dvqspjr6va55zwmnnc2mmpqc7mm65kxig9ya44x1z8aadzxpa4p"))))
     (build-system python-build-system)
     (arguments
       `(#:phases (modify-phases %standard-phases
@@ -6902,16 +6997,17 @@ framework which enables you to test server connections locally.")
 (define-public python-wsgi-intercept
   (package
     (name "python-wsgi-intercept")
-    (version "0.10.3")
+    (version "1.1.2")
     (source (origin
              (method url-fetch)
              (uri (pypi-uri "wsgi_intercept" version))
              (sha256
               (base32
-               "0xyfchacywb1mql84270mcidsqc5ssyspd18yacjk82x2xc68h0r"))))
+               "14ajy415ch5d0dnspg4b592p66wlgzah7ay218flp13517fp49zl"))))
     (build-system python-build-system)
     (native-inputs
-     `(("python-pytest" ,python-pytest)))
+     `(("python-pytest" ,python-pytest)
+       ("python-six" ,python-six)))
     (propagated-inputs
      `(("python-httplib2" ,python-httplib2)
        ("python-requests" ,python-requests)))
@@ -7140,7 +7236,7 @@ authenticated session objects providing things like keep-alive.")
     (package (inherit rauth)
       (propagated-inputs `(("python2-requests" ,python2-requests)))
       (native-inputs
-       `(("python2-unittest2", python2-unittest2)
+       `(("python2-unittest2" ,python2-unittest2)
          ,@(package-native-inputs rauth))))))
 
 (define-public python2-functools32
@@ -7424,17 +7520,14 @@ Amazon Web Services (AWS) API.")
 (define-public python-hypothesis
   (package
     (name "python-hypothesis")
-    (version "2.0.0")
+    (version "3.0.4")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "hypothesis" version))
               (sha256
                (base32
-                "1la6mfpvcn640gs2v35iv8b4sh6xdhp9j5ghay0jd86c9n4fkgxr"))))
+                "0bh6pqyc56cqlbpg0ffzjs6466blyylix4nsw11qrqwf01cg9gdq"))))
     (build-system python-build-system)
-    (native-inputs
-     `(;; setuptools required for python-2 variant
-       ("python-setuptools" ,python-setuptools)))
     (propagated-inputs
      `(("python-flake8" ,python-flake8)
        ("python-pytest" ,python-pytest)))
@@ -7444,10 +7537,16 @@ much larger range of examples than you would ever want to write by hand.  It’s
 based on the Haskell library, Quickcheck, and is designed to integrate
 seamlessly into your existing Python unit testing work flow.")
     (home-page "https://github.com/DRMacIver/hypothesis")
-    (license mpl2.0)))
+    (license mpl2.0)
+    (properties `((python2-variant . ,(delay python2-hypothesis))))))
 
 (define-public python2-hypothesis
-  (package-with-python2 python-hypothesis))
+  (let ((hypothesis (package-with-python2
+                     (strip-python2-variant python-hypothesis))))
+    (package (inherit hypothesis)
+      (native-inputs
+       `(("python2-enum34" ,python2-enum34)
+         ("python2-setuptools" ,python2-setuptools))))))
 
 (define-public python-pytest-subtesthack
   (package
@@ -7503,3 +7602,657 @@ input.  (Note that this is mostly a legacy library; you may wish to look at
 python-xdo for newer bindings.)")
     (license bsd-3)))
 
+(define-public python-wtforms
+  (package
+    (name "python-wtforms")
+    (version "2.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "WTForms" version ".zip"))
+       (sha256
+        (base32
+         "0vyl26y9cg409cfyj8rhqxazsdnd0jipgjw06civhrd53yyi1pzz"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("unzip" ,unzip)))
+    (home-page "http://wtforms.simplecodes.com/")
+    (synopsis
+     "Form validation and rendering library for Python web development")
+    (description
+     "WTForms is a flexible forms validation and rendering library
+for Python web development.  It is very similar to the web form API
+available in Django, but is a standalone package.")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-wtforms))))))
+
+(define-public python2-wtforms
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-wtforms)))
+    (inputs `(("python2-setuptools" ,python2-setuptools)))))
+
+(define-public python-mako
+  (package
+    (name "python-mako")
+    (version "1.0.3")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "Mako" version))
+       (sha256
+        (base32
+         "136kcjbs0s98qkx8a418b05dfblqp0kiiqyx8vhx4rarwc7bqi3n"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-markupsafe" ,python-markupsafe)
+       ("python-mock" ,python-mock)
+       ("python-nose" ,python-nose)))
+    (home-page "http://www.makotemplates.org/")
+    (synopsis "Templating language for Python")
+    (description "Mako is a templating language for Python that compiles
+templates into Python modules.")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-mako))))))
+
+(define-public python2-mako
+  (let ((base (package-with-python2
+               (strip-python2-variant python-mako))))
+    (package
+      (inherit base)
+      (native-inputs
+       (cons `("python2-setuptools" ,python2-setuptools)
+             (package-native-inputs base))))))
+
+(define-public python-waitress
+  (package
+    (name "python-waitress")
+    (version "0.8.10")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "waitress" version))
+       (sha256
+        (base32
+         "017n9ra6vvmq9d5sfhdzyzr1mg15x2hj2dhm4pdlw98c1ypw2h3w"))))
+    (build-system python-build-system)
+    (home-page "https://github.com/Pylons/waitress")
+    (synopsis "Waitress WSGI server")
+    (description "Waitress is meant to be a production-quality pure-Python WSGI
+server with very acceptable performance.")
+    (license zpl2.1)
+    (properties `((python2-variant . ,(delay python2-waitress))))))
+
+(define-public python2-waitress
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-waitress)))
+    (native-inputs `(("python2-setuptools" ,python2-setuptools)))))
+
+(define-public python-wsgiproxy2
+  (package
+    (name "python-wsgiproxy2")
+    (version "0.4.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "WSGIProxy2" version ".zip"))
+       (sha256
+        (base32
+         "13kf9bdxrc95y9vriaz0viry3ah11nz4rlrykcfvb8nlqpx3dcm4"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("unzip" ,unzip)
+       ("python-nose" ,python-nose)
+       ("python-coverage" ,python-coverage)))
+    (propagated-inputs
+     `(("python-six" ,python-six)
+       ("python-webob" ,python-webob)))
+    (home-page
+     "https://github.com/gawel/WSGIProxy2/")
+    (synopsis "WSGI Proxy with various http client backends")
+    (description "WSGI turns HTTP requests into WSGI function calls.
+WSGIProxy turns WSGI function calls into HTTP requests.
+It also includes code to sign requests and pass private data,
+and to spawn subprocesses to handle requests.")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-wsgiproxy2))))))
+
+(define-public python2-wsgiproxy2
+  (let ((wsgiproxy2 (package-with-python2
+                     (strip-python2-variant python-wsgiproxy2))))
+    (package
+      (inherit wsgiproxy2)
+      (inputs `(("python2-setuptools" ,python2-setuptools)
+                ,@(package-inputs wsgiproxy2))))))
+
+(define-public python-pastedeploy
+  (package
+    (name "python-pastedeploy")
+    (version "1.5.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "PasteDeploy" version))
+       (sha256
+        (base32
+         "1jz3m4hq8v6hyhfjz9425nd3nvn52cvbfipdcd72krjmla4qz1fm"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)))
+    (propagated-inputs
+     ;; This package uses pkg_resources, part of setuptools, during runtime,
+     ;; hence why not a native-input.
+     `(("python-setuptools" ,python-setuptools)))
+    (home-page "http://pythonpaste.org/deploy/")
+    (synopsis
+     "Load, configure, and compose WSGI applications and servers")
+    (description
+     "This tool provides code to load WSGI applications and servers from URIs;
+these URIs can refer to Python Eggs for INI-style configuration files.  Paste
+Script provides commands to serve applications based on this configuration
+file.")
+    (license license:expat)))
+
+(define-public python2-pastedeploy
+  (package-with-python2 python-pastedeploy))
+
+(define-public python-paste
+  (package
+    (name "python-paste")
+    (version "2.0.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "Paste" version))
+       (sha256
+        (base32
+         "16dsv9qi0r4qsrsb6dilpq2rx0fnglvh36flzywcdnm2jg43mb5d"))
+       (patches (list (search-patch
+                       "python-paste-remove-website-test.patch")
+                      (search-patch
+                       "python-paste-remove-timing-test.patch")))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)))
+    (propagated-inputs
+     `(;; Uses pkg_resources provided by setuptools internally.
+       ("python-setuptools" ,python-setuptools)
+       ("python-six" ,python-six)))
+    (arguments
+     '(;; Tests don't pass on Python 3, but work fine on Python 2.
+       ;; (As of 2.0.2, Python 3 support in Paste is presently a bit broken,
+       ;; but is usable enough for the minimal amount it's used in MediaGoblin
+       ;; still... things should be better by the next Paste release.)
+       #:tests? #f))
+    (home-page "http://pythonpaste.org")
+    (synopsis
+     "Python web development tools, focusing on WSGI")
+    (description
+     "Paste provides a variety of web development tools and middleware which
+can be nested together to build web applications.  Paste's design closely
+follows ideas flowing from WSGI (Web Standard Gateway Interface).")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-paste))))))
+
+(define-public python2-paste
+  (let ((paste (package-with-python2
+                (strip-python2-variant python-paste))))
+    (package
+      (inherit paste)
+      (arguments
+       ;; Tests are back for Python 2!
+       `(#:tests? #t
+         ,@(package-arguments paste))))))
+
+(define-public python-pastescript
+  (package
+    (name "python-pastescript")
+    (version "2.0.2")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "PasteScript" version))
+       (sha256
+        (base32
+         "1h3nnhn45kf4pbcv669ik4faw04j58k8vbj1hwrc532k0nc28gy0"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)))
+    (propagated-inputs
+     `(;; Uses pkg_resources provided by setuptools internally.
+       ("python-setuptools" ,python-setuptools)
+       ("python-paste" ,python-paste)
+       ("python-pastedeploy" ,python-pastedeploy)))
+    (home-page "http://pythonpaste.org/script/")
+    (arguments
+     '(;; Unfortunately, this requires the latest unittest2,
+       ;; but that requires traceback2 which requires linecache2 which requires
+       ;; unittest2.  So we're skipping tests for now.
+       ;; (Note: Apparently linetest2 only needs unittest2 for its tests,
+       ;; so in theory we could get around this situation somehow.)
+       #:tests? #f))
+    (synopsis
+     "Pluggable command line tool for serving web applications and more")
+    (description
+     "PasteScript is a plugin-friendly command line tool which provides a
+variety of features, from launching web applications to bootstrapping project
+layouts.")
+    (license license:expat)))
+
+(define-public python2-pastescript
+  (package-with-python2 python-pastescript))
+
+(define-public python-pyquery
+  (package
+    (name "python-pyquery")
+    (version "1.2.11")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "pyquery" version))
+       (sha256
+        (base32
+         "1ikz1387nsp0pp7mzzr6ip9n5gr67acpap24yn33987v7fkjp0sa"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-lxml" ,python-lxml)
+       ("python-cssselect" ,python-cssselect)))
+    (home-page "https://github.com/gawel/pyquery")
+    (synopsis "Make jQuery-like queries on xml documents")
+    (description "pyquery allows you to make jQuery queries on xml documents.
+The API is as much as possible the similar to jQuery.  pyquery uses lxml for
+fast xml and html manipulation.")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-pyquery))))))
+
+(define-public python2-pyquery
+  (let ((pyquery (package-with-python2
+                  (strip-python2-variant python-pyquery))))
+    (package
+      (inherit pyquery)
+      (native-inputs `(("python2-setuptools" ,python2-setuptools))))))
+
+(define-public python-webtest
+  (package
+    (name "python-webtest")
+    (version "2.0.20")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "WebTest" version))
+       (sha256
+        (base32
+         "0bv0qhdjakdsdgj4sk21gnpp8xp8bga4x03p6gjb83ihrsb7n4xv"))))
+    (build-system python-build-system)
+    (arguments
+     `(;; Unfortunately we have to disable tests!
+       ;; This release of WebTest is pinned to python-nose < 1.3,
+       ;; but older versions of python-nose are plagued with the following
+       ;; bug(s), which rears its ugly head during test execution:
+       ;;   https://github.com/nose-devs/nose/issues/759
+       ;;   https://github.com/nose-devs/nose/pull/811
+       #:tests? #f))
+    ;; Commented out code is no good, but in this case, once tests
+    ;; are ready to be enabled again, we should put the following
+    ;; in place:
+    ;;  (native-inputs
+    ;;   `(("python-nose" ,python-nose) ; technially < 1.3,
+    ;;                                  ; but see above comment
+    ;;     ("python-coverage" ,python-coverage)
+    ;;     ("python-mock" ,python-mock)
+    ;;     ("python-pastedeploy" ,python-pastedeploy)
+    ;;     ("python-wsgiproxy2" ,python-wsgiproxy2)
+    ;;     ("python-pyquery" ,python-pyquery)))
+    (propagated-inputs
+     `(("python-waitress" ,python-waitress)
+       ("python-webob" ,python-webob)
+       ("python-six" ,python-six)
+       ("python-beautifulsoup4" ,python-beautifulsoup4)))
+    (home-page "http://webtest.pythonpaste.org/")
+    (synopsis "Helper to test WSGI applications")
+    (description "Webtest allows you to test your Python web applications
+without starting an HTTP server.  It supports anything that supports the
+minimum of WSGI.")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-webtest))))))
+
+(define-public python2-webtest
+  (let ((webtest (package-with-python2
+                  (strip-python2-variant python-webtest))))
+    (package
+      (inherit webtest)
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ,@(package-native-inputs webtest))))))
+
+(define-public python-anyjson
+  (package
+    (name "python-anyjson")
+    (version "0.3.3")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "anyjson" version))
+       (sha256
+        (base32
+         "1fjph4alvcscsl5d4b6qpv1yh31jy05jxi1l0xff7lws7j32v09p"))))
+    (build-system python-build-system)
+    (arguments
+     `(;; We could possibly get tests working, but on Python 3 it's not so easy.
+       ;; Very strangely, 2to3 is run *during setup.py install* (or bdist, or
+       ;; whatever) so this transformation needs to be done before the tests
+       ;; can be run.  Maybe we could add a build step to transform beforehand
+       ;; but it could be annoying/difficult.
+       ;; We can enable tests for the Python 2 version, though, and do below.
+       #:tests? #f))
+    (home-page "http://bitbucket.org/runeh/anyjson/")
+    (synopsis
+     "Wraps best available JSON implementation in a common interface")
+    (description
+     "Anyjson loads whichever is the fastest JSON module installed
+and provides a uniform API regardless of which JSON implementation is used.")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-anyjson))))))
+
+(define-public python2-anyjson
+  (let ((anyjson (package-with-python2
+                  (strip-python2-variant python-anyjson))))
+    (package
+      (inherit anyjson)
+      (arguments `(;; Unlike the python 3 variant, we do run tests.  See above!
+                   #:tests? #t
+                   ,@(package-arguments anyjson)))
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ("python2-nose" ,python2-nose))))))
+
+(define-public python-amqp
+  (package
+    (name "python-amqp")
+    (version "1.4.9")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "amqp" version))
+       (sha256
+        (base32
+         "06n6q0kxhjnbfz3vn8x9yz09lwmn1xi9d6wxp31h5jbks0b4vsid"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)
+       ("python-mock" ,python-mock)))
+    (home-page "http://github.com/celery/py-amqp")
+    (synopsis
+     "Low-level AMQP client for Python (fork of amqplib)")
+    (description
+     "This is a fork of amqplib which was originally written by Barry Pederson.
+It is maintained by the Celery project, and used by kombu as a pure python
+alternative when librabbitmq is not available.")
+    (license lgpl2.1+)
+    (properties `((python2-variant . ,(delay python2-amqp))))))
+
+(define-public python2-amqp
+  (let ((amqp (package-with-python2
+               (strip-python2-variant python-amqp))))
+    (package
+      (inherit amqp)
+      (arguments `(;; Tries to run coverage tests with nose-cover3, which seems
+                   ;; unmaintained.  Weirdly, does not do this on the python 3
+                   ;; version?
+                   #:tests? #f
+                   ,@(package-arguments amqp)))
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ,@(package-native-inputs amqp))))))
+
+(define-public python-kombu
+  (package
+    (name "python-kombu")
+    (version "3.0.33")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "kombu" version))
+       (sha256
+        (base32
+         "16brjx2lgwbj2a37d0pjbfb84nvld6irghmqrs3qfncajp51hgc5"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-mock" ,python-mock)
+       ("python-nose" ,python-nose)))
+    (propagated-inputs
+     `(("python-anyjson" ,python-anyjson)
+       ("python-amqp" ,python-amqp)))
+    (home-page "http://kombu.readthedocs.org")
+    (synopsis "Message passing library for Python")
+    (description "The aim of Kombu is to make messaging in Python as easy as
+possible by providing an idiomatic high-level interface for the AMQ protocol,
+and also provide proven and tested solutions to common messaging problems.
+AMQP is the Advanced Message Queuing Protocol, an open standard protocol for
+message orientation, queuing, routing, reliability and security, for which the
+RabbitMQ messaging server is the most popular implementation.")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-kombu))))))
+
+(define-public python2-kombu
+  (let ((kombu (package-with-python2
+                (strip-python2-variant python-kombu))))
+    (package
+      (inherit kombu)
+      (inputs `(("python2-setuptools" ,python2-setuptools)
+                ("python2-unittest2" ,python2-unittest2)
+                ,@(package-inputs kombu))))))
+
+(define-public python-billiard
+  (package
+    (name "python-billiard")
+    (version "3.3.0.22")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "billiard" version))
+       (sha256
+        (base32
+         "0zp7h6a58alrb3mwdw61jds07395j4j0mj6iqsb8czrihw9ih5nj"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)))
+    (home-page "http://github.com/celery/billiard")
+    (synopsis
+     "Python multiprocessing fork with improvements and bugfixes")
+    (description
+     "Billiard is a fork of the Python 2.7 multiprocessing package.  The
+multiprocessing package itself is a renamed and updated version of R Oudkerk's
+pyprocessing package.  This standalone variant is intended to be compatible with
+Python 2.4 and 2.5, and will draw its fixes/improvements from python-trunk.")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-billiard))))))
+
+(define-public python2-billiard
+  (let ((billiard (package-with-python2
+                   (strip-python2-variant python-billiard))))
+    (package
+      (inherit billiard)
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ("python2-unittest2" ,python2-unittest2)
+                       ("python2-mock" ,python2-mock)
+                       ,@(package-native-inputs billiard))))))
+
+(define-public python-celery
+  (package
+    (name "python-celery")
+    (version "3.1.20")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "celery" version))
+       (sha256
+        (base32
+         "1md6ywg1s0946qyp8ndnsd677wm0yax933h2sb4m3a4j7lf1jbyh"))))
+    (build-system python-build-system)
+    (native-inputs
+     `(("python-nose" ,python-nose)))
+    (propagated-inputs
+     `(("python-pytz" ,python-pytz)
+       ("python-billiard" ,python-billiard)
+       ("python-kombu" ,python-kombu)))
+    (home-page "http://celeryproject.org")
+    (synopsis "Distributed Task Queue")
+    (description "Celery is an asynchronous task queue/job queue based on
+distributed message passing.  It is focused on real-time operation, but
+supports scheduling as well.  The execution units, called tasks, are executed
+concurrently on a single or more worker servers using multiprocessing,
+Eventlet, or gevent.  Tasks can execute asynchronously (in the background) or
+synchronously (wait until ready).")
+    (license bsd-3)
+    (properties `((python2-variant . ,(delay python2-celery))))))
+
+(define-public python2-celery
+  (let ((celery (package-with-python2
+                 (strip-python2-variant python-celery))))
+    (package
+      (inherit celery)
+      (native-inputs `(("python2-setuptools" ,python2-setuptools)
+                       ("python2-unittest2" ,python2-unittest2)
+                       ("python2-mock" ,python2-mock)
+                       ,@(package-native-inputs celery))))))
+
+(define-public python-translitcodec
+  (package
+    (name "python-translitcodec")
+    (version "0.4.0")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "translitcodec" version))
+       (sha256
+        (base32
+         "10x6pvblkzky1zhjs8nmx64nb9jdzxad4bxhq4iwv0j4z2aqjnki"))))
+    (build-system python-build-system)
+    (arguments
+     `(#:tests? #f))  ; no tests provided
+    (home-page
+     "https://github.com/claudep/translitcodec")
+    (synopsis
+     "Unicode to 8-bit charset transliteration codec")
+    (description
+     "This package contains codecs for transliterating ISO 10646 texts into
+best-effort representations using smaller coded character sets (ASCII,
+ISO 8859, etc.).")
+    (license license:expat)
+    (properties `((python2-variant . ,(delay python2-translitcodec))))))
+
+(define-public python2-translitcodec
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-translitcodec)))
+    (native-inputs `(("python2-setuptools" ,python2-setuptools)))))
+
+(define-public python-editor
+  (package
+  (name "python-editor")
+  (version "0.5")
+  (source
+    (origin
+      (method url-fetch)
+      (uri (pypi-uri "python-editor" version))
+      (sha256
+        (base32
+          "1ypnpgvzpkbwsg4rdvy4sy51j28b5xq9v8pnkwxncn07vqz06p7n"))))
+  (build-system python-build-system)
+  (home-page
+    "https://github.com/fmoo/python-editor")
+  (synopsis
+    "Programmatically open an editor, capture the result")
+  (description
+    "python-editor is a library that provides the editor module for
+programmatically interfacing with your system's $EDITOR.")
+  (license asl2.0)
+  (properties `((python2-variant . ,(delay python2-editor))))))
+
+(define-public python2-editor
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-editor)))
+    (inputs `(("python2-setuptools" ,python2-setuptools)))))
+
+(define-public python-sphinxcontrib-programoutput
+  (package
+    (name "python-sphinxcontrib-programoutput")
+    (version "0.8")
+    (source (origin
+              (method url-fetch)
+              (uri (pypi-uri "sphinxcontrib-programoutput" version))
+              (sha256
+               (base32
+                "098as6z1s0gb4dh5xcr1fd2vpm91zj93jzvgawspxf5s4hqs0xhp"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-docutils" ,python-docutils)
+       ("python-sphinx" ,python-sphinx)))
+    (synopsis "Sphinx extension to include program output")
+    (description "A Sphinx extension to literally insert the output of arbitrary
+commands into documents, helping you to keep your command examples up to date.")
+    (home-page "https://github.com/lunaryorn/sphinxcontrib-programoutput")
+    (license bsd-2)
+    (properties `((python2-variant . ,(delay python2-sphinxcontrib-programoutput))))))
+
+(define-public python2-sphinxcontrib-programoutput
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-sphinxcontrib-programoutput)))
+    (native-inputs `(("python2-setuptools" ,python2-setuptools)))))
+
+(define-public python-sphinx-repoze-autointerface
+  (package
+    (name "python-sphinx-repoze-autointerface")
+    (version "0.7.1")
+    (source (origin
+              (method url-fetch)
+              (uri (pypi-uri "repoze.sphinx.autointerface" version))
+              (sha256
+               (base32
+                "016mv3wbylw278wl7z33y2liyra8ljp08zq1g0anzadh1an5zvwp"))))
+    (build-system python-build-system)
+    (propagated-inputs
+     `(("python-docutils" ,python-docutils)
+       ("python-sphinx" ,python-sphinx)
+       ("python-zope-interface" ,python-zope-interface)))
+    (synopsis "Auto-generate Sphinx API docs from Zope interfaces")
+    (description "This package defines an extension for the Sphinx documentation
+system.  The extension allows generation of API documentation by
+introspection of @code{zope.interface} instances in code.")
+    (home-page "https://github.com/repoze/repoze.sphinx.autointerface")
+    (license repoze)))
+
+(define-public python2-sphinx-repoze-autointerface
+  (package-with-python2 python-sphinx-repoze-autointerface))
+
+(define-public python-psycopg2
+  (package
+    (name "python-psycopg2")
+    (version "2.6.1")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (pypi-uri "psycopg2" version))
+       (sha256
+        (base32
+         "0k4hshvrwsh8yagydyxgmd0pjm29lwdxkngcq9fzfzkmpsxrmkva"))))
+    (build-system python-build-system)
+    (arguments
+     ;; Tests would require a postgresql database "psycopg2_test"
+     ;; and a running postgresql database management service.
+     `(#:tests? #f)) ; TODO re-enable after providing a test-db.
+    (inputs
+     `(("postgresql" ,postgresql))) ; libpq
+    (home-page "http://initd.org/psycopg/")
+    (synopsis "Python PostgreSQL adapter")
+    (description
+     "psycopg2 is a thread-safe PostgreSQL adapter that implements DB-API 2.0. ")
+    (license lgpl3+)
+    (properties `((python2-variant . ,(delay python2-psycopg2))))))
+
+(define-public python2-psycopg2
+  (package
+    (inherit (package-with-python2
+              (strip-python2-variant python-psycopg2)))
+    (native-inputs `(("python2-setuptools" ,python2-setuptools)))))
diff --git a/gnu/packages/qemu.scm b/gnu/packages/qemu.scm
index 7624cdcae9..1104a2da6a 100644
--- a/gnu/packages/qemu.scm
+++ b/gnu/packages/qemu.scm
@@ -71,7 +71,11 @@
                      "qemu-CVE-2015-8613.patch"
                      "qemu-CVE-2015-8701.patch"
                      "qemu-CVE-2015-8743.patch"
-                     "qemu-CVE-2016-1568.patch")))))
+                     "qemu-CVE-2016-1568.patch"
+                     "qemu-CVE-2015-8619.patch"
+                     "qemu-CVE-2016-1981.patch"
+                     "qemu-usb-ehci-oob-read.patch"
+                     "qemu-CVE-2016-2197.patch")))))
     (build-system gnu-build-system)
     (arguments
      '(#:phases (alist-replace
diff --git a/gnu/packages/qt.scm b/gnu/packages/qt.scm
index dccc9a2e48..bfd99b6519 100644
--- a/gnu/packages/qt.scm
+++ b/gnu/packages/qt.scm
@@ -20,7 +20,7 @@
 ;;; along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.
 
 (define-module (gnu packages qt)
-  #:use-module ((guix licenses) #:select (bsd-3 gpl2 gpl3 lgpl2.1 x11-style))
+  #:use-module ((guix licenses) #:select (bsd-3 gpl2 gpl3 lgpl2.1 lgpl2.1+ x11-style))
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build utils)
@@ -337,6 +337,30 @@ developers using C++ or QML, a CSS & JavaScript like language.")
               (delete-file-recursively olddoc)
               #t))))))))
 
+(define-public qjson
+  (package
+    (name "qjson")
+    (version "0.8.1")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "https://github.com/flavio/qjson/archive/"
+                                 version ".tar.gz"))
+             (file-name (string-append name "-" version ".tar.gz"))
+             (sha256
+              (base32
+               "163fspi0xc705irv79qw861fmh68pjyla9vx3kqiq6xrdhb9834j"))))
+    (build-system cmake-build-system)
+    (inputs
+     `(("qt" ,qt-4)))
+    (arguments
+     `(#:tests? #f)) ; no test target
+    (home-page "http://qjson.sourceforge.net/")
+    (synopsis "Qt-based library for handling JSON")
+    (description "QJson is a Qt-based library that maps JSON data to QVariant
+objects and vice versa.  JSON arrays are mapped to QVariantList instances,
+while JSON objects are mapped to QVariantMap.")
+    (license lgpl2.1+)))
+
 (define-public python-sip
   (package
     (name "python-sip")
@@ -517,15 +541,6 @@ contain over 620 classes.")
          %standard-phases)))
     (license (list gpl2 gpl3)))) ; choice of either license
 
-(define-public python2-pyqt-4
-  (package (inherit python-pyqt-4)
-    (name "python2-pyqt")
-    (native-inputs
-     `(("python-sip" ,python2-sip)
-       ("qt" ,qt-4)))
-    (inputs
-     `(("python" ,python-2)))))
-
 (define-public qtkeychain
   (package
     (name "qtkeychain")
@@ -540,7 +555,7 @@ contain over 620 classes.")
          (base32 "055mkd4pz6cyff4cw0784wjc1w92m8x223sxi96ph15fr3lplbg6"))))
     (build-system cmake-build-system)
     (inputs
-     `(("qt", qt)))
+     `(("qt" ,qt)))
     (arguments
      `(#:tests? #f ; No tests included
        #:phases
diff --git a/gnu/packages/rdf.scm b/gnu/packages/rdf.scm
index 13ffa2a8fe..b577e266f9 100644
--- a/gnu/packages/rdf.scm
+++ b/gnu/packages/rdf.scm
@@ -19,7 +19,7 @@
 
 (define-module (gnu packages rdf)
   #:use-module ((guix licenses)
-                #:select (non-copyleft isc gpl2 lgpl2.0+ lgpl2.1 lgpl2.1+))
+                #:select (non-copyleft isc gpl2 lgpl2.1 lgpl2.1+))
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix build-system cmake)
@@ -298,35 +298,6 @@ ideal (e.g. in LV2 implementations or embedded applications).")
      "Sord is a lightweight C library for storing RDF data in memory.")
     (license isc)))
 
-(define-public soprano
-  (package
-    (name "soprano")
-    (version "2.9.4")
-    (source (origin
-             (method url-fetch)
-             (uri (string-append "mirror://sourceforge/soprano/Soprano/"
-                                version "/"
-                                "soprano-" version ".tar.bz2"))
-             (sha256
-              (base32
-               "1rg0x7yg0a1cbnxz7kqk52580wla8jbnj4d4r3j7l7g7ajyny1k4"))
-             (patches (list (search-patch "soprano-find-clucene.patch")))))
-    (build-system cmake-build-system)
-    (native-inputs
-     `(("doxygen" ,doxygen)
-       ("pkg-config" ,pkg-config)))
-    (inputs
-     `(("clucene" ,clucene)
-       ("qt" ,qt-4)
-       ("redland" ,redland)))
-    (home-page "http://soprano.sourceforge.net/")
-    (synopsis "RDF data library for Qt")
-    (description "Soprano (formerly known as QRDF) is a library which
-provides a highly usable object-oriented C++/Qt4 framework for RDF data.  It
-uses different RDF storage solutions as backends through a simple plugin
-system.")
-    (license lgpl2.0+)))
-
 (define-public python-rdflib
   (package
     (name "python-rdflib")
diff --git a/gnu/packages/ruby.scm b/gnu/packages/ruby.scm
index fa7c2f7691..a1669d4238 100644
--- a/gnu/packages/ruby.scm
+++ b/gnu/packages/ruby.scm
@@ -1905,7 +1905,7 @@ to reproduce user environments.")
                                         "/include/libxml2" ))))
     (native-inputs
      `(("ruby-hoe" ,ruby-hoe)
-       ("ruby-rake-compiler", ruby-rake-compiler)))
+       ("ruby-rake-compiler" ,ruby-rake-compiler)))
     (inputs
      `(("zlib" ,zlib)
        ("libxml2" ,libxml2)
diff --git a/gnu/packages/scheme.scm b/gnu/packages/scheme.scm
index 352b66c59b..00b573fc0b 100644
--- a/gnu/packages/scheme.scm
+++ b/gnu/packages/scheme.scm
@@ -526,12 +526,6 @@ an isolated heap allowing multiple VMs to run simultaneously in different OS
 threads.")
     (license bsd-3)))
 
-;; FIXME: This function is temporarily in the engineering module and not
-;; exported.  It will be moved to an utility module for general use.  Once
-;; this is done, we should remove this definition.
-(define broken-tarball-fetch
-  (@@ (gnu packages engineering) broken-tarball-fetch))
-
 (define-public scmutils
   (let ()
     (define (system-suffix)
@@ -546,7 +540,7 @@ threads.")
       (version "20140302")
       (source
        (origin
-         (method broken-tarball-fetch)
+         (method url-fetch/tarbomb)
          (modules '((guix build utils)))
          (snippet
           ;; Remove binary code
diff --git a/gnu/packages/screen.scm b/gnu/packages/screen.scm
index fa5235c115..088ca559d8 100644
--- a/gnu/packages/screen.scm
+++ b/gnu/packages/screen.scm
@@ -44,7 +44,7 @@
     (native-inputs
      `(("makeinfo" ,texinfo)))
     (inputs
-     `(("ncurses", ncurses)
+     `(("ncurses" ,ncurses)
        ("perl" ,perl)))
     (arguments
      `(#:configure-flags
diff --git a/gnu/packages/ssh.scm b/gnu/packages/ssh.scm
index d4bf29cc20..081c7cbe32 100644
--- a/gnu/packages/ssh.scm
+++ b/gnu/packages/ssh.scm
@@ -1,7 +1,8 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014 Andreas Enge <andreas@enge.fr>
 ;;; Copyright © 2014, 2015, 2016 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2015 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2015, 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -44,15 +45,15 @@
 (define-public libssh
   (package
     (name "libssh")
-    (version "0.6.5")
+    (version "0.7.3")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "https://red.libssh.org/attachments/download/121/libssh-"
+                    "https://red.libssh.org/attachments/download/195/libssh-"
                     version ".tar.xz"))
               (sha256
                (base32
-                "0b6wyx6bwbb8jpn8x4rhlrdiqwqrwrs0mxjmrnqykm9kw1ijgm8g"))))
+                "165g49i4kmm3bfsjm0n8hm21kadv79g9yjqyq09138jxanz4dvr6"))))
     (build-system cmake-build-system)
     (arguments
      '(#:configure-flags '("-DWITH_GCRYPT=ON")
@@ -60,7 +61,7 @@
        ;; TODO: Add 'CMockery' and '-DWITH_TESTING=ON' for the test suite.
        #:tests? #f))
     (inputs `(("zlib" ,zlib)
-              ("libgcrypt", libgcrypt)))
+              ("libgcrypt" ,libgcrypt)))
     (synopsis "SSH client library")
     (description
      "libssh is a C library implementing the SSHv2 and SSHv1 protocol for
@@ -70,29 +71,32 @@ remote applications.")
     (home-page "http://www.libssh.org")
     (license license:lgpl2.1+)))
 
-(define libssh-0.5                                ; kept private
+(define libssh-0.6 ; kept private for use in guile-ssh
   (package (inherit libssh)
-    (version "0.5.5")
+    (version "0.6.5")
     (source (origin
               (method url-fetch)
-              (uri (string-append "https://red.libssh.org/attachments/download/51/libssh-"
-                                  version ".tar.gz"))
+              (uri (string-append "https://red.libssh.org/attachments/"
+                                  "download/121/libssh-"
+                                  version ".tar.xz"))
               (sha256
                (base32
-                "17cfdff4hc0ijzrr15biq29fiabafz0bw621zlkbwbc1zh2hzpy0"))
-              (patches (list (search-patch "libssh-CVE-2014-0017.patch")))))))
+                "0b6wyx6bwbb8jpn8x4rhlrdiqwqrwrs0mxjmrnqykm9kw1ijgm8g"))
+              (patches (list
+                        (search-patch "libssh-0.6.5-CVE-2016-0739.patch")))))))
 
 (define-public libssh2
   (package
    (name "libssh2")
-   (version "1.4.3")
+   (version "1.7.0")
    (source (origin
             (method url-fetch)
             (uri (string-append
-                   "http://www.libssh2.org/download/libssh2-"
+                   "https://www.libssh2.org/download/libssh2-"
                    version ".tar.gz"))
-            (sha256 (base32
-                     "0vdr478dbhbdgnniqmirawjb7mrcxckn4slhhrijxnzrkmgziipa"))))
+            (sha256
+             (base32
+              "116mh112w48vv9k3f15ggp5kxw5sj4b88dzb5j69llsh7ba1ymp4"))))
    (build-system gnu-build-system)
    ;; The installed libssh2.pc file does not include paths to libgcrypt and
    ;; zlib libraries, so we need to propagate the inputs.
@@ -108,6 +112,24 @@ a server that supports the SSH-2 protocol.")
    (license license:bsd-3)
    (home-page "http://www.libssh2.org/")))
 
+;;; XXX This is a temporary package for use only by curl, to allow most users
+;;; of libssh2 to get the security update sooner while postponing the large
+;;; number of rebuilds entailed by updating curl.
+;;;
+;;; XXX This package is vulnerable to CVE-2016-7087.
+;;;
+;;; https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-0787
+(define-public libssh2-1.4
+  (package (inherit libssh2)
+    (version "1.4.3")
+    (source (origin
+             (method url-fetch)
+             (uri (string-append "https://www.libssh2.org/download/libssh2-"
+                                 version ".tar.gz"))
+             (sha256
+              (base32
+                "0vdr478dbhbdgnniqmirawjb7mrcxckn4slhhrijxnzrkmgziipa"))))))
+
 (define-public openssh
   (package
    (name "openssh")
@@ -235,7 +257,7 @@ Additionally, various channel-specific options can be negotiated.")
                      ("pkg-config" ,pkg-config)
                      ("which" ,which)))
     (inputs `(("guile" ,guile-2.0)
-              ("libssh" ,libssh)
+              ("libssh" ,libssh-0.6)
               ("libgcrypt" ,libgcrypt)))
     (synopsis "Guile bindings to libssh")
     (description
@@ -332,14 +354,15 @@ especially over Wi-Fi, cellular, and long-distance links.")
 (define-public dropbear
   (package
     (name "dropbear")
-    (version "2014.63")
+    (version "2015.71")
     (source (origin
               (method url-fetch)
               (uri (string-append
-                    "http://matt.ucc.asn.au/" name "/releases/"
+                    "https://matt.ucc.asn.au/" name "/releases/"
                     name "-" version ".tar.bz2"))
               (sha256
-               (base32 "1bjpbg2vi5f332q4bqxkidkjfxsqmnqvp4g1wyh8d99b8gg94nar"))))
+               (base32
+                "1bw3lzmisn6gs6zy9vcqbfnicl437ydskqcayklpw60fkhb18qip"))))
     (build-system gnu-build-system)
     (arguments  `(#:tests? #f)) ; There is no "make check" or anything similar
     (inputs `(("zlib" ,zlib)))
diff --git a/gnu/packages/statistics.scm b/gnu/packages/statistics.scm
index ee6fd4a20d..08e8654228 100644
--- a/gnu/packages/statistics.scm
+++ b/gnu/packages/statistics.scm
@@ -1,7 +1,8 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;; Copyright © 2015 Vicente Vera Parra <vicentemvp@gmail.com>
-;;; Copyright ©2016 Andreas Enge <andreas@enge.fr>
+;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -945,14 +946,13 @@ and fast file reading.")
 (define-public python-patsy
   (package
     (name "python-patsy")
-    (version "0.4.0")
+    (version "0.4.1")
     (source (origin
               (method url-fetch)
-              (uri (string-append "https://pypi.python.org/packages/source/"
-                                  "p/patsy/patsy-" version ".zip"))
+              (uri (pypi-uri "patsy" version ".zip"))
               (sha256
                (base32
-                "1kbs996xc2haxalmhd19rr1wh5fa4gbbxf81czkf5w4kam7h7wz4"))))
+                "1m6knyq8hbqlx242y4da02j0x86j4qggs1j7q186w3jv0j0c476w"))))
     (build-system python-build-system)
     (arguments
      `(#:phases
@@ -979,20 +979,15 @@ building design matrices.")
     ;; The majority of the code is distributed under BSD-2.  The module
     ;; patsy.compat contains code derived from the Python standard library,
     ;; and is covered by the PSFL.
-    (license (list license:bsd-2 license:psfl))))
+    (license (list license:bsd-2 license:psfl))
+    (properties `((python2-variant . ,(delay python2-patsy))))))
 
 (define-public python2-patsy
-  (let ((patsy (package-with-python2 python-patsy)))
+  (let ((patsy (package-with-python2 (strip-python2-variant python-patsy))))
     (package (inherit patsy)
       (native-inputs
        `(("python2-setuptools" ,python2-setuptools)
-         ,@(package-native-inputs patsy)))
-      (propagated-inputs
-       `(("python2-numpy" ,python2-numpy)
-         ("python2-scipy" ,python2-scipy)
-         ,@(alist-delete "python-numpy"
-                         (alist-delete "python-scipy"
-                                       (package-propagated-inputs patsy))))))))
+         ,@(package-native-inputs patsy))))))
 
 (define-public python-statsmodels
   (package
diff --git a/gnu/packages/tcl.scm b/gnu/packages/tcl.scm
index 2c4c750997..1f301458a9 100644
--- a/gnu/packages/tcl.scm
+++ b/gnu/packages/tcl.scm
@@ -3,6 +3,7 @@
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
 ;;; Copyright © 2014 Eric Bavier <bavier@member.fsf.org>
 ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,6 +30,7 @@
   #:use-module (gnu packages fontutils)
   #:use-module (gnu packages perl)
   #:use-module (gnu packages pkg-config)
+  #:use-module (gnu packages xml)
   #:use-module (gnu packages xorg)
   #:use-module (guix licenses))
 
@@ -80,8 +82,7 @@
     (home-page "http://www.tcl.tk/")
     (synopsis "The Tcl scripting language")
     (description "The Tcl (Tool Command Language) scripting language.")
-    (license (non-copyleft "http://www.tcl.tk/software/tcltk/license.html"
-                        "Tcl/Tk license"))))
+    (license tcl/tk)))
 
 
 (define-public expect
@@ -219,3 +220,73 @@ interfaces (GUIs) in the Tcl language.")
     ;; pTk/license.terms, pTk/license.html_lib, and pTk/Tix.license for
     ;; details of this license."
     (license (package-license perl))))
+
+(define-public tcllib
+  (package
+    (name "tcllib")
+    (version "1.18")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://sourceforge/" name "/"
+                                  name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "05dmrk9qsryah2n17z6z85dj9l9lfyvnsd7faw0p9bs1pp5pwrkj"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("tcl" ,tcl)))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "TCLLIBPATH")
+            (separator " ")
+            (files (list (string-append "lib/tcllib" version))))))
+    (home-page "https://core.tcl.tk/tcllib/home")
+    (synopsis "Standard Tcl Library")
+    (description "Tcllib, the standard Tcl library, is a collection of common
+utility functions and modules all written in high-level Tcl.")
+    (license (package-license tcl))))
+
+(define-public tclxml
+  (package
+    (name "tclxml")
+    (version "3.2")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "mirror://sourceforge/" name "/"
+                                  name "-" version ".tar.gz"))
+              (sha256
+               (base32
+                "0ffb4aw63inig3aql33g4pk0kjk14dv238anp1scwjdjh1k6n4gl"))
+              (patches (list (search-patch "tclxml-3.2-install.patch")))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("tcl" ,tcl)
+       ("tcllib" ,tcllib)
+       ("libxml2" ,libxml2)
+       ("libxslt" ,libxslt)))
+    (native-search-paths
+     (list (search-path-specification
+            (variable "TCLLIBPATH")
+            (separator " ")
+            (files (list (string-append "lib/Tclxml" version))))))
+    (arguments
+     `(#:configure-flags
+       (list (string-append "--exec-prefix=" (assoc-ref %outputs "out"))
+             (string-append "--with-tclconfig="
+                            (assoc-ref %build-inputs "tcl") "/lib")
+             (string-append "--with-xml2-config="
+                            (assoc-ref %build-inputs "libxml2")
+                            "/bin/xml2-config")
+             (string-append "--with-xslt-config="
+                            (assoc-ref %build-inputs "libxslt")
+                            "/bin/xslt-config"))
+       #:test-target "test"))
+    (home-page "http://tclxml.sourceforge.net/")
+    (synopsis "Tcl library for XML parsing")
+    (description "TclXML provides event-based parsing of XML documents.  The
+application may register callback scripts for certain document features, and
+when the parser encounters those features while parsing the document the
+callback is evaluated.")
+    (license (non-copyleft
+              "file://LICENCE"
+              "See LICENCE in the distribution."))))
diff --git a/gnu/packages/texlive.scm b/gnu/packages/texlive.scm
index 0b2dec41f6..d8200846ac 100644
--- a/gnu/packages/texlive.scm
+++ b/gnu/packages/texlive.scm
@@ -24,6 +24,7 @@
   #:use-module (guix download)
   #:use-module (guix build-system gnu)
   #:use-module (guix build-system trivial)
+  #:use-module (guix utils)
   #:use-module (gnu packages)
   #:use-module (gnu packages bash)
   #:use-module (gnu packages compression)
@@ -45,7 +46,9 @@
   #:use-module (gnu packages xorg)
   #:use-module (gnu packages xdisorg)
   #:use-module (gnu packages zip)
-  #:autoload   (gnu packages texinfo) (texinfo))
+  #:autoload   (gnu packages texinfo) (texinfo)
+  #:use-module (ice-9 ftw)
+  #:use-module (srfi srfi-1))
 
 (define texlive-extra-src
   (origin
@@ -284,6 +287,77 @@ This package contains the complete TeX Live distribution.")
    (license (license:fsf-free "http://tug.org/texlive/copying.html"))
    (home-page "http://www.tug.org/texlive/")))
 
+
+;; texlive-texmf-minimal is a pruned, small version of the texlive tree,
+;; in particular dropping documentation and fonts.
+(define texlive-texmf-minimal
+  (package (inherit texlive-texmf)
+   (name "texlive-texmf-minimal")
+   (arguments
+    (substitute-keyword-arguments
+     (package-arguments texlive-texmf)
+     ((#:modules modules)
+      `((ice-9 ftw)
+        (srfi srfi-1)
+        ,@modules))
+     ((#:phases phases)
+      `(modify-phases ,phases
+         (add-after 'unpack 'prune
+           (lambda _
+             (define (delete subdir exclude)
+               "Delete all files and directories in SUBDIR except for those
+given in the list EXCLUDE."
+               (with-directory-excursion subdir
+                 (for-each delete-file-recursively
+                           (lset-difference equal?
+                                            (scandir ".")
+                                            (append '("." "..")
+                                                    exclude)))))
+             (with-directory-excursion "texmf-dist"
+               (for-each delete-file-recursively
+                         '("doc" "source" "tex4ht"))
+               ;; Delete all subdirectories of "fonts", except for "tfm" and
+               ;; any directories named "cm".
+               (delete "fonts" '("afm" "map" "pk" "source" "tfm" "type1"))
+               (delete "fonts/afm" '("public"))
+               (delete "fonts/afm/public" '("amsfonts"))
+               (delete "fonts/afm/public/amsfonts" '("cm"))
+               (delete "fonts/map" '("dvips"))
+               (delete "fonts/map/dvips" '("cm"))
+               (delete "fonts/source" '("public"))
+               (delete "fonts/source/public" '("cm"))
+               (delete "fonts/tfm" '("public"))
+               (delete "fonts/type1" '("public"))
+               (delete "fonts/type1/public" '("amsfonts"))
+               (delete "fonts/type1/public/amsfonts" '("cm")))
+             #t))))))
+   (description
+    "TeX Live provides a comprehensive TeX document production system.
+It includes all the major TeX-related programs, macro packages, and fonts
+that are free software, including support for many languages around the
+world.
+
+This package contains a small subset of the texmf-dist data.")))
+
+
+;; texlive-minimal is the same as texlive, but using texlive-texmf-minimal
+;; instead of the full texlive-texmf. It can be used, for instance, as a
+;; native input to packages that need texlive to build their documentation.
+(define-public texlive-minimal
+  (package (inherit texlive)
+   (name "texlive-minimal")
+   (inputs
+    `(("texlive-texmf" ,texlive-texmf-minimal)
+      ,@(alist-delete "texlive-texmf" (package-inputs texlive))))
+   (description
+    "TeX Live provides a comprehensive TeX document production system.
+It includes all the major TeX-related programs, macro packages, and fonts
+that are free software, including support for many languages around the
+world.
+
+This package contains a small working part of the TeX Live distribution.")))
+
+
 (define-public rubber
   (package
     (name "rubber")
diff --git a/gnu/packages/textutils.scm b/gnu/packages/textutils.scm
index f2c60ddadf..6f3782fa7b 100644
--- a/gnu/packages/textutils.scm
+++ b/gnu/packages/textutils.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 Taylan Ulrich Bayırlı/Kammer <taylanbayirli@gmail.com>
 ;;; Copyright © 2015, 2016 Ricardo Wurmus <rekado@elephly.net>
-;;; Copyright © 2015 Ben Woodcroft <donttrustben@gmail.com>
+;;; Copyright © 2015, 2016 Ben Woodcroft <donttrustben@gmail.com>
 ;;; Copyright © 2015 Roel Janssen <roel@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
@@ -152,11 +152,10 @@ the Hannon Lab.")
     (license license:agpl3+)))
 
 (define-public cityhash
-  (let ((commit "8af9b8c")
-        (revision "1"))
+  (let ((commit "8af9b8c"))
     (package
       (name "cityhash")
-      (version (string-append "1.1." revision "." commit))
+      (version (string-append "1.1-2." commit))
       (source (origin
                 (method git-fetch)
                 (uri (git-reference
@@ -166,13 +165,25 @@ the Hannon Lab.")
                 (sha256
                  (base32
                   "0n6skf5dv8yfl1ckax8dqhvsbslkwc9158zf2ims0xqdvzsahbi6"))))
-    (build-system gnu-build-system)
-    (home-page "https://github.com/google/cityhash")
-    (synopsis "C++ hash functions for strings")
-    (description
-     "CityHash provides hash functions for strings.  The functions mix the
+      (build-system gnu-build-system)
+      (arguments
+       '(#:make-flags (list "CXXFLAGS=-g -O3")
+         #:phases
+         (modify-phases %standard-phases
+           ;; citycrc is not installed by default but is used by some
+           ;; programs.
+           (add-after 'install 'install-citycrc
+             (lambda* (#:key outputs #:allow-other-keys)
+               (let* ((out (assoc-ref outputs "out"))
+                      (include (string-append out "/include")))
+                 (install-file "src/citycrc.h" include))
+               #t)))))
+      (home-page "https://github.com/google/cityhash")
+      (synopsis "C++ hash functions for strings")
+      (description
+       "CityHash provides hash functions for strings.  The functions mix the
 input bits thoroughly but are not suitable for cryptography.")
-    (license license:expat))))
+      (license license:expat))))
 
 (define-public libconfig
   (package
diff --git a/gnu/packages/tls.scm b/gnu/packages/tls.scm
index 703cb299e1..4f2c7af3de 100644
--- a/gnu/packages/tls.scm
+++ b/gnu/packages/tls.scm
@@ -73,7 +73,7 @@ specifications.")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "http://p11-glue.freedesktop.org/releases/p11-kit-"
+      (uri (string-append "https://p11-glue.freedesktop.org/releases/p11-kit-"
                           version ".tar.gz"))
       (sha256
        (base32
@@ -318,57 +318,107 @@ security, and applying best practice development processes.")
                      "file://COPYING"
                      "See COPYING in the distribution.")))))
 
-(define-public acme
+(define-public python-acme
   (package
-    (name "acme")
-    (version "0.2.0")
+    (name "python-acme")
+    (version "0.4.0")
     (source (origin
       (method url-fetch)
       (uri (pypi-uri "acme" version))
       (sha256
         (base32
-         "1xcbywzrwrj2cmqhaj4k6b11wfkbm3i7za2k9j1sd74rs1zh5abl"))))
+         "173j2zkslh43fzf3wkl1jdzfjry361m0mhlc3jpwp7hk7lrclzjg"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
-    ;; TODO: Add optional inputs for testing and building documentation.
+     `(#:phases
+       (modify-phases %standard-phases
+         (add-before 'install 'disable-egg-compression
+           (lambda _
+             ;; Do not compress the egg.
+             ;; See <http://bugs.gnu.org/20765>.
+             (let ((port (open-file "setup.cfg" "a")))
+               (display "\n[easy_install]\nzip_ok = 0\n"
+                        port)
+               (close-port port)
+               #t)))
+         (add-after 'install 'docs
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (man (string-append out "/share/man/man1"))
+                    (info (string-append out "/info")))
+               (and (zero? (system* "make" "-C" "docs" "man" "info"))
+                    (install-file "docs/_build/texinfo/acme-python.info" info)
+                    (install-file "docs/_build/man/acme-python.1" man)
+                    #t)))))))
+    ;; TODO: Add optional inputs for testing.
     (native-inputs
-     `(("python2-mock" ,python2-mock)
-       ("python2-setuptools" ,python2-setuptools)))
+     `(("python-mock" ,python-mock)
+       ;; For documentation
+       ("python-sphinx" ,python-sphinx)
+       ("python-sphinxcontrib-programoutput" ,python-sphinxcontrib-programoutput)
+       ("python-sphinx-rtd-theme" ,python-sphinx-rtd-theme)
+       ("python-setuptools" ,python-setuptools)
+       ("texinfo" ,texinfo)))
     (propagated-inputs
-     `(("python2-ndg-httpsclient" ,python2-ndg-httpsclient)
-       ("python2-werkzeug" ,python2-werkzeug)
-       ("python2-six" ,python2-six)
-       ("python2-requests" ,python2-requests)
-       ("python2-pytz" ,python2-pytz)
-       ("python2-pyrfc3339" ,python2-pyrfc3339)
-       ("python2-pyasn1" ,python2-pyasn1)
-       ("python2-cryptography" ,python2-cryptography)
-       ("python2-pyopenssl" ,python2-pyopenssl)))
+     `(("python-ndg-httpsclient" ,python-ndg-httpsclient)
+       ("python-werkzeug" ,python-werkzeug)
+       ("python-six" ,python-six)
+       ("python-requests" ,python-requests)
+       ("python-pytz" ,python-pytz)
+       ("python-pyrfc3339" ,python-pyrfc3339)
+       ("python-pyasn1" ,python-pyasn1)
+       ("python-cryptography" ,python-cryptography)
+       ("python-pyopenssl" ,python-pyopenssl)))
     (home-page "https://github.com/letsencrypt/letsencrypt")
     (synopsis "ACME protocol implementation in Python")
     (description "ACME protocol implementation in Python")
     (license license:asl2.0)))
 
+(define-public python2-acme
+  (package-with-python2 python-acme))
+
 (define-public letsencrypt
   (package
     (name "letsencrypt")
-    (version "0.2.0")
+    (version "0.4.0")
     (source (origin
               (method url-fetch)
               (uri (pypi-uri "letsencrypt" version))
               (sha256
                (base32
-                "0q57ylx00b6kl9zvawgag5yl03vlv1cjhp18xm96682pdibbgjci"))))
+                "1wwq8yvfdybf4d0gv4yfddkrg865s7rhng5xg563kks4wza1a2wp"))))
     (build-system python-build-system)
     (arguments
-     `(#:python ,python-2))
-    ;; TODO: Add optional inputs for testing building documentation.
+     `(#:python ,python-2
+       #:phases
+       (modify-phases %standard-phases
+         (add-after 'install 'docs
+           (lambda* (#:key outputs #:allow-other-keys)
+             (let* ((out (assoc-ref outputs "out"))
+                    (man1 (string-append out "/share/man/man1"))
+                    (man7 (string-append out "/share/man/man7"))
+                    (info (string-append out "/info")))
+               (substitute* "docs/man/letsencrypt.rst"
+                 (("letsencrypt --help all")
+                  (string-append out "/bin/letsencrypt" " --help all")))
+               (and
+                 (zero? (system* "make" "-C" "docs" "man" "info"))
+                 (install-file "docs/_build/texinfo/LetsEncrypt.info" info)
+                 (install-file "docs/_build/man/letsencrypt.1" man1)
+                 (install-file "docs/_build/man/letsencrypt.7" man7)
+                 #t)))))))
+    ;; TODO: Add optional inputs for testing.
     (native-inputs
      `(("python2-nose" ,python2-nose)
-       ("python2-mock" ,python2-mock)))
+       ("python2-mock" ,python2-mock)
+       ;; For documentation
+       ("python2-sphinx" ,python2-sphinx)
+       ("python2-sphinx-rtd-theme" ,python2-sphinx-rtd-theme)
+       ("python2-sphinx-repoze-autointerface" ,python2-sphinx-repoze-autointerface)
+       ("python2-sphinxcontrib-programoutput" ,python2-sphinxcontrib-programoutput)
+       ("texinfo" ,texinfo)))
     (propagated-inputs
-     `(("acme" ,acme)
+     `(("python2-acme" ,python2-acme)
        ("python2-zope-interface" ,python2-zope-interface)
        ("python2-pythondialog" ,python2-pythondialog)
        ("python2-pyrfc3339" ,python2-pyrfc3339)
diff --git a/gnu/packages/version-control.scm b/gnu/packages/version-control.scm
index e0626cb3ac..0712f9f392 100644
--- a/gnu/packages/version-control.scm
+++ b/gnu/packages/version-control.scm
@@ -30,6 +30,7 @@
                 #:select (asl2.0 bsd-2
                           gpl1+ gpl2 gpl2+ gpl3+ lgpl2.1
                           x11-style))
+  #:use-module (guix utils)
   #:use-module (guix packages)
   #:use-module (guix download)
   #:use-module (guix git-download)
@@ -75,15 +76,16 @@
 (define-public bazaar
   (package
     (name "bazaar")
-    (version "2.6.0")
+    (version "2.7.0")
     (source
      (origin
       (method url-fetch)
-      (uri (string-append "https://launchpad.net/bzr/2.6/" version
+      (uri (string-append "https://launchpad.net/bzr/"
+                          (version-major+minor version) "/" version
                           "/+download/bzr-" version ".tar.gz"))
       (sha256
        (base32
-        "1c6sj77h5f97qimjc14kr532kgc0jk3wq778xrkqi0pbh9qpk509"))))
+        "1cysix5k3wa6y7jjck3ckq3abls4gvz570s0v0hxv805nwki4i8d"))))
     (build-system python-build-system)
     (inputs
      ;; Note: 'tools/packaging/lp-upload-release' and 'tools/weavemerge.sh'
diff --git a/gnu/packages/video.scm b/gnu/packages/video.scm
index bc155fba18..7d6c363da8 100644
--- a/gnu/packages/video.scm
+++ b/gnu/packages/video.scm
@@ -187,14 +187,14 @@ television and DVD.  It is also known as AC-3.")
 (define-public libx264
   (package
     (name "libx264")
-    (version "20150706-2245")
+    (version "20160220-2245")
     (source (origin
               (method url-fetch)
-              (uri (string-append "ftp://ftp.videolan.org/pub/x264/snapshots/"
+              (uri (string-append "http://download.videolan.org/pub/x264/snapshots/"
                                   "x264-snapshot-" version ".tar.bz2"))
               (sha256
                (base32
-                "0v04xq25q66gsk78i4kryy7503ki87jxbhln2c0qpvyy0d47p466"))))
+                "12zyzbiihfhamf7yi4qqaj6k0nisnrydvfr36kxadvmsm7dg4sj3"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
@@ -327,7 +327,7 @@ SMPTE 314M.")
      (origin
        (method url-fetch)
        (uri (string-append
-             "http://www.freedesktop.org/software/vaapi/releases/libva/libva-"
+             "https://www.freedesktop.org/software/vaapi/releases/libva/libva-"
              version".tar.bz2"))
        (sha256
         (base32 "0bjfb5s8dk3lql843l91ffxzlq47isqks5sj19cxh7j3nhzw58kz"))))
@@ -406,7 +406,7 @@ standards (MPEG-2, MPEG-4 ASP/H.263, MPEG-4 AVC/H.264, and VC-1/VMW3).")
        ("speex" ,speex)
        ("twolame" ,twolame)
        ("xvid" ,xvid)
-       ("zlib", zlib)))
+       ("zlib" ,zlib)))
     (native-inputs
      `(("bc" ,bc)
        ("perl" ,perl)
@@ -608,7 +608,7 @@ treaming protocols.")
     (source (origin
              (method url-fetch)
              (uri (string-append
-                   "http://www.mplayerhq.hu/MPlayer/releases/MPlayer-"
+                   "https://www.mplayerhq.hu/MPlayer/releases/MPlayer-"
                    version ".tar.xz"))
              (sha256
               (base32
@@ -620,23 +620,28 @@ treaming protocols.")
     (inputs
      `(("alsa-lib" ,alsa-lib)
        ("cdparanoia" ,cdparanoia)
+       ("ffmpeg" ,ffmpeg)
        ("fontconfig" ,fontconfig)
-       ("ffmpeg", ffmpeg)
        ("freetype" ,freetype)
-       ("lame" ,lame)
-       ("libdvdcss", libdvdcss)
-       ("libdvdnav", libdvdnav)
-       ("libmpg123" ,mpg123)                      ; audio codec for MP3
 ;;        ("giflib" ,giflib) ; uses QuantizeBuffer, requires version >= 5
+       ("lame" ,lame)
+       ("libass" ,libass)
+       ("libdvdcss" ,libdvdcss)
+       ("libdvdnav" ,libdvdnav)
        ("libjpeg" ,libjpeg)
+       ("libmpeg2" ,libmpeg2)
+       ("libmpg123" ,mpg123)                      ; audio codec for MP3
        ("libpng" ,libpng)
        ("libtheora" ,libtheora)
+       ("libvdpau" ,libvdpau)
        ("libvorbis" ,libvorbis)
        ("libx11" ,libx11)
-       ("libxxf86dga" ,libxxf86dga)
+       ("libx264" ,libx264)
        ("libxinerama" ,libxinerama)
        ("libxv" ,libxv)
+       ("libxxf86dga" ,libxxf86dga)
        ("mesa" ,mesa)
+       ("opus" ,opus)
        ("perl" ,perl)
        ("pulseaudio" ,pulseaudio)
        ("python" ,python-wrapper)
@@ -647,8 +652,8 @@ treaming protocols.")
     (arguments
      `(#:tests? #f ; no test target
        #:phases
-         (alist-replace
-          'configure
+       (modify-phases %standard-phases
+        (replace 'configure
           ;; configure does not work followed by "SHELL=..." and
           ;; "CONFIG_SHELL=..."; set environment variables instead
           (lambda* (#:key inputs outputs #:allow-other-keys)
@@ -662,7 +667,7 @@ treaming protocols.")
                       "./configure"
                       (string-append "--extra-cflags=-I"
                                      libx11 "/include") ; to detect libx11
-		       "--disable-ffmpeg_a" ; disables bundled ffmpeg
+                      "--disable-ffmpeg_a" ; disables bundled ffmpeg
                       (string-append "--prefix=" out)
                       ;; Enable runtime cpu detection where supported,
                       ;; and choose a suitable target.
@@ -681,9 +686,8 @@ treaming protocols.")
                                     (or (%current-target-system)
                                         (nix-system->gnu-triplet
                                          (%current-system)))))))
-                      "--disable-iwmmxt"))))
-          %standard-phases)))
-    (home-page "http://www.mplayerhq.hu/design7/news.html")
+                      "--disable-iwmmxt"))))))))
+    (home-page "https://www.mplayerhq.hu/design7/news.html")
     (synopsis "Audio and video player")
     (description "MPlayer is a movie player.  It plays most MPEG/VOB, AVI,
 Ogg/OGM, VIVO, ASF/WMA/WMV, QT/MOV/MP4, RealMedia, Matroska, NUT,
@@ -770,7 +774,7 @@ projects while introducing many more.")
 (define-public libvpx
   (package
     (name "libvpx")
-    (version "1.4.0")
+    (version "1.5.0")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://storage.googleapis.com/"
@@ -778,23 +782,23 @@ projects while introducing many more.")
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
-                "1r0ql5kgy0c8mh5w7iiqvsd7w5njl9f9cclc7m52ln8assrdk0pm"))))
+                "15v7qw0ydyxn08ksb6lxn1l51pxgpwgshdwd3275yrr5hs86fv9h"))))
     (build-system gnu-build-system)
     (arguments
-     `(#:phases (alist-replace
-                 'configure
-                 (lambda* (#:key outputs #:allow-other-keys)
-                   (setenv "CONFIG_SHELL" (which "bash"))
-                   (let ((out (assoc-ref outputs "out")))
-                     (setenv "LDFLAGS"
-                             (string-append "-Wl,-rpath=" out "/lib"))
-                     (zero? (system* "./configure"
-                                     "--enable-shared"
-                                     "--as=yasm"
-                                     ;; Limit size to avoid CVE-2015-1258
-                                     "--size-limit=16384x16384"
-                                     (string-append "--prefix=" out)))))
-                 %standard-phases)
+     `(#:phases
+       (modify-phases %standard-phases
+         (replace 'configure
+           (lambda* (#:key outputs #:allow-other-keys)
+             (setenv "CONFIG_SHELL" (which "bash"))
+             (let ((out (assoc-ref outputs "out")))
+               (setenv "LDFLAGS"
+                       (string-append "-Wl,-rpath=" out "/lib"))
+               (zero? (system* "./configure"
+                               "--enable-shared"
+                               "--as=yasm"
+                               ;; Limit size to avoid CVE-2015-1258
+                               "--size-limit=16384x16384"
+                               (string-append "--prefix=" out)))))))
        #:tests? #f)) ; no check target
     (native-inputs
      `(("perl" ,perl)
@@ -807,7 +811,7 @@ projects while introducing many more.")
 (define-public youtube-dl
   (package
     (name "youtube-dl")
-    (version "2016.02.01")
+    (version "2016.02.22")
     (source (origin
               (method url-fetch)
               (uri (string-append "http://youtube-dl.org/downloads/"
@@ -815,7 +819,7 @@ projects while introducing many more.")
                                   version ".tar.gz"))
               (sha256
                (base32
-                "04r68acrhx7wapmxph6lcf8hh0pnp76h9p85gcxpidc9m7ypzjfa"))))
+                "02k3kmcrhd04j5y4iivbdms9kvkjw27cqbwd3hf4agd2jjpigkql"))))
     (build-system python-build-system)
     (native-inputs `(("python-setuptools" ,python-setuptools)))
     (home-page "http://youtube-dl.org")
@@ -1157,7 +1161,7 @@ format changes.")
 (define-public xvid
   (package
     (name "xvid")
-    (version "1.3.3")
+    (version "1.3.4")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -1165,18 +1169,18 @@ format changes.")
                     version ".tar.bz2"))
               (sha256
                (base32
-                "0m5g75qvapr7xpywg6a83v5x19kw1nm9l2q48lg7jvvpba0bmqdh"))))
+                "1xwbmp9wqshc0ckm970zdpi0yvgqxlqg0s8bkz98mnr8p2067bsz"))))
     (build-system gnu-build-system)
     (native-inputs `(("yasm" ,yasm)))
     (arguments
      '(#:phases
-       (alist-cons-before
-        'configure 'pre-configure
-        (lambda _
-          (chdir "build/generic")
-          (substitute* "configure"
-            (("#! /bin/sh") (string-append "#!" (which "sh")))))
-        %standard-phases)
+       (modify-phases %standard-phases
+         (add-before
+          'configure 'pre-configure
+          (lambda _
+            (chdir "build/generic")
+            (substitute* "configure"
+              (("#! /bin/sh") (string-append "#!" (which "sh")))))))
        ;; No 'check' target.
        #:tests? #f))
     (home-page "https://www.xvid.com/")
@@ -1300,7 +1304,7 @@ be used for realtime video capture via Linux-specific APIs.")
 (define-public obs
   (package
     (name "obs")
-    (version "0.13.0")
+    (version "0.13.1")
     (source (origin
               (method url-fetch)
               (uri (string-append "https://github.com/jp9000/obs-studio"
@@ -1308,7 +1312,7 @@ be used for realtime video capture via Linux-specific APIs.")
               (file-name (string-append name "-" version ".tar.gz"))
               (sha256
                (base32
-                "1rk5yfcqwjj4a8bj35fsfzk5qlsf5ylsy0z7kdrpl3fhnmla2izz"))))
+                "1vsn4r3wzfdwjrn69kgx3c5wfx17i72nxdv298pq772fp4j2iy2r"))))
     (build-system cmake-build-system)
     (arguments '(#:tests? #f)) ; no tests
     (native-inputs
diff --git a/gnu/packages/vim.scm b/gnu/packages/vim.scm
index e117fc4dff..241896323c 100644
--- a/gnu/packages/vim.scm
+++ b/gnu/packages/vim.scm
@@ -53,10 +53,10 @@
              (("/bin/sh") (which "sh"))))
           %standard-phases)))
     (inputs
-     `(("gawk", gawk)
-       ("inetutils", inetutils)
-       ("ncurses", ncurses)
-       ("perl", perl)
+     `(("gawk" ,gawk)
+       ("inetutils" ,inetutils)
+       ("ncurses" ,ncurses)
+       ("perl" ,perl)
        ("tcsh" ,tcsh))) ; For runtime/tools/vim32
     (home-page "http://www.vim.org/")
     (synopsis "Text editor based on vi")
diff --git a/gnu/packages/wine.scm b/gnu/packages/wine.scm
index 4c7e7a4596..54cb65503c 100644
--- a/gnu/packages/wine.scm
+++ b/gnu/packages/wine.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 Sou Bunnbu <iyzsong@gmail.com>
+;;; Copyright © 2016 Ricardo Wurmus <rekado@elephly.net>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -20,6 +21,7 @@
   #:use-module ((guix licenses) #:prefix license:)
   #:use-module (guix packages)
   #:use-module (guix download)
+  #:use-module (guix utils)
   #:use-module (guix build-system gnu)
   #:use-module (gnu packages)
   #:use-module (gnu packages audio)
@@ -50,18 +52,15 @@
 (define-public wine
   (package
     (name "wine")
-    (version "1.7.52")
+    (version "1.9.4")
     (source (origin
               (method url-fetch)
-              (uri (string-append "mirror://sourceforge/wine/"
-                                  name "-" version ".tar.bz2"))
+              (uri (string-append "https://dl.winehq.org/wine/source/"
+                                  (version-major+minor version)
+                                  "/wine-" version ".tar.bz2"))
               (sha256
                (base32
-                "0jsm1p7zwhfb5fpp0xd39vnx9m98kqgfng1q9kdj70rm1hmb6wq7"))
-              (modules '((guix build utils)))
-              (snippet
-               '(substitute* "Make.vars.in"
-                  (("/bin/sh") "@SHELL@")))))
+                "1f5v1gns0xs512a6ym785cn29j8dxdbnxnvkg8v0p1w0p6vfmhbm"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)
                      ("gettext" ,gnu-gettext)
@@ -114,6 +113,9 @@
        #:configure-flags
        (list (string-append "LDFLAGS=-Wl,-rpath=" %output "/lib"))
 
+       #:make-flags
+       (list "SHELL=bash")
+
        #:phases
        (alist-cons-after
         'configure 'patch-dlopen-paths
diff --git a/gnu/packages/xdisorg.scm b/gnu/packages/xdisorg.scm
index 3ec3e69645..5bc2faba1c 100644
--- a/gnu/packages/xdisorg.scm
+++ b/gnu/packages/xdisorg.scm
@@ -211,7 +211,7 @@ rasterisation.")
       (origin
         (method url-fetch)
         (uri (string-append
-               "http://dri.freedesktop.org/libdrm/libdrm-"
+               "https://dri.freedesktop.org/libdrm/libdrm-"
                version
                ".tar.bz2"))
         (sha256
@@ -268,7 +268,7 @@ tracking.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://www.freedesktop.org/software/" name
+       (uri (string-append "https://www.freedesktop.org/software/" name
                            "/releases/" name "-" version ".tar.gz"))
        (sha256
         (base32
@@ -542,7 +542,7 @@ compact configuration syntax.")
     (version "9.21")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://dist.schmorp.de/rxvt-unicode/"
+              (uri (string-append "http://dist.schmorp.de/rxvt-unicode/Attic/"
                                   name "-" version ".tar.bz2"))
               (sha256
                (base32
@@ -626,19 +626,21 @@ Escape key when Left Control is pressed and released on its own.")
     (native-inputs
      `(("pkg-config" ,pkg-config)))
     (inputs
-     `(("glib" ,glib)
-       ("gtk+" ,gtk+)
+     `(("gtk+" ,gtk+)
        ("libgudev" ,libgudev)
        ("eudev" ,eudev)
        ("libxml2" ,libxml2)))
+    (propagated-inputs
+     ;; libwacom includes header files that include GLib, and libinput uses
+     ;; those header files.
+     `(("glib" ,glib)))
     (home-page "http://linuxwacom.sourceforge.net/")
     (synopsis "Helper library for Wacom tablet settings")
     (description
-     "Libwacom is a library to help implement Wacom tablet settings.  It
-is intended to be used by client-programs that need model identification.  It
-is already being used by the gnome-settings-daemon and the GNOME 3.4 Control
-Center Wacom tablet applet.  In the future, the xf86-input-wacom driver may
-use it as well.")
+     "Libwacom is a library to help implement Wacom tablet settings.  It is
+intended to be used by client-programs that need model identification.  It is
+already being used by the gnome-settings-daemon and the GNOME Control Center
+Wacom tablet applet.")
     (license license:x11)))
 
 (define-public xf86-input-wacom
@@ -680,7 +682,7 @@ the X.Org X Server version 1.7 and later (X11R7.5 or later).")
 (define-public redshift
   (package
     (name "redshift")
-    (version "1.10")
+    (version "1.11")
     (source
      (origin
        (method url-fetch)
@@ -690,7 +692,7 @@ the X.Org X Server version 1.7 and later (X11R7.5 or later).")
                        "/redshift-" version ".tar.xz"))
        (sha256
         (base32
-         "19pfk9il5x2g2ivqix4a555psz8mj3m0cvjwnjpjvx0llh5fghjv"))))
+         "0ngkwj7rg8nfk806w0sg443w6wjr91xdc0zisqfm5h2i77wm1qqh"))))
     (build-system gnu-build-system)
     (native-inputs
      `(("pkg-config" ,pkg-config)
@@ -699,7 +701,7 @@ the X.Org X Server version 1.7 and later (X11R7.5 or later).")
      `(("libdrm" ,libdrm)
        ("libx11" ,libx11)
        ("libxcb" ,libxcb)
-       ("libxxf86vm", libxxf86vm)
+       ("libxxf86vm" ,libxxf86vm)
        ("glib" ,glib)))                           ;for Geoclue2 support
     (home-page "https://github.com/jonls/redshift")
     (synopsis "Adjust the color temperature of your screen")
diff --git a/gnu/packages/xfce.scm b/gnu/packages/xfce.scm
index e213fb6067..2aef842d5a 100644
--- a/gnu/packages/xfce.scm
+++ b/gnu/packages/xfce.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014, 2015 Sou Bunnbu <iyzsong@gmail.com>
 ;;; Copyright © 2014, 2015 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2016 Andreas Enge <andreas@enge.fr>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -281,7 +282,7 @@ management D-Bus specification.")
      `(("libxfce4util" ,libxfce4util))) ; required by libxfce4panel-1.0.pc
     (inputs
      `(("exo" ,exo)
-       ("garcon", garcon)
+       ("garcon" ,garcon)
        ("libwnck" ,libwnck-1)
        ("libxfce4ui" ,libxfce4ui)))
     (native-search-paths
@@ -387,6 +388,44 @@ to an auto mixer tool like pavucontrol.  It can optionally handle multimedia
 keys for controlling the audio volume.")
     (license gpl2+)))
 
+(define-public xfce4-xkb-plugin
+  (package
+    (name "xfce4-xkb-plugin")
+    (version "0.7.1")
+    (source (origin
+              (method url-fetch)
+              (uri (string-append "http://archive.xfce.org/src/panel-plugins/"
+                                  name "/" (version-major+minor version) "/"
+                                  name "-" version ".tar.bz2"))
+              (sha256
+               (base32
+                "10g65j5ia389ahhn3b9hr52ghpp0817fk0m60rfrv4wrzqrjxzk1"))))
+    (build-system gnu-build-system)
+    (native-inputs
+     `(("intltool" ,intltool)
+       ("pkg-config" ,pkg-config)))
+    (inputs
+     `(("garcon" ,garcon)
+       ("librsvg" ,librsvg)
+       ("libwnck" ,libwnck-1)
+       ("libx11" ,libx11)
+       ("libxfce4ui" ,libxfce4ui)
+       ("libxklavier" ,libxklavier)
+       ("xfce4-panel" ,xfce4-panel)))
+    (home-page "http://git.xfce.org/panel-plugins/xfce4-xkb-plugin/")
+    (synopsis "XKB layout switching panel plug-in for Xfce")
+    (description
+     "Xfce XKB plugin makes it possible to set up and use multiple
+keyboard layouts.
+
+One can choose the keyboard model, what key combination to
+use to switch between the layouts, the actual keyboard layouts,
+the way in which the current layout is being displayed (country
+flag image or text) and the layout policy, which is whether to
+store the layout globally (for all windows), per application or
+per window.")
+    (license bsd-2)))
+
 (define-public xfce4-appfinder
   (package
     (name "xfce4-appfinder")
@@ -480,7 +519,7 @@ allows you to shutdown the computer from Xfce.")
      `(("exo" ,exo)
        ("garcon" ,garcon)
        ("libnotify" ,libnotify)
-       ("libxcursor", libxcursor)
+       ("libxcursor" ,libxcursor)
        ("libxi" ,libxi)
        ("libxklavier" ,libxklavier)
        ("libxrandr" ,libxrandr)
@@ -695,7 +734,8 @@ on your desktop.")
        ;; Panel plugins.
        ("xfce4-battery-plugin"    ,xfce4-battery-plugin)
        ("xfce4-clipman-plugin"    ,xfce4-clipman-plugin)
-       ("xfce4-pulseaudio-plugin" ,xfce4-pulseaudio-plugin)))
+       ("xfce4-pulseaudio-plugin" ,xfce4-pulseaudio-plugin)
+       ("xfce4-xkb-plugin" ,xfce4-xkb-plugin)))
     (home-page "http://www.xfce.org/")
     (synopsis "Desktop environment (meta-package)")
     (description
diff --git a/gnu/packages/xnee.scm b/gnu/packages/xnee.scm
index 4e9135dd5b..84dd85b2e7 100644
--- a/gnu/packages/xnee.scm
+++ b/gnu/packages/xnee.scm
@@ -39,7 +39,7 @@
                "04n2lac0vgpv8zsn7nmb50hf3qb56pmj90dmwnivg09gyrf1x92j"))))
     (build-system gnu-build-system)
     (inputs
-     `(("gtk+", gtk+-2)
+     `(("gtk+" ,gtk+-2)
        ("inputproto" ,inputproto)
        ("libx11" ,libx11)
        ("libxext" ,libxext)
diff --git a/gnu/packages/xorg.scm b/gnu/packages/xorg.scm
index 82a5d994d2..f69661d088 100644
--- a/gnu/packages/xorg.scm
+++ b/gnu/packages/xorg.scm
@@ -132,7 +132,7 @@ autotools system.")
 (define-public bdftopcf
   (package
     (name "bdftopcf")
-    (version "1.0.4")
+    (version "1.0.5")
     (source
       (origin
         (method url-fetch)
@@ -142,7 +142,7 @@ autotools system.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1617zmgnx50n7vxlqyj84fl7vnk813jjqmi6jpigyz1xp9br1xga"))))
+            "09i03sk878cmx2i40lkpsysn7zqcvlczb30j7x3lryb11jz4gx1q"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxfont" ,libxfont)))
@@ -348,7 +348,7 @@ provided.")
     (build-system gnu-build-system)
     (inputs
       `(("bdftopcf" ,bdftopcf)
-        ("font-util", font-util)
+        ("font-util" ,font-util)
         ("mkfontdir" ,mkfontdir)))
     (native-inputs
       `(("pkg-config" ,pkg-config)))
@@ -380,7 +380,7 @@ provided.")
     (build-system gnu-build-system)
     (inputs
       `(("bdftopcf" ,bdftopcf)
-        ("font-util", font-util)
+        ("font-util" ,font-util)
         ("mkfontdir" ,mkfontdir)))
     (native-inputs
       `(("pkg-config" ,pkg-config)))
@@ -817,7 +817,7 @@ For example: '6x10', '9x15bold', etc.")
 (define-public font-util
   (package
     (name "font-util")
-    (version "1.3.0")
+    (version "1.3.1")
     (source
       (origin
         (method url-fetch)
@@ -827,7 +827,7 @@ For example: '6x10', '9x15bold', etc.")
                ".tar.bz2"))
         (sha256
           (base32
-            "15cijajwhjzpy3ydc817zz8x5z4gbkyv3fps687jbq544mbfbafz"))))
+            "08drjb6cf84pf5ysghjpb4i7xkd2p86k3wl2a0jxs1jif6qbszma"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (home-page "http://www.x.org/wiki/")
@@ -939,7 +939,7 @@ rendering commands to the X server.")
 (define-public iceauth
   (package
     (name "iceauth")
-    (version "1.0.6")
+    (version "1.0.7")
     (source
       (origin
         (method url-fetch)
@@ -949,7 +949,7 @@ rendering commands to the X server.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1x72y99dxf2fxnlyf0yrf9yzd8xzimxshy6l8mprwhrv6lvhi6dx"))))
+            "02izdyzhwpgiyjd8brzilwvwnfr72ncjb6mzz3y1icwrxqnsy5hj"))))
     (build-system gnu-build-system)
     (inputs
       `(("libice" ,libice)))
@@ -992,7 +992,7 @@ devices management such as graphic tablets.")
 (define-public kbproto
   (package
     (name "kbproto")
-    (version "1.0.6")
+    (version "1.0.7")
     (source
       (origin
         (method url-fetch)
@@ -1002,7 +1002,7 @@ devices management such as graphic tablets.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0yal11hhpiisy3w8wmacsdzzzcnc3xwnswxz8k7zri40xc5aqz03"))))
+            "0mxqj1pzhjpz9495vrjnpi10kv2n1s4vs7di0sh3yvipfq5j30pq"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (home-page "http://www.x.org/wiki/")
@@ -1049,7 +1049,7 @@ of new capabilities and controls for text keyboards.")
 (define-public libxshmfence
   (package
     (name "libxshmfence")
-    (version "1.1")
+    (version "1.2")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -1057,7 +1057,7 @@ of new capabilities and controls for text keyboards.")
                     name "-" version ".tar.bz2"))
               (sha256
                (base32
-                "1gnfb1z8sbbdc3xpz1zmm94lv7yvfh4kvip9s5pj37ya4llxphnv"))))
+                "032b0nlkdrpbimdld4gqvhqx53rzn8fawvf1ybhzn7lcswgjs6yj"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (inputs `(("xproto" ,xproto)))
@@ -1074,7 +1074,7 @@ synchronization between the X server and direct-rendering clients.")
 (define-public libfontenc
   (package
     (name "libfontenc")
-    (version "1.1.2")
+    (version "1.1.3")
     (source
       (origin
         (method url-fetch)
@@ -1084,7 +1084,7 @@ synchronization between the X server and direct-rendering clients.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0qign0ivqk166l9yfd51gw9lbhgs718bcrmvc40yicjr6gnyz959"))))
+            "08gxmrhgw97mv0pvkfmd46zzxrn6zdw4g27073zl55gwwqq8jn3h"))))
     (build-system gnu-build-system)
     (inputs
       `(("zlib" ,zlib)
@@ -1100,7 +1100,7 @@ synchronization between the X server and direct-rendering clients.")
 (define-public libfs
   (package
     (name "libfs")
-    (version "1.0.6")
+    (version "1.0.7")
     (source
       (origin
         (method url-fetch)
@@ -1110,7 +1110,7 @@ synchronization between the X server and direct-rendering clients.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1mxfsvj9m3pn8cdkcn4kg190zp665mf4pv0083g6xykvsgxzq1wh"))))
+            "1wy4km3qwwajbyl8y9pka0zwizn7d9pfiyjgzba02x3a083lr79f"))))
     (build-system gnu-build-system)
     (inputs
       `(("xtrans" ,xtrans)
@@ -1272,7 +1272,7 @@ with the Cygwin XWin server when running X11 in a rootless mode.")
 (define-public libxdmcp
   (package
     (name "libxdmcp")
-    (version "1.1.1")
+    (version "1.1.2")
     (source
       (origin
         (method url-fetch)
@@ -1282,7 +1282,7 @@ with the Cygwin XWin server when running X11 in a rootless mode.")
                ".tar.bz2"))
         (sha256
           (base32
-            "13highx4xpgkiwykpcl7z2laslrjc4pzi4h617ny9p7r6116vkls"))))
+            "1qp4yhxbfnpj34swa0fj635kkihdkwaiw7kf55cg5zqqg630kzl1"))))
     (build-system gnu-build-system)
     (inputs
       `(("xproto" ,xproto)))
@@ -1331,7 +1331,7 @@ configuration files.")
 (define-public libxkbfile
   (package
     (name "libxkbfile")
-    (version "1.0.8")
+    (version "1.0.9")
     (source
       (origin
         (method url-fetch)
@@ -1341,7 +1341,7 @@ configuration files.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0flg5arw6n3njagmsi4i4l0zl5bfx866a1h9ydc3bi1pqlclxaca"))))
+            "0smimr14zvail7ar68n7spvpblpdnih3jxrva7cpa6cn602px0ai"))))
     (build-system gnu-build-system)
     (inputs
       `(("libx11" ,libx11)))
@@ -1557,7 +1557,7 @@ input from UTF-8 into the locale's encoding.")
 (define-public mkfontscale
   (package
     (name "mkfontscale")
-    (version "1.1.1")
+    (version "1.1.2")
     (source
       (origin
         (method url-fetch)
@@ -1567,7 +1567,7 @@ input from UTF-8 into the locale's encoding.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0cdpn1ii2iw1vg2ga4w62acrh78gzgf0vza4g8wx5kkp4jcifh14"))))
+            "081z8lwh9c1gyrx3ad12whnpv3jpfbqsc366mswpfm48mwl54vcc"))))
     (build-system gnu-build-system)
     (inputs
       `(("zlib" ,zlib)
@@ -1636,7 +1636,7 @@ network-transparent printing system.")
 (define-public randrproto
   (package
     (name "randrproto")
-    (version "1.4.0")
+    (version "1.5.0")
     (source
       (origin
         (method url-fetch)
@@ -1646,7 +1646,7 @@ network-transparent printing system.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1kq9h93qdnniiivry8jmhlgwn9fbx9xp5r9cmzfihlx5cs62xi45"))))
+            "0s4496z61y5q45q20gldwpf788b9nsa8hb13gnck1mwwwwrmarsc"))))
     (build-system gnu-build-system)
     (native-inputs `(("pkg-config" ,pkg-config)))
     (home-page "http://www.x.org/wiki/")
@@ -1757,7 +1757,7 @@ features and to query screensaver info on specific windows.")
 (define-public sessreg
   (package
     (name "sessreg")
-    (version "1.0.8")
+    (version "1.1.0")
     (source
       (origin
         (method url-fetch)
@@ -1767,7 +1767,7 @@ features and to query screensaver info on specific windows.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1hy4wvgawajf4qw2k51fkcjzxw0drx60ydzpmqhj7k1g4z3cqahf"))))
+            "0z013rskwmdadd8cdlxvh4asmgim61qijyzfbqmr1q1mg1jpf4am"))))
     (build-system gnu-build-system)
     (inputs
       `(("xproto" ,xproto)))
@@ -1785,7 +1785,7 @@ used with other display managers such as gdm or kdm.")
 (define-public setxkbmap
   (package
     (name "setxkbmap")
-    (version "1.3.0")
+    (version "1.3.1")
     (source
       (origin
         (method url-fetch)
@@ -1795,7 +1795,7 @@ used with other display managers such as gdm or kdm.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1inygpvlgc6vr5h9laxw9lnvafnccl3fy0g5n9ll28iq3yfmqc1x"))))
+            "1qfk097vjysqb72pq89h0la3462kbb2dh1d11qzs2fr67ybb7pd9"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxkbfile" ,libxkbfile)
@@ -1820,7 +1820,7 @@ listed on the command line.")
 (define-public smproxy
   (package
     (name "smproxy")
-    (version "1.0.5")
+    (version "1.0.6")
     (source
       (origin
         (method url-fetch)
@@ -1830,7 +1830,7 @@ listed on the command line.")
                ".tar.bz2"))
         (sha256
           (base32
-            "02fn5wa1gs2jap6sr9j9yk6zsvz82j8l61pf74iyqwa99q4wnb67"))))
+            "0rkjyzmsdqmlrkx8gy2j4q6iksk58hcc92xzdprkf8kml9ar3wbc"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxt" ,libxt)
@@ -1939,7 +1939,7 @@ server.")
 (define-public x11perf
   (package
     (name "x11perf")
-    (version "1.5.4")
+    (version "1.6.0")
     (source
       (origin
         (method url-fetch)
@@ -1949,7 +1949,7 @@ server.")
                ".tar.bz2"))
         (sha256
           (base32
-            "111iwpxhnxjiq44w96zf0kszg5zpgv1g3ayx18v4nhdzl9bqivi4"))))
+            "0lb716yfdb8f11h4cz93d1bapqdxf1xplsb21kbp4xclq7g9hw78"))))
     (build-system gnu-build-system)
     (inputs
       `(("libx11" ,libx11)
@@ -2112,7 +2112,7 @@ to query the server for available resource IDs.")
 (define-public xcmsdb
   (package
     (name "xcmsdb")
-    (version "1.0.4")
+    (version "1.0.5")
     (source
       (origin
         (method url-fetch)
@@ -2122,7 +2122,7 @@ to query the server for available resource IDs.")
                ".tar.bz2"))
         (sha256
           (base32
-            "03ms731l3kvaldq7ycbd30j6134b61i3gbll4b2gl022wyzbjq74"))))
+            "1ik7gzlp2igz183x70883000ygp99r20x3aah6xhaslbpdhm6n75"))))
     (build-system gnu-build-system)
     (inputs
       `(("libx11" ,libx11)))
@@ -2201,7 +2201,7 @@ X server: 'handhelds', 'redglass' and 'whiteglass'.")
 (define-public xdpyinfo
   (package
     (name "xdpyinfo")
-    (version "1.3.1")
+    (version "1.3.2")
     (source
       (origin
         (method url-fetch)
@@ -2211,7 +2211,7 @@ X server: 'handhelds', 'redglass' and 'whiteglass'.")
                ".tar.bz2"))
         (sha256
           (base32
-            "154b29zlrq33lmni883jgwyrb2kx7z8h52jx1s3ys5x5d582iydf"))))
+            "0ldgrj4w2fa8jng4b3f3biaj0wyn8zvya88pnk70d7k12pcqw8rh"))))
     (build-system gnu-build-system)
     (inputs
       `(("inputproto" ,inputproto)
@@ -2240,7 +2240,7 @@ available.")
 (define-public xdriinfo
   (package
     (name "xdriinfo")
-    (version "1.0.4")
+    (version "1.0.5")
     (source
       (origin
         (method url-fetch)
@@ -2250,7 +2250,7 @@ available.")
                ".tar.bz2"))
         (sha256
           (base32
-            "076bjix941znyjmh3j5jjsnhp2gv2iq53d0ks29mvvv87cyy9iim"))))
+            "0681d0y8liqakkpz7mmsf689jcxrvs5291r20qi78mc9xxk3gfjc"))))
     (build-system gnu-build-system)
     (inputs
       `(("mesa" ,mesa)
@@ -2268,7 +2268,7 @@ DRI (Direct Rendering Infrastructure) drivers.")
 (define-public xev
   (package
     (name "xev")
-    (version "1.2.1")
+    (version "1.2.2")
     (source
       (origin
         (method url-fetch)
@@ -2278,7 +2278,7 @@ DRI (Direct Rendering Infrastructure) drivers.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0hv296mysglcgkx6lj1wxc23kshb2kix1a8yqppxj5vz16mpzw8i"))))
+            "0krivhrxpq6719103r541xpi3i3a0y15f7ypc4lnrx8sdhmfcjnr"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxrender" ,libxrender)
@@ -2333,7 +2333,7 @@ XC-APPGROUP, XTEST.")
     (source
      (origin
        (method url-fetch)
-       (uri (string-append "http://www.freedesktop.org/software/" name "/"
+       (uri (string-append "https://www.freedesktop.org/software/" name "/"
                            name "-" version ".tar.xz"))
        (sha256
         (base32
@@ -2355,7 +2355,7 @@ devices, thus making direct access unnecessary.")
 (define-public xf86-input-evdev
   (package
     (name "xf86-input-evdev")
-    (version "2.8.4")
+    (version "2.10.1")
     (source
       (origin
         (method url-fetch)
@@ -2365,11 +2365,12 @@ devices, thus making direct access unnecessary.")
                ".tar.bz2"))
         (sha256
           (base32
-            "030haki1h0m85h91c91812gdnk6znfamw5kpr010zxwwbsgxxyl5"))))
+            "05z05n39v8s2b0hwhcjb1bca7j8gc62bv9jxnibawwmjym3jp75g"))))
     (build-system gnu-build-system)
     (inputs
       `(("udev" ,eudev)
         ("libevdev" ,libevdev)
+        ("mtdev" ,mtdev)
         ("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
     (arguments
@@ -2388,7 +2389,7 @@ including most mice, keyboards, tablets and touchscreens.")
 (define-public xf86-input-libinput
   (package
     (name "xf86-input-libinput")
-    (version "0.8.0")
+    (version "0.16.0")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -2396,7 +2397,7 @@ including most mice, keyboards, tablets and touchscreens.")
                     name "-" version ".tar.bz2"))
               (sha256
                (base32
-                "0fm4vrkw7azipbnwvc2l18g65z77pllsznaajd8q3zpg9ycb0li1"))))
+                "0jbgnxsbr3g4g9vkspcc6pqy7av59zx5bb78vkvaqy8yx4qybbgx"))))
     (build-system gnu-build-system)
     (arguments
      '(#:configure-flags
@@ -2448,7 +2449,7 @@ It is used to cotrol the pointer with a joystick device.")
 (define-public xf86-input-keyboard
   (package
     (name "xf86-input-keyboard")
-    (version "1.8.0")
+    (version "1.8.1")
     (source
       (origin
         (method url-fetch)
@@ -2458,7 +2459,7 @@ It is used to cotrol the pointer with a joystick device.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0nyb61w30z32djrllgr2s1i13di3vsl6hg4pqjhxdal71971ria1"))))
+            "04d27kwqq03fc26an6051hs3i0bff8albhnngzyd59wxpwwzzj0s"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -2504,7 +2505,7 @@ as USB mice.")
 (define-public xf86-input-synaptics
   (package
     (name "xf86-input-synaptics")
-    (version "1.8.1")
+    (version "1.8.3")
     (source
       (origin
         (method url-fetch)
@@ -2514,7 +2515,7 @@ as USB mice.")
                ".tar.bz2"))
         (sha256
           (base32
-            "16phzd7yhl4wns957c35qz2nahmjvnlx05jf975s524qkvrdlkyp"))))
+            "009zx199pilcvlaqm6fx4mg94q81d6vvl5rznmw3frzkfh6117yk"))))
     (build-system gnu-build-system)
     (inputs `(("libx11" ,libx11)
               ("libxi" ,libxi)
@@ -2540,7 +2541,7 @@ as USB mice.")
 (define-public xf86-input-void
   (package
     (name "xf86-input-void")
-    (version "1.4.0")
+    (version "1.4.1")
     (source
       (origin
         (method url-fetch)
@@ -2550,7 +2551,7 @@ as USB mice.")
                ".tar.bz2"))
         (sha256
           (base32
-            "01bmk324fq48wydvy1qrnxbw6qz0fjd0i80g0n4cqr1c4mjmif9a"))))
+            "171k8b8s42s3w73l7ln9jqwk88w4l7r1km2blx1vy898c854yvpr"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -2616,7 +2617,7 @@ as USB mice.")
 (define-public xf86-video-ati
   (package
     (name "xf86-video-ati")
-    (version "7.5.0")
+    (version "7.6.1")
     (source
       (origin
         (method url-fetch)
@@ -2626,7 +2627,7 @@ as USB mice.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0dkrw036ikym8aacl43lnf04q0wbms5498xg5b3l16ngnq36ygpc"))))
+            "0k6kw69mcarlmxlb4jlhz887jxqr94qx2pin04xcv2ysp3pdj5i5"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xxf86driproto" ,xf86driproto)
@@ -2644,7 +2645,7 @@ X server.")
 (define-public xf86-video-cirrus
   (package
     (name "xf86-video-cirrus")
-    (version "1.5.2")
+    (version "1.5.3")
     (source
       (origin
         (method url-fetch)
@@ -2654,7 +2655,7 @@ X server.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1mycqgjp18b6adqj2h90vp324xh8ysyi5migfmjc914vbnkf2q9k"))))
+            "1asifc6ld2g9kap15vfhvsvyl69lj7pw3d9ra9mi4najllh7pj7d"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -2698,7 +2699,7 @@ framebuffer device.")
 (define-public xf86-video-geode
   (package
     (name "xf86-video-geode")
-    (version "2.11.16")
+    (version "2.11.18")
     (source
       (origin
         (method url-fetch)
@@ -2708,7 +2709,7 @@ framebuffer device.")
                ".tar.bz2"))
         (sha256
           (base32
-           "19y13xl7yfrgyis92rmxi0ld95ajgr5il0n9j1dridwzw9aizz1q"))
+           "1s59kdj573v38sb14xfhp1l926aypbhy11vaz36y72x6calfkv6n"))
         (patches (list (search-patch "xf86-video-geode-glibc-2.20.patch")))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
@@ -2810,45 +2811,54 @@ X server.")
 
 
 (define-public xf86-video-intel
-  (package
-    (name "xf86-video-intel")
-    (version "2.21.15")
-    (source
-      (origin
-        (method url-fetch)
-        (uri (string-append
-               "mirror://xorg/individual/driver/xf86-video-intel-"
-               version
-               ".tar.bz2"))
-        (sha256
-          (base32
-           "1z6ncmpszmwqi9xr590c4kp4gjjf7mndcr56r35x2bx7h87i8nkx"))
-        (patches (list (search-patch "xf86-video-intel-compat-api.patch")
-                       (search-patch "xf86-video-intel-glibc-2.20.patch")))))
-    (build-system gnu-build-system)
-    (inputs `(("mesa" ,mesa)
-              ("udev" ,eudev)
-              ("libx11" ,libx11)
-              ("xorg-server" ,xorg-server)))
-    (native-inputs
-     `(("pkg-config" ,pkg-config)))
-    (supported-systems
-     ;; This driver is only supported on Intel systems.
-     (filter (lambda (system) (or (string-prefix? "i686-" system)
-                                  (string-prefix? "x86_64-" system)))
-             %supported-systems))
-    (home-page "http://www.x.org/wiki/")
-    (synopsis "Intel video driver for X server")
-    (description
-     "xf86-video-intel is a 2D graphics driver for the Xorg X server.
+  (let ((commit "d167280"))
+    (package
+      (name "xf86-video-intel")
+      (version (string-append "2.99.917-1-" commit))
+      (source
+       (origin
+         ;; there's no current tarball
+         (method git-fetch)
+         (uri (git-reference
+               (url "http://anongit.freedesktop.org/git/xorg/driver/xf86-video-intel.git")
+               (commit commit)))
+         (sha256
+          (base32
+           "16hfcj11lbn6lp0hgrixidbfb7mghm1yn4lynmymm985w1gg0n72"))
+         (file-name (string-append name "-" version))))
+      (build-system gnu-build-system)
+      (inputs `(("mesa" ,mesa)
+                ("udev" ,eudev)
+                ("libx11" ,libx11)
+                ("libxfont" ,libxfont)
+                ("xorg-server" ,xorg-server)))
+      (native-inputs
+       `(("pkg-config" ,pkg-config)
+         ("autoconf" ,autoconf)
+         ("automake" ,automake)
+         ("libtool" ,libtool)))
+      (supported-systems
+       ;; This driver is only supported on Intel systems.
+       (filter (lambda (system) (or (string-prefix? "i686-" system)
+                                    (string-prefix? "x86_64-" system)))
+               %supported-systems))
+      (arguments
+       '(#:phases (modify-phases %standard-phases
+                    (add-after 'unpack 'bootstrap
+                      (lambda _
+                        (zero? (system* "autoreconf" "-vfi")))))))
+      (home-page "http://www.x.org/wiki/")
+      (synopsis "Intel video driver for X server")
+      (description
+       "xf86-video-intel is a 2D graphics driver for the Xorg X server.
 It supports a variety of Intel graphics chipsets.")
-    (license license:x11)))
+      (license license:x11))))
 
 
 (define-public xf86-video-mach64
   (package
     (name "xf86-video-mach64")
-    (version "6.9.4")
+    (version "6.9.5")
     (source
       (origin
         (method url-fetch)
@@ -2858,7 +2868,7 @@ It supports a variety of Intel graphics chipsets.")
                ".tar.bz2"))
         (sha256
           (base32
-           "0pl582vnc6hdxqhf5c0qdyanjqxb4crnhqlmxxml5a60syw0iwcp"))
+           "07xlf5nsjm0x18ij5gyy4lf8hwpl10i8chi3skpqjh84drdri61y"))
         (patches (list (search-patch "xf86-video-mach64-glibc-2.20.patch")))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
@@ -2880,7 +2890,7 @@ the same level of support for generic VGA or 8514/A adapters.")
 (define-public xf86-video-mga
   (package
     (name "xf86-video-mga")
-    (version "1.6.3")
+    (version "1.6.4")
     (source
       (origin
         (method url-fetch)
@@ -2890,8 +2900,7 @@ the same level of support for generic VGA or 8514/A adapters.")
                ".tar.bz2"))
         (sha256
           (base32
-           "1my7y67sadjjmab1dyxckylrggi7p01yk4wwg9w6k1q96pmb213p"))
-        (patches (list (search-patch "xf86-video-mga-glibc-2.20.patch")))))
+           "0kyl8w99arviv27pc349zsy2vinnm7mdpy34vr9nzisicw5nkij8"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xf86driproto" ,xf86driproto)
@@ -2932,7 +2941,7 @@ kernel mode setting (KMS).")
 (define-public xf86-video-neomagic
   (package
     (name "xf86-video-neomagic")
-    (version "1.2.8")
+    (version "1.2.9")
     (source
       (origin
         (method url-fetch)
@@ -2942,7 +2951,7 @@ kernel mode setting (KMS).")
                ".tar.bz2"))
         (sha256
           (base32
-            "0x48sxs1p3kmwk3pq1j7vl93y59gdmgkq1x5xbnh0yal0angdash"))))
+            "1whb2kgyqaxdjim27ya404acz50izgmafwnb6y9m89q5n6b97y3j"))))
     (build-system gnu-build-system)
     (inputs `(("xf86dgaproto" ,xf86dgaproto)
               ("xorg-server" ,xorg-server)))
@@ -3012,28 +3021,20 @@ supported, and the RENDER extension is not accelerated by this driver.")
 (define-public xf86-video-nouveau
   (package
     (name "xf86-video-nouveau")
-    (version "1.0.11")
-    (source (origin
-              ;; There are no tarball releases of Nouveau.
-              (method git-fetch)
-              (uri (git-reference
-                    (url "git://anongit.freedesktop.org/nouveau/xf86-video-nouveau")
-                    (commit (string-append name "-" version))))
-              (sha256
-               (base32
-                "0zdb6b0n7pzf3l8j8hl7gfshg8jsmcmk11isvvl542yc36162ahp"))))
+    (version "1.0.12")
+    (source
+     (origin
+       (method url-fetch)
+       (uri (string-append
+             "mirror://xorg/individual/driver/xf86-video-nouveau-"
+             version
+             ".tar.bz2"))
+       (sha256
+        (base32
+         "07irv1zkk0rkyn1d7f2gn1icgcz2ix0pwv74sjian763gynmg80f"))))
     (build-system gnu-build-system)
-    (arguments
-     '(#:phases (alist-cons-after
-                 'unpack 'bootstrap
-                 (lambda _
-                   (zero? (system* "autoreconf" "-vi")))
-                 %standard-phases)))
     (inputs `(("xorg-server" ,xorg-server)))
-    (native-inputs `(("pkg-config" ,pkg-config)
-                     ("autoconf" ,(autoconf-wrapper))
-                     ("automake" ,automake)
-                     ("libtool" ,libtool)))
+    (native-inputs `(("pkg-config" ,pkg-config)))
     (home-page "http://nouveau.freedesktop.org")
     (synopsis "NVIDIA video driver for X server")
     (description
@@ -3078,7 +3079,7 @@ UniChrome Pro and Chrome9 integrated graphics processors.")
 (define-public xf86-video-r128
   (package
     (name "xf86-video-r128")
-    (version "6.9.2")
+    (version "6.10.1")
     (source
       (origin
         (method url-fetch)
@@ -3088,8 +3089,7 @@ UniChrome Pro and Chrome9 integrated graphics processors.")
                ".tar.bz2"))
         (sha256
           (base32
-           "1q3fsc603k2yinphx5rrcl5356qkpywwz8axlw277l2231gjjbcb"))
-        (patches (list (search-patch "xf86-video-r128-glibc-2.20.patch")))))
+           "1sp4glyyj23rs77vgffmn0mar5h504a86701nzvi56qwhd4yzgsy"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xf86driproto" ,xf86driproto)
@@ -3106,7 +3106,7 @@ This driver is intended for ATI Rage 128 based cards.")
 (define-public xf86-video-savage
   (package
     (name "xf86-video-savage")
-    (version "2.3.7")
+    (version "2.3.8")
     (source
       (origin
         (method url-fetch)
@@ -3116,7 +3116,7 @@ This driver is intended for ATI Rage 128 based cards.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0i2aqp68rfkrz9c1p6d7ny9x7bjrlnby7q56zf01fb12r42l4784"))))
+            "0qzshncynjdmyhavhqw4x5ha3gwbygi0zbsy158fpg1jcnla9kpx"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xf86driproto" ,xf86driproto)
@@ -3132,7 +3132,7 @@ This driver is intended for ATI Rage 128 based cards.")
 (define-public xf86-video-siliconmotion
   (package
     (name "xf86-video-siliconmotion")
-    (version "1.7.7")
+    (version "1.7.8")
     (source
       (origin
         (method url-fetch)
@@ -3142,10 +3142,7 @@ This driver is intended for ATI Rage 128 based cards.")
                ".tar.bz2"))
         (sha256
           (base32
-           "1an321kqvsxq0z35acwl99lc8hpdkayw0q180744ypcl8ffvbf47"))
-        (patches
-         (list
-          (search-patch "xf86-video-siliconmotion-remove-mibstore.patch")))))
+           "1sqv0y31mi4zmh9yaxqpzg7p8y2z01j6qys433hb8n4yznllkm79"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -3160,7 +3157,7 @@ Xorg X server.")
 (define-public xf86-video-sis
   (package
     (name "xf86-video-sis")
-    (version "0.10.7")
+    (version "0.10.8")
     (source
       (origin
         (method url-fetch)
@@ -3170,9 +3167,7 @@ Xorg X server.")
                ".tar.bz2"))
         (sha256
           (base32
-           "1l0w84x39gq4y9j81dny9r6rma1xkqvxpsavpkd8h7h8panbcbmy"))
-        (patches (list (search-patch "xf86-video-sis-update-api.patch")
-                       (search-patch "xf86-video-sis-fix-exa-crash.patch")))))
+           "1znkqwdyd6am23xbsfjzamq125j5rrylg5mzqky4scv9gxbz5wy8"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xf86dgaproto" ,xf86dgaproto)
@@ -3239,7 +3234,7 @@ This driver supports SiS chipsets of 300/315/330/340 series.")
 (define-public xf86-video-tdfx
   (package
     (name "xf86-video-tdfx")
-    (version "1.4.5")
+    (version "1.4.6")
     (source
       (origin
         (method url-fetch)
@@ -3249,9 +3244,7 @@ This driver supports SiS chipsets of 300/315/330/340 series.")
                ".tar.bz2"))
         (sha256
           (base32
-           "0nfqf1c8939s21ci1g7gacwzlr4g4nnilahgz7j2bz30zfnzpmbh"))
-        (patches (list
-                  (search-patch "xf86-video-tdfx-remove-mibstore.patch")))))
+           "0dvdrhyn1iv6rr85v1c52s1gl0j1qrxgv7x0r7qn3ba0gj38i2is"))))
     (build-system gnu-build-system)
     (inputs `(("mesa" ,mesa)
               ("xf86driproto" ,xf86driproto)
@@ -3294,7 +3287,7 @@ X server.")
 (define-public xf86-video-trident
   (package
     (name "xf86-video-trident")
-    (version "1.3.6")
+    (version "1.3.7")
     (source
       (origin
         (method url-fetch)
@@ -3304,9 +3297,7 @@ X server.")
                ".tar.bz2"))
         (sha256
           (base32
-           "0141qbfsm32i0pxjyx5czpa8x8m4lvapsp4amw1qigaa0gry6n3a"))
-        (patches (list
-                  (search-patch "xf86-video-trident-remove-mibstore.patch")))))
+           "1bhkwic2acq9za4yz4bwj338cwv5mdrgr2qmgkhlj3bscbg1imgc"))))
     (build-system gnu-build-system)
     (inputs `(("xf86dgaproto" ,xf86dgaproto)
               ("xorg-server" ,xorg-server)))
@@ -3325,7 +3316,7 @@ X server.")
 (define-public xf86-video-vesa
   (package
     (name "xf86-video-vesa")
-    (version "2.3.3")
+    (version "2.3.4")
     (source
       (origin
         (method url-fetch)
@@ -3335,7 +3326,7 @@ X server.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1y5fsg0c4bgmh1cfsbnaaf388fppyy02i7mcy9vax78flkjpb2yf"))))
+            "1haiw8r1z8ihk68d0jqph2wsld13w4qkl86biq46fvyxg7cg9pbv"))))
     (build-system gnu-build-system)
     (inputs `(("xorg-server" ,xorg-server)))
     (native-inputs `(("pkg-config" ,pkg-config)))
@@ -3350,7 +3341,7 @@ X server.")
 (define-public xf86-video-vmware
   (package
     (name "xf86-video-vmware")
-    (version "13.0.2")
+    (version "13.1.0")
     (source
       (origin
         (method url-fetch)
@@ -3360,8 +3351,7 @@ X server.")
                ".tar.bz2"))
         (sha256
           (base32
-           "0m1wfsv34s4pyr5ry87yyjb2p6vmy6vyypdz5jx0sqnkx8n3vfn8"))
-        (patches (list (search-patch "xf86-video-vmware-glibc-2.20.patch")))))
+           "1k50whwnkzxam2ihc1sw456dx0pvr76naycm4qhyjxqv9d72879w"))))
     (build-system gnu-build-system)
     (inputs `(("libx11" ,libx11)
               ("libxext" ,libxext)
@@ -3389,7 +3379,16 @@ X server.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1s6p7yxmi12q4y05va53rljwyzd6ry492r1pgi7wwq6cznivhgly"))))
+           "1s6p7yxmi12q4y05va53rljwyzd6ry492r1pgi7wwq6cznivhgly"))
+        (patches
+         (list (origin
+                 (method url-fetch)
+                 (uri "https://cgit.freedesktop.org/xorg/driver/\
+xf86-video-voodoo/patch/?id=9172ae566a0e85313fc80ab62b4455393eefe593")
+                 (sha256
+                  (base32
+                   "0rndmxf5b8j3hjnhrwrnzsq5024fli134fj1mprhkcrvax2zq8db"))
+                 (file-name "xf86-video-voodoo-pcitag.patch"))))))
     (build-system gnu-build-system)
     (inputs `(("xf86dgaproto" ,xf86dgaproto)
               ("xorg-server" ,xorg-server)))
@@ -3501,7 +3500,7 @@ configuring modelines and gamma.")
 (define-public xgamma
   (package
     (name "xgamma")
-    (version "1.0.5")
+    (version "1.0.6")
     (source
       (origin
         (method url-fetch)
@@ -3511,7 +3510,7 @@ configuring modelines and gamma.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0463sawps86jnxn121ramsz4sicy3az5wa5wsq4rqm8dm3za48p3"))))
+            "1lr2nb1fhg5fk2fchqxdxyl739602ggwhmgl2wiv5c8qbidw7w8f"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxxf86vm" ,libxxf86vm)
@@ -3529,7 +3528,7 @@ monitor via the X video mode extension.")
 (define-public xhost
   (package
     (name "xhost")
-    (version "1.0.6")
+    (version "1.0.7")
     (source
       (origin
         (method url-fetch)
@@ -3539,7 +3538,7 @@ monitor via the X video mode extension.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1hlxm0is9nks1cx033s1733kkib9ivx2bxa3pb9yayqavwibkxd6"))))
+            "16n26xw6l01zq31d4qvsaz50misvizhn7iihzdn5f7s72pp1krlk"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxmu" ,libxmu)
@@ -3588,7 +3587,7 @@ alternative implementations like XRandR or TwinView.")
 (define-public xinput
   (package
     (name "xinput")
-    (version "1.6.1")
+    (version "1.6.2")
     (source
       (origin
         (method url-fetch)
@@ -3598,7 +3597,7 @@ alternative implementations like XRandR or TwinView.")
                ".tar.bz2"))
         (sha256
           (base32
-            "07w7zlpdhpwzzshg8q0y152cy3wl2fj7x1897glnp2la487jsqxp"))))
+            "1i75mviz9dyqyf7qigzmxq8vn31i86aybm662fzjz5c086dx551n"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxrender" ,libxrender)
@@ -3670,7 +3669,7 @@ make keyboards more accessible to people with physical impairments.")
 (define-public xkbevd
   (package
     (name "xkbevd")
-    (version "1.1.3")
+    (version "1.1.4")
     (source
       (origin
         (method url-fetch)
@@ -3680,7 +3679,7 @@ make keyboards more accessible to people with physical impairments.")
                ".tar.bz2"))
         (sha256
           (base32
-            "05h1xcnbalndbrryyqs8wzy9h3wz655vc0ymhlk2q4aik17licjm"))))
+            "0sprjx8i86ljk0l7ldzbz2xlk8916z5zh78cafjv8k1a63js4c14"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxkbfile" ,libxkbfile)
@@ -3734,7 +3733,7 @@ extension to the X11 protocol.  It includes:
 (define-public xkeyboard-config
   (package
     (name "xkeyboard-config")
-    (version "2.13")
+    (version "2.17")
     (source
       (origin
         (method url-fetch)
@@ -3744,7 +3743,7 @@ extension to the X11 protocol.  It includes:
               ".tar.bz2"))
         (sha256
           (base32
-            "1klzbwabzd7bhbg23b14vy4l5xgpapn8lc0m5d8h40d3p7rfjnvv"))))
+            "00878f1v3034ki78pjpf2db0bh7jsmszsnxr3bf5qxripm2bxiny"))))
     (build-system gnu-build-system)
     (inputs
       `(("gettext" ,gnu-gettext)
@@ -3795,7 +3794,7 @@ programs that have displayed undesired windows on a user's screen.")
 (define-public xlsatoms
   (package
     (name "xlsatoms")
-    (version "1.1.1")
+    (version "1.1.2")
     (source
       (origin
         (method url-fetch)
@@ -3805,7 +3804,7 @@ programs that have displayed undesired windows on a user's screen.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1y9nfl8s7njxbnci8c20j986xixharasgg40vdw92y593j6dk2rv"))))
+            "196yjik910xsr7dwy8daa0amr0r22ynfs360z0ndp9mx7mydrra7"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxcb" ,libxcb)))
@@ -3876,7 +3875,7 @@ protocol.")
 (define-public xmodmap
   (package
     (name "xmodmap")
-    (version "1.0.8")
+    (version "1.0.9")
     (source
       (origin
         (method url-fetch)
@@ -3886,7 +3885,7 @@ protocol.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1hwzm54m4ng09ls9i4bq0x84zbyhamgzasgrvhxxp8jqk34f7qpg"))
+            "0y649an3jqfq9klkp9y5gj20xb78fw6g193f5mnzpl0hbz6fbc5p"))
         (patches (list (search-patch "xmodmap-asprintf.patch")))))
     (build-system gnu-build-system)
     (inputs
@@ -4170,7 +4169,7 @@ libICE, the X font server, and related components.")
 (define-public xvinfo
   (package
     (name "xvinfo")
-    (version "1.1.2")
+    (version "1.1.3")
     (source
       (origin
         (method url-fetch)
@@ -4180,7 +4179,7 @@ libICE, the X font server, and related components.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1qsh7fszi727l3vwlaf9pb7bpikdv15smrx5qhlgg3kqzl7xklzf"))))
+            "1sz5wqhxd1fqsfi1w5advdlwzkizf2fgl12hdpk66f7mv9l8pflz"))))
     (build-system gnu-build-system)
     (inputs
       `(("libxext" ,libxext)
@@ -4406,7 +4405,7 @@ cannot be adequately worked around on the client side of the wire.")
 (define-public libxp
   (package
     (name "libxp")
-    (version "1.0.2")
+    (version "1.0.3")
     (source
       (origin
         (method url-fetch)
@@ -4416,7 +4415,7 @@ cannot be adequately worked around on the client side of the wire.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1dfh5w8sjz5b5fl6dl4y63ckq99snslz7bir8zq2rg8ax6syabwm"))))
+            "0mwc2jwmq03b1m9ihax5c6gw2ln8rc70zz4fsj3kb7440nchqdkz"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("printproto" ,printproto)))
@@ -4434,7 +4433,7 @@ cannot be adequately worked around on the client side of the wire.")
 (define-public libxrender
   (package
     (name "libxrender")
-    (version "0.9.8")
+    (version "0.9.9")
     (source
       (origin
         (method url-fetch)
@@ -4444,7 +4443,7 @@ cannot be adequately worked around on the client side of the wire.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0qpwyjhbpp734vnhca992pjh4w7ijslidkzx1pcwbbk000pv050x"))))
+            "06myx7044qqdswxndsmd82fpp670klnizkgzdm194h51h1wyabzw"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("renderproto" ,renderproto)))
@@ -4558,7 +4557,7 @@ script around the mkfontscale program.")
 (define-public xproto
   (package
     (name "xproto")
-    (version "7.0.26")
+    (version "7.0.28")
     (source
       (origin
         (method url-fetch)
@@ -4568,7 +4567,7 @@ script around the mkfontscale program.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0ksi8vhfd916bx2f3xlyhn6azf6cvvzrsdja26haa1cqfp0n4qb3"))))
+            "1jpnvm33vi2dar5y5zgz7jjh0m8fpkcxm0f0lbwfx37ns5l5bs19"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("util-macros" ,util-macros))) ; to get util-macros in (almost?) all package inputs
@@ -4710,7 +4709,7 @@ new API's in libXft, or the legacy API's in libX11.")
 (define-public libxi
   (package
     (name "libxi")
-    (version "1.7.4")
+    (version "1.7.6")
     (source
       (origin
         (method url-fetch)
@@ -4720,7 +4719,7 @@ new API's in libXft, or the legacy API's in libX11.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0i12lj973grlp9fa79v0vh9cahk3nf9csdjnf81iip0qcrlc5zrc"))))
+            "1b5p0l19ynmd6blnqr205wyngh6fagl35nqb4v05dw60rr9aachz"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("inputproto" ,inputproto)
@@ -4740,7 +4739,7 @@ new API's in libXft, or the legacy API's in libX11.")
 (define-public libxrandr
   (package
     (name "libxrandr")
-    (version "1.4.2")
+    (version "1.5.0")
     (source
       (origin
         (method url-fetch)
@@ -4750,7 +4749,7 @@ new API's in libXft, or the legacy API's in libX11.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1b95p3l84ppv6j7dbbmg0zrz6k8xdwvnag1l6ajm3gk9qwdb79ya"))))
+            "0n6ycs1arf4wb1cal9il6v7vbxbf21qhs9sbfl8xndgwnxclk1kg"))))
     (build-system gnu-build-system)
     (propagated-inputs
       ;; In accordance with xrandr.pc.
@@ -4771,7 +4770,7 @@ new API's in libXft, or the legacy API's in libX11.")
 (define-public libxvmc
   (package
     (name "libxvmc")
-    (version "1.0.8")
+    (version "1.0.9")
     (source
       (origin
         (method url-fetch)
@@ -4781,7 +4780,7 @@ new API's in libXft, or the legacy API's in libX11.")
                ".tar.bz2"))
         (sha256
           (base32
-            "015jk3bxfmj6zaw99x282f9npi8qqaw34yg186frags3z8g406jy"))))
+            "0mjp1b21dvkaz7r0iq085r92nh5vkpmx99awfgqq9hgzyvgxf0q7"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("libxv" ,libxv)))
@@ -4800,7 +4799,7 @@ new API's in libXft, or the legacy API's in libX11.")
 (define-public libxxf86vm
   (package
     (name "libxxf86vm")
-    (version "1.1.3")
+    (version "1.1.4")
     (source
       (origin
         (method url-fetch)
@@ -4810,7 +4809,7 @@ new API's in libXft, or the legacy API's in libX11.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1f1pxj018nk7ybxv58jmn5y8gm2288p4q3l2dng9n1p25v1qcpns"))))
+            "0mydhlyn72i7brjwypsqrpkls3nm6vxw0li8b2nw0caz7kwjgvmg"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("libxext" ,libxext)
@@ -4876,7 +4875,7 @@ over Xlib, including:
 (define-public xorg-server
   (package
     (name "xorg-server")
-    (version "1.16.4")
+    (version "1.18.1")
     (source
       (origin
         (method url-fetch)
@@ -4885,7 +4884,7 @@ over Xlib, including:
               name "-" version ".tar.bz2"))
         (sha256
          (base32
-          "0wf8xykcjhvpk9ppjcixvf60p6kkyrpmfj0z29d93a8kjb6f3dmb"))))
+          "17bq40als48v12ld81jysc0gj5g572zkjkyzbhlm3ac9xgdmdv45"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("dri2proto" ,dri2proto)
@@ -4986,7 +4985,7 @@ draggable titlebars and borders.")
 (define-public libx11
   (package
     (name "libx11")
-    (version "1.6.2")
+    (version "1.6.3")
     (source
       (origin
         (method url-fetch)
@@ -4996,7 +4995,7 @@ draggable titlebars and borders.")
                ".tar.bz2"))
         (sha256
           (base32
-            "05mx0s0vqzds3qjc1gmjr2s6x2ll37z4lfhgm7p2w7936zl2g81a"))))
+            "04c1vj53xq2xgyxx5vhln3wm2d76hh1n95fvs3myhligkz1sfcfg"))))
     (build-system gnu-build-system)
     (outputs '("out"
                "doc"))                            ;8 MiB of man pages + XML
@@ -5052,7 +5051,7 @@ draggable titlebars and borders.")
 (define-public libxt
   (package
     (name "libxt")
-    (version "1.1.4")
+    (version "1.1.5")
     (source
       (origin
         (method url-fetch)
@@ -5062,7 +5061,7 @@ draggable titlebars and borders.")
                ".tar.bz2"))
         (sha256
           (base32
-            "0myxwbx9ylam5x3ia5b5f4x8azcqdm420h9ad1r4hrgmi2lrffl4"))))
+            "06lz6i7rbrp19kgikpaz4c97fw7n31k2h2aiikczs482g2zbdvj6"))))
     (build-system gnu-build-system)
     (outputs '("out"
                "doc"))                            ;2 MiB of man pages + XML
@@ -5087,7 +5086,7 @@ draggable titlebars and borders.")
 (define-public libxaw
   (package
     (name "libxaw")
-    (version "1.0.12")
+    (version "1.0.13")
     (source
       (origin
         (method url-fetch)
@@ -5097,7 +5096,7 @@ draggable titlebars and borders.")
                ".tar.bz2"))
         (sha256
           (base32
-            "1xnv7jy86j9vhmw74frkzcraynqbw1p1s79jasargsgwfi433z4n"))))
+            "1kdhxplwrn43d9jp3v54llp05kwx210lrsdvqb6944jp29rhdy4f"))))
     (build-system gnu-build-system)
     (propagated-inputs
       `(("libxext" ,libxext)
@@ -5158,7 +5157,7 @@ The XCB util module provides the following libraries:
     (version "0.1.2")
     (source (origin
               (method url-fetch)
-              (uri (string-append "http://xcb.freedesktop.org/dist/"
+              (uri (string-append "https://xcb.freedesktop.org/dist/"
                                   "xcb-util-cursor-" version ".tar.gz"))
               (sha256
                (base32
diff --git a/gnu/packages/yasm.scm b/gnu/packages/yasm.scm
index abf6663187..31a9083cdf 100644
--- a/gnu/packages/yasm.scm
+++ b/gnu/packages/yasm.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013 Andreas Enge <andreas@enge.fr>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -28,7 +29,7 @@
 (define-public yasm
   (package
     (name "yasm")
-    (version "1.2.0")
+    (version "1.3.0")
     (source
      (origin
       (method url-fetch)
@@ -36,7 +37,7 @@
                           version ".tar.gz"))
       (sha256
        (base32
-        "0cfg7ji3ia2in628w42wrfvw2ixmmm4rghwmv2k202mraysgm3vn"))))
+        "0gv0slmm0qpq91za3v2v9glff3il594x5xsrbgab7xcmnh0ndkix"))))
     (build-system gnu-build-system)
     (inputs
      `(("python" ,python-wrapper)
diff --git a/gnu/packages/yubico.scm b/gnu/packages/yubico.scm
index f2e8ff133c..469d93d0dc 100644
--- a/gnu/packages/yubico.scm
+++ b/gnu/packages/yubico.scm
@@ -1,5 +1,6 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2014 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -29,7 +30,7 @@
 (define-public libyubikey
   (package
     (name "libyubikey")
-    (version "1.12")
+    (version "1.13")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -37,7 +38,7 @@
                     name "-" version ".tar.gz"))
               (sha256
                (base32
-                "1f0plzmr1gwry4rfgq9q70v6qwqny009hac289ad5m6sj7vqflxr"))))
+                "009l3k2zyn06dbrlja2d4p2vfnzjhlcqxi88v02mlrnb17mx1v84"))))
     (build-system gnu-build-system)
     (synopsis "Development kit for the YubiKey authentication device")
     (description
@@ -49,7 +50,7 @@ the low-level development kit for the Yubico YubiKey authentication device.")
 (define-public ykclient
   (package
     (name "ykclient")
-    (version "2.13")
+    (version "2.15")
     (source (origin
               (method url-fetch)
               (uri (string-append
@@ -57,7 +58,7 @@ the low-level development kit for the Yubico YubiKey authentication device.")
                     name "-" version ".tar.gz"))
               (sha256
                (base32
-                "1lw1j61rfjngs8vvv9m348zl4166zg24bq0dy72r44wiz79yic4j"))))
+                "05jhx9waj3pl120ddnwap1v3bjrnbfhvf3lxs2xmhpcmwzpwsqgl"))))
     (build-system gnu-build-system)
 
     ;; There's just one test, and it requires network access to access
diff --git a/gnu/packages/zsh.scm b/gnu/packages/zsh.scm
index 6d25fd4671..fba7bb19b8 100644
--- a/gnu/packages/zsh.scm
+++ b/gnu/packages/zsh.scm
@@ -64,10 +64,10 @@
                                      "Util/preconfig")
                                  (("/bin/sh") (which "sh")))))
                            %standard-phases)))
-    (native-inputs `(("autoconf", autoconf)))
-    (inputs `(("ncurses", ncurses)
-              ("pcre", pcre)
-              ("perl", perl)))
+    (native-inputs `(("autoconf" ,autoconf)))
+    (inputs `(("ncurses" ,ncurses)
+              ("pcre" ,pcre)
+              ("perl" ,perl)))
     (synopsis "Powerful shell for interactive use and scripting")
     (description "The Z shell (zsh) is a Unix shell that can be used
 as an interactive login shell and as a powerful command interpreter
diff --git a/gnu/services/databases.scm b/gnu/services/databases.scm
index 8b1420116d..6c3b829df7 100644
--- a/gnu/services/databases.scm
+++ b/gnu/services/databases.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2015 David Thompson <davet@gnu.org>
 ;;; Copyright © 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -56,7 +57,7 @@ host	all	all	::1/128 	trust"))
 (define %default-postgres-config
   (mixed-text-file "postgresql.conf"
                    "hba_file = '" %default-postgres-hba "'\n"
-                   "ident_file = '" %default-postgres-ident "\n"))
+                   "ident_file = '" %default-postgres-ident "'\n"))
 
 (define %postgresql-accounts
   (list (user-group (name "postgres") (system? #t))
diff --git a/gnu/services/desktop.scm b/gnu/services/desktop.scm
index e4f0736b89..02bcf1b19f 100644
--- a/gnu/services/desktop.scm
+++ b/gnu/services/desktop.scm
@@ -378,7 +378,7 @@ site} for more information."
 (define polkit-etc-files
   (match-lambda
     (($ <polkit-configuration> polkit packages)
-     `(("polkit-1" ,(polkit-directory packages))))))
+     `(("polkit-1" ,(polkit-directory (cons polkit packages)))))))
 
 (define polkit-setuid-programs
   (match-lambda
diff --git a/gnu/services/herd.scm b/gnu/services/herd.scm
index a3a9bf0230..9cb33a9fd0 100644
--- a/gnu/services/herd.scm
+++ b/gnu/services/herd.scm
@@ -66,19 +66,19 @@ return the socket."
 command object."
   (match error
     (('error ('version 0 x ...) 'service-not-found service)
-     (report-error (_ "service '~a' could not be found")
+     (report-error (_ "service '~a' could not be found~%")
                    service))
     (('error ('version 0 x ...) 'action-not-found action service)
-     (report-error (_ "service '~a' does not have an action '~a'")
+     (report-error (_ "service '~a' does not have an action '~a'~%")
                    service action))
     (('error ('version 0 x ...) 'action-exception action service
              key (args ...))
      (report-error (_ "exception caught while executing '~a' \
-on service '~a':")
+on service '~a':~%")
                    action service)
      (print-exception (current-error-port) #f key args))
     (('error . _)
-     (report-error (_ "something went wrong: ~s")
+     (report-error (_ "something went wrong: ~s~%")
                    error))
     (#f                                           ;not an error
      #t)))
diff --git a/gnu/services/xorg.scm b/gnu/services/xorg.scm
index a93dbfe7c4..980b5a6ba5 100644
--- a/gnu/services/xorg.scm
+++ b/gnu/services/xorg.scm
@@ -40,6 +40,7 @@
   #:use-module (srfi srfi-26)
   #:use-module (ice-9 match)
   #:export (xorg-configuration-file
+            %default-xorg-modules
             xorg-start-command
             %default-slim-theme
             %default-slim-theme-name
@@ -137,9 +138,52 @@ EndSection
   "\n"
   extra-config))
 
+(define %default-xorg-modules
+  (list xf86-video-vesa
+        xf86-video-fbdev
+        xf86-video-modesetting
+        xf86-video-cirrus
+        xf86-video-intel
+        xf86-video-mach64
+        xf86-video-nouveau
+        xf86-video-nv
+        xf86-video-sis
+        xf86-input-libinput
+        xf86-input-evdev
+        xf86-input-keyboard
+        xf86-input-mouse
+        xf86-input-synaptics))
+
+(define (xorg-configuration-directory modules)
+  "Return a directory that contains the @code{.conf} files for X.org that
+includes the @code{share/X11/xorg.conf.d} directories of each package listed
+in @var{modules}."
+  (computed-file "xorg.conf.d"
+                 #~(begin
+                     (use-modules (guix build utils)
+                                  (srfi srfi-1))
+
+                     (define files
+                       (append-map (lambda (module)
+                                     (find-files (string-append
+                                                  module
+                                                  "/share/X11/xorg.conf.d")
+                                                 "\\.conf$"))
+                                   (list #$@modules)))
+
+                     (mkdir #$output)
+                     (for-each (lambda (file)
+                                 (symlink file
+                                          (string-append #$output "/"
+                                                         (basename file))))
+                               files)
+                     #t)
+                 #:modules '((guix build utils))))
+
 (define* (xorg-start-command #:key
                              (guile (canonical-package guile-2.0))
                              (configuration-file (xorg-configuration-file))
+                             (modules %default-xorg-modules)
                              (xorg-server xorg-server))
   "Return a derivation that builds a @var{guile} script to start the X server
 from @var{xorg-server}.  @var{configuration-file} is the server configuration
@@ -158,6 +202,7 @@ Usually the X server is started by a login manager."
                "-logverbose" "-verbose"
                "-xkbdir" (string-append #$xkeyboard-config "/share/X11/xkb")
                "-config" #$configuration-file
+               "-configdir" #$(xorg-configuration-directory modules)
                "-nolisten" "tcp" "-terminate"
 
                ;; Note: SLiM and other display managers add the
diff --git a/gnu/system.scm b/gnu/system.scm
index 9540324df0..d600d3a293 100644
--- a/gnu/system.scm
+++ b/gnu/system.scm
@@ -1,7 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
-;;; Copyright © 2015 Alex Kost <alezost@gmail.com>
+;;; Copyright © 2015, 2016 Alex Kost <alezost@gmail.com>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -362,6 +362,7 @@ explicitly appear in OS."
          ;; many people are familiar with, so keep it around.
          iw wireless-tools
 
+         iproute
          net-tools                        ; XXX: remove when Inetutils suffices
          man-db
          texinfo                               ;for the standalone Info reader
@@ -669,18 +670,31 @@ hardware-related operations as necessary when booting a Linux container."
                                            #:mapped-devices mapped-devices)))
     (return #~(string-append #$initrd "/initrd"))))
 
+(define (locale-name->definition* name)
+  "Variant of 'locale-name->definition' that raises an error upon failure."
+  (match (locale-name->definition name)
+    (#f
+     (raise (condition
+             (&message
+              (message (format #f (_ "~a: invalid locale name") name))))))
+    (def def)))
+
 (define (operating-system-locale-directory os)
   "Return the directory containing the locales compiled for the definitions
 listed in OS.  The C library expects to find it under
 /run/current-system/locale."
-  ;; While we're at it, check whether the locale of OS is defined.
-  (unless (member (operating-system-locale os)
-                  (map locale-definition-name
-                       (operating-system-locale-definitions os)))
-    (raise (condition
-            (&message (message "system locale lacks a definition")))))
-
-  (locale-directory (operating-system-locale-definitions os)
+  (define name
+    (operating-system-locale os))
+
+  (define definitions
+    ;; While we're at it, check whether NAME is defined and add it if needed.
+    (if (member name (map locale-definition-name
+                          (operating-system-locale-definitions os)))
+        (operating-system-locale-definitions os)
+        (cons (locale-name->definition* name)
+              (operating-system-locale-definitions os))))
+
+  (locale-directory definitions
                     #:libcs (operating-system-locale-libcs os)))
 
 (define (kernel->grub-label kernel)
diff --git a/gnu/system/install.scm b/gnu/system/install.scm
index 0cfc8fa5c9..b380716b69 100644
--- a/gnu/system/install.scm
+++ b/gnu/system/install.scm
@@ -237,7 +237,12 @@ the user's target storage device rather than on the RAM disk."
   ;; Minimal in-memory caching policy for nscd.
   (list (nscd-cache (database 'hosts)
                     (positive-time-to-live (* 3600 12))
-                    (negative-time-to-live 20)
+
+                    ;; Do not cache lookup failures at all since they are
+                    ;; quite likely (for instance when someone tries to ping a
+                    ;; host before networking is functional.)
+                    (negative-time-to-live 0)
+
                     (persistent? #f)
                     (max-database-size (* 5 (expt 2 20)))))) ;5 MiB
 
@@ -365,6 +370,7 @@ Use Alt-F2 for documentation.
                      parted ddrescue
                      grub                  ;mostly so xrefs to its manual work
                      cryptsetup
+                     btrfs-progs
                      wireless-tools iw wpa-supplicant-minimal iproute
                      ;; XXX: We used to have GNU fdisk here, but as of version
                      ;; 2.0.0a, that pulls Guile 1.8, which takes unreasonable
diff --git a/gnu/system/locale.scm b/gnu/system/locale.scm
index e798827a01..f9d713e0cf 100644
--- a/gnu/system/locale.scm
+++ b/gnu/system/locale.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2014, 2015 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -33,6 +33,7 @@
             locale-definition-source
             locale-definition-charset
 
+            locale-name->definition
             locale-directory
 
             %default-locale-libcs
@@ -52,6 +53,35 @@
   (charset locale-definition-charset              ;string--e.g., "UTF-8"
            (default "UTF-8")))
 
+(define %not-dot
+  (char-set-complement (char-set #\.)))
+
+(define (denormalize-codeset codeset)
+  "Attempt to guess the \"real\" name of CODESET, a normalized codeset as
+defined in (info \"(libc) Using gettextized software\")."
+  (cond ((string=? codeset "utf8")
+         "UTF-8")
+        ((string-prefix? "iso8859" codeset)
+         (string-append "ISO-8859-" (string-drop codeset 7)))
+        ((string=? codeset "eucjp")
+         "EUC-JP")
+        (else                                ;cross fingers, hope for the best
+         codeset)))
+
+(define (locale-name->definition name)
+  "Return a <locale-definition> corresponding to NAME, guessing the charset,
+or #f on failure."
+  (match (string-tokenize name %not-dot)
+    ((source charset)
+     ;; XXX: NAME is supposed to use the "normalized codeset", such as "utf8",
+     ;; whereas the actual name used is different.  Add a special case to make
+     ;; the right guess for UTF-8.
+     (locale-definition (name name)
+                        (source source)
+                        (charset (denormalize-codeset charset))))
+    (_
+     #f)))
+
 (define* (localedef-command locale
                             #:key (libc (canonical-package glibc)))
   "Return a gexp that runs 'localedef' from LIBC to build LOCALE."
diff --git a/gnu/system/vm.scm b/gnu/system/vm.scm
index a7c03bda17..58a476a468 100644
--- a/gnu/system/vm.scm
+++ b/gnu/system/vm.scm
@@ -1,5 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2013, 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016 Christopher Allan Webber <cwebber@dustycloud.org>
+;;; Copyright © 2016 Leo Famulari <leo@famulari.name>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -457,7 +459,13 @@ with '-virtfs' options for the host file systems listed in SHARED-FS."
                      "\" "))
 
   #~(string-append
-     " -enable-kvm -no-reboot -net nic,model=virtio \
+     ;; Only enable kvm if we see /dev/kvm exists.
+     ;; This allows users without hardware virtualization to still use these
+     ;; commands.
+     #$(if (file-exists? "/dev/kvm")
+           " -enable-kvm "
+           "")
+     " -no-reboot -net nic,model=virtio \
   " #$@(map virtfs-option shared-fs) " \
   -net user \
   -serial stdio -vga std \