diff --git a/HACKS.txt b/HACKS.txt
deleted file mode 100644
index 8750d457e7c6fe083480533902e15542dfb1aaad..0000000000000000000000000000000000000000
--- a/HACKS.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-Libs with customisations...
-
-/tornado
diff --git a/gui/slick/images/network/esquire network.png b/gui/slick/images/network/esquire network.png
new file mode 100644
index 0000000000000000000000000000000000000000..43d4adf0c208f70d83407cf70a9f371fede534a6
Binary files /dev/null and b/gui/slick/images/network/esquire network.png differ
diff --git a/gui/slick/images/network/smithsonian channel.png b/gui/slick/images/network/smithsonian channel.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f811e4202ea9006a95da5c9ed1b2a01f01a83c3
Binary files /dev/null and b/gui/slick/images/network/smithsonian channel.png differ
diff --git a/gui/slick/interfaces/default/apiBuilder.tmpl b/gui/slick/interfaces/default/apiBuilder.tmpl
index fedb826773b5899c0358fb3a7423a34171c3426f..4ff364f3beb8743b8606acdd545d2f1e548f383c 100644
--- a/gui/slick/interfaces/default/apiBuilder.tmpl
+++ b/gui/slick/interfaces/default/apiBuilder.tmpl
@@ -51,6 +51,8 @@ addList("Command", "Scene Exceptions", "?cmd=exceptions", "exceptions");
 addList("Command", "History", "?cmd=history", "history");
 addOption("Command", "History.Clear", "?cmd=history.clear", "", "", "action");
 addOption("Command", "History.Trim", "?cmd=history.trim", "", "", "action");
+addList("Command", "Failed", "?cmd=failed", "failed");
+addOption("Command", "Backlog", "?cmd=backlog");
 addList("Command", "PostProcess", "?cmd=postprocess", "postprocess", "", "","action");
 
 addList("Command", "Logs", "?cmd=logs", "logs");
@@ -321,6 +323,15 @@ addOption("history-limit", "Optional Param", "", 1);
 addOption("history-limit", "Show Only Downloaded", "&type=downloaded");
 addOption("history-limit", "Show Only Snatched", "&type=snatched");
 
+addOption("failed", "Optional Param", "", 1);
+//addOptGroup("failed", "Limit Results");
+addList("failed", "Limit Results (2)", "&limit=2", "failed-limit");
+addList("failed", "Limit Results (25)", "&limit=25", "failed-limit");
+addList("failed", "Limit Results (50)", "&limit=50", "failed-limit");
+//endOptGroup("failed");
+
+addOption("failed-limit", "Optional Param", "", 1);
+
 addOption("exceptions", "Optional Param", "", 1);
 #for $curShow in $sortedShowList:
 addOption("exceptions", "$curShow.name", "&indexerid=$curShow.indexerid");
diff --git a/gui/slick/interfaces/default/config_search.tmpl b/gui/slick/interfaces/default/config_search.tmpl
index a0230412aa83a9f86379f4f0a206398b197519c3..5956180b5bc5c6d09d4e7178a4c7e5264291d259 100755
--- a/gui/slick/interfaces/default/config_search.tmpl
+++ b/gui/slick/interfaces/default/config_search.tmpl
@@ -259,6 +259,16 @@
 									</span>
 								</label>
 							</div>
+
+                            <div class="field-pair">
+								<label>
+									<span class="component-title">Use SABnzbd category for anime</span>
+									<span class="component-desc">
+										<input type="text" name="sab_category_anime" id="sab_category_anime" value="$sickbeard.SAB_CATEGORY_ANIME" class="form-control input-sm input200" />
+										<p>add anime downloads to this category (e.g. anime)</p>
+									</span>
+								</label>
+							</div>
 						</div>
 
 						<div id="nzbget_settings">
@@ -314,6 +324,16 @@
 								</label>
 							</div>
 
+                            <div class="field-pair">
+								<label>
+									<span class="component-title">Use NZBget category for anime</span>
+									<span class="component-desc">
+										<input type="text" name="nzbget_category_anime" id="nzbget_category_anime" value="$sickbeard.NZBGET_CATEGORY_ANIME" class="form-control input-sm input200" />
+										<p>send anime downloads marked this category (e.g. anime)</p>
+									</span>
+								</label>
+							</div>
+
 #set $prio_verylow = ''
 #set $prio_low = ''
 #set $prio_normal = ''
@@ -468,6 +488,18 @@
 								</label>
 							</div>
 
+                            <div class="field-pair" id="torrent_label_anime_option">
+								<label>
+									<span class="component-title">Add label to torrent for anime</span>
+									<span class="component-desc">
+										<input type="text" name="torrent_label_anime" id="torrent_label_anime" value="$sickbeard.TORRENT_LABEL_ANIME" class="form-control input-sm input200" />
+										<span id="label_anime_warning_deluge" style="display:none"><p>(blank spaces are not allowed)</p>
+											<div class="clear-left"><p>note: label plugin must be enabled in Deluge clients</p></div>
+										</span>
+									</span>
+								</label>
+							</div>
+
 							<div class="field-pair" id="torrent_path_option">
 								<label>
 									<span class="component-title" id="directory_title">Downloaded files location</span>
diff --git a/gui/slick/js/configSearch.js b/gui/slick/js/configSearch.js
index ecf7cccf639735fa5fb646f29f962f622704952b..1543cd4d94d8b2db2ac7a2bbee5ce3e3634b6ded 100644
--- a/gui/slick/js/configSearch.js
+++ b/gui/slick/js/configSearch.js
@@ -50,6 +50,7 @@ $(document).ready(function(){
 
         if ('blackhole' != selectedProvider) {
             var label_warning_deluge = '#label_warning_deluge',
+                label_anime_warning_deluge = '#label_anime_warning_deluge',
                 host_desc_rtorrent = '#host_desc_rtorrent',
                 host_desc_torrent = '#host_desc_torrent',
                 torrent_verify_cert_option = '#torrent_verify_cert_option',
@@ -57,10 +58,13 @@ $(document).ready(function(){
                 torrent_seed_time_option = '#torrent_seed_time_option',
                 torrent_high_bandwidth_option = '#torrent_high_bandwidth_option',
                 torrent_label_option = '#torrent_label_option',
+                torrent_label_anime_option = '#torrent_label_anime_option',
                 path_synology = '#path_synology',
                 torrent_paused_option = '#torrent_paused_option';
 
             $(label_warning_deluge).hide();
+            $(label_anime_warning_deluge).hide();
+            $(label_anime_warning_deluge).hide();
             $(host_desc_rtorrent).hide();
             $(host_desc_torrent).show();
             $(torrent_verify_cert_option).hide();
@@ -69,6 +73,7 @@ $(document).ready(function(){
             $(torrent_seed_time_option).hide();
             $(torrent_high_bandwidth_option).hide();
             $(torrent_label_option).show();
+            $(torrent_label_anime_option).show();
             $(path_synology).hide();
             $(torrent_paused_option).show();
 
@@ -81,15 +86,18 @@ $(document).ready(function(){
                 $(torrent_seed_time_option).show();
                 $(torrent_high_bandwidth_option).show();
                 $(torrent_label_option).hide();
+                $(torrent_label_anime_option).hide();
                 //$('#directory_title').text(client + directory);
             } else if ('deluge' == selectedProvider){
                 client = 'Deluge';
                 $(torrent_verify_cert_option).show();
                 $(label_warning_deluge).show();
+                $(label_anime_warning_deluge).show();
                 //$('#directory_title').text(client + directory);
             } else if ('download_station' == selectedProvider){
                 client = 'Synology DS';
                 $(torrent_label_option).hide();
+                $(torrent_label_anime_option).hide();
                 $('#torrent_paused_option').hide();
                 $(torrent_path_option).find('.fileBrowser').hide();
                 //$('#directory_title').text(client + directory);
diff --git a/sickbeard/__init__.py b/sickbeard/__init__.py
index 4c45f39e4c1b4952711c75091db708fc4e87f739..3571ff8a2ec833bc1a86e06f1e70aeee64d0fcda 100755
--- a/sickbeard/__init__.py
+++ b/sickbeard/__init__.py
@@ -255,11 +255,13 @@ SAB_USERNAME = None
 SAB_PASSWORD = None
 SAB_APIKEY = None
 SAB_CATEGORY = None
+SAB_CATEGORY_ANIME = None
 SAB_HOST = ''
 
 NZBGET_USERNAME = None
 NZBGET_PASSWORD = None
 NZBGET_CATEGORY = None
+NZBGET_CATEGORY_ANIME = None
 NZBGET_HOST = None
 NZBGET_USE_HTTPS = False
 NZBGET_PRIORITY = 100
@@ -272,6 +274,7 @@ TORRENT_SEED_TIME = None
 TORRENT_PAUSED = False
 TORRENT_HIGH_BANDWIDTH = False
 TORRENT_LABEL = ''
+TORRENT_LABEL_ANIME = ''
 TORRENT_VERIFY_CERT = False
 
 USE_XBMC = False
@@ -477,9 +480,9 @@ def initialize(consoleLogging=True):
 
         global BRANCH, GIT_REMOTE, GIT_REMOTE_URL, CUR_COMMIT_HASH, CUR_COMMIT_BRANCH, ACTUAL_LOG_DIR, LOG_DIR, WEB_PORT, WEB_LOG, ENCRYPTION_VERSION, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, \
             HANDLE_REVERSE_PROXY, USE_NZBS, USE_TORRENTS, NZB_METHOD, NZB_DIR, DOWNLOAD_PROPERS, CHECK_PROPERS_INTERVAL, ALLOW_HIGH_PRIORITY, TORRENT_METHOD, \
-            SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_HOST, \
-            NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \
-            TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_VERIFY_CERT, \
+            SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_CATEGORY_ANIME, SAB_HOST, \
+            NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_CATEGORY_ANIME, NZBGET_PRIORITY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \
+            TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_LABEL_ANIME, TORRENT_VERIFY_CERT, \
             USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, \
             XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, BACKLOG_FREQUENCY, \
             USE_TRAKT, TRAKT_USERNAME, TRAKT_PASSWORD, TRAKT_API, TRAKT_REMOVE_WATCHLIST, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_USE_RECOMMENDED, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, \
@@ -619,7 +622,8 @@ def initialize(consoleLogging=True):
         ANON_REDIRECT = check_setting_str(CFG, 'General', 'anon_redirect', 'http://dereferer.org/?')
         PROXY_SETTING = check_setting_str(CFG, 'General', 'proxy_setting', '')
         PROXY_INDEXERS = bool(check_setting_int(CFG, 'General', 'proxy_indexers', 1))
-        # attempt to help prevent users from breaking links by using a bad url 
+
+        # attempt to help prevent users from breaking links by using a bad url
         if not ANON_REDIRECT.endswith('?'):
             ANON_REDIRECT = ''
 
@@ -745,11 +749,13 @@ def initialize(consoleLogging=True):
         SAB_PASSWORD = check_setting_str(CFG, 'SABnzbd', 'sab_password', '')
         SAB_APIKEY = check_setting_str(CFG, 'SABnzbd', 'sab_apikey', '')
         SAB_CATEGORY = check_setting_str(CFG, 'SABnzbd', 'sab_category', 'tv')
+        SAB_CATEGORY_ANIME = check_setting_str(CFG, 'SABnzbd', 'sab_category_anime', 'anime')
         SAB_HOST = check_setting_str(CFG, 'SABnzbd', 'sab_host', '')
 
         NZBGET_USERNAME = check_setting_str(CFG, 'NZBget', 'nzbget_username', 'nzbget')
         NZBGET_PASSWORD = check_setting_str(CFG, 'NZBget', 'nzbget_password', 'tegbzn6789')
         NZBGET_CATEGORY = check_setting_str(CFG, 'NZBget', 'nzbget_category', 'tv')
+        NZBGET_CATEGORY_ANIME = check_setting_str(CFG, 'NZBget', 'nzbget_category_anime', 'anime')
         NZBGET_HOST = check_setting_str(CFG, 'NZBget', 'nzbget_host', '')
         NZBGET_USE_HTTPS = bool(check_setting_int(CFG, 'NZBget', 'nzbget_use_https', 0))
         NZBGET_PRIORITY = check_setting_int(CFG, 'NZBget', 'nzbget_priority', 100)
@@ -762,6 +768,7 @@ def initialize(consoleLogging=True):
         TORRENT_PAUSED = bool(check_setting_int(CFG, 'TORRENT', 'torrent_paused', 0))
         TORRENT_HIGH_BANDWIDTH = bool(check_setting_int(CFG, 'TORRENT', 'torrent_high_bandwidth', 0))
         TORRENT_LABEL = check_setting_str(CFG, 'TORRENT', 'torrent_label', '')
+        TORRENT_LABEL_ANIME = check_setting_str(CFG, 'TORRENT', 'torrent_label_anime', '')
         TORRENT_VERIFY_CERT = bool(check_setting_int(CFG, 'TORRENT', 'torrent_verify_cert', 0))
 
         USE_XBMC = bool(check_setting_int(CFG, 'XBMC', 'use_xbmc', 0))
@@ -1588,6 +1595,7 @@ def save_config():
     new_config['SABnzbd']['sab_password'] = helpers.encrypt(SAB_PASSWORD, ENCRYPTION_VERSION)
     new_config['SABnzbd']['sab_apikey'] = SAB_APIKEY
     new_config['SABnzbd']['sab_category'] = SAB_CATEGORY
+    new_config['SABnzbd']['sab_category_anime'] = SAB_CATEGORY_ANIME
     new_config['SABnzbd']['sab_host'] = SAB_HOST
 
     new_config['NZBget'] = {}
@@ -1595,6 +1603,7 @@ def save_config():
     new_config['NZBget']['nzbget_username'] = NZBGET_USERNAME
     new_config['NZBget']['nzbget_password'] = helpers.encrypt(NZBGET_PASSWORD, ENCRYPTION_VERSION)
     new_config['NZBget']['nzbget_category'] = NZBGET_CATEGORY
+    new_config['NZBget']['nzbget_category_anime'] = NZBGET_CATEGORY_ANIME
     new_config['NZBget']['nzbget_host'] = NZBGET_HOST
     new_config['NZBget']['nzbget_use_https'] = int(NZBGET_USE_HTTPS)
     new_config['NZBget']['nzbget_priority'] = NZBGET_PRIORITY
@@ -1608,6 +1617,7 @@ def save_config():
     new_config['TORRENT']['torrent_paused'] = int(TORRENT_PAUSED)
     new_config['TORRENT']['torrent_high_bandwidth'] = int(TORRENT_HIGH_BANDWIDTH)
     new_config['TORRENT']['torrent_label'] = TORRENT_LABEL
+    new_config['TORRENT']['torrent_label_anime'] = TORRENT_LABEL_ANIME
     new_config['TORRENT']['torrent_verify_cert'] = int(TORRENT_VERIFY_CERT)
 
     new_config['XBMC'] = {}
diff --git a/sickbeard/clients/deluge.py b/sickbeard/clients/deluge.py
index 3cd840ef70214158fa3e9b7250312bae968adc8a..6946abd9e01629758fe6cc1cc05f210879b8d053 100644
--- a/sickbeard/clients/deluge.py
+++ b/sickbeard/clients/deluge.py
@@ -124,6 +124,8 @@ class DelugeAPI(GenericClient):
     def _set_torrent_label(self, result):
 
         label = sickbeard.TORRENT_LABEL
+        if result.show.is_anime:
+            label = sickbeard.TORRENT_LABEL_ANIME
         if ' ' in label:
             logger.log(self.name + u': Invalid label. Label must not contain a space', logger.ERROR)
             return False
diff --git a/sickbeard/clients/rtorrent.py b/sickbeard/clients/rtorrent.py
index b1a92286e03c8d8e59a83ea25f4974dc36ce7aff..82f760461c36f511f53f7bf323b2d532effcfc1c 100644
--- a/sickbeard/clients/rtorrent.py
+++ b/sickbeard/clients/rtorrent.py
@@ -61,8 +61,11 @@ class rTorrentAPI(GenericClient):
                 return False
 
             # Set label
-            if sickbeard.TORRENT_LABEL:
-                torrent.set_custom(1, sickbeard.TORRENT_LABEL.lower())
+            label = sickbeard.TORRENT_LABEL
+            if result.show.is_anime:
+                label = sickbeard.TORRENT_LABEL_ANIME
+            if label:
+                torrent.set_custom(1, label.lower())
 
             if sickbeard.TORRENT_PATH:
                 torrent.set_directory(sickbeard.TORRENT_PATH)
@@ -97,8 +100,11 @@ class rTorrentAPI(GenericClient):
                 return False
 
             # Set label
-            if sickbeard.TORRENT_LABEL:
-                torrent.set_custom(1, sickbeard.TORRENT_LABEL.lower())
+            label = sickbeard.TORRENT_LABEL
+            if result.show.is_anime:
+                label = sickbeard.TORRENT_LABEL_ANIME
+            if label:
+                torrent.set_custom(1, label.lower())
 
             if sickbeard.TORRENT_PATH:
                 torrent.set_directory(sickbeard.TORRENT_PATH)
diff --git a/sickbeard/clients/utorrent.py b/sickbeard/clients/utorrent.py
index eda8646a16ea36624f41d7df039feb6a172592c8..fd9adc2e11ab71eebc9457f12aab79e73505fab7 100644
--- a/sickbeard/clients/utorrent.py
+++ b/sickbeard/clients/utorrent.py
@@ -58,10 +58,14 @@ class uTorrentAPI(GenericClient):
 
     def _set_torrent_label(self, result):
 
+        label = sickbeard.TORRENT_LABEL
+        if result.show.is_anime:
+            label = sickbeard.TORRENT_LABEL_ANIME
+
         params = {'action': 'setprops',
                   'hash': result.hash,
                   's': 'label',
-                  'v': sickbeard.TORRENT_LABEL
+                  'v': label
         }
         return self._request(params=params)
 
diff --git a/sickbeard/nzbget.py b/sickbeard/nzbget.py
index 469e4e4d7c0f9c4edbb4aa6b5c2e722dc12640f9..a1cb5746338d4994900d502efe2c89768a898acc 100644
--- a/sickbeard/nzbget.py
+++ b/sickbeard/nzbget.py
@@ -37,6 +37,9 @@ from common import Quality
 def sendNZB(nzb, proper=False):
     addToTop = False
     nzbgetprio = 0
+    category = sickbeard.NZBGET_CATEGORY
+    if nzb.show.is_anime:
+        category = sickbeard.NZBGET_CATEGORY_ANIME
     
     if sickbeard.NZBGET_USE_HTTPS:
         nzbgetXMLrpc = "https://%(username)s:%(password)s@%(host)s/xmlrpc"
@@ -103,7 +106,7 @@ def sendNZB(nzb, proper=False):
         nzbget_version = helpers.tryInt(nzbget_version_str[:nzbget_version_str.find(".")])
         if nzbget_version == 0:
             if nzbcontent64 is not None:
-                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, addToTop, nzbcontent64)
+                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", category, addToTop, nzbcontent64)
             else:
                 if nzb.resultType == "nzb":
                     genProvider = GenericProvider("")
@@ -111,27 +114,27 @@ def sendNZB(nzb, proper=False):
                     if (data == None):
                         return False
                     nzbcontent64 = standard_b64encode(data)
-                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, addToTop, nzbcontent64)
+                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", category, addToTop, nzbcontent64)
         elif nzbget_version == 12:
             if nzbcontent64 is not None:
-                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
+                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", category, nzbgetprio, False,
                                                  nzbcontent64, False, dupekey, dupescore, "score")
             else:
-                nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
+                nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", category, nzbgetprio, False,
                                                     nzb.url, False, dupekey, dupescore, "score")
         # v13+ has a new combined append method that accepts both (url and content)
         # also the return value has changed from boolean to integer 
         # (Positive number representing NZBID of the queue item. 0 and negative numbers represent error codes.)
         elif nzbget_version >= 13:
             nzbget_result = True if nzbGetRPC.append(nzb.name + ".nzb", nzbcontent64 if nzbcontent64 is not None else nzb.url,
-                                                     sickbeard.NZBGET_CATEGORY, nzbgetprio, False, False, dupekey, dupescore,
+                                                     category, nzbgetprio, False, False, dupekey, dupescore,
                                                      "score") > 0 else False
         else:
             if nzbcontent64 is not None:
-                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
+                nzbget_result = nzbGetRPC.append(nzb.name + ".nzb", category, nzbgetprio, False,
                                                  nzbcontent64)
             else:
-                nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", sickbeard.NZBGET_CATEGORY, nzbgetprio, False,
+                nzbget_result = nzbGetRPC.appendurl(nzb.name + ".nzb", category, nzbgetprio, False,
                                                     nzb.url)
 
         if nzbget_result:
diff --git a/sickbeard/sab.py b/sickbeard/sab.py
index 3df53421e4a726be6cae3329dba4776ddea46be6..078e92f06403878b476656ad48fef1d88ff043c2 100644
--- a/sickbeard/sab.py
+++ b/sickbeard/sab.py
@@ -51,8 +51,11 @@ def sendNZB(nzb):
         params['ma_password'] = sickbeard.SAB_PASSWORD
     if sickbeard.SAB_APIKEY != None:
         params['apikey'] = sickbeard.SAB_APIKEY
-    if sickbeard.SAB_CATEGORY != None:
-        params['cat'] = sickbeard.SAB_CATEGORY
+    category = sickbeard.SAB_CATEGORY
+    if nzb.show.is_anime:
+        category = sickbeard.SAB_CATEGORY_ANIME
+    if category != None:
+        params['cat'] = category
 
     # use high priority if specified (recently aired episode)
     if nzb.priority == 1:
diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py
index 9e962f8ab46b378de9e650e8820f44586471a648..f5f41d6ed422f63bae91787113482f014d88af8f 100644
--- a/sickbeard/webapi.py
+++ b/sickbeard/webapi.py
@@ -37,7 +37,7 @@ from sickbeard import processTV
 from sickbeard import network_timezones, sbdatetime
 from sickbeard.exceptions import ex
 from sickbeard.common import SNATCHED, SNATCHED_PROPER, DOWNLOADED, SKIPPED, UNAIRED, IGNORED, ARCHIVED, WANTED, UNKNOWN
-from common import Quality, qualityPresetStrings, statusStrings
+from common import Quality, Overview, qualityPresetStrings, statusStrings
 
 try:
     import json
@@ -162,19 +162,17 @@ class Api(webserve.MainHandler):
         return webserve._munge(t)
 
     def _out_as_json(self, dict):
-        self.set_header("Content-Type", "application/json")
+        self.set_header("Content-Type", "application/json;charset=UTF-8'")
         try:
             out = json.dumps(dict, indent=self.intent, ensure_ascii=False, sort_keys=True)
-            if 'jsonp' in self.request.query_arguments:
-                out = self.request.arguments['jsonp'] + '(' + out + ');'  # wrap with JSONP call if requested
-
+            callback = self.get_query_argument('callback', None) or self.get_query_argument('jsonp', None)
+            if callback != None:
+                out = callback + '(' + out + ');'  # wrap with JSONP call if requested
         except Exception, e:  # if we fail to generate the output fake an error
             logger.log(u"API :: " + traceback.format_exc(), logger.DEBUG)
             out = '{"result":"' + result_type_map[RESULT_ERROR] + '", "message": "error while composing output: "' + ex(
                 e) + '"}'
-
-        tornado_write_hack_dict = {'unwrap_json': out}
-        return tornado_write_hack_dict
+        return out
 
     def _grand_access(self, realKey, args, kwargs):
         """ validate api key and log result """
@@ -188,7 +186,7 @@ class Api(webserve.MainHandler):
             del kwargs["apikey"]
 
         if not sickbeard.USE_API:
-            msg = u"API :: " + remoteIp + " - SB API Disabled. ACCESS DENIED"
+            msg = u"API :: " + remoteIp + " - SR API Disabled. ACCESS DENIED"
             return False, msg, args, kwargs
         elif apiKey == realKey:
             msg = u"API :: " + remoteIp + " - gave correct API KEY. ACCESS GRANTED"
@@ -715,7 +713,7 @@ class CMD_ComingEpisodes(ApiCall):
              "optionalParameters": {"sort": {"desc": "change the sort order"},
                                     "type": {"desc": "one or more of allowedValues separated by |"},
                                     "paused": {
-                                        "desc": "0 to exclude paused shows, 1 to include them, or omitted to use the SB default"},
+                                        "desc": "0 to exclude paused shows, 1 to include them, or omitted to use the SR default"},
              }
     }
 
@@ -1260,6 +1258,70 @@ class CMD_HistoryTrim(ApiCall):
 
         return _responds(RESULT_SUCCESS, msg="Removed history entries greater than 30 days old")
 
+class CMD_Failed(ApiCall):
+    _help = {"desc": "display failed downloads",
+             "optionalParameters": {"limit": {"desc": "limit returned results"}
+             }
+    }
+
+    def __init__(self, handler, args, kwargs):
+        # required
+        # optional
+        self.limit, args = self.check_params(args, kwargs, "limit", 100, False, "int", [])
+        # super, missing, help
+        ApiCall.__init__(self, handler, args, kwargs)
+
+    def run(self):
+        """ display failed downloads """
+
+        myDB = db.DBConnection('failed.db', row_type="dict")
+
+        ulimit = min(int(self.limit), 100)
+        if ulimit == 0:
+            sqlResults = myDB.select("SELECT * FROM failed")
+        else:
+            sqlResults = myDB.select("SELECT * FROM failed LIMIT ?", [ulimit])
+
+        return _responds(RESULT_SUCCESS, sqlResults)
+
+class CMD_Backlog(ApiCall):
+    _help = {"desc": "display backlogged episodes"}
+
+    def __init__(self, handler, args, kwargs):
+        # required
+        # optional
+        # super, missing, help
+        ApiCall.__init__(self, handler, args, kwargs)
+
+    def run(self):
+        """ display backlogged episodes """
+
+        shows = []
+
+        myDB = db.DBConnection(row_type="dict")
+        for curShow in sickbeard.showList:
+
+            showEps = []
+
+            sqlResults = myDB.select(
+                "SELECT * FROM tv_episodes WHERE showid = ? ORDER BY season DESC, episode DESC",
+                [curShow.indexerid])
+
+            for curResult in sqlResults:
+
+                curEpCat = curShow.getOverview(int(curResult["status"]))
+                if curEpCat and curEpCat in (Overview.WANTED, Overview.QUAL):
+                    showEps.append(curResult)
+            
+            if showEps:
+                shows.append({
+                    "indexerid": curShow.indexerid,
+                    "show_name": curShow.name,
+                    "status": curShow.status,
+                    "episodes": showEps
+                })
+               
+        return _responds(RESULT_SUCCESS, shows)
 
 class CMD_Logs(ApiCall):
     _help = {"desc": "view sickrage's log",
@@ -2724,6 +2786,8 @@ class CMD_Shows(ApiCall):
             if self.paused != None and bool(self.paused) != bool(curShow.paused):
                 continue
 
+            indexerShow = helpers.mapIndexersToShow(curShow)
+
             showDict = {
                 "paused": curShow.paused,
                 "quality": _get_quality_string(curShow.quality),
@@ -2732,8 +2796,8 @@ class CMD_Shows(ApiCall):
                 "sports": curShow.sports,
                 "anime": curShow.anime,
                 "indexerid": curShow.indexerid,
-                "tvdbid": helpers.mapIndexersToShow(curShow)[1],
-                "tvrage_id": helpers.mapIndexersToShow(curShow)[2],
+                "tvdbid": indexerShow[1],
+                "tvrage_id": indexerShow[2],
                 "tvrage_name": curShow.name,
                 "network": curShow.network,
                 "show_name": curShow.name,
@@ -2805,6 +2869,8 @@ _functionMaper = {"help": CMD_Help,
                   "history": CMD_History,
                   "history.clear": CMD_HistoryClear,
                   "history.trim": CMD_HistoryTrim,
+                  "failed": CMD_Failed,
+                  "backlog": CMD_Backlog,
                   "logs": CMD_Logs,
                   "sb": CMD_SickBeard,
                   "postprocess": CMD_PostProcess,
diff --git a/sickbeard/webserve.py b/sickbeard/webserve.py
index 0827781166a199dc80683c0f6d2a216cdb58da6c..dd3593b79e35d4e4be3356d411c1f9cf219de9e6 100644
--- a/sickbeard/webserve.py
+++ b/sickbeard/webserve.py
@@ -264,7 +264,7 @@ class MainHandler(RequestHandler):
         else:
             default_image_name = 'banner.png'
 
-        default_image_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick', 'images', default_image_name)
+        image_path = ek.ek(os.path.join, sickbeard.PROG_DIR, 'gui', 'slick', 'images', default_image_name)
         if show and sickbeard.helpers.findCertainShow(sickbeard.showList, int(show)):
             cache_obj = image_cache.ImageCache()
 
@@ -279,10 +279,12 @@ class MainHandler(RequestHandler):
                 image_file_name = cache_obj.banner_thumb_path(show)
 
             if ek.ek(os.path.isfile, image_file_name):
-                with file(image_file_name, 'rb') as img:
-                    return img.read()
+                image_path = image_file_name
 
-        with file(default_image_path, 'rb') as img:
+        from mimetypes import MimeTypes
+        mime_type, encoding = MimeTypes().guess_type(image_path)
+        self.set_header('Content-Type', mime_type)
+        with file(image_path, 'rb') as img:
             return img.read()
 
     def setHomeLayout(self, layout):
@@ -1669,14 +1671,14 @@ class ConfigSearch(MainHandler):
 
 
     def saveSearch(self, use_nzbs=None, use_torrents=None, nzb_dir=None, sab_username=None, sab_password=None,
-                   sab_apikey=None, sab_category=None, sab_host=None, nzbget_username=None, nzbget_password=None,
-                   nzbget_category=None, nzbget_priority=None, nzbget_host=None, nzbget_use_https=None,
-                   backlog_days=None, backlog_frequency=None, dailysearch_frequency=None,
-                   nzb_method=None, torrent_method=None, usenet_retention=None,
+                   sab_apikey=None, sab_category=None, sab_category_anime=None, sab_host=None, nzbget_username=None,
+                   nzbget_password=None, nzbget_category=None, nzbget_category_anime=None, nzbget_priority=None,
+                   nzbget_host=None, nzbget_use_https=None, backlog_days=None, backlog_frequency=None,
+                   dailysearch_frequency=None, nzb_method=None, torrent_method=None, usenet_retention=None,
                    download_propers=None, check_propers_interval=None, allow_high_priority=None,
                    backlog_startup=None, dailysearch_startup=None,
                    torrent_dir=None, torrent_username=None, torrent_password=None, torrent_host=None,
-                   torrent_label=None, torrent_path=None, torrent_verify_cert=None,
+                   torrent_label=None, torrent_label_anime=None, torrent_path=None, torrent_verify_cert=None,
                    torrent_seed_time=None, torrent_paused=None, torrent_high_bandwidth=None, ignore_words=None,
                    require_words=None):
 
@@ -1715,11 +1717,13 @@ class ConfigSearch(MainHandler):
         sickbeard.SAB_PASSWORD = sab_password
         sickbeard.SAB_APIKEY = sab_apikey.strip()
         sickbeard.SAB_CATEGORY = sab_category
+        sickbeard.SAB_CATEGORY_ANIME = sab_category_anime
         sickbeard.SAB_HOST = config.clean_url(sab_host)
 
         sickbeard.NZBGET_USERNAME = nzbget_username
         sickbeard.NZBGET_PASSWORD = nzbget_password
         sickbeard.NZBGET_CATEGORY = nzbget_category
+        sickbeard.NZBGET_CATEGORY_ANIME = nzbget_category_anime
         sickbeard.NZBGET_HOST = config.clean_host(nzbget_host)
         sickbeard.NZBGET_USE_HTTPS = config.checkbox_to_value(nzbget_use_https)
         sickbeard.NZBGET_PRIORITY = config.to_int(nzbget_priority, default=100)
@@ -1727,6 +1731,7 @@ class ConfigSearch(MainHandler):
         sickbeard.TORRENT_USERNAME = torrent_username
         sickbeard.TORRENT_PASSWORD = torrent_password
         sickbeard.TORRENT_LABEL = torrent_label
+        sickbeard.TORRENT_LABEL_ANIME = torrent_label_anime
         sickbeard.TORRENT_VERIFY_CERT = config.checkbox_to_value(torrent_verify_cert)
         sickbeard.TORRENT_PATH = torrent_path
         sickbeard.TORRENT_SEED_TIME = torrent_seed_time
diff --git a/sickbeard/webserveInit.py b/sickbeard/webserveInit.py
index 567ce865f26b5960715cdc56a135f60c318f375d..f0c440c630f28c36e76125a59875010c94ad5d5b 100644
--- a/sickbeard/webserveInit.py
+++ b/sickbeard/webserveInit.py
@@ -149,6 +149,4 @@ class SRWebServer(threading.Thread):
 
     def shutDown(self):
         self.alive = False
-        if self.server:
-            self.server.stop()
-            self.io_loop.stop()
\ No newline at end of file
+        self.io_loop.stop()
\ No newline at end of file
diff --git a/tornado/http1connection.py b/tornado/http1connection.py
index 8a5f46c48c8642506ebd0efc4192d811b9ca33cf..90895cc94393d8ef0fd662f759bc4b1d76f0d931 100644
--- a/tornado/http1connection.py
+++ b/tornado/http1connection.py
@@ -686,9 +686,8 @@ class HTTP1ServerConnection(object):
                     # This exception was already logged.
                     conn.close()
                     return
-                except Exception as e:
-                    if 1 != e.errno:
-                        gen_log.error("Uncaught exception", exc_info=True)
+                except Exception:
+                    gen_log.error("Uncaught exception", exc_info=True)
                     conn.close()
                     return
                 if not ret:
diff --git a/tornado/iostream.py b/tornado/iostream.py
index 69f43957902da4ce8e9753b60dd769178d5558d0..eced6d6482bd017efff1c27c3dd61d5638df3957 100644
--- a/tornado/iostream.py
+++ b/tornado/iostream.py
@@ -601,9 +601,8 @@ class BaseIOStream(object):
             pos = self._read_to_buffer_loop()
         except UnsatisfiableReadError:
             raise
-        except Exception as e:
-            if 1 != e.errno:
-                gen_log.warning("error on read", exc_info=True)
+        except Exception:
+            gen_log.warning("error on read", exc_info=True)
             self.close(exc_info=True)
             return
         if pos is not None:
diff --git a/tornado/web.py b/tornado/web.py
index 9edd719a1ef1329fe527446f6222715b11bd1a2a..a038265fd3fd4a726d8e1f2f993c79dc9e5ab1e7 100644
--- a/tornado/web.py
+++ b/tornado/web.py
@@ -652,10 +652,7 @@ class RequestHandler(object):
         if not isinstance(chunk, (bytes, unicode_type, dict)):
             raise TypeError("write() only accepts bytes, unicode, and dict objects")
         if isinstance(chunk, dict):
-            if 'unwrap_json' in chunk:
-                chunk = chunk['unwrap_json']
-            else:
-                chunk = escape.json_encode(chunk)
+            chunk = escape.json_encode(chunk)
             self.set_header("Content-Type", "application/json; charset=UTF-8")
         chunk = utf8(chunk)
         self._write_buffer.append(chunk)