diff --git a/gui/slick/js/configProviders.js b/gui/slick/js/configProviders.js
index 05d93164b7320c1976db57db469f0fd0bc06e3a2..dfbe3000168b3f80f51518a769b8b169927ee3d7 100644
--- a/gui/slick/js/configProviders.js
+++ b/gui/slick/js/configProviders.js
@@ -54,7 +54,9 @@ $(document).ready(function() {
     const newznabProviders = [];
     const torrentRssProviders = [];
 
-    $.fn.addProvider = function(id, name, url, key, cat, isDefault, showProvider) { // eslint-disable-line max-params
+    const newznabProvidersCapabilities = [];
+
+    $.fn.addProvider = function(id, name, url, key, cat, isDefault) { // eslint-disable-line max-params
         url = $.trim(url);
         if (!url) {
             return;
@@ -68,32 +70,30 @@ $(document).ready(function() {
             url += '/';
         }
 
-        const newData = [isDefault, [name, url, key, cat]];
-        newznabProviders[id] = newData;
+        newznabProviders[id] = [isDefault, [name, url, key, cat]];
 
         $('#editANewznabProvider').addOption(id, name);
         $(this).populateNewznabSection();
 
-        if ($('#provider_order_list > #' + id).length === 0 && showProvider !== false) {
-            const toAdd = '<li class="ui-state-default" id="' + id + '"> <input type="checkbox" id="enable_' + id + '" class="provider_enabler" CHECKED> <a href="' + anonURL + url + '" class="imgLink" target="_new"><img src="' + srRoot + '/images/providers/newznab.png" alt="' + name + '" width="16" height="16"></a> ' + name + '</li>';
-
-            $('#provider_order_list').append(toAdd);
-            $('#provider_order_list').sortable('refresh');
+        if ($('#provider_order_list > #' + id).length === 0) {
+            let providerOrderList = $('#provider_order_list');
+            providerOrderList.append('<li class="ui-state-default" id="' + id + '"> <input type="checkbox" id="enable_' + id + '" class="provider_enabler" CHECKED> <a href="' + anonURL + url + '" class="imgLink" target="_new"><img src="' + srRoot + '/images/providers/newznab.png" alt="' + name + '" width="16" height="16"></a> ' + name + '</li>');
+            providerOrderList.sortable('refresh');
         }
 
         $(this).makeNewznabProviderString();
     };
 
     $.fn.addTorrentRssProvider = function(id, name, url, cookies, titleTAG) { // eslint-disable-line max-params
-        const newData = [name, url, cookies, titleTAG];
-        torrentRssProviders[id] = newData;
+        torrentRssProviders[id] = [name, url, cookies, titleTAG];
 
         $('#editATorrentRssProvider').addOption(id, name);
         $(this).populateTorrentRssSection();
 
         if ($('#provider_order_list > #' + id).length === 0) {
-            $('#provider_order_list').append('<li class="ui-state-default" id="' + id + '"> <input type="checkbox" id="enable_' + id + '" class="provider_enabler" CHECKED> <a href="' + anonURL + url + '" class="imgLink" target="_new"><img src="' + srRoot + '/images/providers/torrentrss.png" alt="' + name + '" width="16" height="16"></a> ' + name + '</li>');
-            $('#provider_order_list').sortable('refresh');
+            let providerOrderList = $('#provider_order_list');
+            providerOrderList.append('<li class="ui-state-default" id="' + id + '"> <input type="checkbox" id="enable_' + id + '" class="provider_enabler" CHECKED> <a href="' + anonURL + url + '" class="imgLink" target="_new"><img src="' + srRoot + '/images/providers/torrentrss.png" alt="' + name + '" width="16" height="16"></a> ' + name + '</li>');
+            providerOrderList.sortable('refresh');
         }
 
         $(this).makeTorrentRssProviderString();
@@ -204,7 +204,7 @@ $(document).ready(function() {
             }
 
             // Get Categories Capabilities
-            if (data[0] && data[1] && data[2] && !ifExists($.fn.newznabProvidersCapabilities, data[0])) {
+            if (data[0] && data[1] && data[2] && !ifExists(newznabProvidersCapabilities, data[0])) {
                 $(this).getCategories(isDefault, data);
             }
             $(this).updateNewznabCaps(null, data);
@@ -212,22 +212,22 @@ $(document).ready(function() {
     };
 
     /**
-     * Updates the Global array $.fn.newznabProvidersCapabilities with a combination of newznab prov name
+     * Updates the Global constant array newznabProvidersCapabilities with a combination of newznab prov name
      * and category capabilities. Return
      * @param {Array} newzNabCaps, is the returned object with newznabprovider Name and Capabilities.
      * @param {Array} selectedProvider
      * @return no return data. The multiselect input $("#newznab_cap") is updated, as a result.
      */
     $.fn.updateNewznabCaps = function(newzNabCaps, selectedProvider) {
-        if (newzNabCaps && !ifExists($.fn.newznabProvidersCapabilities, selectedProvider[0])) {
-            $.fn.newznabProvidersCapabilities.push({name: selectedProvider[0], categories: newzNabCaps.tv_categories});
+        if (newzNabCaps && !ifExists(newznabProvidersCapabilities, selectedProvider[0])) {
+            newznabProvidersCapabilities.push({name: selectedProvider[0], categories: newzNabCaps.tv_categories});
         }
 
         // Loop through the array and if currently selected newznab provider name matches one in the array, use it to
         // update the capabilities select box (on the left).
         $('#newznab_cap').empty();
         if (selectedProvider[0]) {
-            $.fn.newznabProvidersCapabilities.forEach(function(newzNabCap) {
+            newznabProvidersCapabilities.forEach(function(newzNabCap) {
                 if (newzNabCap.name && newzNabCap.name === selectedProvider[0] && newzNabCap.categories instanceof Array) {
                     const newCapOptions = [];
                     newzNabCap.categories.forEach(function(categorySet) {
@@ -243,13 +243,11 @@ $(document).ready(function() {
 
     $.fn.makeNewznabProviderString = function() {
         const provStrings = [];
-
-        for (let id = 0; id < newznabProviders.length; id++) {
-            if ({}.hasOwnProperty.call(newznabProviders, id)) {
+        for (let id in newznabProviders) {
+            if (Object.prototype.hasOwnProperty.call(newznabProviders, id)) {
                 provStrings.push(newznabProviders[id][1].join('|'));
             }
         }
-
         $('#newznab_string').val(provStrings.join('!!!'));
     };
 
@@ -523,9 +521,6 @@ $(document).ready(function() {
         });
     };
 
-    // Initialization stuff
-    $.fn.newznabProvidersCapabilities = [];
-
     $(this).showHideProviders();
 
     $('#provider_order_list').sortable({
diff --git a/gui/slick/views/config_providers.mako b/gui/slick/views/config_providers.mako
index aaebae5c7b8e6db87cc099b41cc5a78a9fcba390..9600daff87c5ebfa461e590aebbef6cca111f052 100644
--- a/gui/slick/views/config_providers.mako
+++ b/gui/slick/views/config_providers.mako
@@ -11,9 +11,8 @@
         $(document).ready(function() {
             $('#config-components').tabs();
             % if sickbeard.USE_NZBS:
-                var show_nzb_providers = ${("false", "true")[bool(sickbeard.USE_NZBS)]};
                 % for curNewznabProvider in sickbeard.newznabProviderList:
-                    $(this).addProvider('${curNewznabProvider.get_id()}', '${curNewznabProvider.name}', '${curNewznabProvider.url}', '${curNewznabProvider.key}', '${curNewznabProvider.catIDs}', ${int(curNewznabProvider.default)}, show_nzb_providers);
+                    $(this).addProvider('${curNewznabProvider.get_id()}', '${curNewznabProvider.name}', '${curNewznabProvider.url}', '${curNewznabProvider.key}', '${curNewznabProvider.catIDs}', ${int(curNewznabProvider.default)});
                 % endfor
             % endif
             % if sickbeard.USE_TORRENTS:
@@ -50,8 +49,8 @@
                         <p>${_('At least one provider is required but two are recommended.')}</p>
 
                         % if not sickbeard.USE_NZBS or not sickbeard.USE_TORRENTS:
-                            <blockquote style="margin: 20px 0;">NZB/${_('Torrent providers can be toggled in ')}
-                                <b><a href="${srRoot}/config/search">Search Settings</a></b></blockquote>
+                            <blockquote style="margin: 20px 0;">NZB/${_('Torrent and NZB providers can be toggled in ')}
+                                <b><a href="/config/search">Search Settings</a></b></blockquote>
                         % else:
                             <br>
                         % endif
@@ -78,9 +77,9 @@
 
                                 curName = curProvider.get_id()
                                 if hasattr(curProvider, 'custom_url'):
-                                        curURL = curProvider.custom_url or curProvider.url
+                                    curURL = curProvider.custom_url or curProvider.url
                                 else:
-                                        curURL = curProvider.url
+                                    curURL = curProvider.url
                             %>
                                 <li class="ui-state-default ${('nzb-provider', 'torrent-provider')[bool(curProvider.provider_type == GenericProvider.TORRENT)]}" id="${curName}">
                                     <input type="checkbox" id="enable_${curName}" class="provider_enabler" ${('', 'checked="checked"')[curProvider.is_enabled() is True]}/>
@@ -148,7 +147,7 @@
 
 
                         <!-- start div for editing providers //-->
-                        % for curNewznabProvider in [curProvider for curProvider in sickbeard.newznabProviderList]:
+                        % for curNewznabProvider in sickbeard.newznabProviderList:
                             <div class="providerDiv" id="${curNewznabProvider.get_id()}Div">
                                 % if curNewznabProvider.default and curNewznabProvider.needs_auth:
 
diff --git a/sickbeard/helpers.py b/sickbeard/helpers.py
index 19758f3ae1867b867b0f9ee9404afcb2be84787d..2aaf09b675bf7eff68d024b71022f526b4bf1481 100644
--- a/sickbeard/helpers.py
+++ b/sickbeard/helpers.py
@@ -63,6 +63,7 @@ import sickbeard
 from sickbeard import classes, db, logger
 from sickbeard.common import USER_AGENT
 from sickrage.helper import episode_num, MEDIA_EXTENSIONS, pretty_file_size, SUBTITLE_EXTENSIONS
+from sickrage.helper.common import replace_extension
 from sickrage.helper.encoding import ek
 from sickrage.helper.exceptions import ex
 from sickrage.show.Show import Show
@@ -1480,6 +1481,8 @@ def download_file(url, filename, session=None, headers=None, **kwargs):  # pylin
     :return: True on success, False on failure
     """
 
+    return_filename = kwargs.get('return_filename', False)
+
     try:
         hooks, cookies, verify, proxies = request_defaults(kwargs)
 
@@ -1490,10 +1493,8 @@ def download_file(url, filename, session=None, headers=None, **kwargs):  # pylin
             resp.raise_for_status()
 
             # Workaround for jackett.
-            if resp.headers.get('content-type') == 'application/x-bittorrent':
-                group = re.findall('filename=["\'](.+)["\']', resp.headers.get('content-disposition', ''))
-                if group:
-                    filename = group[0]
+            if filename.endswith('nzb') and resp.headers.get('content-type') == 'application/x-bittorrent':
+                filename = replace_extension(filename, 'torrent')
 
             try:
                 with io.open(filename, 'wb') as fp:
@@ -1508,9 +1509,9 @@ def download_file(url, filename, session=None, headers=None, **kwargs):  # pylin
 
     except Exception as error:
         handle_requests_exception(error)
-        return False
+        return False if not return_filename else ""
 
-    return True
+    return True if not return_filename else filename
 
 
 def handle_requests_exception(requests_exception):  # pylint: disable=too-many-branches, too-many-statements
diff --git a/sickbeard/providers/newznab.py b/sickbeard/providers/newznab.py
index 83bff45bc8662b685ae9a22071ef0279c3adae4c..e21863a70c2ae9f507bd778afb6bcc1658a1f5db 100644
--- a/sickbeard/providers/newznab.py
+++ b/sickbeard/providers/newznab.py
@@ -282,7 +282,6 @@ class NewznabProvider(NZBProvider):  # pylint: disable=too-many-instance-attribu
                 return results
 
         for mode in search_strings:
-            torznab = False
             search_params = {
                 't': ('search', 'tvsearch')[bool(self.use_tv_search)],
                 'limit': 100,
@@ -330,9 +329,9 @@ class NewznabProvider(NZBProvider):  # pylint: disable=too-many-instance-attribu
                         break
 
                     try:
-                        torznab = 'xmlns:torznab' in html.rss.attrs
+                        self.torznab = 'xmlns:torznab' in html.rss.attrs
                     except AttributeError:
-                        torznab = False
+                        self.torznab = False
 
                     for item in html('item'):
                         try:
@@ -362,7 +361,7 @@ class NewznabProvider(NZBProvider):  # pylint: disable=too-many-instance-attribu
                                     seeders = try_int(attr['value']) if attr['name'] == 'seeders' else seeders
                                     leechers = try_int(attr['value']) if attr['name'] == 'peers' else leechers
 
-                            if not item_size or (torznab and (seeders is None or leechers is None)):
+                            if not item_size or (self.torznab and (seeders is None or leechers is None)):
                                 continue
 
                             size = convert_size(item_size) or -1
@@ -377,7 +376,7 @@ class NewznabProvider(NZBProvider):  # pylint: disable=too-many-instance-attribu
                 if 'tvdbid' in search_params:
                     break
 
-            if torznab:
+            if self.torznab:
                 results.sort(key=lambda d: try_int(d.get('seeders', 0)), reverse=True)
             results += items
 
diff --git a/sickbeard/search.py b/sickbeard/search.py
index 613ab5997c7cc308ad499178599eff555ca2c998..e75efa4e3a340adcd5401c2c6aeff530a1ad1a89 100644
--- a/sickbeard/search.py
+++ b/sickbeard/search.py
@@ -47,11 +47,11 @@ def _downloadResult(result):
         logger.log("Invalid provider name - this is a coding error, report it please", logger.ERROR)
         return False
 
-    # nzbs with an URL can just be downloaded from the provider
-    if result.resultType == "nzb":
+    # nzbs/torrents with an URL can just be downloaded from the provider
+    if result.resultType in (GenericProvider.NZB, GenericProvider.TORRENT):
         newResult = resProvider.download_result(result)
     # if it's an nzb data result
-    elif result.resultType == "nzbdata":
+    elif result.resultType == GenericProvider.NZBDATA:
 
         # get the final file path to the nzb
         fileName = ek(os.path.join, sickbeard.NZB_DIR, result.name + ".nzb")
@@ -70,8 +70,6 @@ def _downloadResult(result):
         except EnvironmentError as e:
             logger.log("Error trying to save NZB to black hole: " + ex(e), logger.ERROR)
             newResult = False
-    elif result.resultType == "torrent":
-        newResult = resProvider.download_result(result)
     else:
         logger.log("Invalid provider type - this is a coding error, report it please", logger.ERROR)
         newResult = False
@@ -101,11 +99,8 @@ def snatchEpisode(result, endStatus=SNATCHED):  # pylint: disable=too-many-branc
 
     endStatus = SNATCHED_PROPER if re.search(r'\b(proper|repack|real)\b', result.name, re.I) else endStatus
 
-    if result.url.startswith('magnet') or result.url.endswith('torrent'):
-        result.resultType = 'torrent'
-
     # NZBs can be sent straight to SAB or saved to disk
-    if result.resultType in ("nzb", "nzbdata"):
+    if result.resultType in (GenericProvider.NZB, GenericProvider.NZBDATA):
         if sickbeard.NZB_METHOD == "blackhole":
             dlResult = _downloadResult(result)
         elif sickbeard.NZB_METHOD == "sabnzbd":
@@ -122,7 +117,7 @@ def snatchEpisode(result, endStatus=SNATCHED):  # pylint: disable=too-many-branc
             dlResult = False
 
     # Torrents can be sent to clients or saved to disk
-    elif result.resultType == "torrent":
+    elif result.resultType == GenericProvider.TORRENT:
         # torrents are saved to disk when blackhole mode
         if sickbeard.TORRENT_METHOD == "blackhole":
             dlResult = _downloadResult(result)
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 8afa32c9e156fa147853034ce119d96c54b823cb..655019036031dab4d935b27587b3934cca9f343c 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -4510,12 +4510,12 @@ class ConfigProviders(Config):
 
         providerDict = dict(zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
 
-        tempProvider = newznab.NewznabProvider(name, '')
+        cur_id = GenericProvider.make_id(name)
 
-        if tempProvider.get_id() in providerDict:
-            return json.dumps({'error': 'Provider Name already exists as ' + providerDict[tempProvider.get_id()].name})
+        if cur_id in providerDict:
+            return json.dumps({'error': 'Provider Name already exists as ' + name})
         else:
-            return json.dumps({'success': tempProvider.get_id()})
+            return json.dumps({'success': cur_id})
 
     @staticmethod
     def getNewznabCategories(name, url, key):
@@ -4601,75 +4601,56 @@ class ConfigProviders(Config):
         return '1'
 
     def saveProviders(self, newznab_string='', torrentrss_string='', provider_order=None, **kwargs):
-        provider_str_list = provider_order.split()
-        provider_list = []
-
         newznabProviderDict = dict(
             zip([x.get_id() for x in sickbeard.newznabProviderList], sickbeard.newznabProviderList))
 
-        finishedNames = []
+        finished_names = []
 
         # add all the newznab info we got into our list
-        if newznab_string:
-            for curNewznabProviderStr in newznab_string.split('!!!'):
-
-                if not curNewznabProviderStr:
-                    continue
-
-                cur_name, cur_url, cur_key, cur_cat = curNewznabProviderStr.split('|')
-                cur_url = config.clean_url(cur_url)
-
-                newProvider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key)
-
-                cur_id = newProvider.get_id()
-
-                # if it already exists then update it
-                if cur_id in newznabProviderDict:
-                    newznabProviderDict[cur_id].name = cur_name
-                    newznabProviderDict[cur_id].url = cur_url
-                    newznabProviderDict[cur_id].key = cur_key
-                    newznabProviderDict[cur_id].catIDs = cur_cat
-                    # a 0 in the key spot indicates that no key is needed
-                    if cur_key == '0':
-                        newznabProviderDict[cur_id].needs_auth = False
-                    else:
-                        newznabProviderDict[cur_id].needs_auth = True
-
-                    try:
-                        newznabProviderDict[cur_id].search_mode = str(kwargs[cur_id + '_search_mode']).strip()
-                    except Exception:
-                        pass
-
-                    try:
-                        newznabProviderDict[cur_id].search_fallback = config.checkbox_to_value(
-                            kwargs[cur_id + '_search_fallback'])
-                    except Exception:
-                        newznabProviderDict[cur_id].search_fallback = 0
+        if not newznab_string:
+            logger.log('No newznab_string passed to saveProviders', logger.ERROR)
+            # newznab_string = sickbeard.NEWZNAB_DATA
 
-                    try:
-                        newznabProviderDict[cur_id].enable_daily = config.checkbox_to_value(
-                            kwargs[cur_id + '_enable_daily'])
-                    except Exception:
-                        newznabProviderDict[cur_id].enable_daily = 0
-
-                    try:
-                        newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(
-                            kwargs[cur_id + '_enable_backlog'])
-                    except Exception:
-                        newznabProviderDict[cur_id].enable_backlog = 0
-                else:
-                    sickbeard.newznabProviderList.append(newProvider)
-
-                finishedNames.append(cur_id)
+        for curNewznabProviderStr in newznab_string.split('!!!'):
+            if not curNewznabProviderStr:
+                continue
 
-        # delete anything that is missing
-        for curProvider in sickbeard.newznabProviderList:
-            if curProvider.get_id() not in finishedNames:
-                sickbeard.newznabProviderList.remove(curProvider)
+            cur_name, cur_url, cur_key, cur_cat = curNewznabProviderStr.split('|')
+            cur_url = config.clean_url(cur_url)
+            cur_id = GenericProvider.make_id(cur_name)
+
+            # if it does not already exist then add it
+            if cur_id not in newznabProviderDict:
+                new_provider = newznab.NewznabProvider(cur_name, cur_url, key=cur_key, catIDs=cur_cat)
+                sickbeard.newznabProviderList.append(new_provider)
+                newznabProviderDict[cur_id] = new_provider
+
+            # set all params
+            newznabProviderDict[cur_id].name = cur_name
+            newznabProviderDict[cur_id].url = cur_url
+            newznabProviderDict[cur_id].key = cur_key
+            newznabProviderDict[cur_id].catIDs = cur_cat
+            # a 0 in the key spot indicates that no key is needed
+            newznabProviderDict[cur_id].needs_auth = cur_key and cur_key != '0'
+            newznabProviderDict[cur_id].search_mode = str(kwargs.get(cur_id + '_search_mode', 'eponly')).strip()
+            newznabProviderDict[cur_id].search_fallback = config.checkbox_to_value(kwargs.get(cur_id + 'search_fallback', 0), value_on=1, value_off=0)
+            newznabProviderDict[cur_id].enable_daily = config.checkbox_to_value(kwargs.get(cur_id + 'enable_daily', 0), value_on=1, value_off=0)
+            newznabProviderDict[cur_id].enable_backlog = config.checkbox_to_value(kwargs.get(cur_id + 'enable_backlog', 0), value_on=1, value_off=0)
+
+            # mark it finished
+            finished_names.append(cur_id)
+
+        # delete anything that is in the list that was not processed just now
+        if newznab_string:
+            for curProvider in sickbeard.newznabProviderList:
+                if curProvider.get_id() not in finished_names:
+                    sickbeard.newznabProviderList.remove(curProvider)
+                    del newznabProviderDict[curProvider.get_id()]
 
         torrentRssProviderDict = dict(
             zip([x.get_id() for x in sickbeard.torrentRssProviderList], sickbeard.torrentRssProviderList))
-        finishedNames = []
+
+        finished_names = []
 
         if torrentrss_string:
             for curTorrentRssProviderStr in torrentrss_string.split('!!!'):
@@ -4677,51 +4658,52 @@ class ConfigProviders(Config):
                 if not curTorrentRssProviderStr:
                     continue
 
-                curName, curURL, curCookies, curTitleTAG = curTorrentRssProviderStr.split('|')
-                curURL = config.clean_url(curURL)
+                cur_name, cur_url, cur_cookies, cur_title_tag = curTorrentRssProviderStr.split('|')
+                cur_url = config.clean_url(cur_url)
+                cur_id = GenericProvider.make_id(cur_name)
 
-                newProvider = rsstorrent.TorrentRssProvider(curName, curURL, curCookies, curTitleTAG)
+                # if it does not already exist then create it
+                if cur_id not in torrentRssProviderDict:
+                    new_provider = rsstorrent.TorrentRssProvider(cur_name, cur_url, cur_cookies, cur_title_tag)
+                    sickbeard.torrentRssProviderList.append(new_provider)
+                    torrentRssProviderDict[cur_id] = new_provider
 
-                curID = newProvider.get_id()
+                # update values
+                torrentRssProviderDict[cur_id].name = cur_name
+                torrentRssProviderDict[cur_id].url = cur_url
+                torrentRssProviderDict[cur_id].cookies = cur_cookies
+                torrentRssProviderDict[cur_id].cur_title_tag = cur_title_tag
 
-                # if it already exists then update it
-                if curID in torrentRssProviderDict:
-                    torrentRssProviderDict[curID].name = curName
-                    torrentRssProviderDict[curID].url = curURL
-                    torrentRssProviderDict[curID].cookies = curCookies
-                    torrentRssProviderDict[curID].curTitleTAG = curTitleTAG
-                else:
-                    sickbeard.torrentRssProviderList.append(newProvider)
-
-                finishedNames.append(curID)
+                # mark it finished
+                finished_names.append(cur_id)
 
         # delete anything that is missing
         for curProvider in sickbeard.torrentRssProviderList:
-            if curProvider.get_id() not in finishedNames:
+            if curProvider.get_id() not in finished_names:
                 sickbeard.torrentRssProviderList.remove(curProvider)
+                del torrentRssProviderDict[curProvider.get_id()]
 
-        disabled_list = []
         # do the enable/disable
-        for curProviderStr in provider_str_list:
-            curProvider, curEnabled = curProviderStr.split(':')
-            curEnabled = bool(try_int(curEnabled))
+        enabled_provider_list = []
+        disabled_provider_list = []
+        for cur_id, cur_enabled in (cur_provider_str.split(':') for cur_provider_str in provider_order.split()):
+            cur_enabled = bool(try_int(cur_enabled))
 
-            curProvObj = [x for x in sickbeard.providers.sortedProviderList() if
-                          x.get_id() == curProvider and hasattr(x, 'enabled')]
-            if curProvObj:
-                curProvObj[0].enabled = curEnabled
+            cur_provider_obj = [x for x in sickbeard.providers.sortedProviderList() if
+                          x.get_id() == cur_id and hasattr(x, 'enabled')]
 
-            if curEnabled:
-                provider_list.append(curProvider)
-            else:
-                disabled_list.append(curProvider)
+            if cur_provider_obj:
+                cur_provider_obj[0].enabled = cur_enabled
 
-            if curProvider in newznabProviderDict:
-                newznabProviderDict[curProvider].enabled = curEnabled
-            elif curProvider in torrentRssProviderDict:
-                torrentRssProviderDict[curProvider].enabled = curEnabled
+            if cur_enabled:
+                enabled_provider_list.append(cur_id)
+            else:
+                disabled_provider_list.append(cur_id)
 
-        provider_list = provider_list + disabled_list
+            if cur_id in newznabProviderDict:
+                newznabProviderDict[cur_id].enabled = cur_enabled
+            elif cur_id in torrentRssProviderDict:
+                torrentRssProviderDict[cur_id].enabled = cur_enabled
 
         # dynamically load provider settings
         for curTorrentProvider in [prov for prov in sickbeard.providers.sortedProviderList() if
@@ -4924,7 +4906,7 @@ class ConfigProviders(Config):
                     curNzbProvider.enable_backlog = 0  # these exceptions are actually catching unselected checkboxes
 
         sickbeard.NEWZNAB_DATA = '!!!'.join([x.configStr() for x in sickbeard.newznabProviderList])
-        sickbeard.PROVIDER_ORDER = provider_list
+        sickbeard.PROVIDER_ORDER = enabled_provider_list + disabled_provider_list
 
         sickbeard.save_config()
 
diff --git a/sickrage/providers/GenericProvider.py b/sickrage/providers/GenericProvider.py
index b1de4591b82570ad85f29c0218126c7453f1197e..c801b8e316a56070159e5abbb720b8cf0e9d6a2b 100644
--- a/sickrage/providers/GenericProvider.py
+++ b/sickrage/providers/GenericProvider.py
@@ -44,6 +44,7 @@ from sickrage.helper.encoding import ek
 
 class GenericProvider(object):  # pylint: disable=too-many-instance-attributes
     NZB = 'nzb'
+    NZBDATA = 'nzbdata'
     TORRENT = 'torrent'
 
     def __init__(self, name):
@@ -99,16 +100,15 @@ class GenericProvider(object):  # pylint: disable=too-many-instance-attributes
 
             logger.log('Downloading a result from {0} at {1}'.format(self.name, url))
 
-            if url.endswith(GenericProvider.TORRENT) and filename.endswith(GenericProvider.NZB):
-                filename = replace_extension(filename, GenericProvider.TORRENT)
-
-            if download_file(url, filename, session=self.session, headers=self.headers, hooks={'response': self.get_url_hook}):
-                if self._verify_download(filename):
-                    logger.log('Saved result to {0}'.format(filename), logger.INFO)
+            downloaded_filename = download_file(url, filename, session=self.session, headers=self.headers,
+                                                hooks={'response': self.get_url_hook}, return_filename=True)
+            if downloaded_filename:
+                if self._verify_download(downloaded_filename):
+                    logger.log('Saved result to {0}'.format(downloaded_filename), logger.INFO)
                     return True
 
                 logger.log('Could not download {0}'.format(url), logger.WARNING)
-                remove_file_failed(filename)
+                remove_file_failed(downloaded_filename)
 
         if urls:
             logger.log('Failed to download any results', logger.WARNING)
diff --git a/sickrage/providers/nzb/NZBProvider.py b/sickrage/providers/nzb/NZBProvider.py
index 8fd2aceb42f955b1c2abe4e48014332704a1d53b..d053e414a11fa3276a66faa7aa6c023119f96646 100644
--- a/sickrage/providers/nzb/NZBProvider.py
+++ b/sickrage/providers/nzb/NZBProvider.py
@@ -31,12 +31,17 @@ class NZBProvider(GenericProvider):
         GenericProvider.__init__(self, name)
 
         self.provider_type = GenericProvider.NZB
+        self.torznab = False
 
     def is_active(self):
         return bool(sickbeard.USE_NZBS) and self.is_enabled()
 
     def _get_result(self, episodes):
-        return NZBSearchResult(episodes)
+        result = NZBSearchResult(episodes)
+        if self.torznab or result.url.startswith('magnet'):
+            result.resultType = GenericProvider.TORRENT
+
+        return result
 
     def _get_size(self, item):
         try: