Index: src/sas/sasgui/guiframe/CategoryInstaller.py
===================================================================
--- src/sas/sasgui/guiframe/CategoryInstaller.py	(revision 235f514ba93b57fa63e44309f182acef0b98bb55)
+++ src/sas/sasgui/guiframe/CategoryInstaller.py	(revision 235f514ba93b57fa63e44309f182acef0b98bb55)
@@ -14,4 +14,6 @@
 import logging
 from collections import defaultdict, OrderedDict
+
+from sas.sasgui import get_user_dir
 
 USER_FILE = 'categories.json'
@@ -69,11 +71,4 @@
 
     @staticmethod
-    def _get_home_dir():
-        """
-        returns the users sasview config dir
-        """
-        return os.path.join(os.path.expanduser("~"), ".sasview")
-
-    @staticmethod
     def _regenerate_model_dict(master_category_dict):
         """
@@ -85,5 +80,5 @@
         by_model_dict = defaultdict(list)
         model_enabled_dict = defaultdict(bool)
-        
+
         for category in master_category_dict:
             for (model, enabled) in master_category_dict[category]:
@@ -96,5 +91,5 @@
     def _regenerate_master_dict(by_model_dict, model_enabled_dict):
         """
-        regenerates master_category_dict from by_model_dict 
+        regenerates master_category_dict from by_model_dict
         and model_enabled_dict
         returns the master category dictionary
@@ -112,5 +107,5 @@
         returns the user data file, eg .sasview/categories.json.json
         """
-        return os.path.join(CategoryInstaller._get_home_dir(), USER_FILE)
+        return os.path.join(get_user_dir(), USER_FILE)
 
     @staticmethod
@@ -150,5 +145,5 @@
                 model_name, enabled = master_category_dict[cat][ind]
                 if model_name not in _model_list:
-                    del_name = True 
+                    del_name = True
                     try:
                         by_model_dict.pop(model_name)
Index: src/sas/sasgui/guiframe/aboutbox.py
===================================================================
--- src/sas/sasgui/guiframe/aboutbox.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/guiframe/aboutbox.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
@@ -24,27 +24,16 @@
 import os.path
 import os
-try:
-    # Try to find a local config
-    import imp
-    path = os.getcwd()
-    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
-      (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
-        fObj, path, descr = imp.find_module('local_config', [path])
-        config = imp.load_module('local_config', fObj, path, descr)  
-    else:
-        # Try simply importing local_config
-        import local_config as config
-except:
-    # Didn't find local config, load the default 
-    import config
+
+from sas.sasgui import get_local_config
+config = get_local_config()
 
 def launchBrowser(url):
     """
     Launches browser and opens specified url
-    
+
     In some cases may require BROWSER environment variable to be set up.
-    
+
     :param url: URL to open
-    
+
     """
     import webbrowser
@@ -55,10 +44,10 @@
     """
     "About" Dialog
-    
+
     Shows product name, current version, authors, and link to the product page.
     Current version is taken from version.py
-    
-    """
-    
+
+    """
+
     def __init__(self, *args, **kwds):
 
@@ -66,11 +55,11 @@
         kwds["style"] = wx.DEFAULT_DIALOG_STYLE
         wx.Dialog.__init__(self, *args, **kwds)
-        
+
         file_dir = os.path.dirname(__file__)
-        
+
         # Mac doesn't display images with transparent background so well,
         # keep it for Windows
         image = file_dir + "/images/angles_flat.png"
-        
+
         if os.path.isfile(config._corner_image):
             image = config._corner_image
@@ -80,5 +69,5 @@
         else:
             self.bitmap_logo = wx.StaticBitmap(self, -1, wx.Bitmap(image))
-        
+
         self.label_title = wx.StaticText(self, -1, config.__appname__)
         self.label_version = wx.StaticText(self, -1, "")
@@ -112,5 +101,5 @@
         #self.bitmap_button_danse = wx.BitmapButton(self, -1, wx.NullBitmap)
         self.bitmap_button_msu = wx.BitmapButton(self, -1, wx.NullBitmap)
-        
+
         self.bitmap_button_isis = wx.BitmapButton(self, -1, wx.NullBitmap)
         self.bitmap_button_ess = wx.BitmapButton(self, -1, wx.NullBitmap)
@@ -119,5 +108,5 @@
         self.bitmap_button_tudelft = wx.BitmapButton(self, -1, wx.NullBitmap)
         self.bitmap_button_dls = wx.BitmapButton(self, -1, wx.NullBitmap)
-        
+
         self.static_line_3 = wx.StaticLine(self, -1)
         self.button_OK = wx.Button(self, wx.ID_OK, "OK")
@@ -125,5 +114,5 @@
         self.__set_properties()
         self.__do_layout()
-        
+
         self.Bind(wx.EVT_BUTTON, self.onNistLogo, self.bitmap_button_nist)
         self.Bind(wx.EVT_BUTTON, self.onUmdLogo, self.bitmap_button_umd)
@@ -145,5 +134,5 @@
         random.shuffle(config._authors)
         strLabel = ", ".join(config._authors)
-        
+
         # display version and svn revison numbers
         verwords = config.__version__.split('.')
@@ -157,16 +146,16 @@
         self.label_version.SetLabel(config.__version__)#(version)
         self.label_svnrevision.SetLabel(build_num)
-        
+
         # set bitmaps for logo buttons
         image = file_dir + "/images/nist_logo.png"
         if os.path.isfile(config._nist_logo):
             image = config._nist_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_nist.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/umd_logo.png"
         if os.path.isfile(config._umd_logo):
             image = config._umd_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_umd.SetBitmapLabel(logo)
 
@@ -174,5 +163,5 @@
         if os.path.isfile(config._ornl_logo):
             image = config._ornl_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_ornl.SetBitmapLabel(logo)
 
@@ -181,11 +170,11 @@
         if os.path.isfile(config._sns_logo):
             image = config._sns_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_sns.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/nsf_logo.png"
         if os.path.isfile(config._nsf_logo):
             image = config._nsf_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_nsf.SetBitmapLabel(logo)
 
@@ -201,9 +190,9 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_msu.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/isis_logo.png"
         if os.path.isfile(config._isis_logo):
             image = config._isis_logo
-        logo = wx.Bitmap(image)        
+        logo = wx.Bitmap(image)
         self.bitmap_button_isis.SetBitmapLabel(logo)
 
@@ -213,5 +202,5 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_ess.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/ill_logo.png"
         if os.path.isfile(config._ill_logo):
@@ -219,5 +208,5 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_ill.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/ansto_logo.png"
         if os.path.isfile(config._ansto_logo):
@@ -225,5 +214,5 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_ansto.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/tudelft_logo.png"
         if os.path.isfile(config._tudelft_logo):
@@ -231,5 +220,5 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_tudelft.SetBitmapLabel(logo)
-        
+
         image = file_dir + "/images/dls_logo.png"
         if os.path.isfile(config._dls_logo):
@@ -237,5 +226,5 @@
         logo = wx.Bitmap(image)
         self.bitmap_button_dls.SetBitmapLabel(logo)
-                
+
         # resize dialog window to fit version number nicely
         if wx.VERSION >= (2, 7, 2, 0):
@@ -244,5 +233,5 @@
             size = [self.GetBestFittingSize()[0], self.GetSize()[1]]
         self.Fit()
-        
+
     def __set_properties(self):
         """
@@ -310,36 +299,36 @@
         sizer_main.Add(self.static_line_2, 0, wx.EXPAND, 0)
 
-        sizer_logos.Add(self.bitmap_button_msu, 0, 
+        sizer_logos.Add(self.bitmap_button_msu, 0,
                         wx.LEFT|wx.ADJUST_MINSIZE, 2)
         #sizer_logos.Add(self.bitmap_button_danse, 0,
         #                wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        #sizer_logos.Add(self.bitmap_button_nsf, 0, 
+        #sizer_logos.Add(self.bitmap_button_nsf, 0,
         #                wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_umd, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_nist, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        #sizer_logos.Add(self.bitmap_button_sns, 0, 
+        sizer_logos.Add(self.bitmap_button_umd, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_nist, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        #sizer_logos.Add(self.bitmap_button_sns, 0,
         #                wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_ornl, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_isis, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_ess, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_ill, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_ansto, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_tudelft, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-        sizer_logos.Add(self.bitmap_button_dls, 0, 
-                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
-                
+        sizer_logos.Add(self.bitmap_button_ornl, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_isis, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_ess, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_ill, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_ansto, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_tudelft, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+        sizer_logos.Add(self.bitmap_button_dls, 0,
+                        wx.LEFT|wx.ADJUST_MINSIZE, 2)
+
         sizer_logos.Add((10, 50), 0, wx.ADJUST_MINSIZE, 0)
         sizer_main.Add(sizer_logos, 0, wx.EXPAND, 0)
         sizer_main.Add(self.static_line_3, 0, wx.EXPAND, 0)
         sizer_button.Add((20, 40), 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
-        sizer_button.Add(self.button_OK, 0, 
+        sizer_button.Add(self.button_OK, 0,
                          wx.RIGHT|wx.ADJUST_MINSIZE|wx.CENTER, 10)
         sizer_main.Add(sizer_button, 0, wx.EXPAND, 0)
@@ -350,5 +339,5 @@
         # end wxGlade
 
-    def onNistLogo(self, event): 
+    def onNistLogo(self, event):
         """
         """
@@ -356,6 +345,6 @@
         launchBrowser(config._nist_url)
         event.Skip()
-        
-    def onUmdLogo(self, event): 
+
+    def onUmdLogo(self, event):
         """
         """
@@ -363,6 +352,6 @@
         launchBrowser(config._umd_url)
         event.Skip()
-        
-    def onOrnlLogo(self, event): 
+
+    def onOrnlLogo(self, event):
         """
         """
@@ -370,6 +359,6 @@
         launchBrowser(config._ornl_url)
         event.Skip()
-        
-    def onSnsLogo(self, event): 
+
+    def onSnsLogo(self, event):
         """
         """
@@ -377,6 +366,6 @@
         launchBrowser(config._sns_url)
         event.Skip()
-                
-    def onNsfLogo(self, event): 
+
+    def onNsfLogo(self, event):
         """
         """
@@ -394,10 +383,10 @@
     def onUTLogo(self, event):
         """
-        """ 
+        """
         # wxGlade: DialogAbout.<event_handler>
         launchBrowser(config._inst_url)
         event.Skip()
 
-    def onIsisLogo(self, event): 
+    def onIsisLogo(self, event):
         """
         """
@@ -415,5 +404,5 @@
     def onIllLogo(self, event):
         """
-        """ 
+        """
         # wxGlade: DialogAbout.<event_handler>
         launchBrowser(config._ill_url)
@@ -422,5 +411,5 @@
     def onAnstoLogo(self, event):
         """
-        """ 
+        """
         # wxGlade: DialogAbout.<event_handler>
         launchBrowser(config._ansto_url)
@@ -429,5 +418,5 @@
     def onTudelftLogo(self, event):
         """
-        """ 
+        """
         # wxGlade: DialogAbout.<event_handler>
         launchBrowser(config._tudelft_url)
@@ -436,5 +425,5 @@
     def onDlsLogo(self, event):
         """
-        """ 
+        """
         # wxGlade: DialogAbout.<event_handler>
         launchBrowser(config._dls_url)
@@ -462,4 +451,4 @@
     app = MyApp(0)
     app.MainLoop()
-    
-##### end of testing code #####################################################    
+
+##### end of testing code #####################################################
Index: src/sas/sasgui/guiframe/acknowledgebox.py
===================================================================
--- src/sas/sasgui/guiframe/acknowledgebox.py	(revision 74c8cd08df1c5d3f23477827c0f272e88bbbea9d)
+++ src/sas/sasgui/guiframe/acknowledgebox.py	(revision 74c8cd08df1c5d3f23477827c0f272e88bbbea9d)
@@ -12,22 +12,7 @@
 import wx.lib.hyperlink
 from wx.lib.expando import ExpandoTextCtrl
-import random
-import os.path
-import os
-try:
-    # Try to find a local config
-    import imp
-    path = os.getcwd()
-    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
-      (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
-        fObj, path, descr = imp.find_module('local_config', [path])
-        config = imp.load_module('local_config', fObj, path, descr)
-    else:
-        # Try simply importing local_config
-        import local_config as config
-except:
-    # Didn't find local config, load the default
-    import config
 
+from sas.sasgui import get_local_config
+config = get_local_config()
 
 class DialogAcknowledge(wx.Dialog):
Index: src/sas/sasgui/guiframe/config.py
===================================================================
--- src/sas/sasgui/guiframe/config.py	(revision a1b8fee73528559155793dd74cda07d0c32e9d72)
+++ src/sas/sasgui/guiframe/config.py	(revision c6bdb3b56ff2c1bf95baa3241ca1df10d74a79d7)
@@ -1,4 +1,4 @@
 """
-    Application settings
+Application settings
 """
 from __future__ import print_function
@@ -6,8 +6,8 @@
 import time
 import os
+import logging
+
 from sas.sasgui.guiframe.gui_style import GUIFRAME
 import sas.sasview
-import logging
-
 
 logger = logging.getLogger(__name__)
@@ -75,4 +75,5 @@
 _ansto_logo = os.path.join(icon_path, "ansto_logo.png")
 _tudelft_logo = os.path.join(icon_path, "tudelft_logo.png")
+_dls_logo = os.path.join(icon_path, "dls_logo.png")
 _nsf_logo = os.path.join(icon_path, "nsf_logo.png")
 _danse_logo = os.path.join(icon_path, "danse_logo.png")
@@ -147,4 +148,7 @@
 SAS_OPENCL = None
 
+# Time out for updating sasview
+UPDATE_TIMEOUT = 2
+
 def printEVT(message):
     if __EVT_DEBUG__:
Index: src/sas/sasgui/guiframe/customdir.py
===================================================================
--- src/sas/sasgui/guiframe/customdir.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/guiframe/customdir.py	(revision c6bdb3b56ff2c1bf95baa3241ca1df10d74a79d7)
@@ -1,68 +1,59 @@
 # Setup and find Custom config dir
+from __future__ import print_function
+
 import os.path
+import logging
 import shutil
 
-CONF_DIR = 'config' 
-APPLICATION_NAME = 'sasview'
+from sasmodels.custom import load_module_from_path
 
-def _find_usersasview_dir():
-    """
-    Find and return user/.sasview dir
-    """
-    return os.path.join(os.path.expanduser("~"), ("." + APPLICATION_NAME))
+from sas.sasgui import get_custom_config_path, get_app_dir
 
-def _find_customconf_dir():
-    """
-    Find path of the config directory.
-    The plugin directory is located in the user's home directory.
-    """
-    u_dir = _find_usersasview_dir()
-    return os.path.join(u_dir, CONF_DIR)
+logger = logging.getLogger(__name__)
 
-def _setup_conf_dir(path):
+_config_cache = None
+def setup_custom_config():
     """
     Setup the custom config dir and cat file
     """
-    conf_dir = _find_customconf_dir()
-    # If the plugin directory doesn't exist, create it
-    if not os.path.isdir(conf_dir):
-        os.makedirs(conf_dir)
-    config_file = os.path.join(conf_dir, "custom_config.py")
-
-    # Place example user models as needed
-    try:
-        if not os.path.isfile(config_file):
-            shutil.copyfile(os.path.join(path, "custom_config.py"), config_file)
-
-        #Adding SAS_OPENCL if it doesn't exist in the config file
-        # - to support backcompability
-        if not "SAS_OPENCL" in open(config_file).read():
-            open(config_file,"a+").write("SAS_OPENCL = \"None\"\n")
-    except:
-        # Check for data path next to exe/zip file.
-        #Look for maximum n_dir up of the current dir to find plugins dir
-        n_dir = 12
-        is_dir = False
-        f_dir = path
-        for i in range(n_dir):
-            if i > 1:
-                f_dir, _ = os.path.split(f_dir)
-            temp_path = os.path.join(f_dir, "custom_config.py")
-            if os.path.isfile(temp_path):
-                shutil.copyfile(temp_path, config_file)
-                is_dir = True
-                break
-        if not is_dir:
-            raise
-    return conf_dir
+    global _config_cache
+    if not _config_cache:
+        _config_cache = _setup_custom_config()
+    return _config_cache
 
 
-class SetupCustom(object):
-    """
-    implement custom config dir
-    """
-    def find_dir(self):
-        return _find_customconf_dir()
-    
-    def setup_dir(self, path):
-        return _setup_conf_dir(path)
+def _setup_custom_config():
+    path = get_custom_config_path()
+    if not os.path.isfile(path):
+        try:
+            # if the custom config file does not exist, copy the default from
+            # the app dir
+            shutil.copyfile(os.path.join(get_app_dir(), "custom_config.py"),
+                            path)
+        except Exception:
+            logger.error("Could not copy default custom config.")
+
+    #Adding SAS_OPENCL if it doesn't exist in the config file
+    # - to support backcompability
+    if not "SAS_OPENCL" in open(path).read():
+        try:
+            open(config_file, "a+").write("SAS_OPENCL = \"None\"\n")
+        except Exception:
+            logger.error("Could not update custom config with SAS_OPENCL.")
+
+    custom_config = _load_config(path)
+    return custom_config
+
+
+def _load_config(path):
+    if os.path.exists(path):
+        try:
+            module = load_module_from_path('sas.sasview.custom_config', path)
+            logger.info("GuiManager loaded %s", path)
+            return module
+        except Exception as exc:
+            logger.error("Error loading %s: %s", path, exc)
+
+    from sas.sasview import custom_config
+    logger.info("GuiManager custom_config defaults to sas.sasview.custom_config")
+    return custom_config
Index: src/sas/sasgui/guiframe/data_panel.py
===================================================================
--- src/sas/sasgui/guiframe/data_panel.py	(revision a1b8fee73528559155793dd74cda07d0c32e9d72)
+++ src/sas/sasgui/guiframe/data_panel.py	(revision c6bdb3b56ff2c1bf95baa3241ca1df10d74a79d7)
@@ -33,5 +33,7 @@
 from sas.sasgui.guiframe.local_perspectives.plotting.SimplePlot \
     import PlotFrame as QucikPlotDialog
-import sas.sasgui.guiframe.config as config
+from sas.sasgui import get_local_config
+
+config = get_local_config()
 
 # Check version
Index: src/sas/sasgui/guiframe/documentation_window.py
===================================================================
--- src/sas/sasgui/guiframe/documentation_window.py	(revision 959eb0181ad06828a748f04512f953aad5b31659)
+++ src/sas/sasgui/guiframe/documentation_window.py	(revision d66dbcc8e869f27ec52bbe59173bde142f2c4a60)
@@ -16,21 +16,20 @@
 import os
 import logging
-import wx
 import webbrowser
 import urllib
 import sys
 
+import wx
+try:
+    import wx.html2 as html
+    WX_SUPPORTS_HTML2 = True
+except:
+    WX_SUPPORTS_HTML2 = False
+
+from sas.sasgui import get_app_dir
+
 logger = logging.getLogger(__name__)
 
 SPHINX_DOC_ENV = "SASVIEW_DOC_PATH"
-WX_SUPPORTS_HTML2 = True
-try:
-    import wx.html2 as html
-except:
-    WX_SUPPORTS_HTML2 = False
-
-
-from gui_manager import get_app_dir
-
 
 class DocumentationWindow(wx.Frame):
Index: src/sas/sasgui/guiframe/gui_manager.py
===================================================================
--- src/sas/sasgui/guiframe/gui_manager.py	(revision 2f22db96dce134a5ac8f4dba0b22c4df370c5431)
+++ src/sas/sasgui/guiframe/gui_manager.py	(revision 2f22db96dce134a5ac8f4dba0b22c4df370c5431)
@@ -22,10 +22,11 @@
 import re
 import logging
-import httplib
 import traceback
 import urllib
-import urllib2
 import json
 
+from matplotlib import _pylab_helpers
+
+from sas.sasgui import get_local_config, get_app_dir, get_user_dir
 from sas.sasgui.guiframe.events import EVT_CATEGORY
 from sas.sasgui.guiframe.events import EVT_STATUS
@@ -46,102 +47,11 @@
 from sas.sascalc.dataloader.loader import Loader
 from sas.sasgui.guiframe.proxy import Connection
-from matplotlib import _pylab_helpers
+from sas.sasgui.guiframe.customdir import setup_custom_config
 
 logger = logging.getLogger(__name__)
-
 warnings.simplefilter("ignore")
 
-def get_app_dir():
-    """
-        The application directory is the one where the default custom_config.py
-        file resides.
-
-        :returns: app_path - the path to the applicatin directory
-    """
-    # First, try the directory of the executable we are running
-    app_path = sys.path[0]
-    if os.path.isfile(app_path):
-        app_path = os.path.dirname(app_path)
-    if os.path.isfile(os.path.join(app_path, "custom_config.py")):
-        app_path = os.path.abspath(app_path)
-        logger.info("Using application path: %s", app_path)
-        return app_path
-
-    # Next, try the current working directory
-    if os.path.isfile(os.path.join(os.getcwd(), "custom_config.py")):
-        logger.info("Using application path: %s", os.getcwd())
-        return os.path.abspath(os.getcwd())
-
-    # Finally, try the directory of the sasview module
-    # TODO: gui_manager will have to know about sasview until we
-    # clean all these module variables and put them into a config class
-    # that can be passed by sasview.py.
-    logger.debug(sys.executable)
-    logger.debug(str(sys.argv))
-    from sas import sasview as sasview
-    app_path = os.path.dirname(sasview.__file__)
-    logger.debug("Using application path: %s", app_path)
-    return app_path
-
-
-def get_user_directory():
-    """
-        Returns the user's home directory
-    """
-    userdir = os.path.join(os.path.expanduser("~"), ".sasview")
-    if not os.path.isdir(userdir):
-        os.makedirs(userdir)
-    return userdir
-
-
-def _find_local_config(file, path):
-    """
-        Find configuration file for the current application
-    """
-    config_module = None
-    fObj = None
-    try:
-        fObj, path_config, descr = imp.find_module(file, [path])
-        config_module = imp.load_module(file, fObj, path_config, descr)
-    except:
-        logger.error("Error loading %s/%s: %s" % (path, file, sys.exc_value))
-    finally:
-        if fObj is not None:
-            fObj.close()
-    logger.debug("GuiManager loaded %s/%s" % (path, file))
-    return config_module
-
-# Get APP folder
-PATH_APP = get_app_dir()
-DATAPATH = PATH_APP
-
-# GUI always starts from the App folder
-# os.chdir(PATH_APP)
-# Read in the local config, which can either be with the main
-# application or in the installation directory
-config = _find_local_config('local_config', PATH_APP)
-if config is None:
-    config = _find_local_config('local_config', os.getcwd())
-    if config is None:
-        # Didn't find local config, load the default
-        import sas.sasgui.guiframe.config as config
-        logger.debug("using default local_config")
-    else:
-        logger.debug("found local_config in %s" % os.getcwd())
-else:
-    logger.debug("found local_config in %s" % PATH_APP)
-
-from sas.sasgui.guiframe.customdir import SetupCustom
-c_conf_dir = SetupCustom().setup_dir(PATH_APP)
-custom_config = _find_local_config('custom_config', c_conf_dir)
-if custom_config is None:
-    custom_config = _find_local_config('custom_config', os.getcwd())
-    if custom_config is None:
-        msgConfig = "Custom_config file was not imported"
-        logger.debug(msgConfig)
-    else:
-        logger.debug("using custom_config in %s" % os.getcwd())
-else:
-    logger.debug("using custom_config from %s" % c_conf_dir)
+config = get_local_config()
+custom_config = setup_custom_config()
 
 # read some constants from config
@@ -177,5 +87,5 @@
         DEFAULT_OPEN_FOLDER = os.path.abspath(open_folder)
     else:
-        DEFAULT_OPEN_FOLDER = PATH_APP
+        DEFAULT_OPEN_FOLDER = get_app_dir()
     SAS_OPENCL = custom_config.SAS_OPENCL
 except:
@@ -192,4 +102,5 @@
     DEFAULT_PERSPECTIVE = None
     CLEANUP_PLOT = False
+    DEFAULT_OPEN_FOLDER = get_app_dir()
     DEFAULT_OPEN_FOLDER = PATH_APP
     SAS_OPENCL = None
@@ -265,5 +176,5 @@
                 if os.path.isfile(ico_file):
                     self.SetIcon(wx.Icon(ico_file, wx.BITMAP_TYPE_ICO))
-        self.path = PATH_APP
+        self.path = get_app_dir()
         self.application_name = APPLICATION_NAME
         # Application manager
@@ -540,7 +451,7 @@
         try:
             fd = open(file_name, 'w')
-        except:
+        except Exception:
             # On Permission denied: IOError
-            temp_dir = get_user_directory()
+            temp_dir = get_user_dir()
             temp_file_name = os.path.join(temp_dir, name)
             fd = open(temp_file_name, 'w')
@@ -1532,5 +1443,5 @@
             # want Analysis.  This is NOT an issue on the Mac which does not
             # have the extra Window menu item.
-            #      March 2016 Code Camp  -- PDB 
+            #      March 2016 Code Camp  -- PDB
             Tools_pos = self._menubar.FindMenu("Tools")
             self._menubar.Insert(Tools_pos+1, self._applications_menu,
@@ -2163,4 +2074,5 @@
                 logger.info("Failed to connect to www.sasview.org")
         self._process_version(version_info, standalone=event is None)
+
 
     def _process_version(self, version_info, standalone=True):
@@ -3351,5 +3263,5 @@
                 if basename.lower() in [app_py, app_exe, app_app, app_base]:
                     data_base = sys.argv[1]
-                    input_file = os.path.normpath(os.path.join(DATAPATH,
+                    input_file = os.path.normpath(os.path.join(get_app_dir(),
                                                                data_base))
         if input_file is None:
@@ -3366,5 +3278,5 @@
         # do it only the first time app loaded
         # delete unused model folder
-        model_folder = os.path.join(PATH_APP, path)
+        model_folder = os.path.join(get_app_dir(), path)
         if os.path.exists(model_folder) and os.path.isdir(model_folder):
             if len(os.listdir(model_folder)) > 0:
Index: src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py
===================================================================
--- src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py	(revision dcb91cf83e474bdbe1c788d87690ca5f5e7841cb)
+++ src/sas/sasgui/guiframe/local_perspectives/data_loader/data_loader.py	(revision dcb91cf83e474bdbe1c788d87690ca5f5e7841cb)
@@ -12,27 +12,12 @@
 from sas.sascalc.dataloader.loader import Loader
 from sas.sascalc.dataloader.loader_exceptions import NoKnownLoaderException
+
+from sas.sasgui import get_local_config
 from sas.sasgui.guiframe.plugin_base import PluginBase
 from sas.sasgui.guiframe.events import StatusEvent
 from sas.sasgui.guiframe.gui_style import GUIFRAME
 from sas.sasgui.guiframe.gui_manager import DEFAULT_OPEN_FOLDER
-try:
-    # Try to find a local config
-    import imp
-    path = os.getcwd()
-    if(os.path.isfile("%s/%s.py" % (path, 'local_config'))) or \
-        (os.path.isfile("%s/%s.pyc" % (path, 'local_config'))):
-        fObj, path, descr = imp.find_module('local_config', [path])
-        config = imp.load_module('local_config', fObj, path, descr)
-    else:
-        # Try simply importing local_config
-        import local_config as config
-except:
-    # Didn't find local config, load the default
-    import sas.sasgui.guiframe.config as config
-
-if config is None:
-    import sas.sasgui.guiframe.config as config
-
-
+
+config = get_local_config()
 extension_list = []
 if config.APPLICATION_STATE_EXTENSION is not None:
Index: src/sas/sasgui/guiframe/startup_configuration.py
===================================================================
--- src/sas/sasgui/guiframe/startup_configuration.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
+++ src/sas/sasgui/guiframe/startup_configuration.py	(revision 7432acb919f4013119ca918a73350297e0d4c93f)
@@ -1,7 +1,6 @@
-
 ################################################################################
 #This software was developed by the University of Tennessee as part of the
 #Distributed Data Analysis of Neutron Scattering Experiments (DANSE)
-#project funded by the US National Science Foundation. 
+#project funded by the US National Science Foundation.
 #
 #See the license text in license.txt
@@ -9,13 +8,15 @@
 #copyright 2009, University of Tennessee
 ################################################################################
+import os
+import copy
+
 import wx
-import os
-import sys
-import copy
-#import sas.sasgui.guiframe.gui_manager as gui
-from sas.sasgui.guiframe.events import StatusEvent  
+
+from sas.sasgui import get_custom_config_path
+from sas.sasgui.guiframe.events import StatusEvent
 from sas.sasgui.guiframe.gui_style import GUIFRAME
 from sas.sasgui.guiframe import gui_manager as CURRENT
-from sas.sasgui.guiframe.customdir  import SetupCustom
+
+
 # default configuration
 DEFAULT_STRINGS = {'GUIFRAME_WIDTH':-1,
@@ -62,11 +63,10 @@
     """
     def __init__(self, parent, gui, id=-1, title="Startup Setting"):
-        wx.Dialog.__init__(self, parent, id, title, 
+        wx.Dialog.__init__(self, parent, id, title,
                            size=(PANEL_WIDTH, PANEL_HEIGHT))
         # parent
         self.parent = parent
-        self.path = SetupCustom().find_dir()
         self._gui = gui
-        # font size 
+        # font size
         self.SetWindowVariant(variant=FONT_VARIANT)
         self.current_string = copy.deepcopy(CURRENT_STRINGS)
@@ -76,5 +76,5 @@
         title_text = wx.StaticText(self, id=wx.NewId(), label='Set interface configuration')
 
-        default_bt = wx.RadioButton(self, -1, 'Default View', (15, 30), 
+        default_bt = wx.RadioButton(self, -1, 'Default View', (15, 30),
                                     style=wx.RB_GROUP)
         default_bt.Bind(wx.EVT_RADIOBUTTON, self.OnDefault)
@@ -87,8 +87,8 @@
         note_txt = wx.StaticText(self, -1, msg, (15, 75))
         note_txt.SetForegroundColour("black")
-        
+
         hbox = wx.BoxSizer(wx.HORIZONTAL)
         okButton = wx.Button(self, wx.ID_OK, 'Set', size=(70, 25))
-        closeButton = wx.Button(self,wx.ID_CANCEL, 'Cancel', size=(70, 25))
+        closeButton = wx.Button(self, wx.ID_CANCEL, 'Cancel', size=(70, 25))
         hbox.Add(closeButton, 1, wx.RIGHT, 5)
         hbox.Add(okButton, 1, wx.RIGHT, 5)
@@ -102,5 +102,5 @@
         self.SetSizer(vbox)
 
-        
+
     def OnDefault(self, event=None):
         """
@@ -111,5 +111,5 @@
         self.return_string = copy.deepcopy(DEFAULT_STRINGS)
         return self.return_string
-        
+
     def OnCurrent(self, event=None):
         """
@@ -134,5 +134,5 @@
                 p_size = CURRENT_STRINGS['PLOPANEL_WIDTH']
             self.current_string['PLOPANEL_WIDTH'] = p_size
-            
+
             try:
                 control_frame = self.parent.get_current_perspective().frame
@@ -143,10 +143,10 @@
                 self.current_string['CONTROL_WIDTH'] = -1
                 self.current_string['CONTROL_HEIGHT'] = -1
-                
+
             data_pw, _ = self.parent.panels["data_panel"].frame.GetSizeTuple()
             if data_pw is None:
                 data_pw = CURRENT_STRINGS['DATAPANEL_WIDTH']
             self.current_string['DATAPANEL_WIDTH'] = data_pw
-            
+
             #label = self.parent._data_panel_menu.GetText()
             label = self.parent.panels['data_panel'].frame.IsShown()
@@ -155,16 +155,16 @@
             else:
                 self.current_string['DATALOADER_SHOW'] = False
-                
+
             if self.parent._toolbar.IsShown():
                 self.current_string['TOOLBAR_SHOW'] = True
             else:
                 self.current_string['TOOLBAR_SHOW'] = False
-                
+
             style = self._gui & GUIFRAME.FLOATING_PANEL
-            if style == GUIFRAME.FLOATING_PANEL: 
+            if style == GUIFRAME.FLOATING_PANEL:
                 self.current_string['FIXED_PANEL'] = False
             else:
                 self.current_string['FIXED_PANEL'] = True
-                
+
             if self.parent.panels['default'].frame.IsShown():
                 self.current_string['WELCOME_PANEL_SHOW'] = True
@@ -182,5 +182,5 @@
             self.current_string['DEFAULT_OPEN_FOLDER'] = location
                         #self.parent._default_save_location.ascii_letters
-            
+
         except:
             raise
@@ -188,29 +188,17 @@
         self.return_string = self.current_string
         return self.return_string
-    
+
+
     def write_custom_config(self):
         """
-            Write custom configuration
-        """
-        fname = os.path.join(self.path, 'custom_config.py')
-        self.write_string(fname, self.return_string)
-
-    def write_string(self, fname, strings):
-        """
-        Write and Save file
-        """
-        
-        try:
-            out_f =  open(fname,'w')
-        except :
-            raise  #RuntimeError, "Error: Can not change the configuration..."
-        out_f.write("#Application appearance custom configuration\n" )
-        for key, item in strings.iteritems():
-            if (key == 'DEFAULT_PERSPECTIVE') or \
-                (key == 'DEFAULT_OPEN_FOLDER' and item is not None):
-                out_f.write("%s = \"%s\"\n" % (key,str(item)))
-            else:
-                out_f.write("%s = %s\n" % (key,str(item)))
-    
-        out_f.close() 
-        
+        Write custom configuration
+        """
+        path = get_custom_config_path()
+        with open(path, 'w') as out_f:
+            out_f.write("#Application appearance custom configuration\n")
+            for key, item in self.return_string.iteritems():
+                if (key == 'DEFAULT_PERSPECTIVE') or \
+                    (key == 'DEFAULT_OPEN_FOLDER' and item != None):
+                    out_f.write("%s = \"%s\"\n" % (key, str(item)))
+                else:
+                    out_f.write("%s = %s\n" % (key, str(item)))
