diff --git a/fsl/data/dicom.py b/fsl/data/dicom.py
index 53b7edefe067583d0ea94aaddcc4024b5faa663e..1457c54eed7f4e017500de67d033f5b4b5626052 100644
--- a/fsl/data/dicom.py
+++ b/fsl/data/dicom.py
@@ -32,7 +32,6 @@ import               re
 import               glob
 import               json
 import               logging
-import               deprecation
 
 import nibabel    as nib
 
@@ -80,38 +79,6 @@ class DicomImage(fslimage.Image):
         return self.__dicomDir
 
 
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use metaKeys instead')
-    def keys(self):
-        """Deprecated - use :meth:`.Image.metaKeys`. """
-        return self.metaKeys()
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use metaValues instead')
-    def values(self):
-        """Deprecated - use :meth:`.Image.metaValues`. """
-        return self.metaValues()
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use metaItems instead')
-    def items(self):
-        """Deprecated - use :meth:`.Image.metaItems`. """
-        return self.metaItems()
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use getMeta instead')
-    def get(self, *args, **kwargs):
-        """Deprecated - use :meth:`.Image.getMeta`. """
-        return self.getMeta(*args, **kwargs)
-
-
 @memoize.memoize
 def enabled():
     """Returns ``True`` if ``dcm2niix`` is present, and recent enough,
diff --git a/fsl/data/gifti.py b/fsl/data/gifti.py
index cd5185183d1770db9080f512d6df7b99a61dad51..d957d75c18e2898693fd95161c16c10c2bfc484e 100644
--- a/fsl/data/gifti.py
+++ b/fsl/data/gifti.py
@@ -25,7 +25,6 @@ are available:
 
 import            glob
 import os.path as op
-import            deprecation
 
 import numpy   as np
 import nibabel as nib
@@ -306,48 +305,3 @@ def relatedFiles(fname, ftypes=None):
             glob.glob(op.join(dirname, '{}*{}'.format(prefix, ftype))))
 
     return [r for r in related if r != path]
-
-
-class GiftiSurface(fslmesh.TriangleMesh):
-    """Deprecated - use GiftiMesh instead. """
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use GiftiMesh instead')
-    def __init__(self, infile, fixWinding=False):
-        """Deprecated - use GiftiMesh instead. """
-        surfimg, vertices, indices = loadGiftiSurface(infile)
-
-        fslmesh.TriangleMesh.__init__(self, vertices, indices, fixWinding)
-
-        name   = fslpath.removeExt(op.basename(infile), ALLOWED_EXTENSIONS)
-        infile = op.abspath(infile)
-
-        self._Mesh__name       = name
-        self._Mesh__dataSource = infile
-        self.surfImg           = surfimg
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use GiftiMesh instead')
-    def loadVertexData(self, dataSource, vertexData=None):
-        """Deprecated - use GiftiMesh instead. """
-
-        if vertexData is None:
-            if dataSource.endswith('.gii'):
-                vertexData = loadGiftiVertexData(dataSource)[1]
-            else:
-                vertexData = None
-
-        return fslmesh.TriangleMesh.loadVertexData(
-            self, dataSource, vertexData)
-
-
-@deprecation.deprecated(deprecated_in='1.6.0',
-                        removed_in='2.0.0',
-                        details='Use loadGiftiMesh instead')
-def loadGiftiSurface(filename):
-    """Deprecated - use loadGiftiMesh instead."""
-    return loadGiftiMesh(filename)
diff --git a/fsl/data/image.py b/fsl/data/image.py
index 6d1a7e4a831b7539805adb6c8068d22d677b7db2..c607cf47dbeac31e50bdcd21be87aa2d1ef9f975 100644
--- a/fsl/data/image.py
+++ b/fsl/data/image.py
@@ -41,7 +41,6 @@ import                      logging
 import                      tempfile
 
 import                      six
-import                      deprecation
 import numpy             as np
 import scipy.ndimage     as ndimage
 
@@ -502,23 +501,6 @@ class Nifti(notifier.Notifier, meta.Meta):
         return len(self.__shape)
 
 
-    @property
-    @deprecation.deprecated(deprecated_in='1.9.0',
-                            removed_in='2.0.0',
-                            details='Use ndim instead')
-    def ndims(self):
-        """Deprecated - use :mod::meth:``ndim`` instead. """
-        return self.ndim
-
-
-    @deprecation.deprecated(deprecated_in='1.1.0',
-                            removed_in='2.0.0',
-                            details='Use ndims instead')
-    def is4DImage(self):
-        """Returns ``True`` if this image is 4D, ``False`` otherwise. """
-        return len(self.__shape) > 3 and self.__shape[3] > 1
-
-
     def getXFormCode(self, code=None):
         """This method returns the code contained in the NIFTI header,
         indicating the space to which the (transformed) image is oriented.
@@ -605,15 +587,6 @@ class Nifti(notifier.Notifier, meta.Meta):
         return npla.det(self.__voxToWorldMat) > 0
 
 
-    @memoize.Instanceify(memoize.memoize)
-    @deprecation.deprecated(deprecated_in='1.2.0',
-                            removed_in='2.0.0',
-                            details='Use voxToScaledVoxMat instead')
-    def voxelsToScaledVoxels(self):
-        """See :meth:`voxToScaledVoxMat`."""
-        return self.voxToScaledVoxMat
-
-
     @property
     def voxToScaledVoxMat(self):
         """Returns a transformation matrix which transforms from voxel
@@ -1519,78 +1492,3 @@ def loadIndexedImageFile(filename):
     image = ftype.from_file_map(fmap)
 
     return image, fobj
-
-
-@deprecation.deprecated(deprecated_in='1.3.0',
-                        removed_in='2.0.0',
-                        details='Upgrade to nibabel 2.2.0')
-def read_segments(fileobj, segments, n_bytes):
-    """This function is used in place of the
-    ``nibabel.fileslice.read_segments`` function to ensure thread-safe read
-    access to image data via the ``nibabel.arrayproxy.ArrayProxy`` (the
-    ``dataobj`` attribute of a ``nibabel`` image).
-
-    The ``nibabel`` implementation uses multiple calls to ``seek`` and
-    ``read`` to read segments of data from the file. When accessed by multiple
-    threads, these seeks and reads can become intertwined, which causes a read
-    from one thread to read data from the seek location requested by the other
-    thread.
-
-    This implementation protects the seek/read pairs with a
-    ``threading.Lock``, which is added to ``IndexedGzipFile`` instances that
-    are created in the :func:`loadIndexedImageFile` function.
-
-    .. note:: This patch is not required in nibabel 2.2.0 and newer. It will
-              be removed from ``fslpy`` in version 2.0.0.
-    """
-
-    from mmap import mmap
-
-    try:
-        # fileobj is a nibabel.openers.ImageOpener - the
-        # actual file is available via the fobj attribute
-        lock = getattr(fileobj.fobj, '_arrayproxy_lock')
-
-    except AttributeError:
-        return fileslice.orig_read_segments(fileobj, segments, n_bytes)
-
-    if len(segments) == 0:
-        if n_bytes != 0:
-            raise ValueError("No segments, but non-zero n_bytes")
-        return b''
-    if len(segments) == 1:
-        offset, length = segments[0]
-
-        lock.acquire()
-        try:
-            fileobj.seek(offset)
-            bytes = fileobj.read(length)
-        finally:
-            lock.release()
-
-        if len(bytes) != n_bytes:
-            raise ValueError("Whoops, not enough data in file")
-        return bytes
-
-    # More than one segment
-    bytes = mmap(-1, n_bytes)
-    for offset, length in segments:
-
-        lock.acquire()
-        try:
-            fileobj.seek(offset)
-            bytes.write(fileobj.read(length))
-        finally:
-            lock.release()
-
-    if bytes.tell() != n_bytes:
-        raise ValueError("Oh dear, n_bytes does not look right")
-    return bytes
-
-
-# Monkey-patch the above implementation into
-# nibabel. FSLeyes requires at least 2.1.0 -
-# newer versions do not need to be patched.
-if nib.__version__ == '2.1.0':
-    fileslice.orig_read_segments = fileslice.read_segments
-    fileslice.read_segments      = read_segments
diff --git a/fsl/data/imagewrapper.py b/fsl/data/imagewrapper.py
index 559c0d974f5563edbafef459870cbbb5b504ddac..eccf8518485bdbb921f4c010db1bf197962f21e2 100644
--- a/fsl/data/imagewrapper.py
+++ b/fsl/data/imagewrapper.py
@@ -41,8 +41,6 @@ import logging
 import collections
 import itertools as it
 
-import deprecation
-
 import numpy     as np
 import nibabel   as nib
 
@@ -717,16 +715,6 @@ class ImageWrapper(notifier.Notifier):
         self.__updateDataRangeOnWrite(slices, values)
 
 
-@deprecation.deprecated(deprecated_in='1.7.0',
-                        removed_in='2.0.0',
-                        details='Moved to fsl.utils.naninfrange')
-def naninfrange(data):
-    """Deprecated - moved to :mod:`fsl.utils.naninfrange`. """
-
-    from fsl.utils.naninfrange import naninfrange
-    return naninfrange(data)
-
-
 def isValidFancySliceObj(sliceobj, shape):
     """Returns ``True`` if the given ``sliceobj`` is a valid and fancy slice
     object.
@@ -768,15 +756,6 @@ def canonicalSliceObj(sliceobj, shape):
         return nib.fileslice.canonical_slicers(sliceobj, shape)
 
 
-@deprecation.deprecated(deprecated_in='1.7.0',
-                        removed_in='2.0.0',
-                        details='moved to the fsl.data.image module')
-def canonicalShape(shape):
-    """Deprecated - moved to the :mod:`fsl.data.image` module. """
-    from fsl.data.image import canonicalShape
-    return canonicalShape(shape)
-
-
 def expectedShape(sliceobj, shape):
     """Given a slice object, and the shape of an array to which
     that slice object is going to be applied, returns the expected
diff --git a/fsl/data/mesh.py b/fsl/data/mesh.py
index 59fc266c702e3b82427be74fc764ab41d0797c70..55b996069dfcb54b616bcc616b8b70eff90e02a7 100644
--- a/fsl/data/mesh.py
+++ b/fsl/data/mesh.py
@@ -30,9 +30,6 @@ various things with meshes:
 import logging
 import collections
 
-import six
-import deprecation
-
 import os.path as op
 import numpy   as np
 
@@ -763,109 +760,3 @@ def needsFixing(vertices, indices, fnormals, loBounds, hiBounds):
     # If it isn't, we need to flip the
     # triangle winding order.
     return np.dot(n, transform.normalise(camera - vert)) < 0
-
-
-class TriangleMesh(Mesh):
-    """Deprecated - use :class:`fsl.data.mesh.Mesh`, or one of its sub-classes
-    instead.
-    """
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use fsl.data.mesh.Mesh, or one '
-                                    'of its sub-classes instead')
-    def __init__(self, data, indices=None, fixWinding=False):
-
-        import fsl.data.vtk as fslvtk
-
-        if isinstance(data, six.string_types):
-            name       = op.basename(data)
-            dataSource = data
-            mesh       = fslvtk.VTKMesh(data, fixWinding=False)
-            vertices   = mesh.vertices
-            indices    = mesh.indices
-
-        else:
-            name       = 'TriangleMesh'
-            dataSource = None
-            vertices   = data
-
-        Mesh.__init__(self, indices, name=name, dataSource=dataSource)
-        self.addVertices(vertices, 'default', fixWinding=fixWinding)
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use the Mesh class instead')
-    def loadVertexData(self, dataSource, vertexData=None):
-
-        nvertices = self.vertices.shape[0]
-
-        # Currently only white-space delimited
-        # text files are supported
-        if vertexData is None:
-            vertexData = np.loadtxt(dataSource)
-            vertexData.reshape(nvertices, -1)
-
-        if vertexData.shape[0] != nvertices:
-            raise ValueError('Incompatible size: {}'.format(dataSource))
-
-        self.addVertexData(dataSource, vertexData)
-
-        return vertexData
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use bounds instead')
-    def getBounds(self):
-        """Deprecated - use :meth:`bounds` instead. """
-        return self.bounds
-
-
-    @deprecation.deprecated(deprecated_in='1.6.0',
-                            removed_in='2.0.0',
-                            details='Use the Mesh class instead')
-    def getVertexData(self, dataSource):
-        try:
-            return Mesh.getVertexData(self, dataSource)
-        except KeyError:
-            return self.loadVertexData(dataSource)
-
-
-@deprecation.deprecated(deprecated_in='1.6.0',
-                        removed_in='2.0.0',
-                        details='Use fsl.data.vtk.loadVTKPolydataFile instead')
-def loadVTKPolydataFile(*args, **kwargs):
-    """Deprecated - use :func:`fsl.data.vtk.loadVTKPolydataFile` instead. """
-    import fsl.data.vtk as fslvtk
-    return fslvtk.loadVTKPolydataFile(*args, **kwargs)
-
-
-@deprecation.deprecated(deprecated_in='1.6.0',
-                        removed_in='2.0.0',
-                        details='Use fsl.data.vtk.getFIRSTPrefix instead')
-def getFIRSTPrefix(*args, **kwargs):
-    """Deprecated - use :func:`fsl.data.vtk.getFIRSTPrefix` instead. """
-    import fsl.data.vtk as fslvtk
-    return fslvtk.getFIRSTPrefix(*args, **kwargs)
-
-
-@deprecation.deprecated(deprecated_in='1.6.0',
-                        removed_in='2.0.0',
-                        details='Use fsl.data.vtk.findReferenceImage instead')
-def findReferenceImage(*args, **kwargs):
-    """Deprecated - use :func:`fsl.data.vtk.findReferenceImage` instead. """
-    import fsl.data.vtk as fslvtk
-    return fslvtk.findReferenceImage(*args, **kwargs)
-
-
-ALLOWED_EXTENSIONS = ['.vtk']
-"""Deprecated, will be removed in fslpy 2.0.0. Use
-:attr:`fsl.data.vtk.ALLOWED_EXTENSIONS` instead."""
-
-
-EXTENSION_DESCRIPTIONS = ['VTK polygon model file']
-"""Deprecated, will be removed in fslpy 2.0.0. Use
-:attr:`fsl.data.vtk.EXTENSION_DESCRIPTIONS` instead."""
diff --git a/fsl/utils/async.py b/fsl/utils/async.py
deleted file mode 100644
index 520f77ce62c2c5bd4586571469c305369eb00934..0000000000000000000000000000000000000000
--- a/fsl/utils/async.py
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/usr/bin/env python
-#
-# async.py - Deprecaed - use the idle module instead.
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-"""This module is deprecated - use the :mod:`.idle` module instead. """
-
-
-import logging
-import warnings
-
-from .idle import (run,  # noqa
-                   idleReset,
-                   getIdleTimeout,
-                   setIdleTimeout,
-                   inIdle,
-                   cancelIdle,
-                   idle,
-                   idleWhen,
-                   wait,
-                   TaskThreadVeto,
-                   TaskThread,
-                   mutex)
-
-
-log = logging.getLogger(__name__)
-
-
-warnings.warn('fsl.utils.async is deprecated and will be removed '
-              'in fslpy 2.0.0 - use fsl.utils.idle instead',
-              DeprecationWarning)
-log.warning('fsl.utils.async is deprecated and will be removed '
-            'in fslpy 2.0.0 - use fsl.utils.idle instead')
diff --git a/fsl/utils/callfsl.py b/fsl/utils/callfsl.py
deleted file mode 100644
index 598df885bc0d595dda214aff7d1670e0336df85e..0000000000000000000000000000000000000000
--- a/fsl/utils/callfsl.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-#
-# callfsl.py - The callFSL function.
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-"""Deprecated - use :mod:`fsl.utils.run` instead.
-
-This module provides the :func:`callFSL` function, which can be
-used to call a FSL command, and retrieve the result.
-"""
-
-
-import               logging
-import subprocess as sp
-import os.path    as op
-
-import               deprecation
-
-from fsl.utils.platform import platform as fslplatform
-
-
-log = logging.getLogger(__name__)
-
-
-@deprecation.deprecated(deprecated_in='1.8.0',
-                        removed_in='2.0.0',
-                        details='Use fsl.utils.run.runfsl instead')
-def callFSL(*args):
-    """Call a FSL command and return the result.
-
-    You can pass the command and arguments as a single string, or as a
-    list/tuple.
-    """
-
-    if fslplatform.fsldir is None:
-        raise RuntimeError('FSL cannot be found!')
-
-    # If we've been given a single argument,
-    # assume it is a string containing the
-    # command and its arguments. Otherwise,
-    # assume it is a sequence containing
-    # separate command and arguments.
-    if len(args) == 1:
-        args = args[0].split()
-
-    args    = list(args)
-    args[0] = op.join(fslplatform.fsldir, 'bin', args[0])
-
-    log.debug('callfsl: {}'.format(' '.join(args)))
-
-    result = sp.check_output(args).decode('utf-8')
-
-    log.debug('result: {}'.format(result))
-
-    return result
diff --git a/fsl/utils/platform.py b/fsl/utils/platform.py
index cd2764ef9a9accc9a9f0f1a9d4f7e7837a687a8f..26706f31814ba805062fc04fdbc49abd205bda6f 100644
--- a/fsl/utils/platform.py
+++ b/fsl/utils/platform.py
@@ -17,7 +17,6 @@ import os
 import os.path as op
 import sys
 import importlib
-import deprecation
 
 import fsl.utils.notifier as notifier
 
@@ -73,34 +72,6 @@ are running the Linux/GTK wx build.
 """
 
 
-@deprecation.deprecated(deprecated_in='1.2.2',
-                        removed_in='2.0.0',
-                        details='Use fsleyes_widgets.isalive instead')
-def isWidgetAlive(widget):
-    """Returns ``True`` if the given ``wx.Window`` object is "alive" (i.e.
-    has not been destroyed), ``False`` otherwise. Works in both wxPython
-    and wxPython/Phoenix.
-
-    .. warning:: Don't try to test whether a ``wx.MenuItem`` has been
-                 destroyed, as it will probably result in segmentation
-                 faults. Check the parent ``wx.Menu`` instead.
-    """
-
-    import wx
-
-    if platform.wxFlavour == platform.WX_PHOENIX:
-        excType = RuntimeError
-    elif platform.wxFlavour == platform.WX_PYTHON:
-        excType = wx.PyDeadObjectError
-
-    try:
-        widget.GetParent()
-        return True
-
-    except excType:
-        return False
-
-
 class Platform(notifier.Notifier):
     """The ``Platform`` class contains a handful of properties which contain
     information about the platform we are running on.
@@ -138,7 +109,6 @@ class Platform(notifier.Notifier):
         self.WX_MAC_COCOA  = WX_MAC_COCOA
         self.WX_MAC_CARBON = WX_MAC_CARBON
         self.WX_GTK        = WX_GTK
-        self.isWidgetAlive = isWidgetAlive
 
         self.__inSSHSession = False
         self.__inVNCSession = False
diff --git a/fsl/utils/run.py b/fsl/utils/run.py
index a5b9df816f9605edf62b8daa62d082142a898057..e4a4c51961c74c23554fca53cb3fd0394000467b 100644
--- a/fsl/utils/run.py
+++ b/fsl/utils/run.py
@@ -144,10 +144,6 @@ def run(*args, **kwargs):
                    exception is not raised.  Ignored if ``submit`` is
                    specified.
 
-    :arg err:      Deprecated - use ``stderr`` instead.
-
-    :arg ret:      Deprecated - use ``exitcode`` instead.
-
     :arg submit:   Must be passed as a keyword argument. Defaults to ``None``.
                    If ``True``, the command is submitted as a cluster job via
                    the :func:`.fslsub.submit` function.  May also be a
@@ -175,17 +171,6 @@ def run(*args, **kwargs):
                    ``stderr``, and ``exitcode`` arguments.
     """
 
-    if 'err' in kwargs:
-        warnings.warn('err is deprecated and will be removed '
-                      'in fslpy 2.0.0 - use stderr instead',
-                      DeprecationWarning)
-        kwargs['stderr'] = kwargs.get('stderr', kwargs['err'])
-    if 'ret' in kwargs:
-        warnings.warn('ret is deprecated and will be removed '
-                      'in fslpy 2.0.0 - use exitcode instead',
-                      DeprecationWarning)
-        kwargs['exitcode'] = kwargs.get('exitcode', kwargs['ret'])
-
     returnStdout   = kwargs.get('stdout',   True)
     returnStderr   = kwargs.get('stderr',   False)
     returnExitcode = kwargs.get('exitcode', False)