diff --git a/fsl.py b/fsl.py
deleted file mode 100755
index e3685c2859af6676b81b7d64f8e439a5f4b9ebe6..0000000000000000000000000000000000000000
--- a/fsl.py
+++ /dev/null
@@ -1,283 +0,0 @@
-#!/usr/bin/env python
-#
-# fsl.py - Front end to FSL tools.
-#
-# Author: Paul McCarthy <pauldmccarthy@gmail.com>
-#
-
-import os
-import sys
-import logging
-import argparse
-
-# There's a bug in OpenGL.GL.shaders (which has been fixed in
-# the latest version) - it calls logging.basicConfig(), and
-# thus screws up our own logging. We overcome this by configuring
-# the root logger before OpenGL.GL.shaders is imported (which
-# occurs when fsl.fslview.gl.slicecanvas.SliceCanvas is imported).
-logging.basicConfig(
-    format='%(levelname)8.8s '
-           '%(filename)20.20s '
-           '%(lineno)4d: '
-           '%(funcName)-15.15s - '
-           '%(message)s') 
-log = logging.getLogger('fsl')
-
-import fsl.tools as tools
-
-def loadAllFSLTools():
-    """
-    Looks in the fsl.tools package, loads a description for
-    every FSL tool present, and returns all descriptions in
-    a {toolName->toolObj} dictionary. See loadFSLTool.
-    """
-
-    allTools = {}
-
-    for moduleName in dir(tools):
-        
-        module = getattr(tools, moduleName)
-
-        try:              fsltool = loadFSLTool(moduleName, module)
-        except TypeError: continue
-
-        allTools[moduleName] = fsltool
-
-    return allTools
-
-
-
-def loadFSLTool(moduleName, module):
-    """
-    Inspects the given module to see if it looks like a valid
-    FSL tool. If it is not, a TypeError is raised. If it is,
-    a container object is created and returned, containing
-    all of the elements of the tool.
-    """
-
-    # Each FSL tool module may specify several things
-    toolName  = getattr(module, 'FSL_TOOLNAME',  None)
-    helpPage  = getattr(module, 'FSL_HELPPAGE',  'index')
-    parseArgs = getattr(module, 'FSL_PARSEARGS', None)
-    context   = getattr(module, 'FSL_CONTEXT',   None)
-    interface = getattr(module, 'FSL_INTERFACE', None)
-    execute   = getattr(module, 'FSL_EXECUTE',   None)
-    actions   = getattr(module, 'FSL_ACTIONS',   [])
-
-    # But at the very least, must specify a name, and
-    # either a function which will create an interface,
-    # or a function which can be called to do some work
-    if not all((toolName, any((interface, execute)))):
-        raise TypeError('"{}" does not appear to be a valid FSL tool'.format(
-            moduleName))
-
-    # The tool must either provide an interface,
-    # or do some non-interactive work.
-    if interface and execute:
-        raise TypeError('"{}" does not appear to be a valid FSL tool'.format(
-            moduleName))    
-
-    class FSLTool(object):
-        pass
-
-    fsltool = FSLTool()
-
-    fsltool.module     = module
-    fsltool.moduleName = moduleName
-    fsltool.toolName   = toolName
-    fsltool.helpPage   = helpPage
-    fsltool.parseArgs  = parseArgs
-    fsltool.context    = context
-    fsltool.interface  = interface
-    fsltool.execute    = execute
-    fsltool.actions    = actions
-
-    return fsltool
-
-
-def parseArgs(argv, allTools):
-    """
-    Creates a command line ArgumentParser which will process general
-    arguments for fsl.py (this script) and, arguments for all FSL
-    tools which have defined their own command line arguments (see
-    loadFSLTool). Returns an object containing values for all of the
-    arguments that were passed in.
-    """
-
-    epilog = 'Type fsl.py help <tool> for program-specific help. ' \
-             'Available programs:\n  {}'.format('\n  '.join(allTools.keys()))
-
-    parser = argparse.ArgumentParser(
-        description='Run a FSL program',
-        epilog=epilog,
-        formatter_class=argparse.RawDescriptionHelpFormatter)
-
-    parser.add_argument(
-        '-v', '--verbose', action='count',
-        help='Verbose output (can be used up to 3 times)')
-    parser.add_argument(
-        '-w', '--wxinspect', action='store_true',
-        help='Run wx inspection tool')
-    parser.add_argument('tool', help='FSL program to run')
-
-    # find the index of the first positional argument
-    try:
-        firstPos = map(lambda a: not a.startswith('-'), argv).index(True)
-    except ValueError:
-        firstPos = len(argv)
-
-    # Separate the top level arguments
-    # from the tool arguments, and parse
-    # the top level args
-    fslArgv   = argv[:firstPos + 1]
-    toolArgv  = argv[ firstPos + 1:]
-    namespace = parser.parse_args(fslArgv)
-
-    # if the specified tool is 'help', it should be followed by
-    # one more argument, the name of the tool to print help for
-    if namespace.tool == 'help':
-        
-        # no tool name supplied
-        if len(toolArgv) == 0:
-            parser.print_help()
-            sys.exit(1)
-
-        # unknown tool name supplied
-        if toolArgv[0] not in allTools:
-            print '\nUnknown FSL tool: {}\n'.format(namespace.tool) 
-            parser.print_help()
-            sys.exit(1)
-
-        fslTool = allTools[toolArgv[0]]
-
-        # no tool specific argument parser
-        if fslTool.parseArgs is None:
-            print 'No help for {}'.format(toolArgv[0])
-            
-        # Otherwise, get help from the tool. We assume that
-        # all the argument parser for every  tool will interpret
-        # '-h' as '--help', and will print some help
-        else:
-            fslTool.parseArgs(['-h'])
-        sys.exit(0)
-
-    # Unknown tool name supplied
-    elif namespace.tool not in allTools:
-        print '\nUnknown FSL tool: {}\n'.format(namespace.tool)
-        parser.print_help()
-        sys.exit(1)
-
-    # otherwise, give the remaining arguments to the tool parser
-    fslTool = allTools[namespace.tool]
-
-    if fslTool.parseArgs is not None: toolArgs = fslTool.parseArgs(toolArgv)
-    else:                             toolArgs = None
-    
-    return fslTool, namespace, toolArgs
-
-
-def fslDirWarning(frame, toolName, fslEnvActive):
-    """
-    If fslEnvActive is False, displays a warning.
-    """
-
-    if fslEnvActive: return
-
-    msg = 'The FSLDIR environment variable is not set - '\
-          '{} may not behave correctly.'.format(toolName)
-
-    if frame is not None:
-        import wx
-        wx.MessageDialog(
-            frame,
-            message=msg,
-            style=wx.OK | wx.ICON_EXCLAMATION).ShowModal()
-    else:
-        log.warn(msg)
-        
-
-def buildGUI(args, fslTool, toolCtx, fslEnvActive):
-    """
-    """
-
-    import wx
-    import fsl.utils.webpage as webpage
-
-    frame = fslTool.interface(None, args, ctx)
-
-    menuBar = frame.GetMenuBar()
-
-    if menuBar is None:
-        menuBar  = wx.MenuBar()
-        frame.SetMenuBar(menuBar)
-        
-    fslMenu = wx.Menu()
-    menuBar.Insert(0, fslMenu, 'FSL')
-
-    actions = []
-
-    actions.append((
-        wx.ID_HELP,
-        '{} Help'.format(fslTool.toolName),
-        lambda *ev: webpage.openFSLHelp(fslTool.helpPage)))
-
-    for (name, func) in fslTool.actions:
-        actions.append((wx.ID_ANY, name, lambda ev, f=func: f(frame, ctx)))
-
-    actions.append((
-        wx.ID_EXIT,
-        'Exit',
-        lambda *ev: frame.Close()))
-
-    for wxId, name, func in actions:
-        menuItem = fslMenu.Append(wxId, name)
-        frame.Bind(wx.EVT_MENU, func, menuItem)
-
-    return frame
-
-    
-if __name__ == '__main__':
-
-    fsldir       = os.environ.get('FSLDIR', None)
-    fslEnvActive = fsldir is not None
-
-    allTools                = loadAllFSLTools()
-    fslTool, args, toolArgs = parseArgs(sys.argv[1:], allTools)
-
-    if args.verbose == 1:
-        log.setLevel(logging.DEBUG)
-
-        # make some noisy things quiet
-        logging.getLogger('fsl.fslview.gl')   .setLevel(logging.WARNING)
-        logging.getLogger('fsl.fslview.views').setLevel(logging.WARNING)
-        logging.getLogger('props')            .setLevel(logging.WARNING)
-        logging.getLogger('pwidgets')         .setLevel(logging.WARNING)
-    elif args.verbose == 2:
-        log.setLevel(logging.DEBUG)
-        logging.getLogger('props')   .setLevel(logging.WARNING)
-        logging.getLogger('pwidgets').setLevel(logging.WARNING)
-    elif args.verbose == 3:
-        log.setLevel(logging.DEBUG)
-        logging.getLogger('props')   .setLevel(logging.DEBUG)
-        logging.getLogger('pwidgets').setLevel(logging.DEBUG) 
-
-    if fslTool.context is not None: ctx = fslTool.context(toolArgs)
-    else:                           ctx = None
-
-    if fslTool.interface is not None:
-        import wx
-        app   = wx.App()
-        frame = buildGUI(toolArgs, fslTool, ctx, fslEnvActive)
-        frame.Show()
-
-        wx.CallLater(1, fslDirWarning, frame, fslTool.toolName, fslEnvActive)
-
-        if args.wxinspect:
-            import wx.lib.inspection
-            wx.lib.inspection.InspectionTool().Show()
-        
-        app.MainLoop()
-        
-    elif fslTool.execute is not None:
-        fslDirWarning( None, fslTool.toolName, fslEnvActive)
-        fslTool.execute(toolArgs, ctx)
diff --git a/fsl/__init__.py b/fsl/__init__.py
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c4d539840456fc9791b51e0b03514b0b792e73d6 100644
--- a/fsl/__init__.py
+++ b/fsl/__init__.py
@@ -0,0 +1,288 @@
+#!/usr/bin/env python
+#
+# __init__.py - Front end to fslpy. The entry point is main(), defined
+# at the bottom.
+#
+# Author: Paul McCarthy <pauldmccarthy@gmail.com>
+#
+
+import logging
+log = logging.getLogger(__name__)
+
+import os
+import sys
+import logging
+import argparse
+
+# There's a bug in OpenGL.GL.shaders (which has been fixed in
+# the latest version) - it calls logging.basicConfig(), and
+# thus screws up our own logging. We overcome this by configuring
+# the root logger before OpenGL.GL.shaders is imported (which
+# occurs when fsl.fslview.gl.slicecanvas.SliceCanvas is imported).
+logging.basicConfig(
+    format='%(levelname)8.8s '
+           '%(filename)20.20s '
+           '%(lineno)4d: '
+           '%(funcName)-15.15s - '
+           '%(message)s') 
+log = logging.getLogger('fsl')
+
+import fsl.tools as tools
+
+def loadAllFSLTools():
+    """
+    Looks in the fsl.tools package, loads a description for
+    every FSL tool present, and returns all descriptions in
+    a {toolName->toolObj} dictionary. See loadFSLTool.
+    """
+
+    allTools = {}
+
+    for moduleName in dir(tools):
+        
+        module = getattr(tools, moduleName)
+
+        try:              fsltool = loadFSLTool(moduleName, module)
+        except TypeError: continue
+
+        allTools[moduleName] = fsltool
+
+    return allTools
+
+
+
+def loadFSLTool(moduleName, module):
+    """
+    Inspects the given module to see if it looks like a valid
+    FSL tool. If it is not, a TypeError is raised. If it is,
+    a container object is created and returned, containing
+    all of the elements of the tool.
+    """
+
+    # Each FSL tool module may specify several things
+    toolName  = getattr(module, 'FSL_TOOLNAME',  None)
+    helpPage  = getattr(module, 'FSL_HELPPAGE',  'index')
+    parseArgs = getattr(module, 'FSL_PARSEARGS', None)
+    context   = getattr(module, 'FSL_CONTEXT',   None)
+    interface = getattr(module, 'FSL_INTERFACE', None)
+    execute   = getattr(module, 'FSL_EXECUTE',   None)
+    actions   = getattr(module, 'FSL_ACTIONS',   [])
+
+    # But at the very least, must specify a name, and
+    # either a function which will create an interface,
+    # or a function which can be called to do some work
+    if not all((toolName, any((interface, execute)))):
+        raise TypeError('"{}" does not appear to be a valid FSL tool'.format(
+            moduleName))
+
+    # The tool must either provide an interface,
+    # or do some non-interactive work.
+    if interface and execute:
+        raise TypeError('"{}" does not appear to be a valid FSL tool'.format(
+            moduleName))    
+
+    class FSLTool(object):
+        pass
+
+    fsltool = FSLTool()
+
+    fsltool.module     = module
+    fsltool.moduleName = moduleName
+    fsltool.toolName   = toolName
+    fsltool.helpPage   = helpPage
+    fsltool.parseArgs  = parseArgs
+    fsltool.context    = context
+    fsltool.interface  = interface
+    fsltool.execute    = execute
+    fsltool.actions    = actions
+
+    return fsltool
+
+
+def parseArgs(argv, allTools):
+    """
+    Creates a command line ArgumentParser which will process general
+    arguments for fsl.py (this script) and, arguments for all FSL
+    tools which have defined their own command line arguments (see
+    loadFSLTool). Returns an object containing values for all of the
+    arguments that were passed in.
+    """
+
+    epilog = 'Type fslpy help <tool> for program-specific help. ' \
+             'Available programs:\n  {}'.format('\n  '.join(allTools.keys()))
+
+    parser = argparse.ArgumentParser(
+        prog='fslpy',
+        description='Run a FSL program',
+        epilog=epilog,
+        formatter_class=argparse.RawDescriptionHelpFormatter)
+
+    parser.add_argument(
+        '-v', '--verbose', action='count',
+        help='Verbose output (can be used up to 3 times)')
+    parser.add_argument(
+        '-w', '--wxinspect', action='store_true',
+        help='Run wx inspection tool')
+    parser.add_argument('tool', help='FSL program to run')
+
+    # find the index of the first positional argument
+    try:
+        firstPos = map(lambda a: not a.startswith('-'), argv).index(True)
+    except ValueError:
+        firstPos = len(argv)
+
+    # Separate the top level arguments
+    # from the tool arguments, and parse
+    # the top level args
+    fslArgv   = argv[:firstPos + 1]
+    toolArgv  = argv[ firstPos + 1:]
+    namespace = parser.parse_args(fslArgv)
+
+    # if the specified tool is 'help', it should be followed by
+    # one more argument, the name of the tool to print help for
+    if namespace.tool == 'help':
+        
+        # no tool name supplied
+        if len(toolArgv) == 0:
+            parser.print_help()
+            sys.exit(1)
+
+        # unknown tool name supplied
+        if toolArgv[0] not in allTools:
+            print '\nUnknown FSL tool: {}\n'.format(namespace.tool) 
+            parser.print_help()
+            sys.exit(1)
+
+        fslTool = allTools[toolArgv[0]]
+
+        # no tool specific argument parser
+        if fslTool.parseArgs is None:
+            print 'No help for {}'.format(toolArgv[0])
+            
+        # Otherwise, get help from the tool. We assume that
+        # all the argument parser for every  tool will interpret
+        # '-h' as '--help', and will print some help
+        else:
+            fslTool.parseArgs(['-h'])
+        sys.exit(0)
+
+    # Unknown tool name supplied
+    elif namespace.tool not in allTools:
+        print '\nUnknown FSL tool: {}\n'.format(namespace.tool)
+        parser.print_help()
+        sys.exit(1)
+
+    # otherwise, give the remaining arguments to the tool parser
+    fslTool = allTools[namespace.tool]
+
+    if fslTool.parseArgs is not None: toolArgs = fslTool.parseArgs(toolArgv)
+    else:                             toolArgs = None
+    
+    return fslTool, namespace, toolArgs
+
+
+def fslDirWarning(frame, toolName, fslEnvActive):
+    """
+    If fslEnvActive is False, displays a warning.
+    """
+
+    if fslEnvActive: return
+
+    msg = 'The FSLDIR environment variable is not set - '\
+          '{} may not behave correctly.'.format(toolName)
+
+    if frame is not None:
+        import wx
+        wx.MessageDialog(
+            frame,
+            message=msg,
+            style=wx.OK | wx.ICON_EXCLAMATION).ShowModal()
+    else:
+        log.warn(msg)
+        
+
+def buildGUI(args, fslTool, toolCtx, fslEnvActive):
+    """
+    """
+
+    import wx
+    import fsl.utils.webpage as webpage
+
+    frame = fslTool.interface(None, args, toolCtx)
+
+    menuBar = frame.GetMenuBar()
+
+    if menuBar is None:
+        menuBar  = wx.MenuBar()
+        frame.SetMenuBar(menuBar)
+        
+    fslMenu = wx.Menu()
+    menuBar.Insert(0, fslMenu, 'FSL')
+
+    actions = []
+
+    actions.append((
+        wx.ID_HELP,
+        '{} Help'.format(fslTool.toolName),
+        lambda *ev: webpage.openFSLHelp(fslTool.helpPage)))
+
+    for (name, func) in fslTool.actions:
+        actions.append((wx.ID_ANY, name, lambda ev, f=func: f(frame, toolCtx)))
+
+    actions.append((
+        wx.ID_EXIT,
+        'Exit',
+        lambda *ev: frame.Close()))
+
+    for wxId, name, func in actions:
+        menuItem = fslMenu.Append(wxId, name)
+        frame.Bind(wx.EVT_MENU, func, menuItem)
+
+    return frame
+
+    
+def main():
+
+    fsldir       = os.environ.get('FSLDIR', None)
+    fslEnvActive = fsldir is not None
+
+    allTools                = loadAllFSLTools()
+    fslTool, args, toolArgs = parseArgs(sys.argv[1:], allTools)
+
+    if args.verbose == 1:
+        log.setLevel(logging.DEBUG)
+
+        # make some noisy things quiet
+        logging.getLogger('fsl.fslview.gl')   .setLevel(logging.WARNING)
+        logging.getLogger('fsl.fslview.views').setLevel(logging.WARNING)
+        logging.getLogger('props')            .setLevel(logging.WARNING)
+        logging.getLogger('pwidgets')         .setLevel(logging.WARNING)
+    elif args.verbose == 2:
+        log.setLevel(logging.DEBUG)
+        logging.getLogger('props')   .setLevel(logging.WARNING)
+        logging.getLogger('pwidgets').setLevel(logging.WARNING)
+    elif args.verbose == 3:
+        log.setLevel(logging.DEBUG)
+        logging.getLogger('props')   .setLevel(logging.DEBUG)
+        logging.getLogger('pwidgets').setLevel(logging.DEBUG) 
+
+    if fslTool.context is not None: ctx = fslTool.context(toolArgs)
+    else:                           ctx = None
+
+    if fslTool.interface is not None:
+        import wx
+        app   = wx.App()
+        frame = buildGUI(toolArgs, fslTool, ctx, fslEnvActive)
+        frame.Show()
+
+        wx.CallLater(1, fslDirWarning, frame, fslTool.toolName, fslEnvActive)
+
+        if args.wxinspect:
+            import wx.lib.inspection
+            wx.lib.inspection.InspectionTool().Show()
+        
+        app.MainLoop()
+        
+    elif fslTool.execute is not None:
+        fslDirWarning( None, fslTool.toolName, fslEnvActive)
+        fslTool.execute(toolArgs, ctx)