diff --git a/fsl/data/atlases.py b/fsl/data/atlases.py
index da0abe7855faf131a4d737df9d38c99ab5f0cfd5..daa62700ec0384b8b90ae566f90ef378f2fca1cb 100644
--- a/fsl/data/atlases.py
+++ b/fsl/data/atlases.py
@@ -9,7 +9,7 @@
 ``$FSLDIR/data/atlases/``. The :class:`AtlasRegistry` class provides access
 to these atlases, and allows the user to load atlases stored in other
 locations. A single :class:`.AtlasRegistry` instance is created when this
-module is first imported - it is available as amodule level attribute called
+module is first imported - it is available as a module level attribute called
 :attr:`registry`, and some of its methods are available as module-level
 functions:
 
@@ -17,14 +17,20 @@ functions:
 .. autosummary::
    :nosignatures:
 
+   rescanAtlases
    listAtlases
+   hasAtlas
    getAtlasDescription
    loadAtlas
    addAtlas
+   removeAtlas
+   rescanAtlases
 
 
-The :func:`loadAtlas` function allows you to load an atlas image, which will
-be one of the following  atlas-specific :class:`.Image` sub-classes:
+You must call the :meth:`.AtlasRegistry.rescanAtlases` function before any of
+the other functions will work.  The :func:`loadAtlas` function allows you to
+load an atlas image, which will be one of the following atlas-specific
+:class:`.Image` sub-classes:
 
 .. autosummary::
    :nosignatures:
@@ -34,21 +40,20 @@ be one of the following  atlas-specific :class:`.Image` sub-classes:
 """
 
 
-import                          os
-import xml.etree.ElementTree as et
-import os.path               as op
-import                          glob
-import                          collections
-import                          threading
-import                          logging
+import xml.etree.ElementTree              as et
+import os.path                            as op
+import                                       glob
+import                                       bisect
+import                                       logging
 
-import numpy                 as np
+import numpy                              as np
 
-import fsl.data.image        as fslimage
-import fsl.data.constants    as constants
-import fsl.utils.transform   as transform
-import fsl.utils.notifier    as notifier
-import fsl.utils.settings    as fslsettings
+import fsl.data.image                     as fslimage
+import fsl.data.constants                 as constants
+from   fsl.utils.platform import platform as platform
+import fsl.utils.transform                as transform
+import fsl.utils.notifier                 as notifier
+import fsl.utils.settings                 as fslsettings
 
 
 log = logging.getLogger(__name__)
@@ -58,115 +63,103 @@ class AtlasRegistry(notifier.Notifier):
     """The ``AtlasRegistry`` maintains a list of all known atlases.
 
 
-    When created, the ``AtlasRegistry`` loads all of the FSL XML atlas
-    specification files in ``$FSLDIR/data/atlases``, and builds a list of
-    :class:`AtlasDescription` instances, each of which contains information
-    about one atlas. Each atlas is assigned an identifier, which is simply the
-    XML file name describing the atlas, sans-suffix, and converted to lower
-    case.  For exmaple, the atlas described by:
-
-        ``$FSLDIR/data/atlases/HarvardOxford-Cortical.xml``
-
-    is given the identifier
-
-        ``harvardoxford-cortical``
+    When the :meth:`rescanAtlases` method is called, the ``AtlasRegistry``
+    loads all of the FSL XML atlas specification files in
+    ``$FSLDIR/data/atlases``, and builds a list of :class:`AtlasDescription`
+    instances, each of which contains information about one atlas.
 
     
     The :meth:`addAtlas` method allows other atlases to be added to the
     registry. Whenever a new atlas is added, the ``AtlasRegistry`` notifies
-    any registered listeners via the :class:`.Notifier` interface, passing
-    it the newly loaded class:`AtlasDecsription`.
+    any registered listeners via the :class:`.Notifier` interface with the
+    topic ``'add'``, passing it the newly loaded class:`AtlasDecsription`.
+    Similarly, the :meth:`removeAtlas` method allows individual atlases to be
+    removed. When this occurs, registered listeners on the ``'remove'`` topic
+    are notified, and passed the ``AtlasDescription`` instance of the removed
+    atlas.
+
+
+    The ``AtlasRegistry`` stores a list of all known atlases via the
+    :mod:`.settings` module. When an ``AtlasRegistry`` is created, it loads
+    in any previously known atlases. Whenever a new atlas is added, this 
+    list is updated. See the :meth:`__getKnownAtlases` and
+    :meth:`_saveKnownAtlases` methods.
     """
 
     
     def __init__(self):
         """Create an ``AtlasRegistry``. """
 
-        # This dictionary contains an
-        # {atlasID : AtlasDescription}
-        # mapping for all known atlases
-        self.__atlasDescs = collections.OrderedDict()
-
-        # This is used as a mutual-exclusion
-        # lock by the listAtlases function,
-        # to make it thread-safe.
-        self.__lock   = threading.Lock()
-        self.__loaded = False
+        # A list of all AtlasDescription
+        # instances in existence, sorted 
+        # by AtlasDescription.name. 
+        self.__atlasDescs = []
 
 
-    def __loadAtlasDescs(func):
-        """Used as a decorator on ``AtlasRegistry` methods to lazily load
-        :class:`AtlasDescription` objects on the first registry access.
-        Atlases are loaded from ``$FSLDIR/data/atlases/``, and from any other
-        previously loaded locations.
-                
-        .. note:: This function is thread-safe, because *FSLeyes* calls it
-                  in a multi-threaded manner (to avoid blocking the GUI).
+    def rescanAtlases(self):
+        """Causes the ``AtlasRegistry`` to rescan available atlases from
+        ``$FSLDIR``. Atlases are loaded from the ``fsl.data.atlases`` setting
+        (via the :mod:`.settings` module), and from ``$FSLDIR/data/atlases/``.
         """
 
-        def wrapper(self, *args, **kwargs):
-
-            # Make sure the atlas description
-            # refresh is only performed by one
-            # thread. If a thread is loading
-            # the descriptions, any other thread
-            # which enters the function will
-            # block here until the descriptions
-            # are loaded. When it continues, it
-            # will see a populated atlasDescs
-            # list.
-            self.__lock.acquire()
-
-            try:
-                
-                if self.__loaded:
-                    return func(self, *args, **kwargs)
-
-                if os.environ.get('FSLDIR', None) is None:
-                    fslAtlasDir = None
-                else:
-                    fslAtlasDir = op.join(os.environ['FSLDIR'],
-                                          'data',
-                                          'atlases')
+        log.debug('Initialising atlas registry')
+        self.__atlasDescs = []
 
-                # Any extra atlases that have previously
-                # been loaded from outside of $FSLDIR
-                extraIDs, extraPaths = self.__getExtraAtlases()
+        # Get $FSLDIR atlases 
+        fslPaths = []
+        if platform.fsldir is not None: 
+            fsldir   = op.join(platform.fsldir, 'data', 'atlases')
+            fslPaths = sorted(glob.glob(op.join(fsldir, '*.xml')))
 
-                atlasPaths = sorted(glob.glob(op.join(fslAtlasDir, '*.xml')))
-                atlasPaths = list(atlasPaths)         + extraPaths
-                atlasIDs   = [None] * len(atlasPaths) + extraIDs
+        # Any extra atlases that have
+        # been loaded in the past
+        extraIDs, extraPaths = self.__getKnownAtlases()
 
-                with self.skipAll():
-                    for atlasPath, atlasID in zip(atlasPaths, atlasIDs):
-                        self.addAtlas(atlasPath, atlasID)
+        # FSLDIR atlases first, any 
+        # other atlases second.
+        atlasPaths = list(fslPaths)         + extraPaths
+        atlasIDs   = [None] * len(fslPaths) + extraIDs
 
-                self.__loaded = True
-                return func(self, *args, **kwargs)
-                    
-            finally:
-                self.__lock.release()
-
-        return wrapper
+        with self.skipAll():
+            for atlasID, atlasPath in zip(atlasIDs, atlasPaths):
+                
+                # The FSLDIR atlases are probably
+                # listed twice - from the above glob,
+                # and from the saved extraPaths. So
+                # we remove any duplicates.
+                if atlasID is not None and self.hasAtlas(atlasID):
+                    continue
 
+                self.addAtlas(atlasPath, atlasID, save=False)
 
-    @__loadAtlasDescs
+    
     def listAtlases(self):
         """Returns a list containing :class:`AtlasDescription` objects for
-        all available atlases.
+        all available atlases. The atlases are ordered in terms of the
+        ``AtlasDescription.name`` attribute (converted to lower case).
+        """
+        return list(self.__atlasDescs)
+
+
+    def hasAtlas(self, atlasID):
+        """Returns ``True`` if this ``AtlasRegistry`` has an atlas with the
+        specified ``atlasID``.
         """
-        return list(self.__atlasDescs.values())
+        return atlasID in [d.atlasID for d in self.__atlasDescs]
 
 
-    @__loadAtlasDescs
     def getAtlasDescription(self, atlasID):
         """Returns an :class:`AtlasDescription` instance describing the
         atlas with the given ``atlasID``.
         """
-        return self.__atlasDescs[atlasID]
+        
+        for desc in self.__atlasDescs:
+            if desc.atlasID == atlasID:
+                return desc
+            
+        raise KeyError('Unknown atlas ID: {}'.format(atlasID))
 
 
-    @__loadAtlasDescs
     def loadAtlas(self, atlasID, loadSummary=False, resolution=None):
         """Loads and returns an :class:`Atlas` instance for the atlas
         with the given  ``atlasID``. 
@@ -182,7 +175,7 @@ class AtlasRegistry(notifier.Notifier):
                          resolution atlas will be loaded.
         """
 
-        atlasDesc = self.__atlasDescs[atlasID]
+        atlasDesc = self.getAtlasDescription(atlasID)
 
         # label atlases are only
         # available in 'summary' form
@@ -195,7 +188,7 @@ class AtlasRegistry(notifier.Notifier):
         return atlas
 
 
-    def addAtlas(self, filename, atlasID=None):
+    def addAtlas(self, filename, atlasID=None, save=True):
         """Add an atlas from the given XML specification file to the registry.
 
         :arg filename: Path to a FSL XML atlas specification file.
@@ -204,6 +197,9 @@ class AtlasRegistry(notifier.Notifier):
                        base name (converted to lower-case) is used. If an
                        atlas with the given ID already exists, this new atlas
                        is given a unique id.
+
+        :arg save:     If ``True`` (the default), this atlas will be saved 
+                       so that it will be available in future instantiations. 
         """
 
         filename = op.abspath(filename)
@@ -216,52 +212,69 @@ class AtlasRegistry(notifier.Notifier):
 
         # If an atlas with the same ID/path
         # already exists, raise an error
-        atlasDesc = self.__atlasDescs.get(atlasID, None)
-        if atlasDesc is not None and atlasDesc.specPath == filename:
-            raise KeyError('{} is already in the atlas '
-                           'registry'.format(filename))
-
-        # Find a unique atlas ID 
-        i = 0
-        while atlasID in self.__atlasDescs:
-            atlasID = '{}_{}'.format(atlasIDBase, i)
-            i      += 1
-        
+        if self.hasAtlas(atlasID):
+            raise KeyError('An atlas with ID "{}" already '
+                           'exists'.format(atlasID))
+
         desc = AtlasDescription(filename, atlasID)
 
         log.debug('Adding atlas to registry: {} / {}'.format(
             desc.atlasID,
             desc.specPath))
 
-        self.__atlasDescs[desc.atlasID] = desc
+        bisect.insort_left(self.__atlasDescs, desc)
 
-        fsldir = op.join(os.environ.get('FSLDIR', None), 'data', 'atlases')
-        if not filename.startswith(fsldir):
-            self.__updateExtraAtlases()
+        if save:
+            self.__saveKnownAtlases()
 
-        self.notify(value=desc)
+        self.notify(topic='add', value=desc)
             
         return desc
 
+
+    def removeAtlas(self, atlasID):
+        """Removes the atlas with the specified ``atlasID`` from this
+        ``AtlasRegistry``.
+        """
+
+        for i, desc in enumerate(self.__atlasDescs):
+            if desc.atlasID == atlasID:
+
+                log.debug('Removing atlas from registry: {} / {}'.format(
+                    desc.atlasID,
+                    desc.specPath))
+                
+                self.__atlasDescs.pop(i)
+                break
+        
+        self.__saveKnownAtlases()
+
+        self.notify(topic='remove', value=desc)
+
     
-    def __getExtraAtlases(self):
-        """Returns a list of tuples containing the IDs and paths of all 
-        atlases which are not located in ``$FSLDIR/data/atlases``, and
-        which have previously been in the registry. The atlases are
-        retrieved via the :mod:`.settings` module - see
-        :meth:`__updateExtraAtlases`.
+    def __getKnownAtlases(self):
+        """Returns a list of tuples containing the IDs and paths of all known
+        atlases .
+
+        The atlases are retrieved via the :mod:`.settings` module - a setting
+        with the name ``fsl.data.atlases`` is assumed to contain a string of
+        ``atlasID=specPath`` pairs, separated with the operating system file
+        path separator (``:`` on Unix/Linux).
+        See also :meth:`__saveKnownAtlases`.
         """
         try:
-            extras = fslsettings.read('fsl.utils.atlases.extra')
+            atlases = fslsettings.read('fsl.data.atlases')
 
-            if extras is None: extras = []
-            else:              extras = extras.split(op.pathsep)
+            if atlases is None: atlases = []
+            else:               atlases = atlases.split(op.pathsep)
 
-            extras = [e.split('=') for e in extras]
-            extras = [(name, path) for name, path in extras if op.exists(path)]
+            atlases = [e.split('=') for e in atlases]
+            atlases = [(name.strip(), path.strip())
+                       for name, path in atlases
+                       if op.exists(path)]
 
-            names = [e[0] for e in extras]
-            paths = [e[1] for e in extras]
+            names = [e[0] for e in atlases]
+            paths = [e[1] for e in atlases]
 
             return names, paths
             
@@ -269,39 +282,24 @@ class AtlasRegistry(notifier.Notifier):
             return [], []
 
     
-    def __updateExtraAtlases(self):
-        """Saves the IDs and paths of all atlases which are not located in
-        ``$FSLDIR/data/atlases``, and which have previously been in the
-        registry. The atlases are saved via the :mod:`.settings` module.
+    def __saveKnownAtlases(self):
+        """Saves the IDs and paths of all atlases which are currently in
+        the registry. The atlases are saved via the :mod:`.settings` module.
         """ 
 
         if self.__atlasDescs is None:
             return
 
-        if os.environ.get('FSLDIR', None) is None:
-            fslAtlasDir = None
-        else:
-            fslAtlasDir = op.abspath(
-                op.join(os.environ['FSLDIR'], 'data', 'atlases'))
-
-        extras = []
+        atlases = []
 
-        for desc in self.__atlasDescs.values():
-            if not desc.specPath.startswith(fslAtlasDir):
-                extras.append((desc.atlasID, desc.specPath))
+        for desc in self.__atlasDescs:
+            atlases.append((desc.atlasID, desc.specPath))
 
-        extras = ['{}={}'.format(name, path) for name, path in extras]
-        extras = op.pathsep.join(extras)
+        atlases = ['{}={}'.format(name, path) for name, path in atlases]
+        atlases = op.pathsep.join(atlases)
         
-        fslsettings.write('fsl.utils.atlases.extra', extras)
-
+        fslsettings.write('fsl.data.atlases', atlases)
 
-registry            = AtlasRegistry()
-listAtlases         = registry.listAtlases
-getAtlasDescription = registry.getAtlasDescription
-loadAtlas           = registry.loadAtlas
-addAtlas            = registry.addAtlas
-    
     
 class AtlasDescription(object):
     """An ``AtlasDescription`` instance parses and stores the information
@@ -349,6 +347,20 @@ class AtlasDescription(object):
         </data>
        </atlas>
 
+    
+    Each ``AtlasDescription`` is assigned an identifier, which is simply the
+    XML file name describing the atlas, sans-suffix, and converted to lower
+    case.  For exmaple, the atlas described by:
+
+        ``$FSLDIR/data/atlases/HarvardOxford-Cortical.xml``
+
+    is given the identifier
+
+        ``harvardoxford-cortical``
+
+    
+    This identifier is intended to be unique.
+
 
     The following attributes are available on an ``AtlasDescription`` instance:
 
@@ -398,7 +410,6 @@ class AtlasDescription(object):
               They are in the coordinate system defined by the transformation
               matrix for the first image in the ``images`` list.(typically
               MNI152 space).
-
     """
 
     
@@ -493,6 +504,25 @@ class AtlasDescription(object):
             label.x, label.y, label.z = coords[i]
 
 
+    def __eq__(self, other):
+        """Compares the ``atlasID`` of this ``AtlasDescription`` with another.
+        """
+        return self.atlasID == other.atlasID
+
+    
+    def __neq__(self, other):
+        """Compares the ``atlasID`` of this ``AtlasDescription`` with another.
+        """
+        return self.atlasID != other.atlasID 
+    
+
+    def __cmp__(self, other):
+        """Compares this ``AtlasDescription`` with another by their ``name``
+        attribute.
+        """
+        return cmp(self.name.lower(), other.name.lower())
+
+
 class Atlas(fslimage.Image):
     """This is the base class for the :class:`LabelAtlas` and
     :class:`ProbabilisticAtlas` classes. It contains some initialisation
@@ -624,3 +654,14 @@ class ProbabilisticAtlas(Atlas):
             return []
         
         return self[voxelLoc[0], voxelLoc[1], voxelLoc[2], :]
+
+
+registry            = AtlasRegistry()
+rescanAtlases       = registry.rescanAtlases
+listAtlases         = registry.listAtlases
+hasAtlas            = registry.hasAtlas
+getAtlasDescription = registry.getAtlasDescription
+loadAtlas           = registry.loadAtlas
+addAtlas            = registry.addAtlas
+removeAtlas         = registry.removeAtlas
+rescanAtlases       = registry.rescanAtlases