From a5773999fe1d6791bfc0cbb830527a5b29b84f5d Mon Sep 17 00:00:00 2001
From: shekhar-cis <shekhar.c@cisinlabs.com>
Date: Fri, 28 Jan 2022 18:25:23 +0530
Subject: [PATCH] Refactor BMConfigParser as a Module variable

---
 packages/pyinstaller/bitmessagemain.spec |   2 +-
 setup.py                                 |   2 +-
 src/api.py                               |  28 ++---
 src/bitmessagecli.py                     | 120 ++++++++++----------
 src/bitmessagecurses/__init__.py         |  62 +++++-----
 src/bitmessagemain.py                    |   9 +-
 src/bitmessageqt/__init__.py             | 111 +++++++++---------
 src/bitmessageqt/account.py              |  28 ++---
 src/bitmessageqt/bitmessageui.py         |   8 +-
 src/bitmessageqt/blacklist.py            |  28 ++---
 src/bitmessageqt/foldertree.py           |  24 ++--
 src/bitmessageqt/languagebox.py          |   4 +-
 src/bitmessageqt/settings.py             |  82 +++++++-------
 src/bitmessageqt/support.py              |  10 +-
 src/bitmessageqt/tests/settings.py       |   6 +-
 src/bitmessageqt/utils.py                |   8 +-
 src/bmconfigparser.py                    | 138 +++--------------------
 src/build_osx.py                         |   2 +-
 src/class_addressGenerator.py            |  50 ++++----
 src/class_objectProcessor.py             |  34 +++---
 src/class_singleCleaner.py               |   6 +-
 src/class_singleWorker.py                |  66 +++++------
 src/class_smtpDeliver.py                 |   8 +-
 src/class_smtpServer.py                  |  14 +--
 src/class_sqlThread.py                   |  11 +-
 src/default.ini                          |  47 ++++++++
 src/helper_addressbook.py                |   4 +-
 src/helper_msgcoding.py                  |   6 +-
 src/helper_sent.py                       |   6 +-
 src/helper_startup.py                    |  38 ++-----
 src/highlevelcrypto.py                   |   4 +-
 src/inventory.py                         |   4 +-
 src/l10n.py                              |   6 +-
 src/mock/class_addressGenerator.py       |  14 +--
 src/namecoin.py                          |  33 +++---
 src/network/announcethread.py            |   4 +-
 src/network/bmproto.py                   |   8 +-
 src/network/connectionchooser.py         |   6 +-
 src/network/connectionpool.py            |  52 ++++-----
 src/network/knownnodes.py                |   8 +-
 src/network/proxy.py                     |   8 +-
 src/network/tcp.py                       |  12 +-
 src/openclpow.py                         |   4 +-
 src/proofofwork.py                       |   4 +-
 src/protocol.py                          |  14 +--
 src/shared.py                            |   8 +-
 src/tests/core.py                        |  28 ++---
 src/tests/test_config.py                 |  51 +++++----
 src/tests/test_config_process.py         |   3 +-
 src/upnp.py                              |  14 +--
 50 files changed, 583 insertions(+), 664 deletions(-)
 create mode 100644 src/default.ini

diff --git a/packages/pyinstaller/bitmessagemain.spec b/packages/pyinstaller/bitmessagemain.spec
index d7d4d70d..8d38ec09 100644
--- a/packages/pyinstaller/bitmessagemain.spec
+++ b/packages/pyinstaller/bitmessagemain.spec
@@ -74,7 +74,7 @@ a.datas += [
 
 # append the translations directory
 a.datas += addTranslations()
-
+a.datas += [('default.ini', os.path.join(srcPath, 'default.ini'), 'DATA')]
 
 excluded_binaries = [
     'QtOpenGL4.dll',
diff --git a/setup.py b/setup.py
index f43f3d58..fea2e58a 100644
--- a/setup.py
+++ b/setup.py
@@ -136,7 +136,7 @@ if __name__ == "__main__":
         packages=packages,
         package_data={'': [
             'bitmessageqt/*.ui', 'bitmsghash/*.cl', 'sslkeys/*.pem',
-            'translations/*.ts', 'translations/*.qm',
+            'translations/*.ts', 'translations/*.qm', 'default.ini',
             'images/*.png', 'images/*.ico', 'images/*.icns'
         ]},
         data_files=data_files,
diff --git a/src/api.py b/src/api.py
index 9cab1cfe..736ba024 100644
--- a/src/api.py
+++ b/src/api.py
@@ -87,7 +87,7 @@ from addresses import (
     decodeVarint,
     varintDecodeError
 )
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from helper_sql import SqlBulkExecute, sqlExecute, sqlQuery, sqlStoredProcedure, sql_ready
 from inventory import Inventory
@@ -190,8 +190,8 @@ class singleAPI(StoppableThread):
         s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
         try:
             s.connect((
-                BMConfigParser().get('bitmessagesettings', 'apiinterface'),
-                BMConfigParser().getint('bitmessagesettings', 'apiport')
+                config.get('bitmessagesettings', 'apiinterface'),
+                config.getint('bitmessagesettings', 'apiport')
             ))
             s.shutdown(socket.SHUT_RDWR)
             s.close()
@@ -204,7 +204,7 @@ class singleAPI(StoppableThread):
         :class:`jsonrpclib.SimpleJSONRPCServer` is created and started here
         with `BMRPCDispatcher` dispatcher.
         """
-        port = BMConfigParser().getint('bitmessagesettings', 'apiport')
+        port = config.getint('bitmessagesettings', 'apiport')
         try:
             getattr(errno, 'WSAEADDRINUSE')
         except AttributeError:
@@ -212,7 +212,7 @@ class singleAPI(StoppableThread):
 
         RPCServerBase = SimpleXMLRPCServer
         ct = 'text/xml'
-        if BMConfigParser().safeGet(
+        if config.safeGet(
                 'bitmessagesettings', 'apivariant') == 'json':
             try:
                 from jsonrpclib.SimpleJSONRPCServer import (
@@ -242,7 +242,7 @@ class singleAPI(StoppableThread):
                         'Failed to start API listener on port %s', port)
                     port = random.randint(32767, 65535)
                 se = StoppableRPCServer(
-                    (BMConfigParser().get(
+                    (config.get(
                         'bitmessagesettings', 'apiinterface'),
                      port),
                     BMXMLRPCRequestHandler, True, encoding='UTF-8')
@@ -252,15 +252,15 @@ class singleAPI(StoppableThread):
             else:
                 if attempt > 0:
                     logger.warning('Setting apiport to %s', port)
-                    BMConfigParser().set(
+                    config.set(
                         'bitmessagesettings', 'apiport', str(port))
-                    BMConfigParser().save()
+                    config.save()
                 break
 
         se.register_instance(BMRPCDispatcher())
         se.register_introspection_functions()
 
-        apiNotifyPath = BMConfigParser().safeGet(
+        apiNotifyPath = config.safeGet(
             'bitmessagesettings', 'apinotifypath')
 
         if apiNotifyPath:
@@ -271,7 +271,7 @@ class singleAPI(StoppableThread):
                 logger.warning(
                     'Failed to call %s, removing apinotifypath setting',
                     apiNotifyPath)
-                BMConfigParser().remove_option(
+                config.remove_option(
                     'bitmessagesettings', 'apinotifypath')
 
         se.serve_forever()
@@ -286,7 +286,7 @@ class CommandHandler(type):
         # pylint: disable=protected-access
         result = super(CommandHandler, mcs).__new__(
             mcs, name, bases, namespace)
-        result.config = BMConfigParser()
+        result.config = config
         result._handlers = {}
         apivariant = result.config.safeGet('bitmessagesettings', 'apivariant')
         for func in namespace.values():
@@ -325,7 +325,7 @@ class command(object):  # pylint: disable=too-few-public-methods
 
     def __call__(self, func):
 
-        if BMConfigParser().safeGet(
+        if config.safeGet(
                 'bitmessagesettings', 'apivariant') == 'legacy':
             def wrapper(*args):
                 """
@@ -444,9 +444,9 @@ class BMXMLRPCRequestHandler(SimpleXMLRPCRequestHandler):
             encstr = self.headers.get('Authorization').split()[1]
             emailid, password = encstr.decode('base64').split(':')
             return (
-                emailid == BMConfigParser().get(
+                emailid == config.get(
                     'bitmessagesettings', 'apiusername'
-                ) and password == BMConfigParser().get(
+                ) and password == config.get(
                     'bitmessagesettings', 'apipassword'))
         else:
             logger.warning(
diff --git a/src/bitmessagecli.py b/src/bitmessagecli.py
index adcab8b1..84c618af 100644
--- a/src/bitmessagecli.py
+++ b/src/bitmessagecli.py
@@ -23,7 +23,7 @@ import sys
 import time
 import xmlrpclib
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 
 
 api = ''
@@ -86,15 +86,15 @@ def lookupAppdataFolder():
 def configInit():
     """Initialised the configuration"""
 
-    BMConfigParser().add_section('bitmessagesettings')
+    config.add_section('bitmessagesettings')
     # Sets the bitmessage port to stop the warning about the api not properly
     # being setup. This is in the event that the keys.dat is in a different
     # directory or is created locally to connect to a machine remotely.
-    BMConfigParser().set('bitmessagesettings', 'port', '8444')
-    BMConfigParser().set('bitmessagesettings', 'apienabled', 'true')  # Sets apienabled to true in keys.dat
+    config.set('bitmessagesettings', 'port', '8444')
+    config.set('bitmessagesettings', 'apienabled', 'true')  # Sets apienabled to true in keys.dat
 
     with open(keysName, 'wb') as configfile:
-        BMConfigParser().write(configfile)
+        config.write(configfile)
 
     print('\n     ' + str(keysName) + ' Initalized in the same directory as daemon.py')
     print('     You will now need to configure the ' + str(keysName) + ' file.\n')
@@ -104,15 +104,15 @@ def apiInit(apiEnabled):
     """Initialise the API"""
 
     global usrPrompt
-    BMConfigParser().read(keysPath)
+    config.read(keysPath)
 
     if apiEnabled is False:  # API information there but the api is disabled.
         uInput = userInput("The API is not enabled. Would you like to do that now, (Y)es or (N)o?").lower()
 
         if uInput == "y":
-            BMConfigParser().set('bitmessagesettings', 'apienabled', 'true')  # Sets apienabled to true in keys.dat
+            config.set('bitmessagesettings', 'apienabled', 'true')  # Sets apienabled to true in keys.dat
             with open(keysPath, 'wb') as configfile:
-                BMConfigParser().write(configfile)
+                config.write(configfile)
 
             print('Done')
             restartBmNotify()
@@ -158,15 +158,15 @@ def apiInit(apiEnabled):
             # sets the bitmessage port to stop the warning about the api not properly
             # being setup. This is in the event that the keys.dat is in a different
             # directory or is created locally to connect to a machine remotely.
-            BMConfigParser().set('bitmessagesettings', 'port', '8444')
-            BMConfigParser().set('bitmessagesettings', 'apienabled', 'true')
-            BMConfigParser().set('bitmessagesettings', 'apiport', apiPort)
-            BMConfigParser().set('bitmessagesettings', 'apiinterface', '127.0.0.1')
-            BMConfigParser().set('bitmessagesettings', 'apiusername', apiUsr)
-            BMConfigParser().set('bitmessagesettings', 'apipassword', apiPwd)
-            BMConfigParser().set('bitmessagesettings', 'daemon', daemon)
+            config.set('bitmessagesettings', 'port', '8444')
+            config.set('bitmessagesettings', 'apienabled', 'true')
+            config.set('bitmessagesettings', 'apiport', apiPort)
+            config.set('bitmessagesettings', 'apiinterface', '127.0.0.1')
+            config.set('bitmessagesettings', 'apiusername', apiUsr)
+            config.set('bitmessagesettings', 'apipassword', apiPwd)
+            config.set('bitmessagesettings', 'daemon', daemon)
             with open(keysPath, 'wb') as configfile:
-                BMConfigParser().write(configfile)
+                config.write(configfile)
 
             print('\n     Finished configuring the keys.dat file with API information.\n')
             restartBmNotify()
@@ -191,19 +191,19 @@ def apiData():
     global keysPath
     global usrPrompt
 
-    BMConfigParser().read(keysPath)  # First try to load the config file (the keys.dat file) from the program directory
+    config.read(keysPath)  # First try to load the config file (the keys.dat file) from the program directory
 
     try:
-        BMConfigParser().get('bitmessagesettings', 'port')
+        config.get('bitmessagesettings', 'port')
         appDataFolder = ''
     except:  # noqa:E722
         # Could not load the keys.dat file in the program directory. Perhaps it is in the appdata directory.
         appDataFolder = lookupAppdataFolder()
         keysPath = appDataFolder + keysPath
-        BMConfigParser().read(keysPath)
+        config.read(keysPath)
 
         try:
-            BMConfigParser().get('bitmessagesettings', 'port')
+            config.get('bitmessagesettings', 'port')
         except:  # noqa:E722
             # keys.dat was not there either, something is wrong.
             print('\n     ******************************************************************')
@@ -230,24 +230,24 @@ def apiData():
             main()
 
     try:  # checks to make sure that everyting is configured correctly. Excluding apiEnabled, it is checked after
-        BMConfigParser().get('bitmessagesettings', 'apiport')
-        BMConfigParser().get('bitmessagesettings', 'apiinterface')
-        BMConfigParser().get('bitmessagesettings', 'apiusername')
-        BMConfigParser().get('bitmessagesettings', 'apipassword')
+        config.get('bitmessagesettings', 'apiport')
+        config.get('bitmessagesettings', 'apiinterface')
+        config.get('bitmessagesettings', 'apiusername')
+        config.get('bitmessagesettings', 'apipassword')
 
     except:  # noqa:E722
         apiInit("")  # Initalize the keys.dat file with API information
 
     # keys.dat file was found or appropriately configured, allow information retrieval
     # apiEnabled =
-    # apiInit(BMConfigParser().safeGetBoolean('bitmessagesettings','apienabled'))
+    # apiInit(config.safeGetBoolean('bitmessagesettings','apienabled'))
     # #if false it will prompt the user, if true it will return true
 
-    BMConfigParser().read(keysPath)  # read again since changes have been made
-    apiPort = int(BMConfigParser().get('bitmessagesettings', 'apiport'))
-    apiInterface = BMConfigParser().get('bitmessagesettings', 'apiinterface')
-    apiUsername = BMConfigParser().get('bitmessagesettings', 'apiusername')
-    apiPassword = BMConfigParser().get('bitmessagesettings', 'apipassword')
+    config.read(keysPath)  # read again since changes have been made
+    apiPort = int(config.get('bitmessagesettings', 'apiport'))
+    apiInterface = config.get('bitmessagesettings', 'apiinterface')
+    apiUsername = config.get('bitmessagesettings', 'apiusername')
+    apiPassword = config.get('bitmessagesettings', 'apipassword')
 
     print('\n     API data successfully imported.\n')
 
@@ -277,28 +277,28 @@ def bmSettings():
 
     keysPath = 'keys.dat'
 
-    BMConfigParser().read(keysPath)  # Read the keys.dat
+    config.read(keysPath)  # Read the keys.dat
     try:
-        port = BMConfigParser().get('bitmessagesettings', 'port')
+        port = config.get('bitmessagesettings', 'port')
     except:  # noqa:E722
         print('\n     File not found.\n')
         usrPrompt = 0
         main()
 
-    startonlogon = BMConfigParser().safeGetBoolean('bitmessagesettings', 'startonlogon')
-    minimizetotray = BMConfigParser().safeGetBoolean('bitmessagesettings', 'minimizetotray')
-    showtraynotifications = BMConfigParser().safeGetBoolean('bitmessagesettings', 'showtraynotifications')
-    startintray = BMConfigParser().safeGetBoolean('bitmessagesettings', 'startintray')
-    defaultnoncetrialsperbyte = BMConfigParser().get('bitmessagesettings', 'defaultnoncetrialsperbyte')
-    defaultpayloadlengthextrabytes = BMConfigParser().get('bitmessagesettings', 'defaultpayloadlengthextrabytes')
-    daemon = BMConfigParser().safeGetBoolean('bitmessagesettings', 'daemon')
+    startonlogon = config.safeGetBoolean('bitmessagesettings', 'startonlogon')
+    minimizetotray = config.safeGetBoolean('bitmessagesettings', 'minimizetotray')
+    showtraynotifications = config.safeGetBoolean('bitmessagesettings', 'showtraynotifications')
+    startintray = config.safeGetBoolean('bitmessagesettings', 'startintray')
+    defaultnoncetrialsperbyte = config.get('bitmessagesettings', 'defaultnoncetrialsperbyte')
+    defaultpayloadlengthextrabytes = config.get('bitmessagesettings', 'defaultpayloadlengthextrabytes')
+    daemon = config.safeGetBoolean('bitmessagesettings', 'daemon')
 
-    socksproxytype = BMConfigParser().get('bitmessagesettings', 'socksproxytype')
-    sockshostname = BMConfigParser().get('bitmessagesettings', 'sockshostname')
-    socksport = BMConfigParser().get('bitmessagesettings', 'socksport')
-    socksauthentication = BMConfigParser().safeGetBoolean('bitmessagesettings', 'socksauthentication')
-    socksusername = BMConfigParser().get('bitmessagesettings', 'socksusername')
-    sockspassword = BMConfigParser().get('bitmessagesettings', 'sockspassword')
+    socksproxytype = config.get('bitmessagesettings', 'socksproxytype')
+    sockshostname = config.get('bitmessagesettings', 'sockshostname')
+    socksport = config.get('bitmessagesettings', 'socksport')
+    socksauthentication = config.safeGetBoolean('bitmessagesettings', 'socksauthentication')
+    socksusername = config.get('bitmessagesettings', 'socksusername')
+    sockspassword = config.get('bitmessagesettings', 'sockspassword')
 
     print('\n     -----------------------------------')
     print('     |   Current Bitmessage Settings   |')
@@ -333,60 +333,60 @@ def bmSettings():
             if uInput == "port":
                 print('     Current port number: ' + port)
                 uInput = userInput("Enter the new port number.")
-                BMConfigParser().set('bitmessagesettings', 'port', str(uInput))
+                config.set('bitmessagesettings', 'port', str(uInput))
             elif uInput == "startonlogon":
                 print('     Current status: ' + str(startonlogon))
                 uInput = userInput("Enter the new status.")
-                BMConfigParser().set('bitmessagesettings', 'startonlogon', str(uInput))
+                config.set('bitmessagesettings', 'startonlogon', str(uInput))
             elif uInput == "minimizetotray":
                 print('     Current status: ' + str(minimizetotray))
                 uInput = userInput("Enter the new status.")
-                BMConfigParser().set('bitmessagesettings', 'minimizetotray', str(uInput))
+                config.set('bitmessagesettings', 'minimizetotray', str(uInput))
             elif uInput == "showtraynotifications":
                 print('     Current status: ' + str(showtraynotifications))
                 uInput = userInput("Enter the new status.")
-                BMConfigParser().set('bitmessagesettings', 'showtraynotifications', str(uInput))
+                config.set('bitmessagesettings', 'showtraynotifications', str(uInput))
             elif uInput == "startintray":
                 print('     Current status: ' + str(startintray))
                 uInput = userInput("Enter the new status.")
-                BMConfigParser().set('bitmessagesettings', 'startintray', str(uInput))
+                config.set('bitmessagesettings', 'startintray', str(uInput))
             elif uInput == "defaultnoncetrialsperbyte":
                 print('     Current default nonce trials per byte: ' + defaultnoncetrialsperbyte)
                 uInput = userInput("Enter the new defaultnoncetrialsperbyte.")
-                BMConfigParser().set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(uInput))
+                config.set('bitmessagesettings', 'defaultnoncetrialsperbyte', str(uInput))
             elif uInput == "defaultpayloadlengthextrabytes":
                 print('     Current default payload length extra bytes: ' + defaultpayloadlengthextrabytes)
                 uInput = userInput("Enter the new defaultpayloadlengthextrabytes.")
-                BMConfigParser().set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(uInput))
+                config.set('bitmessagesettings', 'defaultpayloadlengthextrabytes', str(uInput))
             elif uInput == "daemon":
                 print('     Current status: ' + str(daemon))
                 uInput = userInput("Enter the new status.").lower()
-                BMConfigParser().set('bitmessagesettings', 'daemon', str(uInput))
+                config.set('bitmessagesettings', 'daemon', str(uInput))
             elif uInput == "socksproxytype":
                 print('     Current socks proxy type: ' + socksproxytype)
                 print("Possibilities: 'none', 'SOCKS4a', 'SOCKS5'.")
                 uInput = userInput("Enter the new socksproxytype.")
-                BMConfigParser().set('bitmessagesettings', 'socksproxytype', str(uInput))
+                config.set('bitmessagesettings', 'socksproxytype', str(uInput))
             elif uInput == "sockshostname":
                 print('     Current socks host name: ' + sockshostname)
                 uInput = userInput("Enter the new sockshostname.")
-                BMConfigParser().set('bitmessagesettings', 'sockshostname', str(uInput))
+                config.set('bitmessagesettings', 'sockshostname', str(uInput))
             elif uInput == "socksport":
                 print('     Current socks port number: ' + socksport)
                 uInput = userInput("Enter the new socksport.")
-                BMConfigParser().set('bitmessagesettings', 'socksport', str(uInput))
+                config.set('bitmessagesettings', 'socksport', str(uInput))
             elif uInput == "socksauthentication":
                 print('     Current status: ' + str(socksauthentication))
                 uInput = userInput("Enter the new status.")
-                BMConfigParser().set('bitmessagesettings', 'socksauthentication', str(uInput))
+                config.set('bitmessagesettings', 'socksauthentication', str(uInput))
             elif uInput == "socksusername":
                 print('     Current socks username: ' + socksusername)
                 uInput = userInput("Enter the new socksusername.")
-                BMConfigParser().set('bitmessagesettings', 'socksusername', str(uInput))
+                config.set('bitmessagesettings', 'socksusername', str(uInput))
             elif uInput == "sockspassword":
                 print('     Current socks password: ' + sockspassword)
                 uInput = userInput("Enter the new password.")
-                BMConfigParser().set('bitmessagesettings', 'sockspassword', str(uInput))
+                config.set('bitmessagesettings', 'sockspassword', str(uInput))
             else:
                 print("\n     Invalid input. Please try again.\n")
                 invalidInput = True
@@ -397,7 +397,7 @@ def bmSettings():
                 if uInput != "y":
                     print('\n     Changes Made.\n')
                     with open(keysPath, 'wb') as configfile:
-                        BMConfigParser().write(configfile)
+                        config.write(configfile)
                     restartBmNotify()
                     break
 
diff --git a/src/bitmessagecurses/__init__.py b/src/bitmessagecurses/__init__.py
index 7b52457d..542b8e53 100644
--- a/src/bitmessagecurses/__init__.py
+++ b/src/bitmessagecurses/__init__.py
@@ -28,7 +28,7 @@ import shutdown
 import state
 
 from addresses import addBMIfNotPresent, decodeAddress
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute, sqlQuery
 from inventory import Inventory
 
@@ -618,19 +618,19 @@ def handlech(c, stdscr):
                             r, t = d.inputbox("New address label", init=label)
                             if r == d.DIALOG_OK:
                                 label = t
-                                BMConfigParser().set(a, "label", label)
+                                config.set(a, "label", label)
                                 # Write config
-                                BMConfigParser().save()
+                                config.save()
                                 addresses[addrcur][0] = label
                         elif t == "4":      # Enable address
                             a = addresses[addrcur][2]
-                            BMConfigParser().set(a, "enabled", "true")       # Set config
+                            config.set(a, "enabled", "true")       # Set config
                             # Write config
-                            BMConfigParser().save()
+                            config.save()
                             # Change color
-                            if BMConfigParser().safeGetBoolean(a, 'chan'):
+                            if config.safeGetBoolean(a, 'chan'):
                                 addresses[addrcur][3] = 9       # orange
-                            elif BMConfigParser().safeGetBoolean(a, 'mailinglist'):
+                            elif config.safeGetBoolean(a, 'mailinglist'):
                                 addresses[addrcur][3] = 5       # magenta
                             else:
                                 addresses[addrcur][3] = 0       # black
@@ -638,26 +638,26 @@ def handlech(c, stdscr):
                             shared.reloadMyAddressHashes()      # Reload address hashes
                         elif t == "5":       # Disable address
                             a = addresses[addrcur][2]
-                            BMConfigParser().set(a, "enabled", "false")     # Set config
+                            config.set(a, "enabled", "false")     # Set config
                             addresses[addrcur][3] = 8       # Set color to gray
                             # Write config
-                            BMConfigParser().save()
+                            config.save()
                             addresses[addrcur][1] = False
                             shared.reloadMyAddressHashes()      # Reload address hashes
                         elif t == "6":      # Delete address
                             r, t = d.inputbox("Type in \"I want to delete this address\"", width=50)
                             if r == d.DIALOG_OK and t == "I want to delete this address":
-                                BMConfigParser().remove_section(addresses[addrcur][2])
-                                BMConfigParser().save()
+                                config.remove_section(addresses[addrcur][2])
+                                config.save()
                                 del addresses[addrcur]
                         elif t == "7":      # Special address behavior
                             a = addresses[addrcur][2]
                             set_background_title(d, "Special address behavior")
-                            if BMConfigParser().safeGetBoolean(a, "chan"):
+                            if config.safeGetBoolean(a, "chan"):
                                 scrollbox(d, unicode(
                                     "This is a chan address. You cannot use it as a pseudo-mailing list."))
                             else:
-                                m = BMConfigParser().safeGetBoolean(a, "mailinglist")
+                                m = config.safeGetBoolean(a, "mailinglist")
                                 r, t = d.radiolist(
                                     "Select address behavior",
                                     choices=[
@@ -665,24 +665,24 @@ def handlech(c, stdscr):
                                         ("2", "Behave as a pseudo-mailing-list address", m)])
                                 if r == d.DIALOG_OK:
                                     if t == "1" and m:
-                                        BMConfigParser().set(a, "mailinglist", "false")
+                                        config.set(a, "mailinglist", "false")
                                         if addresses[addrcur][1]:
                                             addresses[addrcur][3] = 0       # Set color to black
                                         else:
                                             addresses[addrcur][3] = 8       # Set color to gray
                                     elif t == "2" and m is False:
                                         try:
-                                            mn = BMConfigParser().get(a, "mailinglistname")
+                                            mn = config.get(a, "mailinglistname")
                                         except ConfigParser.NoOptionError:
                                             mn = ""
                                         r, t = d.inputbox("Mailing list name", init=mn)
                                         if r == d.DIALOG_OK:
                                             mn = t
-                                            BMConfigParser().set(a, "mailinglist", "true")
-                                            BMConfigParser().set(a, "mailinglistname", mn)
+                                            config.set(a, "mailinglist", "true")
+                                            config.set(a, "mailinglistname", mn)
                                             addresses[addrcur][3] = 6       # Set color to magenta
                                     # Write config
-                                    BMConfigParser().save()
+                                    config.save()
                 elif menutab == 5:
                     set_background_title(d, "Subscriptions Dialog Box")
                     if len(subscriptions) <= subcur:
@@ -1002,7 +1002,7 @@ def loadInbox():
             if toaddr == BROADCAST_STR:
                 tolabel = BROADCAST_STR
             else:
-                tolabel = BMConfigParser().get(toaddr, "label")
+                tolabel = config.get(toaddr, "label")
         except:  # noqa:E722
             tolabel = ""
         if tolabel == "":
@@ -1011,8 +1011,8 @@ def loadInbox():
 
         # Set label for from address
         fromlabel = ""
-        if BMConfigParser().has_section(fromaddr):
-            fromlabel = BMConfigParser().get(fromaddr, "label")
+        if config.has_section(fromaddr):
+            fromlabel = config.get(fromaddr, "label")
         if fromlabel == "":         # Check Address Book
             qr = sqlQuery("SELECT label FROM addressbook WHERE address=?", fromaddr)
             if qr != []:
@@ -1062,15 +1062,15 @@ def loadSent():
                 for r in qr:
                     tolabel, = r
         if tolabel == "":
-            if BMConfigParser().has_section(toaddr):
-                tolabel = BMConfigParser().get(toaddr, "label")
+            if config.has_section(toaddr):
+                tolabel = config.get(toaddr, "label")
         if tolabel == "":
             tolabel = toaddr
 
         # Set label for from address
         fromlabel = ""
-        if BMConfigParser().has_section(fromaddr):
-            fromlabel = BMConfigParser().get(fromaddr, "label")
+        if config.has_section(fromaddr):
+            fromlabel = config.get(fromaddr, "label")
         if fromlabel == "":
             fromlabel = fromaddr
 
@@ -1146,7 +1146,7 @@ def loadSubscriptions():
 def loadBlackWhiteList():
     """load black/white list"""
     global bwtype
-    bwtype = BMConfigParser().get("bitmessagesettings", "blackwhitelist")
+    bwtype = config.get("bitmessagesettings", "blackwhitelist")
     if bwtype == "black":
         ret = sqlQuery("SELECT label, address, enabled FROM blacklist")
     else:
@@ -1205,16 +1205,16 @@ def run(stdscr):
             curses.init_pair(9, curses.COLOR_YELLOW, curses.COLOR_BLACK)        # orangish
 
     # Init list of address in 'Your Identities' tab
-    configSections = BMConfigParser().addresses()
+    configSections = config.addresses()
     for addressInKeysFile in configSections:
-        isEnabled = BMConfigParser().getboolean(addressInKeysFile, "enabled")
-        addresses.append([BMConfigParser().get(addressInKeysFile, "label"), isEnabled, addressInKeysFile])
+        isEnabled = config.getboolean(addressInKeysFile, "enabled")
+        addresses.append([config.get(addressInKeysFile, "label"), isEnabled, addressInKeysFile])
         # Set address color
         if not isEnabled:
             addresses[len(addresses) - 1].append(8)         # gray
-        elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan'):
+        elif config.safeGetBoolean(addressInKeysFile, 'chan'):
             addresses[len(addresses) - 1].append(9)         # orange
-        elif BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist'):
+        elif config.safeGetBoolean(addressInKeysFile, 'mailinglist'):
             addresses[len(addresses) - 1].append(5)         # magenta
         else:
             addresses[len(addresses) - 1].append(0)         # black
diff --git a/src/bitmessagemain.py b/src/bitmessagemain.py
index e60813b3..4118926b 100755
--- a/src/bitmessagemain.py
+++ b/src/bitmessagemain.py
@@ -35,7 +35,7 @@ import shutdown
 import state
 
 from testmode_init import populate_api_test_data
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger  # this should go before any threads
 from helper_startup import (
     adjustHalfOpenConnectionsLimit, fixSocket, start_proxyconfig)
@@ -92,7 +92,6 @@ class Main(object):
         fixSocket()
         adjustHalfOpenConnectionsLimit()
 
-        config = BMConfigParser()
         daemon = config.safeGetBoolean('bitmessagesettings', 'daemon')
 
         try:
@@ -408,11 +407,11 @@ All parameters are optional.
     @staticmethod
     def getApiAddress():
         """This function returns API address and port"""
-        if not BMConfigParser().safeGetBoolean(
+        if not config.safeGetBoolean(
                 'bitmessagesettings', 'apienabled'):
             return None
-        address = BMConfigParser().get('bitmessagesettings', 'apiinterface')
-        port = BMConfigParser().getint('bitmessagesettings', 'apiport')
+        address = config.get('bitmessagesettings', 'apiinterface')
+        port = config.getint('bitmessagesettings', 'apiport')
         return {'address': address, 'port': port}
 
 
diff --git a/src/bitmessageqt/__init__.py b/src/bitmessageqt/__init__.py
index 6a692f38..98964a62 100644
--- a/src/bitmessageqt/__init__.py
+++ b/src/bitmessageqt/__init__.py
@@ -24,7 +24,7 @@ from debug import logger
 from tr import _translate
 from addresses import decodeAddress, addBMIfNotPresent
 from bitmessageui import Ui_MainWindow
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 import namecoin
 from messageview import MessageView
 from migrationwizard import Ui_MigrationWizard
@@ -516,11 +516,11 @@ class MyForm(settingsmixin.SMainWindow):
         enabled = {}
 
         for toAddress in getSortedAccounts():
-            isEnabled = BMConfigParser().getboolean(
+            isEnabled = config.getboolean(
                 toAddress, 'enabled')
-            isChan = BMConfigParser().safeGetBoolean(
+            isChan = config.safeGetBoolean(
                 toAddress, 'chan')
-            isMaillinglist = BMConfigParser().safeGetBoolean(
+            isMaillinglist = config.safeGetBoolean(
                 toAddress, 'mailinglist')
 
             if treeWidget == self.ui.treeWidgetYourIdentities:
@@ -639,8 +639,8 @@ class MyForm(settingsmixin.SMainWindow):
                 reply = QtGui.QMessageBox.question(
                     self, 'Message', displayMsg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
                 if reply == QtGui.QMessageBox.Yes:
-                    BMConfigParser().remove_section(addressInKeysFile)
-                    BMConfigParser().save()
+                    config.remove_section(addressInKeysFile)
+                    config.save()
 
         self.change_translation()
 
@@ -810,7 +810,7 @@ class MyForm(settingsmixin.SMainWindow):
         self.rerenderComboBoxSendFromBroadcast()
 
         # Put the TTL slider in the correct spot
-        TTL = BMConfigParser().getint('bitmessagesettings', 'ttl')
+        TTL = config.getint('bitmessagesettings', 'ttl')
         if TTL < 3600: # an hour
             TTL = 3600
         elif TTL > 28*24*60*60: # 28 days
@@ -830,7 +830,7 @@ class MyForm(settingsmixin.SMainWindow):
 
         self.ui.updateNetworkSwitchMenuLabel()
 
-        self._firstrun = BMConfigParser().safeGetBoolean(
+        self._firstrun = config.safeGetBoolean(
             'bitmessagesettings', 'dontconnect')
 
         self._contact_selected = None
@@ -849,7 +849,7 @@ class MyForm(settingsmixin.SMainWindow):
         Configure Bitmessage to start on startup (or remove the
         configuration) based on the setting in the keys.dat file
         """
-        startonlogon = BMConfigParser().safeGetBoolean(
+        startonlogon = config.safeGetBoolean(
             'bitmessagesettings', 'startonlogon')
         if sys.platform.startswith('win'):  # Auto-startup for Windows
             RUN_PATH = "HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Run"
@@ -871,8 +871,8 @@ class MyForm(settingsmixin.SMainWindow):
     def updateTTL(self, sliderPosition):
         TTL = int(sliderPosition ** 3.199 + 3600)
         self.updateHumanFriendlyTTLDescription(TTL)
-        BMConfigParser().set('bitmessagesettings', 'ttl', str(TTL))
-        BMConfigParser().save()
+        config.set('bitmessagesettings', 'ttl', str(TTL))
+        config.save()
 
     def updateHumanFriendlyTTLDescription(self, TTL):
         numberOfHours = int(round(TTL / (60*60)))
@@ -923,7 +923,7 @@ class MyForm(settingsmixin.SMainWindow):
             self.appIndicatorShowOrHideWindow()
 
     def appIndicatorSwitchQuietMode(self):
-        BMConfigParser().set(
+        config.set(
             'bitmessagesettings', 'showtraynotifications',
             str(not self.actionQuiet.isChecked())
         )
@@ -1294,7 +1294,7 @@ class MyForm(settingsmixin.SMainWindow):
         # show bitmessage
         self.actionShow = QtGui.QAction(_translate(
             "MainWindow", "Show Bitmessage"), m, checkable=True)
-        self.actionShow.setChecked(not BMConfigParser().getboolean(
+        self.actionShow.setChecked(not config.getboolean(
             'bitmessagesettings', 'startintray'))
         self.actionShow.triggered.connect(self.appIndicatorShowOrHideWindow)
         if not sys.platform[0:3] == 'win':
@@ -1303,7 +1303,7 @@ class MyForm(settingsmixin.SMainWindow):
         # quiet mode
         self.actionQuiet = QtGui.QAction(_translate(
             "MainWindow", "Quiet Mode"), m, checkable=True)
-        self.actionQuiet.setChecked(not BMConfigParser().getboolean(
+        self.actionQuiet.setChecked(not config.getboolean(
             'bitmessagesettings', 'showtraynotifications'))
         self.actionQuiet.triggered.connect(self.appIndicatorSwitchQuietMode)
         m.addAction(self.actionQuiet)
@@ -1647,9 +1647,9 @@ class MyForm(settingsmixin.SMainWindow):
         if dialog.exec_():
             if dialog.radioButtonConnectNow.isChecked():
                 self.ui.updateNetworkSwitchMenuLabel(False)
-                BMConfigParser().remove_option(
+                config.remove_option(
                     'bitmessagesettings', 'dontconnect')
-                BMConfigParser().save()
+                config.save()
             elif dialog.radioButtonConfigureNetwork.isChecked():
                 self.click_actionSettings()
             else:
@@ -1674,7 +1674,7 @@ class MyForm(settingsmixin.SMainWindow):
             self.ui.blackwhitelist.init_blacklist_popup_menu(False)
         if event.type() == QtCore.QEvent.WindowStateChange:
             if self.windowState() & QtCore.Qt.WindowMinimized:
-                if BMConfigParser().getboolean('bitmessagesettings', 'minimizetotray') and not 'darwin' in sys.platform:
+                if config.getboolean('bitmessagesettings', 'minimizetotray') and not 'darwin' in sys.platform:
                     QtCore.QTimer.singleShot(0, self.appIndicatorHide)
             elif event.oldState() & QtCore.Qt.WindowMinimized:
                 # The window state has just been changed to
@@ -1691,7 +1691,7 @@ class MyForm(settingsmixin.SMainWindow):
 
     def setStatusIcon(self, color):
         # print 'setting status icon color'
-        _notifications_enabled = not BMConfigParser().getboolean(
+        _notifications_enabled = not config.getboolean(
             'bitmessagesettings', 'hidetrayconnectionnotifications')
         if color == 'red':
             self.pushButtonStatusIcon.setIcon(
@@ -1703,8 +1703,8 @@ class MyForm(settingsmixin.SMainWindow):
                     'Bitmessage',
                     _translate("MainWindow", "Connection lost"),
                     sound.SOUND_DISCONNECTED)
-            if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp') and \
-                BMConfigParser().get('bitmessagesettings', 'socksproxytype') == "none":
+            if not config.safeGetBoolean('bitmessagesettings', 'upnp') and \
+                config.get('bitmessagesettings', 'socksproxytype') == "none":
                 self.updateStatusBar(
                     _translate(
                         "MainWindow",
@@ -1947,7 +1947,7 @@ class MyForm(settingsmixin.SMainWindow):
         addresses = getSortedAccounts()
         for address in addresses:
             account = accountClass(address)
-            if (account.type == AccountMixin.CHAN and BMConfigParser().safeGetBoolean(address, 'enabled')):
+            if (account.type == AccountMixin.CHAN and config.safeGetBoolean(address, 'enabled')):
                 newRows[address] = [account.getLabel(), AccountMixin.CHAN]
         # normal accounts
         queryreturn = sqlQuery('SELECT * FROM addressbook')
@@ -2065,9 +2065,9 @@ class MyForm(settingsmixin.SMainWindow):
                                 email = ''.join(random.SystemRandom().choice(string.ascii_lowercase) for _ in range(12)) + "@mailchuck.com"
                             acct = MailchuckAccount(fromAddress)
                             acct.register(email)
-                            BMConfigParser().set(fromAddress, 'label', email)
-                            BMConfigParser().set(fromAddress, 'gateway', 'mailchuck')
-                            BMConfigParser().save()
+                            config.set(fromAddress, 'label', email)
+                            config.set(fromAddress, 'gateway', 'mailchuck')
+                            config.save()
                             self.updateStatusBar(_translate(
                                 "MainWindow",
                                 "Error: Your account wasn't registered at"
@@ -2259,18 +2259,18 @@ class MyForm(settingsmixin.SMainWindow):
         self.ui.tabWidgetSend.setCurrentIndex(
             self.ui.tabWidgetSend.indexOf(
                 self.ui.sendBroadcast
-                if BMConfigParser().safeGetBoolean(str(address), 'mailinglist')
+                if config.safeGetBoolean(str(address), 'mailinglist')
                 else self.ui.sendDirect
             ))
 
     def rerenderComboBoxSendFrom(self):
         self.ui.comboBoxSendFrom.clear()
         for addressInKeysFile in getSortedAccounts():
-            isEnabled = BMConfigParser().getboolean(
+            isEnabled = config.getboolean(
                 addressInKeysFile, 'enabled')  # I realize that this is poor programming practice but I don't care. It's easier for others to read.
-            isMaillinglist = BMConfigParser().safeGetBoolean(addressInKeysFile, 'mailinglist')
+            isMaillinglist = config.safeGetBoolean(addressInKeysFile, 'mailinglist')
             if isEnabled and not isMaillinglist:
-                label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
+                label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
                 if label == "":
                     label = addressInKeysFile
                 self.ui.comboBoxSendFrom.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
@@ -2290,11 +2290,11 @@ class MyForm(settingsmixin.SMainWindow):
     def rerenderComboBoxSendFromBroadcast(self):
         self.ui.comboBoxSendFromBroadcast.clear()
         for addressInKeysFile in getSortedAccounts():
-            isEnabled = BMConfigParser().getboolean(
+            isEnabled = config.getboolean(
                 addressInKeysFile, 'enabled')  # I realize that this is poor programming practice but I don't care. It's easier for others to read.
-            isChan = BMConfigParser().safeGetBoolean(addressInKeysFile, 'chan')
+            isChan = config.safeGetBoolean(addressInKeysFile, 'chan')
             if isEnabled and not isChan:
-                label = unicode(BMConfigParser().get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
+                label = unicode(config.get(addressInKeysFile, 'label'), 'utf-8', 'ignore').strip()
                 if label == "":
                     label = addressInKeysFile
                 self.ui.comboBoxSendFromBroadcast.addItem(avatarize(addressInKeysFile), label, addressInKeysFile)
@@ -2395,7 +2395,7 @@ class MyForm(settingsmixin.SMainWindow):
         else:
             acct = ret
         self.propagateUnreadCount(widget=treeWidget if ret else None)
-        if BMConfigParser().safeGetBoolean(
+        if config.safeGetBoolean(
                 'bitmessagesettings', 'showtraynotifications'):
             self.notifierShow(
                 _translate("MainWindow", "New Message"),
@@ -2415,7 +2415,7 @@ class MyForm(settingsmixin.SMainWindow):
             if acct.feedback != GatewayAccount.ALL_OK:
                 if acct.feedback == GatewayAccount.REGISTRATION_DENIED:
                     dialogs.EmailGatewayDialog(
-                        self, BMConfigParser(), acct).exec_()
+                        self, config, acct).exec_()
                 # possible other branches?
         except AttributeError:
             pass
@@ -2497,7 +2497,7 @@ class MyForm(settingsmixin.SMainWindow):
                 ))
 
     def click_pushButtonStatusIcon(self):
-        dialogs.IconGlossaryDialog(self, config=BMConfigParser()).exec_()
+        dialogs.IconGlossaryDialog(self, config=config).exec_()
 
     def click_actionHelp(self):
         dialogs.HelpDialog(self).exec_()
@@ -2524,10 +2524,10 @@ class MyForm(settingsmixin.SMainWindow):
 
     def on_action_SpecialAddressBehaviorDialog(self):
         """Show SpecialAddressBehaviorDialog"""
-        dialogs.SpecialAddressBehaviorDialog(self, BMConfigParser())
+        dialogs.SpecialAddressBehaviorDialog(self, config)
 
     def on_action_EmailGatewayDialog(self):
-        dialog = dialogs.EmailGatewayDialog(self, config=BMConfigParser())
+        dialog = dialogs.EmailGatewayDialog(self, config=config)
         # For Modal dialogs
         dialog.exec_()
         try:
@@ -2589,7 +2589,7 @@ class MyForm(settingsmixin.SMainWindow):
         dialogs.NewAddressDialog(self)
 
     def network_switch(self):
-        dontconnect_option = not BMConfigParser().safeGetBoolean(
+        dontconnect_option = not config.safeGetBoolean(
             'bitmessagesettings', 'dontconnect')
         reply = QtGui.QMessageBox.question(
             self, _translate("MainWindow", "Disconnecting")
@@ -2604,9 +2604,9 @@ class MyForm(settingsmixin.SMainWindow):
             QtGui.QMessageBox.Cancel)
         if reply != QtGui.QMessageBox.Yes:
             return
-        BMConfigParser().set(
+        config.set(
             'bitmessagesettings', 'dontconnect', str(dontconnect_option))
-        BMConfigParser().save()
+        config.save()
         self.ui.updateNetworkSwitchMenuLabel(dontconnect_option)
 
         self.ui.pushButtonFetchNamecoinID.setHidden(
@@ -2668,7 +2668,7 @@ class MyForm(settingsmixin.SMainWindow):
             elif reply == QtGui.QMessageBox.Cancel:
                 return
 
-        if state.statusIconColor == 'red' and not BMConfigParser().safeGetBoolean(
+        if state.statusIconColor == 'red' and not config.safeGetBoolean(
                 'bitmessagesettings', 'dontconnect'):
             reply = QtGui.QMessageBox.question(
                 self, _translate("MainWindow", "Not connected"),
@@ -2804,7 +2804,7 @@ class MyForm(settingsmixin.SMainWindow):
     def closeEvent(self, event):
         """window close event"""
         event.ignore()
-        trayonclose = BMConfigParser().safeGetBoolean(
+        trayonclose = config.safeGetBoolean(
             'bitmessagesettings', 'trayonclose')
         if trayonclose:
             self.appIndicatorHide()
@@ -2873,7 +2873,7 @@ class MyForm(settingsmixin.SMainWindow):
 
     # Format predefined text on message reply.
     def quoted_text(self, message):
-        if not BMConfigParser().safeGetBoolean('bitmessagesettings', 'replybelow'):
+        if not config.safeGetBoolean('bitmessagesettings', 'replybelow'):
             return '\n\n------------------------------------------------------\n' + message
 
         quoteWrapper = textwrap.TextWrapper(
@@ -2960,7 +2960,7 @@ class MyForm(settingsmixin.SMainWindow):
                 self.ui.tabWidgetSend.indexOf(self.ui.sendDirect)
             )
 #            toAddressAtCurrentInboxRow = fromAddressAtCurrentInboxRow
-        elif not BMConfigParser().has_section(toAddressAtCurrentInboxRow):
+        elif not config.has_section(toAddressAtCurrentInboxRow):
             QtGui.QMessageBox.information(
                 self, _translate("MainWindow", "Address is gone"),
                 _translate(
@@ -2968,7 +2968,7 @@ class MyForm(settingsmixin.SMainWindow):
                     "Bitmessage cannot find your address %1. Perhaps you"
                     " removed it?"
                 ).arg(toAddressAtCurrentInboxRow), QtGui.QMessageBox.Ok)
-        elif not BMConfigParser().getboolean(
+        elif not config.getboolean(
                 toAddressAtCurrentInboxRow, 'enabled'):
             QtGui.QMessageBox.information(
                 self, _translate("MainWindow", "Address disabled"),
@@ -3058,7 +3058,8 @@ class MyForm(settingsmixin.SMainWindow):
         queryreturn = sqlQuery('''select * from blacklist where address=?''',
                                addressAtCurrentInboxRow)
         if queryreturn == []:
-            label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + BMConfigParser().get(recipientAddress, "label")
+            label = "\"" + tableWidget.item(currentInboxRow, 2).subject + "\" in " + config.get(
+                recipientAddress, "label")
             sqlExecute('''INSERT INTO blacklist VALUES (?,?, ?)''',
                        label,
                        addressAtCurrentInboxRow, True)
@@ -3575,12 +3576,12 @@ class MyForm(settingsmixin.SMainWindow):
                         " delete the channel?"
                     ), QtGui.QMessageBox.Yes | QtGui.QMessageBox.No
             ) == QtGui.QMessageBox.Yes:
-                BMConfigParser().remove_section(str(account.address))
+                config.remove_section(str(account.address))
             else:
                 return
         else:
             return
-        BMConfigParser().save()
+        config.save()
         shared.reloadMyAddressHashes()
         self.rerenderAddressBook()
         self.rerenderComboBoxSendFrom()
@@ -3596,8 +3597,8 @@ class MyForm(settingsmixin.SMainWindow):
         account.setEnabled(True)
 
     def enableIdentity(self, address):
-        BMConfigParser().set(address, 'enabled', 'true')
-        BMConfigParser().save()
+        config.set(address, 'enabled', 'true')
+        config.save()
         shared.reloadMyAddressHashes()
         self.rerenderAddressBook()
 
@@ -3608,8 +3609,8 @@ class MyForm(settingsmixin.SMainWindow):
         account.setEnabled(False)
 
     def disableIdentity(self, address):
-        BMConfigParser().set(str(address), 'enabled', 'false')
-        BMConfigParser().save()
+        config.set(str(address), 'enabled', 'false')
+        config.save()
         shared.reloadMyAddressHashes()
         self.rerenderAddressBook()
 
@@ -4092,7 +4093,7 @@ class MyForm(settingsmixin.SMainWindow):
 
         # Check to see whether we can connect to namecoin.
         # Hide the 'Fetch Namecoin ID' button if we can't.
-        if BMConfigParser().safeGetBoolean(
+        if config.safeGetBoolean(
             'bitmessagesettings', 'dontconnect'
         ) or self.namecoin.test()[0] == 'failed':
             logger.warning(
@@ -4191,13 +4192,13 @@ def run():
         myapp.showConnectDialog()  # ask the user if we may connect
 
 #    try:
-#        if BMConfigParser().get('bitmessagesettings', 'mailchuck') < 1:
-#            myapp.showMigrationWizard(BMConfigParser().get('bitmessagesettings', 'mailchuck'))
+#        if config.get('bitmessagesettings', 'mailchuck') < 1:
+#            myapp.showMigrationWizard(config.get('bitmessagesettings', 'mailchuck'))
 #    except:
 #        myapp.showMigrationWizard(0)
 
     # only show after wizards and connect dialogs have completed
-    if not BMConfigParser().getboolean('bitmessagesettings', 'startintray'):
+    if not config.getboolean('bitmessagesettings', 'startintray'):
         myapp.show()
 
     app.exec_()
diff --git a/src/bitmessageqt/account.py b/src/bitmessageqt/account.py
index 50ea3548..092b4d45 100644
--- a/src/bitmessageqt/account.py
+++ b/src/bitmessageqt/account.py
@@ -18,7 +18,7 @@ from PyQt4 import QtGui
 
 import queues
 from addresses import decodeAddress
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_ackPayload import genAckPayload
 from helper_sql import sqlQuery, sqlExecute
 from .foldertree import AccountMixin
@@ -28,16 +28,16 @@ from .utils import str_broadcast_subscribers
 def getSortedAccounts():
     """Get a sorted list of configSections"""
 
-    configSections = BMConfigParser().addresses()
+    configSections = config.addresses()
     configSections.sort(
         cmp=lambda x, y: cmp(
             unicode(
-                BMConfigParser().get(
+                config.get(
                     x,
                     'label'),
                 'utf-8').lower(),
             unicode(
-                BMConfigParser().get(
+                config.get(
                     y,
                     'label'),
                 'utf-8').lower()))
@@ -80,7 +80,7 @@ def getSortedSubscriptions(count=False):
 
 def accountClass(address):
     """Return a BMAccount for the address"""
-    if not BMConfigParser().has_section(address):
+    if not config.has_section(address):
         # .. todo:: This BROADCAST section makes no sense
         if address == str_broadcast_subscribers:
             subscription = BroadcastAccount(address)
@@ -93,7 +93,7 @@ def accountClass(address):
                 return NoAccount(address)
         return subscription
     try:
-        gateway = BMConfigParser().get(address, "gateway")
+        gateway = config.get(address, "gateway")
         for _, cls in inspect.getmembers(sys.modules[__name__], inspect.isclass):
             if issubclass(cls, GatewayAccount) and cls.gatewayName == gateway:
                 return cls(address)
@@ -114,9 +114,9 @@ class AccountColor(AccountMixin):  # pylint: disable=too-few-public-methods
         if address_type is None:
             if address is None:
                 self.type = AccountMixin.ALL
-            elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
+            elif config.safeGetBoolean(self.address, 'mailinglist'):
                 self.type = AccountMixin.MAILINGLIST
-            elif BMConfigParser().safeGetBoolean(self.address, 'chan'):
+            elif config.safeGetBoolean(self.address, 'chan'):
                 self.type = AccountMixin.CHAN
             elif sqlQuery(
                     '''select label from subscriptions where address=?''', self.address):
@@ -133,10 +133,10 @@ class BMAccount(object):
     def __init__(self, address=None):
         self.address = address
         self.type = AccountMixin.NORMAL
-        if BMConfigParser().has_section(address):
-            if BMConfigParser().safeGetBoolean(self.address, 'chan'):
+        if config.has_section(address):
+            if config.safeGetBoolean(self.address, 'chan'):
                 self.type = AccountMixin.CHAN
-            elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
+            elif config.safeGetBoolean(self.address, 'mailinglist'):
                 self.type = AccountMixin.MAILINGLIST
         elif self.address == str_broadcast_subscribers:
             self.type = AccountMixin.BROADCAST
@@ -150,7 +150,7 @@ class BMAccount(object):
         """Get a label for this bitmessage account"""
         if address is None:
             address = self.address
-        label = BMConfigParser().safeGet(address, 'label', address)
+        label = config.safeGet(address, 'label', address)
         queryreturn = sqlQuery(
             '''select label from addressbook where address=?''', address)
         if queryreturn != []:
@@ -216,7 +216,7 @@ class GatewayAccount(BMAccount):
 
         # pylint: disable=unused-variable
         status, addressVersionNumber, streamNumber, ripe = decodeAddress(self.toAddress)
-        stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
+        stealthLevel = config.safeGetInt('bitmessagesettings', 'ackstealthlevel')
         ackdata = genAckPayload(streamNumber, stealthLevel)
         sqlExecute(
             '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
@@ -235,7 +235,7 @@ class GatewayAccount(BMAccount):
             'sent',  # folder
             2,  # encodingtype
             # not necessary to have a TTL higher than 2 days
-            min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2)
+            min(config.getint('bitmessagesettings', 'ttl'), 86400 * 2)
         )
 
         queues.workerQueue.put(('sendmessage', self.toAddress))
diff --git a/src/bitmessageqt/bitmessageui.py b/src/bitmessageqt/bitmessageui.py
index 7f2c8c91..f5d61d1c 100644
--- a/src/bitmessageqt/bitmessageui.py
+++ b/src/bitmessageqt/bitmessageui.py
@@ -8,7 +8,7 @@
 # WARNING! All changes made in this file will be lost!
 
 from PyQt4 import QtCore, QtGui
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from foldertree import AddressBookCompleter
 from messageview import MessageView
 from messagecompose import MessageCompose
@@ -561,7 +561,7 @@ class Ui_MainWindow(object):
         self.blackwhitelist = Blacklist()
         self.tabWidget.addTab(self.blackwhitelist, QtGui.QIcon(":/newPrefix/images/blacklist.png"), "")
         # Initialize the Blacklist or Whitelist
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'white':
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'white':
             self.blackwhitelist.radioButtonWhitelist.click()
         self.blackwhitelist.rerenderBlackWhiteList()
 
@@ -663,7 +663,7 @@ class Ui_MainWindow(object):
 
     def updateNetworkSwitchMenuLabel(self, dontconnect=None):
         if dontconnect is None:
-            dontconnect = BMConfigParser().safeGetBoolean(
+            dontconnect = config.safeGetBoolean(
                 'bitmessagesettings', 'dontconnect')
         self.actionNetworkSwitch.setText(
             _translate("MainWindow", "Go online", None)
@@ -710,7 +710,7 @@ class Ui_MainWindow(object):
         self.pushButtonTTL.setText(_translate("MainWindow", "TTL:", None))
         hours = 48
         try:
-            hours = int(BMConfigParser().getint('bitmessagesettings', 'ttl')/60/60)
+            hours = int(config.getint('bitmessagesettings', 'ttl')/60/60)
         except:
             pass
         self.labelHumanFriendlyTTLDescription.setText(_translate("MainWindow", "%n hour(s)", None, QtCore.QCoreApplication.CodecForTr, hours))
diff --git a/src/bitmessageqt/blacklist.py b/src/bitmessageqt/blacklist.py
index 3897bddc..093f23d8 100644
--- a/src/bitmessageqt/blacklist.py
+++ b/src/bitmessageqt/blacklist.py
@@ -2,7 +2,7 @@ from PyQt4 import QtCore, QtGui
 
 import widgets
 from addresses import addBMIfNotPresent
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from dialogs import AddAddressDialog
 from helper_sql import sqlExecute, sqlQuery
 from queues import UISignalQueue
@@ -39,17 +39,17 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
             "rerenderBlackWhiteList()"), self.rerenderBlackWhiteList)
 
     def click_radioButtonBlacklist(self):
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'white':
-            BMConfigParser().set('bitmessagesettings', 'blackwhitelist', 'black')
-            BMConfigParser().save()
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'white':
+            config.set('bitmessagesettings', 'blackwhitelist', 'black')
+            config.save()
             # self.tableWidgetBlacklist.clearContents()
             self.tableWidgetBlacklist.setRowCount(0)
             self.rerenderBlackWhiteList()
 
     def click_radioButtonWhitelist(self):
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
-            BMConfigParser().set('bitmessagesettings', 'blackwhitelist', 'white')
-            BMConfigParser().save()
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
+            config.set('bitmessagesettings', 'blackwhitelist', 'white')
+            config.save()
             # self.tableWidgetBlacklist.clearContents()
             self.tableWidgetBlacklist.setRowCount(0)
             self.rerenderBlackWhiteList()
@@ -65,7 +65,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
                 # address book. The user cannot add it again or else it will
                 # cause problems when updating and deleting the entry.
                 t = (address,)
-                if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+                if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
                     sql = '''select * from blacklist where address=?'''
                 else:
                     sql = '''select * from whitelist where address=?'''
@@ -83,7 +83,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
                     self.tableWidgetBlacklist.setItem(0, 1, newItem)
                     self.tableWidgetBlacklist.setSortingEnabled(True)
                     t = (str(self.NewBlacklistDialogInstance.lineEditLabel.text().toUtf8()), address, True)
-                    if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+                    if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
                         sql = '''INSERT INTO blacklist VALUES (?,?,?)'''
                     else:
                         sql = '''INSERT INTO whitelist VALUES (?,?,?)'''
@@ -158,12 +158,12 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
 
     def rerenderBlackWhiteList(self):
         tabs = self.parent().parent()
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
             tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Blacklist'))
         else:
             tabs.setTabText(tabs.indexOf(self), _translate('blacklist', 'Whitelist'))
         self.tableWidgetBlacklist.setRowCount(0)
-        listType = BMConfigParser().get('bitmessagesettings', 'blackwhitelist')
+        listType = config.get('bitmessagesettings', 'blackwhitelist')
         if listType == 'black':
             queryreturn = sqlQuery('''SELECT label, address, enabled FROM blacklist''')
         else:
@@ -195,7 +195,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
             currentRow, 0).text().toUtf8()
         addressAtCurrentRow = self.tableWidgetBlacklist.item(
             currentRow, 1).text()
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
             sqlExecute(
                 '''DELETE FROM blacklist WHERE label=? AND address=?''',
                 str(labelAtCurrentRow), str(addressAtCurrentRow))
@@ -224,7 +224,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
             currentRow, 0).setTextColor(QtGui.QApplication.palette().text().color())
         self.tableWidgetBlacklist.item(
             currentRow, 1).setTextColor(QtGui.QApplication.palette().text().color())
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
             sqlExecute(
                 '''UPDATE blacklist SET enabled=1 WHERE address=?''',
                 str(addressAtCurrentRow))
@@ -241,7 +241,7 @@ class Blacklist(QtGui.QWidget, RetranslateMixin):
             currentRow, 0).setTextColor(QtGui.QColor(128, 128, 128))
         self.tableWidgetBlacklist.item(
             currentRow, 1).setTextColor(QtGui.QColor(128, 128, 128))
-        if BMConfigParser().get('bitmessagesettings', 'blackwhitelist') == 'black':
+        if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
             sqlExecute(
                 '''UPDATE blacklist SET enabled=0 WHERE address=?''', str(addressAtCurrentRow))
         else:
diff --git a/src/bitmessageqt/foldertree.py b/src/bitmessageqt/foldertree.py
index e6d64427..c50b7d3d 100644
--- a/src/bitmessageqt/foldertree.py
+++ b/src/bitmessageqt/foldertree.py
@@ -8,7 +8,7 @@ from cgi import escape
 
 from PyQt4 import QtCore, QtGui
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute, sqlQuery
 from settingsmixin import SettingsMixin
 from tr import _translate
@@ -106,9 +106,9 @@ class AccountMixin(object):
         if self.address is None:
             self.type = self.ALL
             self.setFlags(self.flags() & ~QtCore.Qt.ItemIsEditable)
-        elif BMConfigParser().safeGetBoolean(self.address, 'chan'):
+        elif config.safeGetBoolean(self.address, 'chan'):
             self.type = self.CHAN
-        elif BMConfigParser().safeGetBoolean(self.address, 'mailinglist'):
+        elif config.safeGetBoolean(self.address, 'mailinglist'):
             self.type = self.MAILINGLIST
         elif sqlQuery(
                 '''select label from subscriptions where address=?''', self.address):
@@ -125,7 +125,7 @@ class AccountMixin(object):
                 AccountMixin.CHAN, AccountMixin.MAILINGLIST):
             try:
                 retval = unicode(
-                    BMConfigParser().get(self.address, 'label'), 'utf-8')
+                    config.get(self.address, 'label'), 'utf-8')
             except Exception:
                 queryreturn = sqlQuery(
                     '''select label from addressbook where address=?''', self.address)
@@ -237,7 +237,7 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
         else:
             try:
                 return unicode(
-                    BMConfigParser().get(self.address, 'label'),
+                    config.get(self.address, 'label'),
                     'utf-8', 'ignore')
             except:
                 return unicode(self.address, 'utf-8')
@@ -263,13 +263,13 @@ class Ui_AddressWidget(BMTreeWidgetItem, SettingsMixin):
         """Save account label (if you edit in the the UI, this will be triggered and will save it to keys.dat)"""
         if role == QtCore.Qt.EditRole \
                 and self.type != AccountMixin.SUBSCRIPTION:
-            BMConfigParser().set(
+            config.set(
                 str(self.address), 'label',
                 str(value.toString().toUtf8())
                 if isinstance(value, QtCore.QVariant)
                 else value.encode('utf-8')
             )
-            BMConfigParser().save()
+            config.save()
         return super(Ui_AddressWidget, self).setData(column, role, value)
 
     def setAddress(self, address):
@@ -382,7 +382,7 @@ class BMAddressWidget(BMTableWidgetItem, AccountMixin):
         if role == QtCore.Qt.ToolTipRole:
             return self.label + " (" + self.address + ")"
         elif role == QtCore.Qt.DecorationRole:
-            if BMConfigParser().safeGetBoolean(
+            if config.safeGetBoolean(
                     'bitmessagesettings', 'useidenticons'):
                 return avatarize(self.address or self.label)
         elif role == QtCore.Qt.ForegroundRole:
@@ -408,7 +408,7 @@ class MessageList_AddressWidget(BMAddressWidget):
                 AccountMixin.CHAN, AccountMixin.MAILINGLIST):
             try:
                 newLabel = unicode(
-                    BMConfigParser().get(self.address, 'label'),
+                    config.get(self.address, 'label'),
                     'utf-8', 'ignore')
             except:
                 queryreturn = sqlQuery(
@@ -521,9 +521,9 @@ class Ui_AddressBookWidgetItem(BMAddressWidget):
                     AccountMixin.NORMAL,
                     AccountMixin.MAILINGLIST, AccountMixin.CHAN):
                 try:
-                    BMConfigParser().get(self.address, 'label')
-                    BMConfigParser().set(self.address, 'label', self.label)
-                    BMConfigParser().save()
+                    config.get(self.address, 'label')
+                    config.set(self.address, 'label', self.label)
+                    config.save()
                 except:
                     sqlExecute('''UPDATE addressbook set label=? WHERE address=?''', self.label, self.address)
             elif self.type == AccountMixin.SUBSCRIPTION:
diff --git a/src/bitmessageqt/languagebox.py b/src/bitmessageqt/languagebox.py
index 9ff78990..34f96b02 100644
--- a/src/bitmessageqt/languagebox.py
+++ b/src/bitmessageqt/languagebox.py
@@ -6,7 +6,7 @@ import os
 from PyQt4 import QtCore, QtGui
 
 import paths
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 
 
 class LanguageBox(QtGui.QComboBox):
@@ -41,7 +41,7 @@ class LanguageBox(QtGui.QComboBox):
                 self.addItem(
                     locale.nativeLanguageName() or localeShort, localeShort)
 
-        configuredLocale = BMConfigParser().safeGet(
+        configuredLocale = config.safeGet(
             'bitmessagesettings', 'userlocale', "system")
         for i in range(self.count()):
             if self.itemData(i) == configuredLocale:
diff --git a/src/bitmessageqt/settings.py b/src/bitmessageqt/settings.py
index 4173ebd2..501b2114 100644
--- a/src/bitmessageqt/settings.py
+++ b/src/bitmessageqt/settings.py
@@ -16,7 +16,7 @@ import paths
 import queues
 import state
 import widgets
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute, sqlStoredProcedure
 from helper_startup import start_proxyconfig
 from network import knownnodes, AnnounceThread
@@ -24,11 +24,11 @@ from network.asyncore_pollchoose import set_rates
 from tr import _translate
 
 
-def getSOCKSProxyType(config):
+def getSOCKSProxyType(config_):
     """Get user socksproxytype setting from *config*"""
     try:
         result = ConfigParser.SafeConfigParser.get(
-            config, 'bitmessagesettings', 'socksproxytype')
+            config_, 'bitmessagesettings', 'socksproxytype')
     except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
         return None
     else:
@@ -45,7 +45,7 @@ class SettingsDialog(QtGui.QDialog):
 
         self.parent = parent
         self.firstrun = firstrun
-        self.config = BMConfigParser()
+        self.config = config
         self.net_restart_needed = False
         self.timer = QtCore.QTimer()
 
@@ -80,7 +80,7 @@ class SettingsDialog(QtGui.QDialog):
             )
         QtGui.QWidget.resize(self, QtGui.QWidget.sizeHint(self))
 
-    def adjust_from_config(self, config):
+    def adjust_from_config(self, config_):
         """Adjust all widgets state according to config settings"""
         # pylint: disable=too-many-branches,too-many-statements
         if not self.parent.tray.isSystemTrayAvailable():
@@ -89,31 +89,31 @@ class SettingsDialog(QtGui.QDialog):
                 "MainWindow", "Tray (not available in your system)"))
             for setting in (
                     'minimizetotray', 'trayonclose', 'startintray'):
-                config.set('bitmessagesettings', setting, 'false')
+                config_.set('bitmessagesettings', setting, 'false')
         else:
             self.checkBoxMinimizeToTray.setChecked(
-                config.getboolean('bitmessagesettings', 'minimizetotray'))
+                config_.getboolean('bitmessagesettings', 'minimizetotray'))
             self.checkBoxTrayOnClose.setChecked(
-                config.safeGetBoolean('bitmessagesettings', 'trayonclose'))
+                config_.safeGetBoolean('bitmessagesettings', 'trayonclose'))
             self.checkBoxStartInTray.setChecked(
-                config.getboolean('bitmessagesettings', 'startintray'))
+                config_.getboolean('bitmessagesettings', 'startintray'))
 
         self.checkBoxHideTrayConnectionNotifications.setChecked(
-            config.getboolean(
+            config_.getboolean(
                 'bitmessagesettings', 'hidetrayconnectionnotifications'))
         self.checkBoxShowTrayNotifications.setChecked(
-            config.getboolean('bitmessagesettings', 'showtraynotifications'))
+            config_.getboolean('bitmessagesettings', 'showtraynotifications'))
 
         self.checkBoxStartOnLogon.setChecked(
-            config.getboolean('bitmessagesettings', 'startonlogon'))
+            config_.getboolean('bitmessagesettings', 'startonlogon'))
 
         self.checkBoxWillinglySendToMobile.setChecked(
-            config.safeGetBoolean(
+            config_.safeGetBoolean(
                 'bitmessagesettings', 'willinglysendtomobile'))
         self.checkBoxUseIdenticons.setChecked(
-            config.safeGetBoolean('bitmessagesettings', 'useidenticons'))
+            config_.safeGetBoolean('bitmessagesettings', 'useidenticons'))
         self.checkBoxReplyBelow.setChecked(
-            config.safeGetBoolean('bitmessagesettings', 'replybelow'))
+            config_.safeGetBoolean('bitmessagesettings', 'replybelow'))
 
         if state.appdata == paths.lookupExeFolder():
             self.checkBoxPortableMode.setChecked(True)
@@ -142,57 +142,57 @@ class SettingsDialog(QtGui.QDialog):
 
         # On the Network settings tab:
         self.lineEditTCPPort.setText(str(
-            config.get('bitmessagesettings', 'port')))
+            config_.get('bitmessagesettings', 'port')))
         self.checkBoxUPnP.setChecked(
-            config.safeGetBoolean('bitmessagesettings', 'upnp'))
+            config_.safeGetBoolean('bitmessagesettings', 'upnp'))
         self.checkBoxUDP.setChecked(
-            config.safeGetBoolean('bitmessagesettings', 'udp'))
+            config_.safeGetBoolean('bitmessagesettings', 'udp'))
         self.checkBoxAuthentication.setChecked(
-            config.getboolean('bitmessagesettings', 'socksauthentication'))
+            config_.getboolean('bitmessagesettings', 'socksauthentication'))
         self.checkBoxSocksListen.setChecked(
-            config.getboolean('bitmessagesettings', 'sockslisten'))
+            config_.getboolean('bitmessagesettings', 'sockslisten'))
         self.checkBoxOnionOnly.setChecked(
-            config.safeGetBoolean('bitmessagesettings', 'onionservicesonly'))
+            config_.safeGetBoolean('bitmessagesettings', 'onionservicesonly'))
 
-        self._proxy_type = getSOCKSProxyType(config)
+        self._proxy_type = getSOCKSProxyType(config_)
         self.comboBoxProxyType.setCurrentIndex(
             0 if not self._proxy_type
             else self.comboBoxProxyType.findText(self._proxy_type))
         self.comboBoxProxyTypeChanged(self.comboBoxProxyType.currentIndex())
 
         self.lineEditSocksHostname.setText(
-            config.get('bitmessagesettings', 'sockshostname'))
+            config_.get('bitmessagesettings', 'sockshostname'))
         self.lineEditSocksPort.setText(str(
-            config.get('bitmessagesettings', 'socksport')))
+            config_.get('bitmessagesettings', 'socksport')))
         self.lineEditSocksUsername.setText(
-            config.get('bitmessagesettings', 'socksusername'))
+            config_.get('bitmessagesettings', 'socksusername'))
         self.lineEditSocksPassword.setText(
-            config.get('bitmessagesettings', 'sockspassword'))
+            config_.get('bitmessagesettings', 'sockspassword'))
 
         self.lineEditMaxDownloadRate.setText(str(
-            config.get('bitmessagesettings', 'maxdownloadrate')))
+            config_.get('bitmessagesettings', 'maxdownloadrate')))
         self.lineEditMaxUploadRate.setText(str(
-            config.get('bitmessagesettings', 'maxuploadrate')))
+            config_.get('bitmessagesettings', 'maxuploadrate')))
         self.lineEditMaxOutboundConnections.setText(str(
-            config.get('bitmessagesettings', 'maxoutboundconnections')))
+            config_.get('bitmessagesettings', 'maxoutboundconnections')))
 
         # Demanded difficulty tab
         self.lineEditTotalDifficulty.setText(str((float(
-            config.getint(
+            config_.getint(
                 'bitmessagesettings', 'defaultnoncetrialsperbyte')
         ) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte)))
         self.lineEditSmallMessageDifficulty.setText(str((float(
-            config.getint(
+            config_.getint(
                 'bitmessagesettings', 'defaultpayloadlengthextrabytes')
         ) / defaults.networkDefaultPayloadLengthExtraBytes)))
 
         # Max acceptable difficulty tab
         self.lineEditMaxAcceptableTotalDifficulty.setText(str((float(
-            config.getint(
+            config_.getint(
                 'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
         ) / defaults.networkDefaultProofOfWorkNonceTrialsPerByte)))
         self.lineEditMaxAcceptableSmallMessageDifficulty.setText(str((float(
-            config.getint(
+            config_.getint(
                 'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')
         ) / defaults.networkDefaultPayloadLengthExtraBytes)))
 
@@ -203,21 +203,21 @@ class SettingsDialog(QtGui.QDialog):
         self.comboBoxOpenCL.addItems(openclpow.vendors)
         self.comboBoxOpenCL.setCurrentIndex(0)
         for i in range(self.comboBoxOpenCL.count()):
-            if self.comboBoxOpenCL.itemText(i) == config.safeGet(
+            if self.comboBoxOpenCL.itemText(i) == config_.safeGet(
                     'bitmessagesettings', 'opencl'):
                 self.comboBoxOpenCL.setCurrentIndex(i)
                 break
 
         # Namecoin integration tab
-        nmctype = config.get('bitmessagesettings', 'namecoinrpctype')
+        nmctype = config_.get('bitmessagesettings', 'namecoinrpctype')
         self.lineEditNamecoinHost.setText(
-            config.get('bitmessagesettings', 'namecoinrpchost'))
+            config_.get('bitmessagesettings', 'namecoinrpchost'))
         self.lineEditNamecoinPort.setText(str(
-            config.get('bitmessagesettings', 'namecoinrpcport')))
+            config_.get('bitmessagesettings', 'namecoinrpcport')))
         self.lineEditNamecoinUser.setText(
-            config.get('bitmessagesettings', 'namecoinrpcuser'))
+            config_.get('bitmessagesettings', 'namecoinrpcuser'))
         self.lineEditNamecoinPassword.setText(
-            config.get('bitmessagesettings', 'namecoinrpcpassword'))
+            config_.get('bitmessagesettings', 'namecoinrpcpassword'))
 
         if nmctype == "namecoind":
             self.radioButtonNamecoinNamecoind.setChecked(True)
@@ -232,9 +232,9 @@ class SettingsDialog(QtGui.QDialog):
 
         # Message Resend tab
         self.lineEditDays.setText(str(
-            config.get('bitmessagesettings', 'stopresendingafterxdays')))
+            config_.get('bitmessagesettings', 'stopresendingafterxdays')))
         self.lineEditMonths.setText(str(
-            config.get('bitmessagesettings', 'stopresendingafterxmonths')))
+            config_.get('bitmessagesettings', 'stopresendingafterxmonths')))
 
     def comboBoxProxyTypeChanged(self, comboBoxIndex):
         """A callback for currentIndexChanged event of comboBoxProxyType"""
diff --git a/src/bitmessageqt/support.py b/src/bitmessageqt/support.py
index ac02e2ca..865d79c4 100644
--- a/src/bitmessageqt/support.py
+++ b/src/bitmessageqt/support.py
@@ -15,7 +15,7 @@ import paths
 import proofofwork
 import queues
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from foldertree import AccountMixin
 from helper_sql import sqlExecute, sqlQuery
 from l10n import getTranslationLanguage
@@ -79,7 +79,7 @@ def checkAddressBook(myapp):
 def checkHasNormalAddress():
     for address in account.getSortedAccounts():
         acct = account.accountClass(address)
-        if acct.type == AccountMixin.NORMAL and BMConfigParser().safeGetBoolean(address, 'enabled'):
+        if acct.type == AccountMixin.NORMAL and config.safeGetBoolean(address, 'enabled'):
             return address
     return False
 
@@ -142,11 +142,11 @@ def createSupportMessage(myapp):
     portablemode = "True" if state.appdata == paths.lookupExeFolder() else "False"
     cpow = "True" if proofofwork.bmpow else "False"
     openclpow = str(
-        BMConfigParser().safeGet('bitmessagesettings', 'opencl')
+        config.safeGet('bitmessagesettings', 'opencl')
     ) if openclEnabled() else "None"
     locale = getTranslationLanguage()
-    socks = getSOCKSProxyType(BMConfigParser()) or "N/A"
-    upnp = BMConfigParser().safeGet('bitmessagesettings', 'upnp', "N/A")
+    socks = getSOCKSProxyType(config) or "N/A"
+    upnp = config.safeGet('bitmessagesettings', 'upnp', "N/A")
     connectedhosts = len(network.stats.connectedHostsList())
 
     myapp.ui.textEditMessage.setText(unicode(SUPPORT_MESSAGE, 'utf-8').format(
diff --git a/src/bitmessageqt/tests/settings.py b/src/bitmessageqt/tests/settings.py
index c0708b5c..0dcf8cf3 100644
--- a/src/bitmessageqt/tests/settings.py
+++ b/src/bitmessageqt/tests/settings.py
@@ -2,7 +2,7 @@ import threading
 import time
 
 from main import TestBase
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from bitmessageqt import settings
 
 
@@ -14,14 +14,14 @@ class TestSettings(TestBase):
 
     def test_udp(self):
         """Test the effect of checkBoxUDP"""
-        udp_setting = BMConfigParser().safeGetBoolean(
+        udp_setting = config.safeGetBoolean(
             'bitmessagesettings', 'udp')
         self.assertEqual(udp_setting, self.dialog.checkBoxUDP.isChecked())
         self.dialog.checkBoxUDP.setChecked(not udp_setting)
         self.dialog.accept()
         self.assertEqual(
             not udp_setting,
-            BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
+            config.safeGetBoolean('bitmessagesettings', 'udp'))
         time.sleep(5)
         for thread in threading.enumerate():
             if thread.name == 'Announcer':  # find Announcer thread
diff --git a/src/bitmessageqt/utils.py b/src/bitmessageqt/utils.py
index e118f487..9f849b3b 100644
--- a/src/bitmessageqt/utils.py
+++ b/src/bitmessageqt/utils.py
@@ -5,7 +5,7 @@ from PyQt4 import QtGui
 
 import state
 from addresses import addBMIfNotPresent
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 
 str_broadcast_subscribers = '[Broadcast subscribers]'
 str_chan = '[chan]'
@@ -14,14 +14,14 @@ str_chan = '[chan]'
 def identiconize(address):
     size = 48
 
-    if not BMConfigParser().getboolean('bitmessagesettings', 'useidenticons'):
+    if not config.getboolean('bitmessagesettings', 'useidenticons'):
         return QtGui.QIcon()
 
     # If you include another identicon library, please generate an
     # example identicon with the following md5 hash:
     # 3fd4bf901b9d4ea1394f0fb358725b28
 
-    identicon_lib = BMConfigParser().safeGet(
+    identicon_lib = config.safeGet(
         'bitmessagesettings', 'identiconlib', 'qidenticon_two_x')
 
     # As an 'identiconsuffix' you could put "@bitmessge.ch" or "@bm.addr"
@@ -30,7 +30,7 @@ def identiconize(address):
     # It can be used as a pseudo-password to salt the generation of
     # the identicons to decrease the risk of attacks where someone creates
     # an address to mimic someone else's identicon.
-    identiconsuffix = BMConfigParser().get('bitmessagesettings', 'identiconsuffix')
+    identiconsuffix = config.get('bitmessagesettings', 'identiconsuffix')
     if identicon_lib[:len('qidenticon')] == 'qidenticon':
         # originally by:
         # :Author:Shin Adachi <shn@glucose.jp>
diff --git a/src/bmconfigparser.py b/src/bmconfigparser.py
index 8bc425c8..312a6f97 100644
--- a/src/bmconfigparser.py
+++ b/src/bmconfigparser.py
@@ -5,6 +5,7 @@ BMConfigParser class definition and default configuration settings
 import os
 import shutil
 import sys  # FIXME: bad style! write more generally
+from threading import Event
 from datetime import datetime
 
 from six import string_types
@@ -12,47 +13,13 @@ from six.moves import configparser
 
 try:
     import state
-    from singleton import Singleton
 except ImportError:
     from pybitmessage import state
-    from pybitmessage.singleton import Singleton
 
 SafeConfigParser = configparser.SafeConfigParser
+config_ready = Event()
 
 
-BMConfigDefaults = {
-    "bitmessagesettings": {
-        "maxaddrperstreamsend": 500,
-        "maxbootstrapconnections": 20,
-        "maxdownloadrate": 0,
-        "maxoutboundconnections": 8,
-        "maxtotalconnections": 200,
-        "maxuploadrate": 0,
-        "apiinterface": "127.0.0.1",
-        "apiport": 8442,
-        "udp": "True"
-    },
-    "threads": {
-        "receive": 3,
-    },
-    "network": {
-        "bind": "",
-        "dandelion": 90,
-    },
-    "inventory": {
-        "storage": "sqlite",
-        "acceptmismatch": "False",
-    },
-    "knownnodes": {
-        "maxnodes": 20000,
-    },
-    "zlib": {
-        "maxsize": 1048576
-    }
-}
-
-
-@Singleton
 class BMConfigParser(SafeConfigParser):
     """
     Singleton class inherited from :class:`ConfigParser.SafeConfigParser`
@@ -69,49 +36,6 @@ class BMConfigParser(SafeConfigParser):
             raise ValueError("Invalid value %s" % value)
         return SafeConfigParser.set(self, section, option, value)
 
-    # pylint: disable=redefined-builtin, too-many-return-statements
-    def get(self, section, option, raw=False, vars=None):
-        if sys.version_info[0] == 3:
-            # pylint: disable=arguments-differ
-            try:
-                if section == "bitmessagesettings" and option == "timeformat":
-                    return SafeConfigParser.get(
-                        self, section, option, raw=True, vars=vars)
-                try:
-                    return self._temp[section][option]
-                except KeyError:
-                    pass
-                return SafeConfigParser.get(
-                    self, section, option, raw=True, vars=vars)
-            except configparser.InterpolationError:
-                return SafeConfigParser.get(
-                    self, section, option, raw=True, vars=vars)
-            except (configparser.NoSectionError, configparser.NoOptionError) as e:
-                try:
-                    return BMConfigDefaults[section][option]
-                except (KeyError, ValueError, AttributeError):
-                    raise e
-        else:
-            # pylint: disable=arguments-differ
-            try:
-                if section == "bitmessagesettings" and option == "timeformat":
-                    return SafeConfigParser.get(
-                        self, section, option, raw, vars)
-                try:
-                    return self._temp[section][option]
-                except KeyError:
-                    pass
-                return SafeConfigParser.get(
-                    self, section, option, True, vars)
-            except configparser.InterpolationError:
-                return SafeConfigParser.get(
-                    self, section, option, True, vars)
-            except (configparser.NoSectionError, configparser.NoOptionError) as e:
-                try:
-                    return BMConfigDefaults[section][option]
-                except (KeyError, ValueError, AttributeError):
-                    raise e
-
     def setTemp(self, section, option, value=None):
         """Temporary set option to value, not saving."""
         try:
@@ -173,33 +97,18 @@ class BMConfigParser(SafeConfigParser):
         for x in sections:
             self.remove_section(x)
 
+    def read(self, filenames=None):
+        self._reset()
+        SafeConfigParser.read(self, os.path.join(os.path.dirname(__file__), 'default.ini'))
+        if filenames:
+            SafeConfigParser.read(self, filenames)
+
     if sys.version_info[0] == 3:
         @staticmethod
         def addresses(hidden=False):
             """Return a list of local bitmessage addresses (from section labels)"""
-            return [x for x in BMConfigParser().sections() if x.startswith('BM-') and (
-                    hidden or not BMConfigParser().safeGetBoolean(x, 'hidden'))]
-
-        def read(self, filenames):
-            self._reset()
-            SafeConfigParser.read(self, filenames)
-            for section in self.sections():
-                for option in self.options(section):
-                    try:
-                        if not self.validate(
-                                section, option,
-                                self[section][option]  # pylint: disable=unsubscriptable-object
-                        ):
-                            try:
-                                newVal = BMConfigDefaults[section][option]
-                            except configparser.NoSectionError:
-                                continue
-                            except KeyError:
-                                continue
-                            SafeConfigParser.set(
-                                self, section, option, newVal)
-                    except configparser.InterpolationError:
-                        continue
+            return [x for x in config.sections() if x.startswith('BM-') and (
+                    hidden or not config.safeGetBoolean(x, 'hidden'))]
 
         def readfp(self, fp, filename=None):
             # pylint: disable=no-member
@@ -209,27 +118,7 @@ class BMConfigParser(SafeConfigParser):
         def addresses():
             """Return a list of local bitmessage addresses (from section labels)"""
             return [
-                x for x in BMConfigParser().sections() if x.startswith('BM-')]
-
-        def read(self, filenames):
-            """Read config and populate defaults"""
-            self._reset()
-            SafeConfigParser.read(self, filenames)
-            for section in self.sections():
-                for option in self.options(section):
-                    try:
-                        if not self.validate(
-                                section, option,
-                                SafeConfigParser.get(self, section, option)
-                        ):
-                            try:
-                                newVal = BMConfigDefaults[section][option]
-                            except KeyError:
-                                continue
-                            SafeConfigParser.set(
-                                self, section, option, newVal)
-                    except configparser.InterpolationError:
-                        continue
+                x for x in config.sections() if x.startswith('BM-')]
 
     def save(self):
         """Save the runtime config onto the filesystem"""
@@ -242,7 +131,7 @@ class BMConfigParser(SafeConfigParser):
             shutil.copyfile(fileName, fileNameBak)
             # The backup succeeded.
             fileNameExisted = True
-        except (IOError, Exception):
+        except(IOError, Exception):
             # The backup failed. This can happen if the file
             # didn't exist before.
             fileNameExisted = False
@@ -270,3 +159,6 @@ class BMConfigParser(SafeConfigParser):
         if value < 0 or value > 8:
             return False
         return True
+
+
+config = BMConfigParser()
diff --git a/src/build_osx.py b/src/build_osx.py
index 83d2f280..3fcefbfb 100644
--- a/src/build_osx.py
+++ b/src/build_osx.py
@@ -9,7 +9,7 @@ version = os.getenv("PYBITMESSAGEVERSION", "custom")
 mainscript = ["bitmessagemain.py"]
 
 DATA_FILES = [
-    ('', ['sslkeys', 'images']),
+    ('', ['sslkeys', 'images', 'default.ini']),
     ('bitmsghash', ['bitmsghash/bitmsghash.cl', 'bitmsghash/bitmsghash.so']),
     ('translations', glob('translations/*.qm')),
     ('ui', glob('bitmessageqt/*.ui')),
diff --git a/src/class_addressGenerator.py b/src/class_addressGenerator.py
index 25b0c5df..a308a52e 100644
--- a/src/class_addressGenerator.py
+++ b/src/class_addressGenerator.py
@@ -12,7 +12,7 @@ import shared
 import state
 import tr
 from addresses import decodeAddress, encodeAddress, encodeVarint
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from fallback import RIPEMD160Hash
 from network import StoppableThread
 from pyelliptic import arithmetic
@@ -72,7 +72,7 @@ class addressGenerator(StoppableThread):
                     eighteenByteRipe = queueValue
 
                 numberOfNullBytesDemandedOnFrontOfRipeHash = \
-                    BMConfigParser().safeGetInt(
+                    config.safeGetInt(
                         'bitmessagesettings',
                         'numberofnullbytesonaddress',
                         2 if eighteenByteRipe else 1
@@ -84,7 +84,7 @@ class addressGenerator(StoppableThread):
                     payloadLengthExtraBytes = queueValue
 
                 numberOfNullBytesDemandedOnFrontOfRipeHash = \
-                    BMConfigParser().safeGetInt(
+                    config.safeGetInt(
                         'bitmessagesettings',
                         'numberofnullbytesonaddress',
                         2 if eighteenByteRipe else 1
@@ -103,14 +103,14 @@ class addressGenerator(StoppableThread):
                     ' one version %s address which it cannot do.\n',
                     addressVersionNumber)
             if nonceTrialsPerByte == 0:
-                nonceTrialsPerByte = BMConfigParser().getint(
+                nonceTrialsPerByte = config.getint(
                     'bitmessagesettings', 'defaultnoncetrialsperbyte')
             if nonceTrialsPerByte < \
                     defaults.networkDefaultProofOfWorkNonceTrialsPerByte:
                 nonceTrialsPerByte = \
                     defaults.networkDefaultProofOfWorkNonceTrialsPerByte
             if payloadLengthExtraBytes == 0:
-                payloadLengthExtraBytes = BMConfigParser().getint(
+                payloadLengthExtraBytes = config.getint(
                     'bitmessagesettings', 'defaultpayloadlengthextrabytes')
             if payloadLengthExtraBytes < \
                     defaults.networkDefaultPayloadLengthExtraBytes:
@@ -178,19 +178,19 @@ class addressGenerator(StoppableThread):
                 privEncryptionKeyWIF = arithmetic.changebase(
                     privEncryptionKey + checksum, 256, 58)
 
-                BMConfigParser().add_section(address)
-                BMConfigParser().set(address, 'label', label)
-                BMConfigParser().set(address, 'enabled', 'true')
-                BMConfigParser().set(address, 'decoy', 'false')
-                BMConfigParser().set(address, 'noncetrialsperbyte', str(
+                config.add_section(address)
+                config.set(address, 'label', label)
+                config.set(address, 'enabled', 'true')
+                config.set(address, 'decoy', 'false')
+                config.set(address, 'noncetrialsperbyte', str(
                     nonceTrialsPerByte))
-                BMConfigParser().set(address, 'payloadlengthextrabytes', str(
+                config.set(address, 'payloadlengthextrabytes', str(
                     payloadLengthExtraBytes))
-                BMConfigParser().set(
+                config.set(
                     address, 'privsigningkey', privSigningKeyWIF)
-                BMConfigParser().set(
+                config.set(
                     address, 'privencryptionkey', privEncryptionKeyWIF)
-                BMConfigParser().save()
+                config.save()
 
                 # The API and the join and create Chan functionality
                 # both need information back from the address generator.
@@ -317,7 +317,7 @@ class addressGenerator(StoppableThread):
                             privEncryptionKey + checksum, 256, 58)
 
                         try:
-                            BMConfigParser().add_section(address)
+                            config.add_section(address)
                             addressAlreadyExists = False
                         except configparser.DuplicateSectionError:
                             addressAlreadyExists = True
@@ -337,25 +337,25 @@ class addressGenerator(StoppableThread):
                             ))
                         else:
                             self.logger.debug('label: %s', label)
-                            BMConfigParser().set(address, 'label', label)
-                            BMConfigParser().set(address, 'enabled', 'true')
-                            BMConfigParser().set(address, 'decoy', 'false')
+                            config.set(address, 'label', label)
+                            config.set(address, 'enabled', 'true')
+                            config.set(address, 'decoy', 'false')
                             if command == 'joinChan' \
                                     or command == 'createChan':
-                                BMConfigParser().set(address, 'chan', 'true')
-                            BMConfigParser().set(
+                                config.set(address, 'chan', 'true')
+                            config.set(
                                 address, 'noncetrialsperbyte',
                                 str(nonceTrialsPerByte))
-                            BMConfigParser().set(
+                            config.set(
                                 address, 'payloadlengthextrabytes',
                                 str(payloadLengthExtraBytes))
-                            BMConfigParser().set(
+                            config.set(
                                 address, 'privSigningKey',
                                 privSigningKeyWIF)
-                            BMConfigParser().set(
+                            config.set(
                                 address, 'privEncryptionKey',
                                 privEncryptionKeyWIF)
-                            BMConfigParser().save()
+                            config.save()
 
                             queues.UISignalQueue.put((
                                 'writeNewAddressToTable',
@@ -387,7 +387,7 @@ class addressGenerator(StoppableThread):
                                     "MainWindow", "Done generating address")
                             ))
                     elif saveAddressToDisk and not live \
-                            and not BMConfigParser().has_section(address):
+                            and not config.has_section(address):
                         listOfNewAddressesToSendOutThroughTheAPI.append(
                             address)
 
diff --git a/src/class_objectProcessor.py b/src/class_objectProcessor.py
index 1bacf639..bbf622e4 100644
--- a/src/class_objectProcessor.py
+++ b/src/class_objectProcessor.py
@@ -26,7 +26,7 @@ from addresses import (
     calculateInventoryHash, decodeAddress, decodeVarint,
     encodeAddress, encodeVarint, varintDecodeError
 )
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from fallback import RIPEMD160Hash
 from helper_sql import sql_ready, SqlBulkExecute, sqlExecute, sqlQuery
 from network import bmproto, knownnodes
@@ -98,7 +98,7 @@ class objectProcessor(threading.Thread):
                     'The object is too big after decompression (stopped'
                     ' decompressing at %ib, your configured limit %ib).'
                     ' Ignoring',
-                    e.size, BMConfigParser().safeGetInt('zlib', 'maxsize'))
+                    e.size, config.safeGetInt('zlib', 'maxsize'))
             except varintDecodeError as e:
                 logger.debug(
                     'There was a problem with a varint while processing an'
@@ -242,12 +242,12 @@ class objectProcessor(threading.Thread):
                 ' one of my pubkeys but the stream number on which we'
                 ' heard this getpubkey object doesn\'t match this'
                 ' address\' stream number. Ignoring.')
-        if BMConfigParser().safeGetBoolean(myAddress, 'chan'):
+        if config.safeGetBoolean(myAddress, 'chan'):
             return logger.info(
                 'Ignoring getpubkey request because it is for one of my'
                 ' chan addresses. The other party should already have'
                 ' the pubkey.')
-        lastPubkeySendTime = BMConfigParser().safeGetInt(
+        lastPubkeySendTime = config.safeGetInt(
             myAddress, 'lastpubkeysendtime')
         # If the last time we sent our pubkey was more recent than
         # 28 days ago...
@@ -613,13 +613,13 @@ class objectProcessor(threading.Thread):
         # If the toAddress version number is 3 or higher and not one of
         # my chan addresses:
         if decodeAddress(toAddress)[1] >= 3 \
-                and not BMConfigParser().safeGetBoolean(toAddress, 'chan'):
+                and not config.safeGetBoolean(toAddress, 'chan'):
             # If I'm not friendly with this person:
             if not shared.isAddressInMyAddressBookSubscriptionsListOrWhitelist(
                     fromAddress):
-                requiredNonceTrialsPerByte = BMConfigParser().getint(
+                requiredNonceTrialsPerByte = config.getint(
                     toAddress, 'noncetrialsperbyte')
-                requiredPayloadLengthExtraBytes = BMConfigParser().getint(
+                requiredPayloadLengthExtraBytes = config.getint(
                     toAddress, 'payloadlengthextrabytes')
                 if not protocol.isProofOfWorkSufficient(
                         data, requiredNonceTrialsPerByte,
@@ -631,7 +631,7 @@ class objectProcessor(threading.Thread):
         # to black or white lists.
         blockMessage = False
         # If we are using a blacklist
-        if BMConfigParser().get(
+        if config.get(
                 'bitmessagesettings', 'blackwhitelist') == 'black':
             queryreturn = sqlQuery(
                 "SELECT label FROM blacklist where address=? and enabled='1'",
@@ -649,7 +649,7 @@ class objectProcessor(threading.Thread):
                     'Message ignored because address not in whitelist.')
                 blockMessage = True
 
-        # toLabel = BMConfigParser().safeGet(toAddress, 'label', toAddress)
+        # toLabel = config.safeGet(toAddress, 'label', toAddress)
         try:
             decodedMessage = helper_msgcoding.MsgDecode(
                 messageEncodingType, message)
@@ -675,18 +675,18 @@ class objectProcessor(threading.Thread):
             # If we are behaving as an API then we might need to run an
             # outside command to let some program know that a new message
             # has arrived.
-            if BMConfigParser().safeGetBoolean(
+            if config.safeGetBoolean(
                     'bitmessagesettings', 'apienabled'):
-                apiNotifyPath = BMConfigParser().safeGet(
+                apiNotifyPath = config.safeGet(
                     'bitmessagesettings', 'apinotifypath')
                 if apiNotifyPath:
                     subprocess.call([apiNotifyPath, "newMessage"])
 
             # Let us now check and see whether our receiving address is
             # behaving as a mailing list
-            if BMConfigParser().safeGetBoolean(toAddress, 'mailinglist') \
+            if config.safeGetBoolean(toAddress, 'mailinglist') \
                     and messageEncodingType != 0:
-                mailingListName = BMConfigParser().safeGet(
+                mailingListName = config.safeGet(
                     toAddress, 'mailinglistname', '')
                 # Let us send out this message as a broadcast
                 subject = self.addMailingListNameToSubject(
@@ -724,8 +724,8 @@ class objectProcessor(threading.Thread):
         if (
             self.ackDataHasAValidHeader(ackData) and not blockMessage
             and messageEncodingType != 0
-            and not BMConfigParser().safeGetBoolean(toAddress, 'dontsendack')
-            and not BMConfigParser().safeGetBoolean(toAddress, 'chan')
+            and not config.safeGetBoolean(toAddress, 'dontsendack')
+            and not config.safeGetBoolean(toAddress, 'chan')
         ):
             self._ack_obj.send_data(ackData[24:])
 
@@ -960,8 +960,8 @@ class objectProcessor(threading.Thread):
         # If we are behaving as an API then we might need to run an
         # outside command to let some program know that a new message
         # has arrived.
-        if BMConfigParser().safeGetBoolean('bitmessagesettings', 'apienabled'):
-            apiNotifyPath = BMConfigParser().safeGet(
+        if config.safeGetBoolean('bitmessagesettings', 'apienabled'):
+            apiNotifyPath = config.safeGet(
                 'bitmessagesettings', 'apinotifypath')
             if apiNotifyPath:
                 subprocess.call([apiNotifyPath, "newBroadcast"])
diff --git a/src/class_singleCleaner.py b/src/class_singleCleaner.py
index 3f3f8ec0..dd7e6bc1 100644
--- a/src/class_singleCleaner.py
+++ b/src/class_singleCleaner.py
@@ -25,7 +25,7 @@ import time
 
 import queues
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute, sqlQuery
 from inventory import Inventory
 from network import BMConnectionPool, knownnodes, StoppableThread
@@ -50,11 +50,11 @@ class singleCleaner(StoppableThread):
         timeWeLastClearedInventoryAndPubkeysTables = 0
         try:
             state.maximumLengthOfTimeToBotherResendingMessages = (
-                BMConfigParser().getfloat(
+                config.getfloat(
                     'bitmessagesettings', 'stopresendingafterxdays')
                 * 24 * 60 * 60
             ) + (
-                BMConfigParser().getfloat(
+                config.getfloat(
                     'bitmessagesettings', 'stopresendingafterxmonths')
                 * (60 * 60 * 24 * 365) / 12)
         except:  # noqa:E722
diff --git a/src/class_singleWorker.py b/src/class_singleWorker.py
index fea842ea..5b97c536 100644
--- a/src/class_singleWorker.py
+++ b/src/class_singleWorker.py
@@ -28,7 +28,7 @@ import tr
 from addresses import (
     calculateInventoryHash, decodeAddress, decodeVarint, encodeVarint
 )
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute, sqlQuery
 from inventory import Inventory
 from network import knownnodes, StoppableThread
@@ -195,9 +195,9 @@ class singleWorker(StoppableThread):
         self.logger.info("Quitting...")
 
     def _getKeysForAddress(self, address):
-        privSigningKeyBase58 = BMConfigParser().get(
+        privSigningKeyBase58 = config.get(
             address, 'privsigningkey')
-        privEncryptionKeyBase58 = BMConfigParser().get(
+        privEncryptionKeyBase58 = config.get(
             address, 'privencryptionkey')
 
         privSigningKeyHex = hexlify(shared.decodeWalletImportFormat(
@@ -299,15 +299,15 @@ class singleWorker(StoppableThread):
         queues.invQueue.put((streamNumber, inventoryHash))
         queues.UISignalQueue.put(('updateStatusBar', ''))
         try:
-            BMConfigParser().set(
+            config.set(
                 myAddress, 'lastpubkeysendtime', str(int(time.time())))
-            BMConfigParser().save()
+            config.save()
         except configparser.NoSectionError:
             # The user deleted the address out of the keys.dat file
             # before this finished.
             pass
         except:  # noqa:E722
-            self.logger.warning("BMConfigParser().set didn't work")
+            self.logger.warning("config.set didn't work")
 
     def sendOutOrStoreMyV3Pubkey(self, adressHash):
         """
@@ -321,7 +321,7 @@ class singleWorker(StoppableThread):
             # The address has been deleted.
             self.logger.warning("Can't find %s in myAddressByHash", hexlify(adressHash))
             return
-        if BMConfigParser().safeGetBoolean(myAddress, 'chan'):
+        if config.safeGetBoolean(myAddress, 'chan'):
             self.logger.info('This is a chan address. Not sending pubkey.')
             return
         _, addressVersionNumber, streamNumber, adressHash = decodeAddress(
@@ -363,9 +363,9 @@ class singleWorker(StoppableThread):
 
         payload += pubSigningKey + pubEncryptionKey
 
-        payload += encodeVarint(BMConfigParser().getint(
+        payload += encodeVarint(config.getint(
             myAddress, 'noncetrialsperbyte'))
-        payload += encodeVarint(BMConfigParser().getint(
+        payload += encodeVarint(config.getint(
             myAddress, 'payloadlengthextrabytes'))
 
         signature = highlevelcrypto.sign(payload, privSigningKeyHex)
@@ -387,9 +387,9 @@ class singleWorker(StoppableThread):
         queues.invQueue.put((streamNumber, inventoryHash))
         queues.UISignalQueue.put(('updateStatusBar', ''))
         try:
-            BMConfigParser().set(
+            config.set(
                 myAddress, 'lastpubkeysendtime', str(int(time.time())))
-            BMConfigParser().save()
+            config.save()
         except configparser.NoSectionError:
             # The user deleted the address out of the keys.dat file
             # before this finished.
@@ -403,10 +403,10 @@ class singleWorker(StoppableThread):
         whereas in the past it directly appended it to the outgoing buffer, I think. Same with all the other methods in
         this class.
         """
-        if not BMConfigParser().has_section(myAddress):
+        if not config.has_section(myAddress):
             # The address has been deleted.
             return
-        if shared.BMConfigParser().safeGetBoolean(myAddress, 'chan'):
+        if config.safeGetBoolean(myAddress, 'chan'):
             self.logger.info('This is a chan address. Not sending pubkey.')
             return
         _, addressVersionNumber, streamNumber, addressHash = decodeAddress(
@@ -437,9 +437,9 @@ class singleWorker(StoppableThread):
 
         dataToEncrypt += pubSigningKey + pubEncryptionKey
 
-        dataToEncrypt += encodeVarint(BMConfigParser().getint(
+        dataToEncrypt += encodeVarint(config.getint(
             myAddress, 'noncetrialsperbyte'))
-        dataToEncrypt += encodeVarint(BMConfigParser().getint(
+        dataToEncrypt += encodeVarint(config.getint(
             myAddress, 'payloadlengthextrabytes'))
 
         # When we encrypt, we'll use a hash of the data
@@ -482,9 +482,9 @@ class singleWorker(StoppableThread):
         queues.invQueue.put((streamNumber, inventoryHash))
         queues.UISignalQueue.put(('updateStatusBar', ''))
         try:
-            BMConfigParser().set(
+            config.set(
                 myAddress, 'lastpubkeysendtime', str(int(time.time())))
-            BMConfigParser().save()
+            config.save()
         except Exception as err:
             self.logger.error(
                 'Error: Couldn\'t add the lastpubkeysendtime'
@@ -628,9 +628,9 @@ class singleWorker(StoppableThread):
             dataToEncrypt += protocol.getBitfield(fromaddress)
             dataToEncrypt += pubSigningKey + pubEncryptionKey
             if addressVersionNumber >= 3:
-                dataToEncrypt += encodeVarint(BMConfigParser().getint(
+                dataToEncrypt += encodeVarint(config.getint(
                     fromaddress, 'noncetrialsperbyte'))
-                dataToEncrypt += encodeVarint(BMConfigParser().getint(
+                dataToEncrypt += encodeVarint(config.getint(
                     fromaddress, 'payloadlengthextrabytes'))
             # message encoding type
             dataToEncrypt += encodeVarint(encoding)
@@ -756,7 +756,7 @@ class singleWorker(StoppableThread):
             # then we won't need an entry in the pubkeys table;
             # we can calculate the needed pubkey using the private keys
             # in our keys.dat file.
-            elif BMConfigParser().has_section(toaddress):
+            elif config.has_section(toaddress):
                 if not sqlExecute(
                     '''UPDATE sent SET status='doingmsgpow' '''
                     ''' WHERE toaddress=? AND status='msgqueued' AND folder='sent' ''',
@@ -905,7 +905,7 @@ class singleWorker(StoppableThread):
             embeddedTime = int(time.time() + TTL)
 
             # if we aren't sending this to ourselves or a chan
-            if not BMConfigParser().has_section(toaddress):
+            if not config.has_section(toaddress):
                 state.ackdataForWhichImWatching[ackdata] = 0
                 queues.UISignalQueue.put((
                     'updateSentItemStatusByAckdata', (
@@ -956,7 +956,7 @@ class singleWorker(StoppableThread):
                 if protocol.isBitSetWithinBitfield(behaviorBitfield, 30):
                     # if we are Not willing to include the receiver's
                     # RIPE hash on the message..
-                    if not shared.BMConfigParser().safeGetBoolean(
+                    if not config.safeGetBoolean(
                             'bitmessagesettings', 'willinglysendtomobile'
                     ):
                         self.logger.info(
@@ -1058,9 +1058,9 @@ class singleWorker(StoppableThread):
                     )
 
                     if status != 'forcepow':
-                        maxacceptablenoncetrialsperbyte = BMConfigParser().getint(
+                        maxacceptablenoncetrialsperbyte = config.getint(
                             'bitmessagesettings', 'maxacceptablenoncetrialsperbyte')
-                        maxacceptablepayloadlengthextrabytes = BMConfigParser().getint(
+                        maxacceptablepayloadlengthextrabytes = config.getint(
                             'bitmessagesettings', 'maxacceptablepayloadlengthextrabytes')
                         cond1 = maxacceptablenoncetrialsperbyte and \
                             requiredAverageProofOfWorkNonceTrialsPerByte > maxacceptablenoncetrialsperbyte
@@ -1096,7 +1096,7 @@ class singleWorker(StoppableThread):
                 behaviorBitfield = protocol.getBitfield(fromaddress)
 
                 try:
-                    privEncryptionKeyBase58 = BMConfigParser().get(
+                    privEncryptionKeyBase58 = config.get(
                         toaddress, 'privencryptionkey')
                 except (configparser.NoSectionError, configparser.NoOptionError) as err:
                     queues.UISignalQueue.put((
@@ -1185,9 +1185,9 @@ class singleWorker(StoppableThread):
                     payload += encodeVarint(
                         defaults.networkDefaultPayloadLengthExtraBytes)
                 else:
-                    payload += encodeVarint(BMConfigParser().getint(
+                    payload += encodeVarint(config.getint(
                         fromaddress, 'noncetrialsperbyte'))
-                    payload += encodeVarint(BMConfigParser().getint(
+                    payload += encodeVarint(config.getint(
                         fromaddress, 'payloadlengthextrabytes'))
 
             # This hash will be checked by the receiver of the message
@@ -1200,7 +1200,7 @@ class singleWorker(StoppableThread):
             )
             payload += encodeVarint(encodedMessage.length)
             payload += encodedMessage.data
-            if BMConfigParser().has_section(toaddress):
+            if config.has_section(toaddress):
                 self.logger.info(
                     'Not bothering to include ackdata because we are'
                     ' sending to ourselves or a chan.'
@@ -1305,7 +1305,7 @@ class singleWorker(StoppableThread):
             objectType = 2
             Inventory()[inventoryHash] = (
                 objectType, toStreamNumber, encryptedPayload, embeddedTime, '')
-            if BMConfigParser().has_section(toaddress) or \
+            if config.has_section(toaddress) or \
                not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
                 queues.UISignalQueue.put((
                     'updateSentItemStatusByAckdata', (
@@ -1333,7 +1333,7 @@ class singleWorker(StoppableThread):
 
             # Update the sent message in the sent table with the
             # necessary information.
-            if BMConfigParser().has_section(toaddress) or \
+            if config.has_section(toaddress) or \
                not protocol.checkBitfield(behaviorBitfield, protocol.BITFIELD_DOESACK):
                 newStatus = 'msgsentnoackexpected'
             else:
@@ -1349,7 +1349,7 @@ class singleWorker(StoppableThread):
 
             # If we are sending to ourselves or a chan, let's put
             # the message in our own inbox.
-            if BMConfigParser().has_section(toaddress):
+            if config.has_section(toaddress):
                 # Used to detect and ignore duplicate messages in our inbox
                 sigHash = hashlib.sha512(hashlib.sha512(
                     signature).digest()).digest()[32:]
@@ -1363,10 +1363,10 @@ class singleWorker(StoppableThread):
                 # If we are behaving as an API then we might need to run an
                 # outside command to let some program know that a new message
                 # has arrived.
-                if BMConfigParser().safeGetBoolean(
+                if config.safeGetBoolean(
                         'bitmessagesettings', 'apienabled'):
 
-                    apiNotifyPath = BMConfigParser().safeGet(
+                    apiNotifyPath = config.safeGet(
                         'bitmessagesettings', 'apinotifypath')
 
                     if apiNotifyPath:
diff --git a/src/class_smtpDeliver.py b/src/class_smtpDeliver.py
index 08cb35ab..ad509bbf 100644
--- a/src/class_smtpDeliver.py
+++ b/src/class_smtpDeliver.py
@@ -10,7 +10,7 @@ from email.mime.text import MIMEText
 
 import queues
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from network.threads import StoppableThread
 
 SMTPDOMAIN = "bmaddr.lan"
@@ -51,7 +51,7 @@ class smtpDeliver(StoppableThread):
                 ackData, message = data
             elif command == 'displayNewInboxMessage':
                 inventoryHash, toAddress, fromAddress, subject, body = data
-                dest = BMConfigParser().safeGet("bitmessagesettings", "smtpdeliver", '')
+                dest = config.safeGet("bitmessagesettings", "smtpdeliver", '')
                 if dest == '':
                     continue
                 try:
@@ -62,9 +62,9 @@ class smtpDeliver(StoppableThread):
                     msg['Subject'] = Header(subject, 'utf-8')
                     msg['From'] = fromAddress + '@' + SMTPDOMAIN
                     toLabel = map(
-                        lambda y: BMConfigParser().safeGet(y, "label"),
+                        lambda y: config.safeGet(y, "label"),
                         filter(
-                            lambda x: x == toAddress, BMConfigParser().addresses())
+                            lambda x: x == toAddress, config.addresses())
                     )
                     if toLabel:
                         msg['To'] = "\"%s\" <%s>" % (Header(toLabel[0], 'utf-8'), toAddress + '@' + SMTPDOMAIN)
diff --git a/src/class_smtpServer.py b/src/class_smtpServer.py
index f5b63c2e..44ea7c9c 100644
--- a/src/class_smtpServer.py
+++ b/src/class_smtpServer.py
@@ -15,7 +15,7 @@ from email.parser import Parser
 
 import queues
 from addresses import decodeAddress
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_ackPayload import genAckPayload
 from helper_sql import sqlExecute
 from network.threads import StoppableThread
@@ -51,8 +51,8 @@ class smtpServerChannel(smtpd.SMTPChannel):
         authstring = arg[6:]
         try:
             decoded = base64.b64decode(authstring)
-            correctauth = "\x00" + BMConfigParser().safeGet(
-                "bitmessagesettings", "smtpdusername", "") + "\x00" + BMConfigParser().safeGet(
+            correctauth = "\x00" + config.safeGet(
+                "bitmessagesettings", "smtpdusername", "") + "\x00" + config.safeGet(
                     "bitmessagesettings", "smtpdpassword", "")
             logger.debug('authstring: %s / %s', correctauth, decoded)
             if correctauth == decoded:
@@ -84,7 +84,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
         """Send a bitmessage"""
         # pylint: disable=arguments-differ
         streamNumber, ripe = decodeAddress(toAddress)[2:]
-        stealthLevel = BMConfigParser().safeGetInt('bitmessagesettings', 'ackstealthlevel')
+        stealthLevel = config.safeGetInt('bitmessagesettings', 'ackstealthlevel')
         ackdata = genAckPayload(streamNumber, stealthLevel)
         sqlExecute(
             '''INSERT INTO sent VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)''',
@@ -103,7 +103,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
             'sent',  # folder
             2,  # encodingtype
             # not necessary to have a TTL higher than 2 days
-            min(BMConfigParser().getint('bitmessagesettings', 'ttl'), 86400 * 2)
+            min(config.getint('bitmessagesettings', 'ttl'), 86400 * 2)
         )
 
         queues.workerQueue.put(('sendmessage', toAddress))
@@ -136,7 +136,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
             sender, domain = p.sub(r'\1', mailfrom).split("@")
             if domain != SMTPDOMAIN:
                 raise Exception("Bad domain %s" % domain)
-            if sender not in BMConfigParser().addresses():
+            if sender not in config.addresses():
                 raise Exception("Nonexisting user %s" % sender)
         except Exception as err:
             logger.debug('Bad envelope from %s: %r', mailfrom, err)
@@ -146,7 +146,7 @@ class smtpServerPyBitmessage(smtpd.SMTPServer):
                 sender, domain = msg_from.split("@")
                 if domain != SMTPDOMAIN:
                     raise Exception("Bad domain %s" % domain)
-                if sender not in BMConfigParser().addresses():
+                if sender not in config.addresses():
                     raise Exception("Nonexisting user %s" % sender)
             except Exception as err:
                 logger.error('Bad headers from %s: %r', msg_from, err)
diff --git a/src/class_sqlThread.py b/src/class_sqlThread.py
index d22ffadb..7df9e253 100644
--- a/src/class_sqlThread.py
+++ b/src/class_sqlThread.py
@@ -16,13 +16,13 @@ try:
     import queues
     import state
     from addresses import encodeAddress
-    from bmconfigparser import BMConfigParser
+    from bmconfigparser import config, config_ready
     from debug import logger
     from tr import _translate
 except ImportError:
     from . import helper_sql, helper_startup, paths, queues, state
     from .addresses import encodeAddress
-    from .bmconfigparser import BMConfigParser
+    from .bmconfigparser import config, config_ready
     from .debug import logger
     from .tr import _translate
 
@@ -36,6 +36,7 @@ class sqlThread(threading.Thread):
     def run(self):  # pylint: disable=too-many-locals, too-many-branches, too-many-statements
         """Process SQL queries from `.helper_sql.sqlSubmitQueue`"""
         helper_sql.sql_available = True
+        config_ready.wait()
         self.conn = sqlite3.connect(state.appdata + 'messages.dat')
         self.conn.text_factory = str
         self.cur = self.conn.cursor()
@@ -93,7 +94,7 @@ class sqlThread(threading.Thread):
         # If the settings version is equal to 2 or 3 then the
         # sqlThread will modify the pubkeys table and change
         # the settings version to 4.
-        settingsversion = BMConfigParser().getint(
+        settingsversion = config.getint(
             'bitmessagesettings', 'settingsversion')
 
         # People running earlier versions of PyBitmessage do not have the
@@ -125,9 +126,9 @@ class sqlThread(threading.Thread):
 
             settingsversion = 4
 
-        BMConfigParser().set(
+        config.set(
             'bitmessagesettings', 'settingsversion', str(settingsversion))
-        BMConfigParser().save()
+        config.save()
 
         helper_startup.updateConfig()
 
diff --git a/src/default.ini b/src/default.ini
new file mode 100644
index 00000000..fbf731f8
--- /dev/null
+++ b/src/default.ini
@@ -0,0 +1,47 @@
+[bitmessagesettings]
+maxaddrperstreamsend = 500
+maxbootstrapconnections = 20
+maxdownloadrate = 0
+maxoutboundconnections = 8
+maxtotalconnections = 200
+maxuploadrate = 0
+apiinterface = 127.0.0.1
+apiport = 8442
+udp = True
+port = 8444
+timeformat = %%c
+blackwhitelist = black
+startonlogon = False
+showtraynotifications = True
+startintray = False
+socksproxytype = none
+sockshostname = localhost
+socksport = 9050
+socksauthentication = False
+socksusername = 
+sockspassword = 
+keysencrypted = False
+messagesencrypted = False
+minimizeonclose = False
+dontconnect = True
+replybelow = False
+stopresendingafterxdays = 
+stopresendingafterxmonths = 
+opencl = 
+
+[threads]
+receive = 3
+
+[network]
+bind = 
+dandelion = 90
+
+[inventory]
+storage = sqlite
+acceptmismatch = False
+
+[knownnodes]
+maxnodes = 20000
+
+[zlib]
+maxsize = 1048576
diff --git a/src/helper_addressbook.py b/src/helper_addressbook.py
index fb572150..6d354113 100644
--- a/src/helper_addressbook.py
+++ b/src/helper_addressbook.py
@@ -2,13 +2,13 @@
 Insert value into addressbook
 """
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_sql import sqlExecute
 
 
 def insert(address, label):
     """perform insert into addressbook"""
 
-    if address not in BMConfigParser().addresses():
+    if address not in config.addresses():
         return sqlExecute('''INSERT INTO addressbook VALUES (?,?)''', label, address) == 1
     return False
diff --git a/src/helper_msgcoding.py b/src/helper_msgcoding.py
index 28f92288..05fa1c1b 100644
--- a/src/helper_msgcoding.py
+++ b/src/helper_msgcoding.py
@@ -6,7 +6,7 @@ import string
 import zlib
 
 import messagetypes
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from tr import _translate
 
@@ -100,10 +100,10 @@ class MsgDecode(object):
         """Handle extended encoding"""
         dc = zlib.decompressobj()
         tmp = ""
-        while len(tmp) <= BMConfigParser().safeGetInt("zlib", "maxsize"):
+        while len(tmp) <= config.safeGetInt("zlib", "maxsize"):
             try:
                 got = dc.decompress(
-                    data, BMConfigParser().safeGetInt("zlib", "maxsize")
+                    data, config.safeGetInt("zlib", "maxsize")
                     + 1 - len(tmp))
                 # EOF
                 if got == "":
diff --git a/src/helper_sent.py b/src/helper_sent.py
index d83afce6..1fc98de2 100644
--- a/src/helper_sent.py
+++ b/src/helper_sent.py
@@ -5,7 +5,7 @@ Insert values into sent table
 import time
 import uuid
 from addresses import decodeAddress
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_ackPayload import genAckPayload
 from helper_sql import sqlExecute
 
@@ -27,7 +27,7 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su
             ripe = new_ripe
 
         if not ackdata:
-            stealthLevel = BMConfigParser().safeGetInt(
+            stealthLevel = config.safeGetInt(
                 'bitmessagesettings', 'ackstealthlevel')
             new_ackdata = genAckPayload(streamNumber, stealthLevel)
             ackdata = new_ackdata
@@ -36,7 +36,7 @@ def insert(msgid=None, toAddress='[Broadcast subscribers]', fromAddress=None, su
         sentTime = sentTime if sentTime else int(time.time())  # sentTime (this doesn't change)
         lastActionTime = lastActionTime if lastActionTime else int(time.time())
 
-        ttl = ttl if ttl else BMConfigParser().getint('bitmessagesettings', 'ttl')
+        ttl = ttl if ttl else config.getint('bitmessagesettings', 'ttl')
 
         t = (msgid, toAddress, ripe, fromAddress, subject, message, ackdata,
              sentTime, lastActionTime, sleeptill, status, retryNumber, folder,
diff --git a/src/helper_startup.py b/src/helper_startup.py
index b4951668..c8a56c09 100644
--- a/src/helper_startup.py
+++ b/src/helper_startup.py
@@ -18,10 +18,11 @@ try:
     import helper_random
     import paths
     import state
-    from bmconfigparser import BMConfigParser
+    from bmconfigparser import config, config_ready
+
 except ImportError:
     from . import defaults, helper_random, paths, state
-    from .bmconfigparser import BMConfigParser
+    from bmconfigparser import config, config_ready
 
 try:
     from plugins.plugin import get_plugin
@@ -38,7 +39,6 @@ StoreConfigFilesInSameDirectoryAsProgramByDefault = False
 
 def loadConfig():
     """Load the config"""
-    config = BMConfigParser()
     if state.appdata:
         config.read(state.appdata + 'keys.dat')
         # state.appdata must have been specified as a startup option.
@@ -70,12 +70,9 @@ def loadConfig():
 
         # This appears to be the first time running the program; there is
         # no config file (or it cannot be accessed). Create config file.
-        config.add_section('bitmessagesettings')
+        # config.add_section('bitmessagesettings')
+        config.read()
         config.set('bitmessagesettings', 'settingsversion', '10')
-        config.set('bitmessagesettings', 'port', '8444')
-        config.set('bitmessagesettings', 'timeformat', '%%c')
-        config.set('bitmessagesettings', 'blackwhitelist', 'black')
-        config.set('bitmessagesettings', 'startonlogon', 'false')
         if 'linux' in sys.platform:
             config.set('bitmessagesettings', 'minimizetotray', 'false')
         # This isn't implimented yet and when True on
@@ -83,31 +80,16 @@ def loadConfig():
         # running when minimized.
         else:
             config.set('bitmessagesettings', 'minimizetotray', 'true')
-        config.set('bitmessagesettings', 'showtraynotifications', 'true')
-        config.set('bitmessagesettings', 'startintray', 'false')
-        config.set('bitmessagesettings', 'socksproxytype', 'none')
-        config.set('bitmessagesettings', 'sockshostname', 'localhost')
-        config.set('bitmessagesettings', 'socksport', '9050')
-        config.set('bitmessagesettings', 'socksauthentication', 'false')
-        config.set('bitmessagesettings', 'socksusername', '')
-        config.set('bitmessagesettings', 'sockspassword', '')
-        config.set('bitmessagesettings', 'keysencrypted', 'false')
-        config.set('bitmessagesettings', 'messagesencrypted', 'false')
         config.set(
             'bitmessagesettings', 'defaultnoncetrialsperbyte',
             str(defaults.networkDefaultProofOfWorkNonceTrialsPerByte))
         config.set(
             'bitmessagesettings', 'defaultpayloadlengthextrabytes',
             str(defaults.networkDefaultPayloadLengthExtraBytes))
-        config.set('bitmessagesettings', 'minimizeonclose', 'false')
-        config.set('bitmessagesettings', 'dontconnect', 'true')
-        config.set('bitmessagesettings', 'replybelow', 'False')
-        config.set('bitmessagesettings', 'maxdownloadrate', '0')
-        config.set('bitmessagesettings', 'maxuploadrate', '0')
 
         # UI setting to stop trying to send messages after X days/months
-        config.set('bitmessagesettings', 'stopresendingafterxdays', '')
-        config.set('bitmessagesettings', 'stopresendingafterxmonths', '')
+        # config.set('bitmessagesettings', 'stopresendingafterxdays', '')
+        # config.set('bitmessagesettings', 'stopresendingafterxmonths', '')
 
         # Are you hoping to add a new option to the keys.dat file? You're in
         # the right place for adding it to users who install the software for
@@ -130,11 +112,11 @@ def loadConfig():
         config.save()
     else:
         updateConfig()
+    config_ready.set()
 
 
 def updateConfig():
     """Save the config"""
-    config = BMConfigParser()
     settingsversion = config.getint('bitmessagesettings', 'settingsversion')
     if settingsversion == 1:
         config.set('bitmessagesettings', 'socksproxytype', 'none')
@@ -286,7 +268,7 @@ def updateConfig():
 
 def adjustHalfOpenConnectionsLimit():
     """Check and satisfy half-open connections limit (mainly XP and Vista)"""
-    if BMConfigParser().safeGet(
+    if config.safeGet(
             'bitmessagesettings', 'socksproxytype', 'none') != 'none':
         state.maximumNumberOfHalfOpenConnections = 4
         return
@@ -373,7 +355,7 @@ def start_proxyconfig():
     """Check socksproxytype and start any proxy configuration plugin"""
     if not get_plugin:
         return
-    config = BMConfigParser()
+    config_ready.wait()
     proxy_type = config.safeGet('bitmessagesettings', 'socksproxytype')
     if proxy_type and proxy_type not in ('none', 'SOCKS4a', 'SOCKS5'):
         try:
diff --git a/src/highlevelcrypto.py b/src/highlevelcrypto.py
index 82743acf..356cded7 100644
--- a/src/highlevelcrypto.py
+++ b/src/highlevelcrypto.py
@@ -13,7 +13,7 @@ import pyelliptic
 from pyelliptic import OpenSSL
 from pyelliptic import arithmetic as a
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 
 __all__ = ['encrypt', 'makeCryptor', 'pointMult', 'privToPub', 'sign', 'verify']
 
@@ -72,7 +72,7 @@ def sign(msg, hexPrivkey):
     Signs with hex private key using SHA1 or SHA256 depending on
     "digestalg" setting
     """
-    digestAlg = BMConfigParser().safeGet(
+    digestAlg = config.safeGet(
         'bitmessagesettings', 'digestalg', 'sha256')
     if digestAlg == "sha1":
         # SHA1, this will eventually be deprecated
diff --git a/src/inventory.py b/src/inventory.py
index fc06e455..985f1382 100644
--- a/src/inventory.py
+++ b/src/inventory.py
@@ -3,7 +3,7 @@
 # TODO make this dynamic, and watch out for frozen, like with messagetypes
 import storage.filesystem
 import storage.sqlite
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from singleton import Singleton
 
 
@@ -14,7 +14,7 @@ class Inventory():
     to manage the inventory.
     """
     def __init__(self):
-        self._moduleName = BMConfigParser().safeGet("inventory", "storage")
+        self._moduleName = config.safeGet("inventory", "storage")
         self._inventoryClass = getattr(
             getattr(storage, self._moduleName),
             "{}Inventory".format(self._moduleName.title())
diff --git a/src/l10n.py b/src/l10n.py
index 3b16f0b6..fe02d3f4 100644
--- a/src/l10n.py
+++ b/src/l10n.py
@@ -8,7 +8,7 @@ import time
 
 from six.moves import range
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 
 logger = logging.getLogger('default')
 
@@ -53,7 +53,7 @@ windowsLanguageMap = {
 }
 
 
-time_format = BMConfigParser().safeGet(
+time_format = config.safeGet(
     'bitmessagesettings', 'timeformat', DEFAULT_TIME_FORMAT)
 
 if not re.search(r'\d', time.strftime(time_format)):
@@ -125,7 +125,7 @@ def formatTimestamp(timestamp=None):
 
 def getTranslationLanguage():
     """Return the user's language choice"""
-    userlocale = BMConfigParser().safeGet(
+    userlocale = config.safeGet(
         'bitmessagesettings', 'userlocale', 'system')
     return userlocale if userlocale and userlocale != 'system' else language
 
diff --git a/src/mock/class_addressGenerator.py b/src/mock/class_addressGenerator.py
index fbb34710..c84b92d5 100644
--- a/src/mock/class_addressGenerator.py
+++ b/src/mock/class_addressGenerator.py
@@ -11,7 +11,7 @@ from six.moves import queue
 from pybitmessage import state
 from pybitmessage import queues
 
-from pybitmessage.bmconfigparser import BMConfigParser
+from pybitmessage.bmconfigparser import config
 
 # from network.threads import StoppableThread
 
@@ -83,14 +83,14 @@ class FakeAddressGenerator(StoppableThread):
                 address = self.address_list.pop(0)
                 label = queueValue[3]
 
-                BMConfigParser().add_section(address)
-                BMConfigParser().set(address, 'label', label)
-                BMConfigParser().set(address, 'enabled', 'true')
-                BMConfigParser().set(
+                config.add_section(address)
+                config.set(address, 'label', label)
+                config.set(address, 'enabled', 'true')
+                config.set(
                     address, 'privsigningkey', fake_addresses[address]['privsigningkey'])
-                BMConfigParser().set(
+                config.set(
                     address, 'privencryptionkey', fake_addresses[address]['privencryptionkey'])
-                BMConfigParser().save()
+                config.save()
 
                 queues.addressGeneratorQueue.task_done()
             except IndexError:
diff --git a/src/namecoin.py b/src/namecoin.py
index 33d39070..a16cb3d7 100644
--- a/src/namecoin.py
+++ b/src/namecoin.py
@@ -12,7 +12,7 @@ import sys
 
 import defaults
 from addresses import decodeAddress
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from tr import _translate  # translate
 
@@ -52,15 +52,15 @@ class namecoinConnection(object):
         actually changing the values (yet).
         """
         if options is None:
-            self.nmctype = BMConfigParser().get(
+            self.nmctype = config.get(
                 configSection, "namecoinrpctype")
-            self.host = BMConfigParser().get(
+            self.host = config.get(
                 configSection, "namecoinrpchost")
-            self.port = int(BMConfigParser().get(
+            self.port = int(config.get(
                 configSection, "namecoinrpcport"))
-            self.user = BMConfigParser().get(
+            self.user = config.get(
                 configSection, "namecoinrpcuser")
-            self.password = BMConfigParser().get(
+            self.password = config.get(
                 configSection, "namecoinrpcpassword")
         else:
             self.nmctype = options["type"]
@@ -321,14 +321,14 @@ def ensureNamecoinOptions():
     that aren't there.
     """
 
-    if not BMConfigParser().has_option(configSection, "namecoinrpctype"):
-        BMConfigParser().set(configSection, "namecoinrpctype", "namecoind")
-    if not BMConfigParser().has_option(configSection, "namecoinrpchost"):
-        BMConfigParser().set(configSection, "namecoinrpchost", "localhost")
+    if not config.has_option(configSection, "namecoinrpctype"):
+        config.set(configSection, "namecoinrpctype", "namecoind")
+    if not config.has_option(configSection, "namecoinrpchost"):
+        config.set(configSection, "namecoinrpchost", "localhost")
 
-    hasUser = BMConfigParser().has_option(configSection, "namecoinrpcuser")
-    hasPass = BMConfigParser().has_option(configSection, "namecoinrpcpassword")
-    hasPort = BMConfigParser().has_option(configSection, "namecoinrpcport")
+    hasUser = config.has_option(configSection, "namecoinrpcuser")
+    hasPass = config.has_option(configSection, "namecoinrpcpassword")
+    hasPort = config.has_option(configSection, "namecoinrpcport")
 
     # Try to read user/password from .namecoin configuration file.
     defaultUser = ""
@@ -364,11 +364,10 @@ def ensureNamecoinOptions():
 
     # If still nothing found, set empty at least.
     if not hasUser:
-        BMConfigParser().set(configSection, "namecoinrpcuser", defaultUser)
+        config.set(configSection, "namecoinrpcuser", defaultUser)
     if not hasPass:
-        BMConfigParser().set(configSection, "namecoinrpcpassword", defaultPass)
+        config.set(configSection, "namecoinrpcpassword", defaultPass)
 
     # Set default port now, possibly to found value.
     if not hasPort:
-        BMConfigParser().set(configSection, "namecoinrpcport",
-                             defaults.namecoinDefaultRpcPort)
+        config.set(configSection, "namecoinrpcport", defaults.namecoinDefaultRpcPort)
diff --git a/src/network/announcethread.py b/src/network/announcethread.py
index e34ed963..6e18e661 100644
--- a/src/network/announcethread.py
+++ b/src/network/announcethread.py
@@ -4,7 +4,7 @@ Announce myself (node address)
 import time
 
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from network.assemble import assemble_addr
 from network.connectionpool import BMConnectionPool
 from node import Peer
@@ -37,7 +37,7 @@ class AnnounceThread(StoppableThread):
                     stream,
                     Peer(
                         '127.0.0.1',
-                        BMConfigParser().safeGetInt(
+                        config.safeGetInt(
                             'bitmessagesettings', 'port')),
                     time.time())
                 connection.append_write_buf(assemble_addr([addr]))
diff --git a/src/network/bmproto.py b/src/network/bmproto.py
index 008eadb0..1295bd34 100644
--- a/src/network/bmproto.py
+++ b/src/network/bmproto.py
@@ -16,7 +16,7 @@ import connectionpool
 import knownnodes
 import protocol
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from inventory import Inventory
 from network.advanceddispatcher import AdvancedDispatcher
 from network.bmobject import (
@@ -403,7 +403,7 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
         try:
             self.object.checkStream()
         except BMObjectUnwantedStreamError:
-            acceptmismatch = BMConfigParser().get(
+            acceptmismatch = config.get(
                 "inventory", "acceptmismatch")
             BMProto.stopDownloadingObject(
                 self.object.inventoryHash, acceptmismatch)
@@ -619,9 +619,9 @@ class BMProto(AdvancedDispatcher, ObjectTracker):
                 Peer(self.destination.host, self.peerNode.port)
                 in connectionpool.BMConnectionPool().inboundConnections
                 or len(connectionpool.BMConnectionPool())
-                > BMConfigParser().safeGetInt(
+                > config.safeGetInt(
                     'bitmessagesettings', 'maxtotalconnections')
-                + BMConfigParser().safeGetInt(
+                + config.safeGetInt(
                     'bitmessagesettings', 'maxbootstrapconnections')
             ):
                 self.append_write_buf(protocol.assembleErrorMessage(
diff --git a/src/network/connectionchooser.py b/src/network/connectionchooser.py
index c31bbb6a..db6f0ff8 100644
--- a/src/network/connectionchooser.py
+++ b/src/network/connectionchooser.py
@@ -8,7 +8,7 @@ import random  # nosec
 import knownnodes
 import protocol
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from queues import queue, portCheckerQueue
 
 logger = logging.getLogger('default')
@@ -29,9 +29,9 @@ def getDiscoveredPeer():
 
 def chooseConnection(stream):
     """Returns an appropriate connection"""
-    haveOnion = BMConfigParser().safeGet(
+    haveOnion = config.safeGet(
         "bitmessagesettings", "socksproxytype")[0:5] == 'SOCKS'
-    onionOnly = BMConfigParser().safeGetBoolean(
+    onionOnly = config.safeGetBoolean(
         "bitmessagesettings", "onionservicesonly")
     try:
         retval = portCheckerQueue.get(False)
diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py
index fffc0bc3..78132cb7 100644
--- a/src/network/connectionpool.py
+++ b/src/network/connectionpool.py
@@ -13,7 +13,7 @@ import helper_random
 import knownnodes
 import protocol
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from connectionchooser import chooseConnection
 from node import Peer
 from proxy import Proxy
@@ -46,9 +46,9 @@ class BMConnectionPool(object):
 
     def __init__(self):
         asyncore.set_rates(
-            BMConfigParser().safeGetInt(
+            config.safeGetInt(
                 "bitmessagesettings", "maxdownloadrate"),
-            BMConfigParser().safeGetInt(
+            config.safeGetInt(
                 "bitmessagesettings", "maxuploadrate")
         )
         self.outboundConnections = {}
@@ -60,7 +60,7 @@ class BMConnectionPool(object):
         self._spawnWait = 2
         self._bootstrapped = False
 
-        trustedPeer = BMConfigParser().safeGet(
+        trustedPeer = config.safeGet(
             'bitmessagesettings', 'trustedpeer')
         try:
             if trustedPeer:
@@ -163,27 +163,27 @@ class BMConnectionPool(object):
     @staticmethod
     def getListeningIP():
         """What IP are we supposed to be listening on?"""
-        if BMConfigParser().safeGet(
+        if config.safeGet(
                 "bitmessagesettings", "onionhostname").endswith(".onion"):
-            host = BMConfigParser().safeGet(
+            host = config.safeGet(
                 "bitmessagesettings", "onionbindip")
         else:
             host = '127.0.0.1'
         if (
-            BMConfigParser().safeGetBoolean("bitmessagesettings", "sockslisten")
-            or BMConfigParser().safeGet("bitmessagesettings", "socksproxytype")
+            config.safeGetBoolean("bitmessagesettings", "sockslisten")
+            or config.safeGet("bitmessagesettings", "socksproxytype")
             == "none"
         ):
             # python doesn't like bind + INADDR_ANY?
             # host = socket.INADDR_ANY
-            host = BMConfigParser().get("network", "bind")
+            host = config.get("network", "bind")
         return host
 
     def startListening(self, bind=None):
         """Open a listening socket and start accepting connections on it"""
         if bind is None:
             bind = self.getListeningIP()
-        port = BMConfigParser().safeGetInt("bitmessagesettings", "port")
+        port = config.safeGetInt("bitmessagesettings", "port")
         # correct port even if it changed
         ls = TCPServer(host=bind, port=port)
         self.listeningSockets[ls.destination] = ls
@@ -205,7 +205,7 @@ class BMConnectionPool(object):
 
     def startBootstrappers(self):
         """Run the process of resolving bootstrap hostnames"""
-        proxy_type = BMConfigParser().safeGet(
+        proxy_type = config.safeGet(
             'bitmessagesettings', 'socksproxytype')
         # A plugins may be added here
         hostname = None
@@ -237,21 +237,21 @@ class BMConnectionPool(object):
         # defaults to empty loop if outbound connections are maxed
         spawnConnections = False
         acceptConnections = True
-        if BMConfigParser().safeGetBoolean(
+        if config.safeGetBoolean(
                 'bitmessagesettings', 'dontconnect'):
             acceptConnections = False
-        elif BMConfigParser().safeGetBoolean(
+        elif config.safeGetBoolean(
                 'bitmessagesettings', 'sendoutgoingconnections'):
             spawnConnections = True
-        socksproxytype = BMConfigParser().safeGet(
+        socksproxytype = config.safeGet(
             'bitmessagesettings', 'socksproxytype', '')
-        onionsocksproxytype = BMConfigParser().safeGet(
+        onionsocksproxytype = config.safeGet(
             'bitmessagesettings', 'onionsocksproxytype', '')
         if (
             socksproxytype[:5] == 'SOCKS'
-            and not BMConfigParser().safeGetBoolean(
+            and not config.safeGetBoolean(
                 'bitmessagesettings', 'sockslisten')
-            and '.onion' not in BMConfigParser().safeGet(
+            and '.onion' not in config.safeGet(
                 'bitmessagesettings', 'onionhostname', '')
         ):
             acceptConnections = False
@@ -264,9 +264,9 @@ class BMConnectionPool(object):
             if not self._bootstrapped:
                 self._bootstrapped = True
                 Proxy.proxy = (
-                    BMConfigParser().safeGet(
+                    config.safeGet(
                         'bitmessagesettings', 'sockshostname'),
-                    BMConfigParser().safeGetInt(
+                    config.safeGetInt(
                         'bitmessagesettings', 'socksport')
                 )
                 # TODO AUTH
@@ -275,9 +275,9 @@ class BMConnectionPool(object):
                     if not onionsocksproxytype.startswith("SOCKS"):
                         raise ValueError
                     Proxy.onion_proxy = (
-                        BMConfigParser().safeGet(
+                        config.safeGet(
                             'network', 'onionsockshostname', None),
-                        BMConfigParser().safeGet(
+                        config.safeGet(
                             'network', 'onionsocksport', None)
                     )
                 except ValueError:
@@ -286,7 +286,7 @@ class BMConnectionPool(object):
                 1 for c in self.outboundConnections.values()
                 if (c.connected and c.fullyEstablished))
             pending = len(self.outboundConnections) - established
-            if established < BMConfigParser().safeGetInt(
+            if established < config.safeGetInt(
                     'bitmessagesettings', 'maxoutboundconnections'):
                 for i in range(
                         state.maximumNumberOfHalfOpenConnections - pending):
@@ -340,22 +340,22 @@ class BMConnectionPool(object):
 
         if acceptConnections:
             if not self.listeningSockets:
-                if BMConfigParser().safeGet('network', 'bind') == '':
+                if config.safeGet('network', 'bind') == '':
                     self.startListening()
                 else:
                     for bind in re.sub(
                         r'[^\w.]+', ' ',
-                        BMConfigParser().safeGet('network', 'bind')
+                        config.safeGet('network', 'bind')
                     ).split():
                         self.startListening(bind)
                 logger.info('Listening for incoming connections.')
             if not self.udpSockets:
-                if BMConfigParser().safeGet('network', 'bind') == '':
+                if config.safeGet('network', 'bind') == '':
                     self.startUDPSocket()
                 else:
                     for bind in re.sub(
                         r'[^\w.]+', ' ',
-                        BMConfigParser().safeGet('network', 'bind')
+                        config.safeGet('network', 'bind')
                     ).split():
                         self.startUDPSocket(bind)
                     self.startUDPSocket(False)
diff --git a/src/network/knownnodes.py b/src/network/knownnodes.py
index 4840aad9..79912a67 100644
--- a/src/network/knownnodes.py
+++ b/src/network/knownnodes.py
@@ -16,7 +16,7 @@ except ImportError:
     from collections import Iterable
 
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from network.node import Peer
 
 state.Peer = Peer
@@ -130,7 +130,7 @@ def addKnownNode(stream, peer, lastseen=None, is_self=False):
             return
 
     if not is_self:
-        if len(knownNodes[stream]) > BMConfigParser().safeGetInt(
+        if len(knownNodes[stream]) > config.safeGetInt(
                 "knownnodes", "maxnodes"):
             return
 
@@ -165,8 +165,6 @@ def readKnownNodes():
             'Failed to read nodes from knownnodes.dat', exc_info=True)
         createDefaultKnownNodes()
 
-    config = BMConfigParser()
-
     # your own onion address, if setup
     onionhostname = config.safeGet('bitmessagesettings', 'onionhostname')
     if onionhostname and ".onion" in onionhostname:
@@ -210,7 +208,7 @@ def decreaseRating(peer):
 def trimKnownNodes(recAddrStream=1):
     """Triming Knownnodes"""
     if len(knownNodes[recAddrStream]) < \
-            BMConfigParser().safeGetInt("knownnodes", "maxnodes"):
+            config.safeGetInt("knownnodes", "maxnodes"):
         return
     with knownNodesLock:
         oldestList = sorted(
diff --git a/src/network/proxy.py b/src/network/proxy.py
index 3bd3cc66..ed1af127 100644
--- a/src/network/proxy.py
+++ b/src/network/proxy.py
@@ -8,7 +8,7 @@ import time
 
 import asyncore_pollchoose as asyncore
 from advanceddispatcher import AdvancedDispatcher
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from node import Peer
 
 logger = logging.getLogger('default')
@@ -114,12 +114,12 @@ class Proxy(AdvancedDispatcher):
         self.isOutbound = True
         self.fullyEstablished = False
         self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
-        if BMConfigParser().safeGetBoolean(
+        if config.safeGetBoolean(
                 "bitmessagesettings", "socksauthentication"):
             self.auth = (
-                BMConfigParser().safeGet(
+                config.safeGet(
                     "bitmessagesettings", "socksusername"),
-                BMConfigParser().safeGet(
+                config.safeGet(
                     "bitmessagesettings", "sockspassword"))
         else:
             self.auth = None
diff --git a/src/network/tcp.py b/src/network/tcp.py
index ff778378..14fc72f0 100644
--- a/src/network/tcp.py
+++ b/src/network/tcp.py
@@ -16,7 +16,7 @@ import helper_random
 import knownnodes
 import protocol
 import state
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_random import randomBytes
 from inventory import Inventory
 from network.advanceddispatcher import AdvancedDispatcher
@@ -177,7 +177,7 @@ class TCPConnection(BMProto, TLSDispatcher):
         # We are going to share a maximum number of 1000 addrs (per overlapping
         # stream) with our peer. 500 from overlapping streams, 250 from the
         # left child stream, and 250 from the right child stream.
-        maxAddrCount = BMConfigParser().safeGetInt(
+        maxAddrCount = config.safeGetInt(
             "bitmessagesettings", "maxaddrperstreamsend", 500)
 
         templist = []
@@ -406,9 +406,9 @@ class TCPServer(AdvancedDispatcher):
             else:
                 if attempt > 0:
                     logger.warning('Setting port to %s', port)
-                    BMConfigParser().set(
+                    config.set(
                         'bitmessagesettings', 'port', str(port))
-                    BMConfigParser().save()
+                    config.save()
                 break
         self.destination = Peer(host, port)
         self.bound = True
@@ -431,9 +431,9 @@ class TCPServer(AdvancedDispatcher):
         state.ownAddresses[Peer(*sock.getsockname())] = True
         if (
             len(connectionpool.BMConnectionPool())
-            > BMConfigParser().safeGetInt(
+            > config.safeGetInt(
                 'bitmessagesettings', 'maxtotalconnections')
-                + BMConfigParser().safeGetInt(
+                + config.safeGetInt(
                     'bitmessagesettings', 'maxbootstrapconnections') + 10
         ):
             # 10 is a sort of buffer, in between it will go through
diff --git a/src/openclpow.py b/src/openclpow.py
index 1091f555..938ffc81 100644
--- a/src/openclpow.py
+++ b/src/openclpow.py
@@ -6,7 +6,7 @@ import os
 from struct import pack
 
 import paths
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from state import shutdown
 
 try:
@@ -42,7 +42,7 @@ def initCL():
         try:
             for platform in cl.get_platforms():
                 gpus.extend(platform.get_devices(device_type=cl.device_type.GPU))
-                if BMConfigParser().safeGet("bitmessagesettings", "opencl") == platform.vendor:
+                if config.safeGet("bitmessagesettings", "opencl") == platform.vendor:
                     enabledGpus.extend(platform.get_devices(
                         device_type=cl.device_type.GPU))
                 if platform.vendor not in vendors:
diff --git a/src/proofofwork.py b/src/proofofwork.py
index 148d6734..5c9448f1 100644
--- a/src/proofofwork.py
+++ b/src/proofofwork.py
@@ -17,7 +17,7 @@ import paths
 import queues
 import state
 import tr
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 
 bitmsglib = 'bitmsghash.so'
@@ -119,7 +119,7 @@ def _doFastPoW(target, initialHash):
     except:  # noqa:E722
         pool_size = 4
     try:
-        maxCores = BMConfigParser().getint('bitmessagesettings', 'maxcores')
+        maxCores = config.getint('bitmessagesettings', 'maxcores')
     except:  # noqa:E722
         maxCores = 99999
     if pool_size > maxCores:
diff --git a/src/protocol.py b/src/protocol.py
index 1934d9cc..6ee35d53 100644
--- a/src/protocol.py
+++ b/src/protocol.py
@@ -18,7 +18,7 @@ import highlevelcrypto
 import state
 from addresses import (
     encodeVarint, decodeVarint, decodeAddress, varintDecodeError)
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from fallback import RIPEMD160Hash
 from helper_sql import sqlExecute
@@ -72,7 +72,7 @@ def getBitfield(address):
     # bitfield of features supported by me (see the wiki).
     bitfield = 0
     # send ack
-    if not BMConfigParser().safeGetBoolean(address, 'dontsendack'):
+    if not config.safeGetBoolean(address, 'dontsendack'):
         bitfield |= BITFIELD_DOESACK
     return pack('>I', bitfield)
 
@@ -238,7 +238,7 @@ def haveSSL(server=False):
 
 def checkSocksIP(host):
     """Predicate to check if we're using a SOCKS proxy"""
-    sockshostname = BMConfigParser().safeGet(
+    sockshostname = config.safeGet(
         'bitmessagesettings', 'sockshostname')
     try:
         if not state.socksIP:
@@ -341,19 +341,19 @@ def assembleVersionMessage(
         '>L', 2130706433)
     # we have a separate extPort and incoming over clearnet
     # or outgoing through clearnet
-    extport = BMConfigParser().safeGetInt('bitmessagesettings', 'extport')
+    extport = config.safeGetInt('bitmessagesettings', 'extport')
     if (
         extport and ((server and not checkSocksIP(remoteHost)) or (
-            BMConfigParser().get('bitmessagesettings', 'socksproxytype')
+            config.get('bitmessagesettings', 'socksproxytype')
             == 'none' and not server))
     ):
         payload += pack('>H', extport)
     elif checkSocksIP(remoteHost) and server:  # incoming connection over Tor
         payload += pack(
-            '>H', BMConfigParser().getint('bitmessagesettings', 'onionport'))
+            '>H', config.getint('bitmessagesettings', 'onionport'))
     else:  # no extport and not incoming over Tor
         payload += pack(
-            '>H', BMConfigParser().getint('bitmessagesettings', 'port'))
+            '>H', config.getint('bitmessagesettings', 'port'))
 
     if nodeid is not None:
         payload += nodeid[0:8]
diff --git a/src/shared.py b/src/shared.py
index 4a654932..d9c1ca13 100644
--- a/src/shared.py
+++ b/src/shared.py
@@ -19,7 +19,7 @@ from binascii import hexlify
 import highlevelcrypto
 import state
 from addresses import decodeAddress, encodeVarint
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from helper_sql import sqlQuery
 
@@ -116,8 +116,8 @@ def reloadMyAddressHashes():
     keyfileSecure = checkSensitiveFilePermissions(os.path.join(
         state.appdata, 'keys.dat'))
     hasEnabledKeys = False
-    for addressInKeysFile in BMConfigParser().addresses():
-        isEnabled = BMConfigParser().getboolean(addressInKeysFile, 'enabled')
+    for addressInKeysFile in config.addresses():
+        isEnabled = config.getboolean(addressInKeysFile, 'enabled')
         if isEnabled:
             hasEnabledKeys = True
             # status
@@ -126,7 +126,7 @@ def reloadMyAddressHashes():
                 # Returns a simple 32 bytes of information encoded
                 # in 64 Hex characters, or null if there was an error.
                 privEncryptionKey = hexlify(decodeWalletImportFormat(
-                    BMConfigParser().get(addressInKeysFile, 'privencryptionkey')))
+                    config.get(addressInKeysFile, 'privencryptionkey')))
                 # It is 32 bytes encoded as 64 hex characters
                 if len(privEncryptionKey) == 64:
                     myECCryptorObjects[hashobj] = \
diff --git a/src/tests/core.py b/src/tests/core.py
index 52cea234..1dca92c0 100644
--- a/src/tests/core.py
+++ b/src/tests/core.py
@@ -21,7 +21,7 @@ import state
 import helper_sent
 import helper_addressbook
 
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from helper_msgcoding import MsgEncode, MsgDecode
 from helper_sql import sqlQuery
 from network import asyncore_pollchoose as asyncore, knownnodes
@@ -66,9 +66,9 @@ class TestCore(unittest.TestCase):
     def tearDown(self):
         """Reset possible unexpected settings after test"""
         knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
-        BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
-        BMConfigParser().remove_option('bitmessagesettings', 'onionservicesonly')
-        BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
+        config.remove_option('bitmessagesettings', 'dontconnect')
+        config.remove_option('bitmessagesettings', 'onionservicesonly')
+        config.set('bitmessagesettings', 'socksproxytype', 'none')
 
     def test_msgcoding(self):
         """test encoding and decoding (originally from helper_msgcoding)"""
@@ -110,7 +110,7 @@ class TestCore(unittest.TestCase):
     @unittest.skip('Bad environment for asyncore.loop')
     def test_tcpconnection(self):
         """initial fill script from network.tcp"""
-        BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
+        config.set('bitmessagesettings', 'dontconnect', 'true')
         try:
             for peer in (Peer("127.0.0.1", 8448),):
                 direct = TCPConnection(peer)
@@ -175,7 +175,7 @@ class TestCore(unittest.TestCase):
                 self.fail("IndexError because of empty knownNodes!")
 
     def _initiate_bootstrap(self):
-        BMConfigParser().set('bitmessagesettings', 'dontconnect', 'true')
+        config.set('bitmessagesettings', 'dontconnect', 'true')
         self._wipe_knownnodes()
         knownnodes.addKnownNode(1, Peer('127.0.0.1', 8444), is_self=True)
         knownnodes.cleanupKnownNodes()
@@ -188,8 +188,8 @@ class TestCore(unittest.TestCase):
         fail otherwise.
         """
         _started = time.time()
-        BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
-        proxy_type = BMConfigParser().safeGet(
+        config.remove_option('bitmessagesettings', 'dontconnect')
+        proxy_type = config.safeGet(
             'bitmessagesettings', 'socksproxytype')
         if proxy_type == 'SOCKS5':
             connection_base = Socks5BMConnection
@@ -250,7 +250,7 @@ class TestCore(unittest.TestCase):
 
     def test_bootstrap(self):
         """test bootstrapping"""
-        BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'none')
+        config.set('bitmessagesettings', 'socksproxytype', 'none')
         self._initiate_bootstrap()
         self._check_connection()
         self._check_knownnodes()
@@ -262,7 +262,7 @@ class TestCore(unittest.TestCase):
     @unittest.skipIf(tor_port_free, 'no running tor detected')
     def test_bootstrap_tor(self):
         """test bootstrapping with tor"""
-        BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
+        config.set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
         self._initiate_bootstrap()
         self._check_connection()
         self._check_knownnodes()
@@ -272,8 +272,8 @@ class TestCore(unittest.TestCase):
         """ensure bitmessage doesn't try to connect to non-onion nodes
         if onionservicesonly set, wait at least 3 onion nodes
         """
-        BMConfigParser().set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
-        BMConfigParser().set('bitmessagesettings', 'onionservicesonly', 'true')
+        config.set('bitmessagesettings', 'socksproxytype', 'SOCKS5')
+        config.set('bitmessagesettings', 'onionservicesonly', 'true')
         self._load_knownnodes(knownnodes_file + '.bak')
         if len([
             node for node in knownnodes.knownNodes[1]
@@ -282,7 +282,7 @@ class TestCore(unittest.TestCase):
             with knownnodes.knownNodesLock:
                 for f in ('a', 'b', 'c', 'd'):
                     knownnodes.addKnownNode(1, Peer(f * 16 + '.onion', 8444))
-        BMConfigParser().remove_option('bitmessagesettings', 'dontconnect')
+        config.remove_option('bitmessagesettings', 'dontconnect')
         tried_hosts = set()
         for _ in range(360):
             time.sleep(1)
@@ -301,7 +301,7 @@ class TestCore(unittest.TestCase):
     def test_udp(self):
         """check default udp setting and presence of Announcer thread"""
         self.assertTrue(
-            BMConfigParser().safeGetBoolean('bitmessagesettings', 'udp'))
+            config.safeGetBoolean('bitmessagesettings', 'udp'))
         for thread in threading.enumerate():
             if thread.name == 'Announcer':  # find Announcer thread
                 break
diff --git a/src/tests/test_config.py b/src/tests/test_config.py
index 7b702016..cb725369 100644
--- a/src/tests/test_config.py
+++ b/src/tests/test_config.py
@@ -1,4 +1,4 @@
-# pylint: disable=no-member
+# pylint: disable=no-member, no-self-use
 """
 Various tests for config
 """
@@ -40,58 +40,59 @@ class TestConfig(unittest.TestCase):
     """A test case for bmconfigparser"""
     configfile = StringIO('')
 
-    def setUp(self):
-        """creates a backup of BMConfigparser current state"""
-        BMConfigParser().write(self.configfile)
-        self.configfile.seek(0)
-
-    def tearDown(self):
-        """restore to the backup of BMConfigparser"""
-        # pylint: disable=protected-access
-        BMConfigParser()._reset()
-        BMConfigParser().readfp(self.configfile)
-
     def test_safeGet(self):
         """safeGet retuns provided default for nonexistent option or None"""
+        config = BMConfigParser()
         self.assertIs(
-            BMConfigParser().safeGet('nonexistent', 'nonexistent'), None)
+            config.safeGet('nonexistent', 'nonexistent'), None)
         self.assertEqual(
-            BMConfigParser().safeGet('nonexistent', 'nonexistent', 42), 42)
+            config.safeGet('nonexistent', 'nonexistent', 42), 42)
 
     def test_safeGetBoolean(self):
         """safeGetBoolean returns False for nonexistent option, no default"""
+        config = BMConfigParser()
         self.assertIs(
-            BMConfigParser().safeGetBoolean('nonexistent', 'nonexistent'),
+            config.safeGetBoolean('nonexistent', 'nonexistent'),
             False
         )
         # no arg for default
         # pylint: disable=too-many-function-args
         with self.assertRaises(TypeError):
-            BMConfigParser().safeGetBoolean(
+            config.safeGetBoolean(
                 'nonexistent', 'nonexistent', True)
 
     def test_safeGetInt(self):
         """safeGetInt retuns provided default for nonexistent option or 0"""
+        config = BMConfigParser()
         self.assertEqual(
-            BMConfigParser().safeGetInt('nonexistent', 'nonexistent'), 0)
+            config.safeGetInt('nonexistent', 'nonexistent'), 0)
         self.assertEqual(
-            BMConfigParser().safeGetInt('nonexistent', 'nonexistent', 42), 42)
+            config.safeGetInt('nonexistent', 'nonexistent', 42), 42)
 
     def test_safeGetFloat(self):
         """safeGetFloat retuns provided default for nonexistent option or 0.0"""
+        config = BMConfigParser()
         self.assertEqual(
-            BMConfigParser().safeGetFloat('nonexistent', 'nonexistent'), 0.0)
+            config.safeGetFloat('nonexistent', 'nonexistent'), 0.0)
         self.assertEqual(
-            BMConfigParser().safeGetFloat('nonexistent', 'nonexistent', 42.0), 42.0)
+            config.safeGetFloat('nonexistent', 'nonexistent', 42.0), 42.0)
 
     def test_reset(self):
         """safeGetInt retuns provided default for bitmessagesettings option or 0"""
+        config = BMConfigParser()
         test_config_object = StringIO(test_config)
-        BMConfigParser().readfp(test_config_object)
-
+        config.readfp(test_config_object)
         self.assertEqual(
-            BMConfigParser().safeGetInt('bitmessagesettings', 'maxaddrperstreamsend'), 100)
+            config.safeGetInt('bitmessagesettings', 'maxaddrperstreamsend'), 100)
         # pylint: disable=protected-access
-        BMConfigParser()._reset()
+        config._reset()
+        self.assertEqual(config.sections(), [])
+
+    def test_defaults(self):
+        """Loading defaults"""
+        config = BMConfigParser()
+        config.add_section('bitmessagesettings')
+        config.set("bitmessagesettings", "maxaddrperstreamsend", "100")
+        config.read()
         self.assertEqual(
-            BMConfigParser().safeGetInt('bitmessagesettings', 'maxaddrperstreamsend'), 500)
+            config.safeGetInt('bitmessagesettings', 'maxaddrperstreamsend'), 500)
diff --git a/src/tests/test_config_process.py b/src/tests/test_config_process.py
index 173d323f..9322a2f0 100644
--- a/src/tests/test_config_process.py
+++ b/src/tests/test_config_process.py
@@ -4,7 +4,7 @@ Various tests for config
 
 import os
 import tempfile
-from pybitmessage.bmconfigparser import BMConfigParser
+from pybitmessage.bmconfigparser import config
 from .test_process import TestProcessProto
 from .common import skip_python3
 
@@ -17,7 +17,6 @@ class TestProcessConfig(TestProcessProto):
 
     def test_config_defaults(self):
         """Test settings in the generated config"""
-        config = BMConfigParser()
         self._stop_process()
         self._kill_process()
         config.read(os.path.join(self.home, 'keys.dat'))
diff --git a/src/upnp.py b/src/upnp.py
index c6db487b..2fa71f9c 100644
--- a/src/upnp.py
+++ b/src/upnp.py
@@ -15,7 +15,7 @@ from xml.dom.minidom import Document, parseString
 import queues
 import state
 import tr
-from bmconfigparser import BMConfigParser
+from bmconfigparser import config
 from debug import logger
 from network import BMConnectionPool, knownnodes, StoppableThread
 from network.node import Peer
@@ -207,7 +207,7 @@ class uPnPThread(StoppableThread):
 
     def __init__(self):
         super(uPnPThread, self).__init__(name="uPnPThread")
-        self.extPort = BMConfigParser().safeGetInt('bitmessagesettings', 'extport', default=None)
+        self.extPort = config.safeGetInt('bitmessagesettings', 'extport', default=None)
         self.localIP = self.getLocalIP()
         self.routers = []
         self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
@@ -233,9 +233,9 @@ class uPnPThread(StoppableThread):
                 time.sleep(1)
 
         # pylint: disable=attribute-defined-outside-init
-        self.localPort = BMConfigParser().getint('bitmessagesettings', 'port')
+        self.localPort = config.getint('bitmessagesettings', 'port')
 
-        while state.shutdown == 0 and BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp'):
+        while state.shutdown == 0 and config.safeGetBoolean('bitmessagesettings', 'upnp'):
             if time.time() - lastSent > self.sendSleep and not self.routers:
                 try:
                     self.sendSearchRouter()
@@ -243,7 +243,7 @@ class uPnPThread(StoppableThread):
                     pass
                 lastSent = time.time()
             try:
-                while state.shutdown == 0 and BMConfigParser().safeGetBoolean('bitmessagesettings', 'upnp'):
+                while state.shutdown == 0 and config.safeGetBoolean('bitmessagesettings', 'upnp'):
                     resp, (ip, _) = self.sock.recvfrom(1000)
                     if resp is None:
                         continue
@@ -337,8 +337,8 @@ class uPnPThread(StoppableThread):
                     extPort)
                 router.AddPortMapping(extPort, self.localPort, localIP, 'TCP', 'BitMessage')
                 self.extPort = extPort
-                BMConfigParser().set('bitmessagesettings', 'extport', str(extPort))
-                BMConfigParser().save()
+                config.set('bitmessagesettings', 'extport', str(extPort))
+                config.save()
                 break
             except UPnPError:
                 logger.debug("UPnP error: ", exc_info=True)