diff --git a/fsl/fslview/actions/__init__.py b/fsl/fslview/actions/__init__.py
index 7f74712ebe517dcccb60e4f83582561419e9483d..7a7b242a0972076556f7bef2e0fa5b68a04ad365 100644
--- a/fsl/fslview/actions/__init__.py
+++ b/fsl/fslview/actions/__init__.py
@@ -127,7 +127,16 @@ class Action(props.HasProperties):
             
         parent.Bind(evType, wrappedAction, widget)
         widget.Enable(self.enabled)
-        self._boundWidgets.append(widget)
+        self._boundWidgets.append((parent, evType, widget))
+
+
+    def unbindAllWidgets(self):
+        """Unbinds all widgets which have been bound via :meth:`bindToWidget`.
+        """
+        for parent, evType, widget in self._boundWidgets:
+            parent.Unbind(evType, source=widget)
+            
+        self._boundWidgets = []
 
 
     def _enabledChanged(self, *args):
@@ -137,7 +146,7 @@ class Action(props.HasProperties):
         if self.enabled: self.doAction = self.__enabledDoAction
         else:            self.doAction = self.__disabledDoAction
 
-        for widget in self._boundWidgets:
+        for _, _, widget in self._boundWidgets:
             widget.Enable(self.enabled)
 
 
@@ -193,6 +202,15 @@ class ActionProvider(props.HasProperties):
             act = Action(overlayList, displayCtx, action=func)
             self.__actions[name] = act
 
+        log.memory('{}.init ({})'.format(type(self).__name__, id(self)))
+
+
+    def __del__(self):
+        """
+        """
+        log.memory('{}.del ({})'.format(type(self).__name__, id(self)))
+        self.__actions = None
+                  
             
     def addActionToggleListener(self, name, listenerName, func):
         """Add a listener function which will be called when the named action
diff --git a/fsl/fslview/frame.py b/fsl/fslview/frame.py
index 456a818ccf71b2a53674718d153f1a6b8655e907..3530734c1496ae6a4f9386f368830c02559102aa 100644
--- a/fsl/fslview/frame.py
+++ b/fsl/fslview/frame.py
@@ -182,21 +182,29 @@ class FSLViewFrame(wx.Frame):
             return
 
         self.__viewPanels             .remove(panel)
+        self.__viewPanelMenus         .pop(   panel, None)
         title = self.__viewPanelTitles.pop(   panel)
 
         log.debug('Destroying view panel {} ({})'.format(
             title, type(panel).__name__))
 
-        # Calling fslpanel.FSLViewPanel.destroy()
-        # - I think that the AUINotebook does the
-        # wx.Window.Destroy side of things ...
-        panel.destroy()
+        # Unbind view panel menu
+        # items, and remove the menu
+        for actionName, actionObj in panel.getActions().items():
+            actionObj.unbindAllWidgets()
 
         menuBar = self.GetMenuBar()
         menuIdx = menuBar.FindMenu(title)
         if menuIdx != wx.NOT_FOUND:
             menuBar.Remove(menuIdx)
 
+        # Calling fslpanel.FSLViewPanel.destroy()
+        # - I think that the AUINotebook does the
+        # wx.Window.Destroy side of things, which
+        # will eventually result in panel.__del__
+        # ...
+        panel.destroy()
+
         
     def __onClose(self, ev):
         """Called on requests to close this :class:`FSLViewFrame`.
diff --git a/fsl/fslview/panel.py b/fsl/fslview/panel.py
index e8ce10a8d3ba9f85912e4b738bd0c0aec3207ae9..4c57902d56177df98748163a294128178352a023 100644
--- a/fsl/fslview/panel.py
+++ b/fsl/fslview/panel.py
@@ -4,19 +4,16 @@
 #
 # Author: Paul McCarthy <pauldmccarthy@gmail.com>
 #
-"""This module provides two classes - the :class:`FSLViewPanel`, and the
-:class:`FSLViewToolBar`.
+"""This module provides an important class - the :class:`FSLViewPanel`.
 
 A :class:`FSLViewPanel` object is a :class:`wx.Panel` which provides some sort
 of view of a collection of overlay objects, contained within an
-:class:`.OverlayList`. Similarly, a :class:`FSLViewToolBar` is a
-:class:`wx.lib.agw.aui.AuiToolBar` which provides some sort of control over
-the view.
-
-Instances of these classes are also :class:`.ActionProvider` instances - any
-actions which are specified during construction may be exposed to the
-user. Furthermore, any display configuration options which should be made
-available available to the user should be added as :class:`.PropertyBase`
+:class:`.OverlayList`. 
+
+``FSLViewPanel`` instances are also :class:`.ActionProvider` instances - any
+actions which are specified during construction may (or may not ) be exposed
+to the user. Furthermore, any display configuration options which should be
+made available available to the user should be added as :class:`.PropertyBase`
 attributes of the :class:`FSLViewPanel` subclass.
 
 See the following for examples of :class:`FSLViewPanel` subclasses:
@@ -55,6 +52,13 @@ class _FSLViewPanel(actions.ActionProvider):
         contains display related properties about the :attr:`_overlayList`.
     
       - :attr:`_name`: A unique name for this :class:`ViewPanel`.
+
+
+    TODO Important notes about:
+
+      - :meth:`destroy`
+
+      - :meth:`__del__`
     """ 
 
     
@@ -107,22 +111,27 @@ class _FSLViewPanel(actions.ActionProvider):
         called. So this method *must* be called by managing code when a panel
         is deleted.
 
-        Overriding subclass implementations should also call this base class
-        method, otherwise warnings will probably be output to the log (see 
-        :meth:`__del__`)
+        Overriding subclass implementations must call this base class
+        method, otherwise memory leaks will probably occur, and warnings will
+        probably be output to the log (see :meth:`__del__`).
         """
         self.__destroyed = True
 
     
     def __del__(self):
+        """Sub-classes which implement ``__del__`` must call this
+        implementation, otherwise memory leaks will occur.
+        """
+        actions.ActionProvider.__del__(self)
+
+        self._overlayList = None
+        self._displayCtx  = None
 
         if not self.__destroyed:
             log.warning('The {}.destroy() method has not been called '
                         '- unless the application is shutting down, '
                         'this is probably a bug!'.format(type(self).__name__))
 
-        actions.ActionProvider.__del__(self)
-
 
 class FSLViewPanel(_FSLViewPanel, wx.Panel):
     """
diff --git a/fsl/fslview/profiles/__init__.py b/fsl/fslview/profiles/__init__.py
index bda866f0476fbdf983acff554dcfc47fcbbd1dfd..1bcc5aeccc9c1b1f63b3a190a7800ea6404f4207 100644
--- a/fsl/fslview/profiles/__init__.py
+++ b/fsl/fslview/profiles/__init__.py
@@ -186,6 +186,19 @@ class Profile(actions.ActionProvider):
             for (mode, handler), (altMode, altHandler) in altHandlers.items():
                 self.addAltHandler(mode, handler, altMode, altHandler)
 
+                
+    def destroy(self):
+        """Calls the :meth:`deregister` method, and clears references to
+        the display context,  view panel, and overlay list. This method
+        is called by the :class:`ProfileManager` when  this ``Profile``
+        instance is no longer needed.  
+        """
+        self.deregister()
+        
+        self._viewPanel   = None
+        self._overlayList = None
+        self._displayCtx  = None
+
 
     def getEventTargets(self):
         """Must be overridden by subclasses, to return a sequence of
@@ -569,6 +582,23 @@ class ProfileManager(object):
             viewPanel.profile = profilez[0]
 
 
+    def destroy(self):
+        """This method should be called by the owning :class:`.ViewPanel` when
+        it is about to be destroyed (or when it no longer needs a
+        ``ProfileManager``).
+
+        This method destros the current profile (if any), and clears some
+        important object references to avoid memory leaks.
+        """
+        if self._currentProfile is not None:
+            self._currentProfile.destroy()
+            
+        self._currentProfile    = None
+        self._viewPanel         = None
+        self._overlayList       = None
+        self._overlaydisplayCtx = None
+
+
     def getCurrentProfile(self):
         """Returns the :class:`Profile` instance currently in use."""
         return self._currentProfile
@@ -592,7 +622,7 @@ class ProfileManager(object):
             log.debug('Deregistering {} profile from {}'.format(
                 self._currentProfile.__class__.__name__,
                 self._viewCls.__name__))
-            self._currentProfile.deregister()
+            self._currentProfile.destroy()
                
         self._currentProfile = profileCls(self._viewPanel,
                                           self._overlayList,
diff --git a/fsl/fslview/views/viewpanel.py b/fsl/fslview/views/viewpanel.py
index ee91ee6acbe72d112c6fc3eb8b93770d1e4b7a2a..a7da9444e3af075aade6e30c703d1461c3acd187 100644
--- a/fsl/fslview/views/viewpanel.py
+++ b/fsl/fslview/views/viewpanel.py
@@ -136,17 +136,31 @@ class ViewPanel(fslpanel.FSLViewPanel):
 
         
     def destroy(self):
+        """
+        """
+
         fslpanel.FSLViewPanel.destroy(self)
         
         # Make sure that any control panels are correctly destroyed
         for panelType, panel in self.__panels.items():
             panel.destroy()
-            
+
+        # Remove listeners from the overlay
+        # list and display context
         lName = 'ViewPanel_{}'.format(self._name)
 
         self             .removeListener('profile',         lName)
         self._overlayList.removeListener('overlays',        lName)
-        self._displayCtx .removeListener('selectedOverlay', lName) 
+        self._displayCtx .removeListener('selectedOverlay', lName)
+
+        # Disable the  ProfileManager
+        self.__profileManager.destroy()
+
+        # Un-initialise the AUI manager
+        self.__auiMgr.UnInit()
+
+        self.__profileManager = None
+        self.__auiMgr         = None
 
 
     def setCentrePanel(self, panel):