diff -pruN 2.6.1-1/data/meson.build 2.7.1-1/data/meson.build
--- 2.6.1-1/data/meson.build	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/data/meson.build	2019-02-01 19:30:50.000000000 +0000
@@ -26,7 +26,7 @@ i18n.merge_file(
   output: 'org.gnome.FeedReader.appdata.xml',
   po_dir: PO_DIR,
   install: true,
-  install_dir: join_paths(SHARE_DIR, 'appdata')
+  install_dir: join_paths(SHARE_DIR, 'metainfo')
 )
 
 
diff -pruN 2.6.1-1/data/org.gnome.FeedReader.appdata.xml.in 2.7.1-1/data/org.gnome.FeedReader.appdata.xml.in
--- 2.6.1-1/data/org.gnome.FeedReader.appdata.xml.in	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/data/org.gnome.FeedReader.appdata.xml.in	2019-02-01 19:30:50.000000000 +0000
@@ -51,6 +51,36 @@
     <binary>feedreader</binary>
   </provides>
   <releases>
+    <release version="2.7.1" date="2019-02-01">
+      <description>
+        <ul>
+		  <li>Fix bugs when adding, deleting and renaming article tags</li>
+		</ul>
+      </description>
+    </release>
+    <release version="2.7.0" date="2019-01-28">
+      <description>
+        <ul>
+		  <li>Fix thread safety issues, hopefully fix a lot of crashes</li>
+		</ul>
+      </description>
+    </release>
+    <release version="2.6.2" date="2019-01-24">
+      <description>
+        <ul>
+		  <li>Fix version number</li>
+		  <li>Fix crash in article list</li>
+		  <li>More translations</li>
+		</ul>
+      </description>
+    </release>
+    <release version="2.6.1" date="2018-12-03">
+      <description>
+        <ul>
+		  <li>Fix release tarballs to contain all necessary code</li>
+		</ul>
+      </description>
+    </release>
     <release version="2.6.0" date="2018-12-03">
       <description>
         <ul>
diff -pruN 2.6.1-1/debian/changelog 2.7.1-1/debian/changelog
--- 2.6.1-1/debian/changelog	2019-01-04 12:23:27.000000000 +0000
+++ 2.7.1-1/debian/changelog	2019-02-08 14:37:47.000000000 +0000
@@ -1,3 +1,17 @@
+feedreader (2.7.1-1) unstable; urgency=medium
+
+  * New upstream release:
+    - Fix bugs when adding, renaming or deleting article tags.
+    - Change db logic to fix thread safety issues, prevent a bunch of crashes.
+    - Fix version numbers.
+    - Fix a crash in the article list.
+    - More translations.
+  * Remove local patch place_appdata_on_proper_metadata_info_dir.patch,
+    addopted upstream.
+  * Bump up standard versions (no changes required).
+
+ -- Ulises Vitulli <dererk@debian.org>  Fri, 08 Feb 2019 11:37:47 -0300
+
 feedreader (2.6.1-1) unstable; urgency=medium
 
   * New upstream release (Closes: #915502).
diff -pruN 2.6.1-1/debian/control 2.7.1-1/debian/control
--- 2.6.1-1/debian/control	2019-01-04 12:23:27.000000000 +0000
+++ 2.7.1-1/debian/control	2019-02-08 14:37:47.000000000 +0000
@@ -24,7 +24,7 @@ Build-Depends:
  libwebkit2gtk-4.0-dev,
  meson,
  valac (>= 0.26),
-Standards-Version: 4.3.0
+Standards-Version: 4.3.0.1
 Homepage: https://jangernert.github.io/FeedReader/
 Vcs-Git: https://salsa.debian.org/debian/FeedReader.git
 Vcs-Browser: https://salsa.debian.org/debian/FeedReader
diff -pruN 2.6.1-1/debian/patches/fix_some_spelling_errors.patch 2.7.1-1/debian/patches/fix_some_spelling_errors.patch
--- 2.6.1-1/debian/patches/fix_some_spelling_errors.patch	2019-01-04 12:23:27.000000000 +0000
+++ 2.7.1-1/debian/patches/fix_some_spelling_errors.patch	2019-02-08 14:37:47.000000000 +0000
@@ -1,24 +1,54 @@
 Author: Dererk
 Description: Fix several typos on source
-
-Index: FeedReader/libraries/libIvy/Printer.vala
-===================================================================
---- FeedReader.orig/libraries/libIvy/Printer.vala
-+++ FeedReader/libraries/libIvy/Printer.vala
-@@ -110,7 +110,7 @@ namespace Ivy {
- 					c,
- 					get_reset_style ());
- 			else
--				result = "%sAn error occured %s(%s)%s".printf (
-+				result = "%sAn error occurred %s(%s)%s".printf (
- 					c,
- 					color,
- 					get_signal_name (),
-Index: FeedReader/libraries/libgtkimageview/gtkimageview.c
-===================================================================
---- FeedReader.orig/libraries/libgtkimageview/gtkimageview.c
-+++ FeedReader/libraries/libgtkimageview/gtkimageview.c
-@@ -2020,7 +2020,7 @@ gtk_image_view_class_init (GtkImageViewC
+diff --git a/libraries/libIvy/Printer.vala b/libraries/libIvy/Printer.vala
+index 1786f89..5ff5a7d 100644
+--- a/libraries/libIvy/Printer.vala
++++ b/libraries/libIvy/Printer.vala
+@@ -110,7 +110,7 @@ private string get_printable_title () {
+ 			c,
+ 			get_reset_style ());
+ 	else
+-		result = "%sAn error occured %s(%s)%s".printf (
++		result = "%sAn error occurred %s(%s)%s".printf (
+ 			c,
+ 			color,
+ 			get_signal_name (),
+diff --git a/libraries/libIvy/Stacktrace.vala b/libraries/libIvy/Stacktrace.vala
+index 1c43ffb..aafc198 100644
+--- a/libraries/libIvy/Stacktrace.vala
++++ b/libraries/libIvy/Stacktrace.vala
+@@ -74,7 +74,7 @@ public enum Color {
+  *
+  * Here's a sample of a printed stacktrace:
+  * {{{
+- * An error occured (SIGSEGV) in samples/vala_file.vala, line 21 in 'this_will_crash_harder'
++ * An error occurred (SIGSEGV) in samples/vala_file.vala, line 21 in 'this_will_crash_harder'
+  * The reason is likely a null reference being used.
+  *
+  *    #1  <unknown>                                   in 'strlen'
+@@ -138,7 +138,7 @@ public static bool enabled { get; set; default = true;}
+  *
+  * Before
+  * {{{
+- *    An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
++ *    An error occurred (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
+  *   The reason is likely an uncaught error.
+  *
+  *    #1  <unknown>                                          in 'g_signal_handlers_disconnect_matched'
+@@ -218,7 +218,7 @@ public static bool enabled { get; set; default = true;}
+  *
+  * After :
+  * {{{
+- * An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
++ * An error occurred (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
+  *    The reason is likely an uncaught error.
+  *
+  *     #1  <unknown>                                         in 'g_signal_handlers_disconnect_matched'
+diff --git a/libraries/libgtkimageview/gtkimageview.c b/libraries/libgtkimageview/gtkimageview.c
+index 30ab733..0b0621e 100644
+--- a/libraries/libgtkimageview/gtkimageview.c
++++ b/libraries/libgtkimageview/gtkimageview.c
+@@ -2020,7 +2020,7 @@ gtk_image_view_class_init (GtkImageViewClass *view_class)
     */
    widget_props[PROP_SCALE_SET] = g_param_spec_boolean ("scale-set",
  													   "Scale Set",
@@ -27,58 +57,6 @@ Index: FeedReader/libraries/libgtkimagev
  													   FALSE,
  													   _PARAM_READABLE|G_PARAM_EXPLICIT_NOTIFY);
    /**
-Index: FeedReader/plugins/backend/demo/demoInterface.vala
-===================================================================
---- FeedReader.orig/plugins/backend/demo/demoInterface.vala
-+++ FeedReader/plugins/backend/demo/demoInterface.vala
-@@ -552,7 +552,7 @@ public class FeedReader.demoInterface :
- 
- 	//--------------------------------------------------------------------------------------
- 	// Get all feeds, categories and tags from the service
--	// Fill up the emtpy LinkedList's that are provided with instances of the
-+	// Fill up the empty LinkedList's that are provided with instances of the
- 	// model-classes category, feed and article
- 	//--------------------------------------------------------------------------------------
- 	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-Index: FeedReader/src/Widgets/ArticleList/ArticleList.vala
-===================================================================
---- FeedReader.orig/src/Widgets/ArticleList/ArticleList.vala
-+++ FeedReader/src/Widgets/ArticleList/ArticleList.vala
-@@ -346,7 +346,7 @@ public class FeedReader.ArticleList : Gt
- 		if(m_stack.get_visible_child_name() == "empty"
- 		|| m_stack.get_visible_child_name() == "syncing")
- 		{
--			Logger.debug("ArticleList: updateArticleList(): emtpy list -> create newList()");
-+			Logger.debug("ArticleList: updateArticleList(): empty list -> create newList()");
- 			newList.begin(Gtk.StackTransitionType.CROSSFADE, (obj, res) => {
- 				newList.end(res);
- 			});
-Index: FeedReader/src/Widgets/MainWindow.vala
-===================================================================
---- FeedReader.orig/src/Widgets/MainWindow.vala
-+++ FeedReader/src/Widgets/MainWindow.vala
-@@ -449,7 +449,7 @@ public class FeedReader.MainWindow : Gtk
- 			case LoginResponse.SUCCESS:
- 			case LoginResponse.FIRST_TRY:
- 			default:
--				Logger.debug("MainWindow: dont show error bar");
-+				Logger.debug("MainWindow: don't show error bar");
- 				m_error_bar.set_visible(false);
- 				return;
- 		}
-diff --git a/plugins/backend/decsync/decsyncListeners.vala b/plugins/backend/decsync/decsyncListeners.vala
-index 6519380..673af0e 100644
---- a/plugins/backend/decsync/decsyncListeners.vala
-+++ b/plugins/backend/decsync/decsyncListeners.vala
-@@ -53,7 +53,7 @@ public class FeedReader.DecsyncListeners : GLib.Object {
- 			Article? article = m_plugin.m_db.read_article(articleID);
- 			if (article == null)
- 			{
--				Logger.info("Unkown article " + articleID);
-+				Logger.info("Unknown article " + articleID);
- 				return;
- 			}
- 			if (m_is_read_entry)
 diff --git a/libraries/libnxml/nxml_parser.c b/libraries/libnxml/nxml_parser.c
 index 8379aa0..5c7c5b9 100644
 --- a/libraries/libnxml/nxml_parser.c
@@ -92,3 +70,42 @@ index 8379aa0..5c7c5b9 100644
  								nxml->priv.line);
  
  			if (freed)
+diff --git a/plugins/backend/decsync/decsyncListeners.vala b/plugins/backend/decsync/decsyncListeners.vala
+index c907d24..c03f309 100644
+--- a/plugins/backend/decsync/decsyncListeners.vala
++++ b/plugins/backend/decsync/decsyncListeners.vala
+@@ -54,7 +54,7 @@ public override void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry en
+ 	Article? article = db.read_article(articleID);
+ 	if (article == null)
+ 	{
+-		Logger.info("Unkown article " + articleID);
++		Logger.info("Unknown article " + articleID);
+ 		return;
+ 	}
+ 	if (m_is_read_entry)
+diff --git a/src/Widgets/ArticleList/ArticleList.vala b/src/Widgets/ArticleList/ArticleList.vala
+index fa2ae03..cb28e47 100644
+--- a/src/Widgets/ArticleList/ArticleList.vala
++++ b/src/Widgets/ArticleList/ArticleList.vala
+@@ -296,7 +296,7 @@ public void updateArticleList()
+ 	if(m_stack.get_visible_child_name() == "empty"
+ 	   || m_stack.get_visible_child_name() == "syncing")
+ 	{
+-		Logger.debug("ArticleList: updateArticleList(): emtpy list -> create newList()");
++		Logger.debug("ArticleList: updateArticleList(): empty list -> create newList()");
+ 		newList(Gtk.StackTransitionType.CROSSFADE);
+ 		return;
+ 	}
+diff --git a/src/Widgets/MainWindow.vala b/src/Widgets/MainWindow.vala
+index 7690197..6d0fe93 100644
+--- a/src/Widgets/MainWindow.vala
++++ b/src/Widgets/MainWindow.vala
+@@ -449,7 +449,7 @@ private void showErrorBar(int ErrorCode)
+ 	case LoginResponse.SUCCESS:
+ 	case LoginResponse.FIRST_TRY:
+ 	default:
+-		Logger.debug("MainWindow: dont show error bar");
++		Logger.debug("MainWindow: don't show error bar");
+ 		m_error_bar.set_visible(false);
+ 		return;
+ 	}
diff -pruN 2.6.1-1/debian/patches/place_appdata_on_proper_metadata_info_dir.patch 2.7.1-1/debian/patches/place_appdata_on_proper_metadata_info_dir.patch
--- 2.6.1-1/debian/patches/place_appdata_on_proper_metadata_info_dir.patch	2019-01-04 12:23:27.000000000 +0000
+++ 2.7.1-1/debian/patches/place_appdata_on_proper_metadata_info_dir.patch	1970-01-01 00:00:00.000000000 +0000
@@ -1,16 +0,0 @@
-Author: Dererk
-Description: Point appdata to a proper location 
-
-diff --git a/data/meson.build b/data/meson.build
-index d26334f..9f28f95 100644
---- a/data/meson.build
-+++ b/data/meson.build
-@@ -26,7 +26,7 @@ i18n.merge_file(
-   output: 'org.gnome.FeedReader.appdata.xml',
-   po_dir: PO_DIR,
-   install: true,
--  install_dir: join_paths(SHARE_DIR, 'appdata')
-+  install_dir: join_paths(SHARE_DIR, 'metainfo')
- )
- 
- 
diff -pruN 2.6.1-1/debian/patches/series 2.7.1-1/debian/patches/series
--- 2.6.1-1/debian/patches/series	2019-01-04 12:23:27.000000000 +0000
+++ 2.7.1-1/debian/patches/series	2019-02-08 14:37:47.000000000 +0000
@@ -1,2 +1 @@
-place_appdata_on_proper_metadata_info_dir.patch
 fix_some_spelling_errors.patch
diff -pruN 2.6.1-1/libraries/libIvy/Extractor.vala 2.7.1-1/libraries/libIvy/Extractor.vala
--- 2.6.1-1/libraries/libIvy/Extractor.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/libraries/libIvy/Extractor.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,407 +16,407 @@
 
 namespace Ivy {
 
-	/**
-	 * Extracts frames and builds a {@link Stacktrace}
-	 *
-	 */
-	public class Extractor {
-
-		private bool show_debug_frames = false;
-
-		private string func = "";
-		private string file_path = "";
-		private string short_file_path = "";
-		private string l = "";
-		private string file_line = "";
-		private string func_line = "";
-		private string lib_address ="";
-
-		private static Gee.List<string> libraries_with_no_info = new Gee.ArrayList<string>();
-
-		private string get_module_name () {
-			var path = new char[1024];
-			Posix.readlink ("/proc/self/exe", path);
-			string result = (string) path;
-			return result;
-		}
-
-		// TODO CARL convert this piece of code to vala conventions
-		private static string get_relative_path (string p_fullDestinationPath, string p_startPath) {
-
-			string[] l_startPathParts = p_startPath.split ("/");
-			string[] l_destinationPathParts = p_fullDestinationPath.split ("/");
-
-			int l_sameCounter = 0;
-			while ((l_sameCounter < l_startPathParts.length) &&
-				   (l_sameCounter < l_destinationPathParts.length) &&
-				   l_startPathParts[l_sameCounter] == l_destinationPathParts[l_sameCounter]) {
-				l_sameCounter++;
-			}
+/**
+ * Extracts frames and builds a {@link Stacktrace}
+ *
+ */
+public class Extractor {
+
+private bool show_debug_frames = false;
+
+private string func = "";
+private string file_path = "";
+private string short_file_path = "";
+private string l = "";
+private string file_line = "";
+private string func_line = "";
+private string lib_address ="";
+
+private static Gee.List<string> libraries_with_no_info = new Gee.ArrayList<string>();
+
+private string get_module_name () {
+	var path = new char[1024];
+	Posix.readlink ("/proc/self/exe", path);
+	string result = (string) path;
+	return result;
+}
 
-			if (l_sameCounter == 0) {
-				return p_fullDestinationPath;             // There is no relative link.
-			}
+// TODO CARL convert this piece of code to vala conventions
+private static string get_relative_path (string p_fullDestinationPath, string p_startPath) {
 
-			StringBuilder l_builder = new StringBuilder ();
-			for (int i = l_sameCounter ; i < l_startPathParts.length ; i++) {
-				l_builder.append ("../");
-			}
+	string[] l_startPathParts = p_startPath.split ("/");
+	string[] l_destinationPathParts = p_fullDestinationPath.split ("/");
 
-			for (int i = l_sameCounter ; i < l_destinationPathParts.length ; i++) {
-				l_builder.append (l_destinationPathParts[i] + "/");
-			}
+	int l_sameCounter = 0;
+	while ((l_sameCounter < l_startPathParts.length) &&
+	       (l_sameCounter < l_destinationPathParts.length) &&
+	       l_startPathParts[l_sameCounter] == l_destinationPathParts[l_sameCounter]) {
+		l_sameCounter++;
+	}
 
-			// CARL l_builder.Length--;
-			// Remove the last /
-			var result = l_builder.str;
-			result = result.substring (0, result.length - 1);
-			return result;
-		}
-
-		private string extract_short_file_path (string file_path) {
-			var path = Environment.get_current_dir ();
-			/*var i = file_path.index_of ( path );
-			   if( i>=0 )
-				return file_path.substring ( path.length, file_path.length - path.length );
-			   return file_path; */
-			var result = get_relative_path (file_path, path);
-			return result;
-		}
-
-		// input : '/home/cran/Documents/Projects/elementary/noise/instant-beta/build/core/libnoise-core.so.0(noise_job_repository_create_job+0x309) [0x7ff60a021e69]'
-		// ouput: 0x309
-		private int extract_base_address (string line) {
-			int result = 0;
-			var start = line.last_index_of ("+");
-			if (start >= 0) {
-				var end = line.last_index_of (")");
-				if( end > start ) {
-					var text = line.substring (start+3,end-start-3);
-					text.scanf("%x",  &result);
-				}
-			}
-			return result;
-		}
+	if (l_sameCounter == 0) {
+		return p_fullDestinationPath;                             // There is no relative link.
+	}
 
-		private void process_info_for_file (string full_line, string str ) {
-			func = "";
-			file_path = "";
-			short_file_path = "";
-			l = "";
-			file_line = "";
-			func_line = "";
-			if (full_line == "")
-				return;
-
-			var lines = full_line.split ("\n");
-
-			if (lines.length > 0)
-				func_line = lines[0];
-
-			if (lines.length > 1)
-				file_line = lines[1];
-			if (file_line == "??:0" || file_line == "??:?")
-				file_line = "";
-			func = extract_function_name (str);
-
-			file_path = "";
-			short_file_path = "";
-			l = "";
-			if (file_line != "") {
-				if (func == "")
-					func = extract_function_name_from_line (func_line);
-				file_path = extract_file_path (file_line);
-				short_file_path = extract_short_file_path (file_path);
-				l = extract_line (file_line);
-			}
+	StringBuilder l_builder = new StringBuilder ();
+	for (int i = l_sameCounter; i < l_startPathParts.length; i++) {
+		l_builder.append ("../");
+	}
+
+	for (int i = l_sameCounter; i < l_destinationPathParts.length; i++) {
+		l_builder.append (l_destinationPathParts[i] + "/");
+	}
+
+	// CARL l_builder.Length--;
+	// Remove the last /
+	var result = l_builder.str;
+	result = result.substring (0, result.length - 1);
+	return result;
+}
+
+private string extract_short_file_path (string file_path) {
+	var path = Environment.get_current_dir ();
+	/*var i = file_path.index_of ( path );
+	   if( i>=0 )
+	        return file_path.substring ( path.length, file_path.length - path.length );
+	   return file_path; */
+	var result = get_relative_path (file_path, path);
+	return result;
+}
+
+// input : '/home/cran/Documents/Projects/elementary/noise/instant-beta/build/core/libnoise-core.so.0(noise_job_repository_create_job+0x309) [0x7ff60a021e69]'
+// ouput: 0x309
+private int extract_base_address (string line) {
+	int result = 0;
+	var start = line.last_index_of ("+");
+	if (start >= 0) {
+		var end = line.last_index_of (")");
+		if( end > start ) {
+			var text = line.substring (start+3,end-start-3);
+			text.scanf("%x",  &result);
 		}
+	}
+	return result;
+}
 
-		private void process_info_from_lib (string file_path, string str) {
-			//stdout.printf( "process_info_from_lib('%s', '%s') func: '%s'\n", file_path, str, func);
-			var has_info = true;
-			var addr1_s = "";
-			var lib_addr = "";
-			var cmd2 = "";
-			lib_address ="";
-			lock( libraries_with_no_info)
-			 {
-				if( libraries_with_no_info.index_of (file_path) == -1 ){
-					 // The library is not on the black list
-					cmd2 = "nm %s".printf(file_path);
-
-					 addr1_s = execute_command_sync_get_output (cmd2);
-					 if( addr1_s == null || addr1_s == "" )
-					 {
-						// stdout.printf( "ADDED TO NO INFO: '%s'\n", file_path);
-						libraries_with_no_info.add (file_path);
-						has_info = false;
+private void process_info_for_file (string full_line, string str ) {
+	func = "";
+	file_path = "";
+	short_file_path = "";
+	l = "";
+	file_line = "";
+	func_line = "";
+	if (full_line == "")
+		return;
+
+	var lines = full_line.split ("\n");
+
+	if (lines.length > 0)
+		func_line = lines[0];
+
+	if (lines.length > 1)
+		file_line = lines[1];
+	if (file_line == "??:0" || file_line == "??:?")
+		file_line = "";
+	func = extract_function_name (str);
+
+	file_path = "";
+	short_file_path = "";
+	l = "";
+	if (file_line != "") {
+		if (func == "")
+			func = extract_function_name_from_line (func_line);
+		file_path = extract_file_path (file_line);
+		short_file_path = extract_short_file_path (file_path);
+		l = extract_line (file_line);
+	}
+}
 
-					 }
-				}
-				else
-					has_info = false;
-			}
-			if( has_info && func != "" )
+private void process_info_from_lib (string file_path, string str) {
+	//stdout.printf( "process_info_from_lib('%s', '%s') func: '%s'\n", file_path, str, func);
+	var has_info = true;
+	var addr1_s = "";
+	var lib_addr = "";
+	var cmd2 = "";
+	lib_address ="";
+	lock( libraries_with_no_info)
+	{
+		if( libraries_with_no_info.index_of (file_path) == -1 ) {
+			// The library is not on the black list
+			cmd2 = "nm %s".printf(file_path);
+
+			addr1_s = execute_command_sync_get_output (cmd2);
+			if( addr1_s == null || addr1_s == "" )
 			{
-				MatchInfo info;
-				var expression = "\\n[^ ]* T "+func;
-				try {
-
-					Regex regex = new Regex (expression);
-					int count = 0;
-					string matches = "";
-					if( regex.match (addr1_s, 0, out info) )
-					 {
-						while( info.matches() ){
-							var lll = info.fetch(0);
-							// stdout.printf ( "lll '%s'\n", lll );
-							lib_addr = lll.substring(0, lll.index_of(" "));
-							matches += lib_addr + "\n";
-							info.next();
-							count++;
-						}
-						if( count >1 )
-						{
-						   stdout.printf ("  XX %d matches for '%s'. Command: '%s'. Matches: '%s'\n", count, func, cmd2, matches);
-						}
-						 // stdout.printf ("  YY %d matches for '%s'. Command: '%s'. Matches: '%s'\n", count, func, cmd2, matches);
-					}
+				// stdout.printf( "ADDED TO NO INFO: '%s'\n", file_path);
+				libraries_with_no_info.add (file_path);
+				has_info = false;
 
-				} catch (RegexError e)
-				{
-					critical( "Error while processing regex '%s. Err: '%s", expression, e.message );
+			}
+		}
+		else
+			has_info = false;
+	}
+	if( has_info && func != "" )
+	{
+		MatchInfo info;
+		var expression = "\\n[^ ]* T "+func;
+		try {
+
+			Regex regex = new Regex (expression);
+			int count = 0;
+			string matches = "";
+			if( regex.match (addr1_s, 0, out info) )
+			{
+				while( info.matches() ) {
+					var lll = info.fetch(0);
+					// stdout.printf ( "lll '%s'\n", lll );
+					lib_addr = lll.substring(0, lll.index_of(" "));
+					matches += lib_addr + "\n";
+					info.next();
+					count++;
 				}
-				//stdout.printf ("addr1_s %s\n", addr1_s);
-				int addr1 = 0;
-				lib_addr.scanf("%x",  &addr1);
-				if( addr1 != 0 ) {
-					int addr2 = extract_base_address (str);
-					string addr3 = "%#08x".printf (addr1+addr2);
-					lib_address = addr3;
-					// stdout.printf ("lib_address : %s\n", lib_address);
-					var new_full_line = process_line (file_path, addr3);
-					//stdout.printf ("STR : %s\n", str);
-					// stdout.printf ("AD1 : %s\n", addr1_s);
-					//stdout.printf ("AD2 : %#08x\n", addr2);
-					//stdout.printf ("AD3 : %s\n", addr3);
-					//stdout.printf ("LIB : %s\n", file_path);
-					//stdout.printf ("RES : %s\n", new_full_line);
-
-					process_info_for_file (new_full_line, str );
+				if( count >1 )
+				{
+					stdout.printf ("  XX %d matches for '%s'. Command: '%s'. Matches: '%s'\n", count, func, cmd2, matches);
 				}
-				else
-					stdout.printf ("NULL\n");
+				// stdout.printf ("  YY %d matches for '%s'. Command: '%s'. Matches: '%s'\n", count, func, cmd2, matches);
 			}
 
-		}
+		} catch (RegexError e)
+		{
+			critical( "Error while processing regex '%s. Err: '%s", expression, e.message );
+		}
+		//stdout.printf ("addr1_s %s\n", addr1_s);
+		int addr1 = 0;
+		lib_addr.scanf("%x",  &addr1);
+		if( addr1 != 0 ) {
+			int addr2 = extract_base_address (str);
+			string addr3 = "%#08x".printf (addr1+addr2);
+			lib_address = addr3;
+			// stdout.printf ("lib_address : %s\n", lib_address);
+			var new_full_line = process_line (file_path, addr3);
+			//stdout.printf ("STR : %s\n", str);
+			// stdout.printf ("AD1 : %s\n", addr1_s);
+			//stdout.printf ("AD2 : %#08x\n", addr2);
+			//stdout.printf ("AD3 : %s\n", addr3);
+			//stdout.printf ("LIB : %s\n", file_path);
+			//stdout.printf ("RES : %s\n", new_full_line);
 
-		private string extract_function_name (string line) {
-			if (line == "")
-				return "";
-			var start = line.index_of ("(");
-			if (start >= 0) {
-				var end = line.index_of ("+", start);
-				if (end >= 0) {
-					var result = line.substring (start + 1, end - start - 1);
-					return result.strip ();
-				}
-			}
-			return "";
+			process_info_for_file (new_full_line, str );
 		}
+		else
+			stdout.printf ("NULL\n");
+	}
 
-		private string extract_function_name_from_line (string line) {
-			return line.strip ();
-		}
+}
 
-		private string extract_file_path_from (string str) {
-			if (str == "")
-				return "";
-			/*if( str.index_of("??") >= 0)
-				//result = result.substring (4, line.length - 4 );
-				stdout.printf ("ERR2?? : %s\n", str ) ; */
-			var start = str.index_of ("(");
-			if (start >= 0) {
-				return str.substring (0, start).strip ();
-			}
-			return str.strip ();
+private string extract_function_name (string line) {
+	if (line == "")
+		return "";
+	var start = line.index_of ("(");
+	if (start >= 0) {
+		var end = line.index_of ("+", start);
+		if (end >= 0) {
+			var result = line.substring (start + 1, end - start - 1);
+			return result.strip ();
 		}
+	}
+	return "";
+}
 
-		private string extract_file_path (string line) {
-			var result = line;
-			if (result == "")
-				return "";
-			if (result == "??:0??:0")
-				return "";
-			// For some reason, the file name can starts with ??:0
-			if (result.has_prefix ("??:0"))
-				result = result.substring (4, line.length - 4);
-			// stdout.printf ("ERR1?? : %s\n", line );
-			var start = result.index_of (":");
-			if (start >= 0) {
-				result = result.substring (0, start);
-				return result.strip ();
-			}
-			return "";
-		}
+private string extract_function_name_from_line (string line) {
+	return line.strip ();
+}
 
-		private static string extract_line (string line) {
-			var result = line;
-			if (result == "")
-				return "";
-			if (result.has_prefix ("??:0"))
-				result = result.substring (4, line.length - 4);
-			var start = result.index_of (":");
-			if (start >= 0) {
-				result = result.substring (start + 1, line.length - start - 1);
-				var end = result.index_of ("(");
-				if (end >= 0) {
-					result = result.substring (0, end);
-				}
-				return result.strip ();
-			}
-			return "";
+private string extract_file_path_from (string str) {
+	if (str == "")
+		return "";
+	/*if( str.index_of("??") >= 0)
+	        //result = result.substring (4, line.length - 4 );
+	        stdout.printf ("ERR2?? : %s\n", str ) ; */
+	var start = str.index_of ("(");
+	if (start >= 0) {
+		return str.substring (0, start).strip ();
+	}
+	return str.strip ();
+}
+
+private string extract_file_path (string line) {
+	var result = line;
+	if (result == "")
+		return "";
+	if (result == "??:0??:0")
+		return "";
+	// For some reason, the file name can starts with ??:0
+	if (result.has_prefix ("??:0"))
+		result = result.substring (4, line.length - 4);
+	// stdout.printf ("ERR1?? : %s\n", line );
+	var start = result.index_of (":");
+	if (start >= 0) {
+		result = result.substring (0, start);
+		return result.strip ();
+	}
+	return "";
+}
+
+private static string extract_line (string line) {
+	var result = line;
+	if (result == "")
+		return "";
+	if (result.has_prefix ("??:0"))
+		result = result.substring (4, line.length - 4);
+	var start = result.index_of (":");
+	if (start >= 0) {
+		result = result.substring (start + 1, line.length - start - 1);
+		var end = result.index_of ("(");
+		if (end >= 0) {
+			result = result.substring (0, end);
 		}
+		return result.strip ();
+	}
+	return "";
+}
 
-		private string extract_address (string line) {
-			if (line == "")
-				return "";
-			var start = line.index_of ("[");
-			if (start >= 0) {
-				var end = line.index_of ("]", start);
-				if (end >= 0) {
-					var result = line.substring (start + 1, end - start - 1);
-					return result.strip ();
-				}
-			}
-			return "";
+private string extract_address (string line) {
+	if (line == "")
+		return "";
+	var start = line.index_of ("[");
+	if (start >= 0) {
+		var end = line.index_of ("]", start);
+		if (end >= 0) {
+			var result = line.substring (start + 1, end - start - 1);
+			return result.strip ();
 		}
+	}
+	return "";
+}
 
-		private string execute_command_sync_get_output (string cmd) {
-			try {
-				int exitCode;
-				string std_out;
-				string std_err;
-				Process.spawn_command_line_sync (cmd, out std_out, out std_err, out exitCode);
-				if( exitCode == 0)
-					return std_out;
-				else
-					print ("Error while executing '%s'. Exit code '%d'\n".printf(cmd, exitCode));
+private string execute_command_sync_get_output (string cmd) {
+	try {
+		int exitCode;
+		string std_out;
+		string std_err;
+		Process.spawn_command_line_sync (cmd, out std_out, out std_err, out exitCode);
+		if( exitCode == 0)
+			return std_out;
+		else
+			print ("Error while executing '%s'. Exit code '%d'\n".printf(cmd, exitCode));
 
-			}
-			catch (Error e) {
-				print ("Error while executing '%s': %s\n".printf(cmd,e.message));
-			}
-			return "";
-		}
+	}
+	catch (Error e) {
+		print ("Error while executing '%s': %s\n".printf(cmd,e.message));
+	}
+	return "";
+}
+
+// Poor's man demangler. libunwind is another dep
+// TODO : Optimize this
+// module : app
+// address : 0x007f80
+// output : /home/cran/Projects/noise/noise-perf-instant-search/tests/errors.vala:87
+private string process_line (string module, string address) {
+	var cmd = "addr2line -f -e %s %s".printf (module, address);
+	var result = execute_command_sync_get_output (cmd);
+	//stdout.printf( "CMD %s\n", cmd);
+	return result;
+}
 
-		// Poor's man demangler. libunwind is another dep
-		// TODO : Optimize this
-		// module : app
-		// address : 0x007f80
-		// output : /home/cran/Projects/noise/noise-perf-instant-search/tests/errors.vala:87
-		private string process_line (string module, string address) {
-			var cmd = "addr2line -f -e %s %s".printf (module, address);
-			var result = execute_command_sync_get_output (cmd);
-			//stdout.printf( "CMD %s\n", cmd);
-			return result;
-		}
-
-	/**
-	 * Populates the stacktrace with frames
-	 *
-	 * The frames are extracted from ``Linux.Backtrace`` and enriched
-	 * via calls to unix tools ``nm`` and ``addr2line``.
-	 *
-	 * ''Warning:'' because this methods calls synchronously other applications (nm and addr2line), it
-	 * can have a significant impact on performance.
-	 *
-	 * @param trace the stacktrace
-	 */
-		public void create_stacktrace (Stacktrace trace) {
-			int frame_count = 100;
-			int skipped_frames_count = 5;
-			// Stacktrace not due to a crash
-			if (trace.is_custom)
-				skipped_frames_count = 3;
-
-			void *[] array = new void *[frame_count];
-
-			trace.frames.clear ();
-			trace.first_vala = null;
-			trace.max_file_name_length = 0;
-			trace.is_all_function_name_blank = true;
-			trace.is_all_file_name_blank = true;
+/**
+ * Populates the stacktrace with frames
+ *
+ * The frames are extracted from ``Linux.Backtrace`` and enriched
+ * via calls to unix tools ``nm`` and ``addr2line``.
+ *
+ * ''Warning:'' because this methods calls synchronously other applications (nm and addr2line), it
+ * can have a significant impact on performance.
+ *
+ * @param trace the stacktrace
+ */
+public void create_stacktrace (Stacktrace trace) {
+	int frame_count = 100;
+	int skipped_frames_count = 5;
+	// Stacktrace not due to a crash
+	if (trace.is_custom)
+		skipped_frames_count = 3;
+
+	void *[] array = new void *[frame_count];
+
+	trace.frames.clear ();
+	trace.first_vala = null;
+	trace.max_file_name_length = 0;
+	trace.is_all_function_name_blank = true;
+	trace.is_all_file_name_blank = true;
 
-			// TODO fix that > 0.26
+	// TODO fix that > 0.26
 			#if VALA_0_26 || VALA_0_28
-			var size = Linux.Backtrace.@get (array);
-			var strings = Linux.Backtrace.symbols (array);
+	var size = Linux.Backtrace.@get (array);
+	var strings = Linux.Backtrace.symbols (array);
 			#else
-			int size = Linux.backtrace (array, frame_count);
-			unowned string[] strings = Linux.backtrace_symbols (array, size);
-			// Needed because of some weird bug
-			strings.length = size;
+	int size = Linux.backtrace (array, frame_count);
+	unowned string[] strings = Linux.backtrace_symbols (array, size);
+	// Needed because of some weird bug
+	strings.length = size;
 			#endif
 
-			int[] addresses = (int[])array;
-			string module = get_module_name ();
-			// First ones are the handler
-			for (int i = skipped_frames_count ; i < size ; i++) {
-				int address = addresses[i];
-				string str = strings[i];
-				var addr = extract_address (str);
-				lib_address ="";
-				//stdout.printf ("9 '%s'. Addr: '%s' \n", func, addr);
-				var full_line = process_line (module, addr);
-				//stdout.printf ("10 '%s'\n", func);
-				if( full_line == "" ) {
-					// Happens when the process memory is going up and up
-					// Likely a memory leak
-					// Like in the test suite for echo
-					// ** (/home/cran/Documents/Projects/i-hate-farms/ide/echo/build/test:2859):
-					// CRITICAL **: vala_data_type_copy: assertion 'self != NULL' failed
-					// Error while executing 'addr2line -f -e /home/cran/Documents/Projects/i-
-					// hate-farms/ide/echo/build/test 0x2afe3b5beb32': Failed to fork (Cannot allocate memory)
-
-					print ("Something went very wrong. Your stacktrace cannot be displayed\n");
-					break;
-				}
-				process_info_for_file( full_line, str);
-				//stdout.printf ("11 '%s'\n", func);
-				if (file_line == "") {
-					file_path = extract_file_path_from (str);
-
-				}
-				//stdout.printf ("12 '%s'\n", func);
-				// The file name may ends with .so or .so.0 ...
-				if( ".so" in file_path ) {
-					process_info_from_lib (file_path, str);
-				}
-				//stdout.printf ("14 '%s'\n", func);
-				if( show_debug_frames )
-				{
-					stdout.printf ("\nFrame %d \n--------\n  . addr: [%s]\n  . full_line: '%s'\n  . file_line: '%s'\n  . func_line: '%s'\n  . str : '%s'\n  . func: '%s'\n  . file: '%s'\n  . line: '%s'\n  . address: '%#08x'\n  . lib_address: '%s'\n",
-					i, addr, full_line, file_line, func_line, str, func, file_path, l, address, lib_address);
-				}
-				if (func != "" && file_path.has_suffix (".vala") && trace.is_all_function_name_blank)
-					trace.is_all_function_name_blank = false;
-
-				if (short_file_path != "" && trace.is_all_file_name_blank)
-					trace.is_all_file_name_blank = false;
-
-				var line_number = extract_line (file_line);
-				var frame = new Frame (addr, file_line, func, file_path, short_file_path, line_number);
-
-				if (trace.first_vala == null && file_path.has_suffix (".vala"))
-					trace.first_vala = frame;
-
-				if (short_file_path.length > trace.max_file_name_length)
-					trace.max_file_name_length = short_file_path.length;
-				if (l.length > trace.max_line_number_length)
-					trace.max_line_number_length = l.length;
-				trace.frames.add (frame);
-			}
-		}
+	int[] addresses = (int[])array;
+	string module = get_module_name ();
+	// First ones are the handler
+	for (int i = skipped_frames_count; i < size; i++) {
+		int address = addresses[i];
+		string str = strings[i];
+		var addr = extract_address (str);
+		lib_address ="";
+		//stdout.printf ("9 '%s'. Addr: '%s' \n", func, addr);
+		var full_line = process_line (module, addr);
+		//stdout.printf ("10 '%s'\n", func);
+		if( full_line == "" ) {
+			// Happens when the process memory is going up and up
+			// Likely a memory leak
+			// Like in the test suite for echo
+			// ** (/home/cran/Documents/Projects/i-hate-farms/ide/echo/build/test:2859):
+			// CRITICAL **: vala_data_type_copy: assertion 'self != NULL' failed
+			// Error while executing 'addr2line -f -e /home/cran/Documents/Projects/i-
+			// hate-farms/ide/echo/build/test 0x2afe3b5beb32': Failed to fork (Cannot allocate memory)
+
+			print ("Something went very wrong. Your stacktrace cannot be displayed\n");
+			break;
+		}
+		process_info_for_file( full_line, str);
+		//stdout.printf ("11 '%s'\n", func);
+		if (file_line == "") {
+			file_path = extract_file_path_from (str);
+
+		}
+		//stdout.printf ("12 '%s'\n", func);
+		// The file name may ends with .so or .so.0 ...
+		if( ".so" in file_path ) {
+			process_info_from_lib (file_path, str);
+		}
+		//stdout.printf ("14 '%s'\n", func);
+		if( show_debug_frames )
+		{
+			stdout.printf ("\nFrame %d \n--------\n  . addr: [%s]\n  . full_line: '%s'\n  . file_line: '%s'\n  . func_line: '%s'\n  . str : '%s'\n  . func: '%s'\n  . file: '%s'\n  . line: '%s'\n  . address: '%#08x'\n  . lib_address: '%s'\n",
+			               i, addr, full_line, file_line, func_line, str, func, file_path, l, address, lib_address);
+		}
+		if (func != "" && file_path.has_suffix (".vala") && trace.is_all_function_name_blank)
+			trace.is_all_function_name_blank = false;
+
+		if (short_file_path != "" && trace.is_all_file_name_blank)
+			trace.is_all_file_name_blank = false;
+
+		var line_number = extract_line (file_line);
+		var frame = new Frame (addr, file_line, func, file_path, short_file_path, line_number);
+
+		if (trace.first_vala == null && file_path.has_suffix (".vala"))
+			trace.first_vala = frame;
+
+		if (short_file_path.length > trace.max_file_name_length)
+			trace.max_file_name_length = short_file_path.length;
+		if (l.length > trace.max_line_number_length)
+			trace.max_line_number_length = l.length;
+		trace.frames.add (frame);
 	}
 }
+}
+}
diff -pruN 2.6.1-1/libraries/libIvy/Frame.vala 2.7.1-1/libraries/libIvy/Frame.vala
--- 2.6.1-1/libraries/libIvy/Frame.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/libraries/libIvy/Frame.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,87 +16,87 @@
 
 namespace Ivy {
 
-	/**
-	 * A part of a stacktrace
-	 *
-	 * This class represent on instance of a frame, ie a particular location
-	 * in a binary (application or library) on the system called by the application
-	 *
-	 * ''Note:'' frames from system libraries without code information available are
-	 * not displayed by default. See {@link Stacktrace.hide_installed_libraries} for how to
-	 * display them.
-	 **/
-	public class Frame {
-
-		/**
-		 * Address of the stack in hexadecimal
-		 *
-		 * Ex: ``0x309``
-		 **/
-		public string address  { get;private set;default = "";}
-
-		/**
-		 * Line of code of the frame
-		 *
-		 * Can point to C code, Vala code or be blank if
-		 * no symbol is available (or if -rdynamic has not been set during the
-		 * compilation of the binary)
-		 *
-		 * Ex:
-		 **/
-		public string line { get;private set;default = "";}
-
-		/**
-		 * Line number in the code file.
-		 *
-		 * May be blank if no code information is available
-		 *
-		 * Ex: ``25``
-		 **/
-		public string line_number { get;private set;default = "";}
-
-		/**
-		 * Full path to the code file as it was stored on the building machine
-		 *
-		 * Returns the path to the installed binary if no code information is available
-		 *
-		 * Ex: ``/home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala``
-		 *
-		 * Ex: ``/lib/x86_64-linux-gnu/libc.so.6`` if no code information is available
-		 **/
-		public string file_path { get;private set;default = "";}
-
-		/**
-		 * Path the code file relative to the current path
-		 *
-		 * Returns the path to the installed binary if no code information is available
-		 *
-		 * Ex: ``/stuff/to/stuff/``
-		 **/
-		public string file_short_path { get;private set;default = "";}
-
-		/**
-		 * C function name
-		 *
-		 * Because only the C function name is avaialable,
-		 * the name mixes the vala class and vala method name (by default separated by ``_``).
-		 *
-		 * For more information about getting full vala names see [[https://bugzilla.gnome.org/show_bug.cgi?id=738784|vala bug #738784]]
-		 *
-		 * Ex: ``namespace_someclass_method``
-		 **/
-		public string function { get;private set;default = "";}
-
-		public Frame (string address, string line, string function, string file_path, string file_short_path, string line_number) {
-			this._address = address;
-			this._line = line;
-
-			this._file_path = file_path;
-			this._file_short_path = file_short_path;
-			this._function = function;
-			this.line_number = line_number;
-		}
+/**
+ * A part of a stacktrace
+ *
+ * This class represent on instance of a frame, ie a particular location
+ * in a binary (application or library) on the system called by the application
+ *
+ * ''Note:'' frames from system libraries without code information available are
+ * not displayed by default. See {@link Stacktrace.hide_installed_libraries} for how to
+ * display them.
+ **/
+public class Frame {
+
+/**
+ * Address of the stack in hexadecimal
+ *
+ * Ex: ``0x309``
+ **/
+public string address  { get; private set; default = "";}
+
+/**
+ * Line of code of the frame
+ *
+ * Can point to C code, Vala code or be blank if
+ * no symbol is available (or if -rdynamic has not been set during the
+ * compilation of the binary)
+ *
+ * Ex:
+ **/
+public string line { get; private set; default = "";}
+
+/**
+ * Line number in the code file.
+ *
+ * May be blank if no code information is available
+ *
+ * Ex: ``25``
+ **/
+public string line_number { get; private set; default = "";}
+
+/**
+ * Full path to the code file as it was stored on the building machine
+ *
+ * Returns the path to the installed binary if no code information is available
+ *
+ * Ex: ``/home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala``
+ *
+ * Ex: ``/lib/x86_64-linux-gnu/libc.so.6`` if no code information is available
+ **/
+public string file_path { get; private set; default = "";}
+
+/**
+ * Path the code file relative to the current path
+ *
+ * Returns the path to the installed binary if no code information is available
+ *
+ * Ex: ``/stuff/to/stuff/``
+ **/
+public string file_short_path { get; private set; default = "";}
+
+/**
+ * C function name
+ *
+ * Because only the C function name is avaialable,
+ * the name mixes the vala class and vala method name (by default separated by ``_``).
+ *
+ * For more information about getting full vala names see [[https://bugzilla.gnome.org/show_bug.cgi?id=738784|vala bug #738784]]
+ *
+ * Ex: ``namespace_someclass_method``
+ **/
+public string function { get; private set; default = "";}
+
+public Frame (string address, string line, string function, string file_path, string file_short_path, string line_number) {
+	this._address = address;
+	this._line = line;
+
+	this._file_path = file_path;
+	this._file_short_path = file_short_path;
+	this._function = function;
+	this.line_number = line_number;
+}
 
-	}
+}
 
 }
diff -pruN 2.6.1-1/libraries/libIvy/Printer.vala 2.7.1-1/libraries/libIvy/Printer.vala
--- 2.6.1-1/libraries/libIvy/Printer.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/libraries/libIvy/Printer.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,227 +16,227 @@
 
 namespace Ivy {
 
-	/**
-	 * Prints the stacktrace to ``stdout`` in colors
-	 *
-	 */
-	public class Printer {
-
-		private Color background_color = Color.BLACK;
-		private int title_length = 0;
-
-		private Stacktrace stacktrace;
-
-	   private string get_reset_code () {
-			// return get_color_code (Style.RESET, Colors.WHITE, Colors.BLACK);
-			return "\x1b[0m";
-		}
+/**
+ * Prints the stacktrace to ``stdout`` in colors
+ *
+ */
+public class Printer {
+
+private Color background_color = Color.BLACK;
+private int title_length = 0;
+
+private Stacktrace stacktrace;
+
+private string get_reset_code () {
+	// return get_color_code (Style.RESET, Colors.WHITE, Colors.BLACK);
+	return "\x1b[0m";
+}
 
-		private string get_reset_style () {
-			return get_color_code (Style.DIM, stacktrace.highlight_color, background_color);
-		}
+private string get_reset_style () {
+	return get_color_code (Style.DIM, stacktrace.highlight_color, background_color);
+}
 
-		private string get_color_code (Style attr, Color fg, Color bg = background_color) {
-			/* Command is the control command to the terminal */
-			if (bg == Color.BLACK)
-				return "%c[%d;%dm".printf (0x1B, (int) attr, (int) fg + 30);
-			else
-				return "%c[%d;%d;%dm".printf (0x1B, (int) attr, (int) fg + 30, (int) bg + 40);
-		}
+private string get_color_code (Style attr, Color fg, Color bg = background_color) {
+	/* Command is the control command to the terminal */
+	if (bg == Color.BLACK)
+		return "%c[%d;%dm".printf (0x1B, (int) attr, (int) fg + 30);
+	else
+		return "%c[%d;%d;%dm".printf (0x1B, (int) attr, (int) fg + 30, (int) bg + 40);
+}
 
-		private string get_signal_name () {
-			return stacktrace.sig.to_string ();
-		}
+private string get_signal_name () {
+	return stacktrace.sig.to_string ();
+}
 
-		private string get_highlight_code () {
-			return get_color_code (Style.BRIGHT, stacktrace.highlight_color);
-		}
+private string get_highlight_code () {
+	return get_color_code (Style.BRIGHT, stacktrace.highlight_color);
+}
 
-		private string get_printable_function (Frame frame, int padding = 0) {
-			var result = "";
-			var is_unknown = false;
-			if (frame.function == "") {
-				result = "<unknown> " + frame.address;
-				is_unknown = true;
-			} else {
-				var s = "";
-				int count = padding - get_signal_name ().length;
-				if (padding != 0 && count > 0)
-					s = string.nfill (count, ' ');
-				result = "'" + frame.function + "'" + s;
-			}
-			if (is_unknown)
-				return result + get_reset_code ();
-			else
-				return get_highlight_code () + result + get_reset_code ();
-		}
+private string get_printable_function (Frame frame, int padding = 0) {
+	var result = "";
+	var is_unknown = false;
+	if (frame.function == "") {
+		result = "<unknown> " + frame.address;
+		is_unknown = true;
+	} else {
+		var s = "";
+		int count = padding - get_signal_name ().length;
+		if (padding != 0 && count > 0)
+			s = string.nfill (count, ' ');
+		result = "'" + frame.function + "'" + s;
+	}
+	if (is_unknown)
+		return result + get_reset_code ();
+	else
+		return get_highlight_code () + result + get_reset_code ();
+}
 
-		private string get_printable_line_number (Frame frame, bool pad = true) {
-			var path = frame.line_number;
-			var max_line_number_length = stacktrace.max_line_number_length;
-			var result = "";
-			var color = get_highlight_code ();
-			if (path.length >= max_line_number_length || !pad)
-				result = color + path + get_reset_style ();
-			else {
-				result = color + path + get_reset_style ();
-				result = string.nfill (max_line_number_length - path.length, ' ') + result;
-			}
-			return result;
-		}
+private string get_printable_line_number (Frame frame, bool pad = true) {
+	var path = frame.line_number;
+	var max_line_number_length = stacktrace.max_line_number_length;
+	var result = "";
+	var color = get_highlight_code ();
+	if (path.length >= max_line_number_length || !pad)
+		result = color + path + get_reset_style ();
+	else {
+		result = color + path + get_reset_style ();
+		result = string.nfill (max_line_number_length - path.length, ' ') + result;
+	}
+	return result;
+}
 
-		private string get_printable_file_short_path (Frame frame, bool pad = true) {
-			var path = frame.file_short_path;
-			var max_file_name_length = stacktrace.max_file_name_length;
-			var result = "";
-			var color = get_highlight_code ();
-			if (path.length >= max_file_name_length || !pad)
-				result = color + path + get_reset_style ();
-			else {
-				result = color + path + get_reset_style ();
-				result = result + string.nfill (max_file_name_length - path.length, ' ');
-			}
-			return result;
-		}
+private string get_printable_file_short_path (Frame frame, bool pad = true) {
+	var path = frame.file_short_path;
+	var max_file_name_length = stacktrace.max_file_name_length;
+	var result = "";
+	var color = get_highlight_code ();
+	if (path.length >= max_file_name_length || !pad)
+		result = color + path + get_reset_style ();
+	else {
+		result = color + path + get_reset_style ();
+		result = result + string.nfill (max_file_name_length - path.length, ' ');
+	}
+	return result;
+}
 
-		private string get_printable_title () {
-			var c = get_color_code (Style.DIM, stacktrace.highlight_color, background_color);
-			var color = get_highlight_code ();
-
-			var result = "";
-
-			if( stacktrace.is_custom)
-				result = "%sA function was called in %s".printf (
-					c,
-					get_reset_style ());
-			else
-				result = "%sAn error occured %s(%s)%s".printf (
-					c,
-					color,
-					get_signal_name (),
-					get_reset_style ());
+private string get_printable_title () {
+	var c = get_color_code (Style.DIM, stacktrace.highlight_color, background_color);
+	var color = get_highlight_code ();
+
+	var result = "";
+
+	if( stacktrace.is_custom)
+		result = "%sA function was called in %s".printf (
+			c,
+			get_reset_style ());
+	else
+		result = "%sAn error occured %s(%s)%s".printf (
+			c,
+			color,
+			get_signal_name (),
+			get_reset_style ());
 
-			title_length = get_signal_name ().length;
-			return result;
-		}
+	title_length = get_signal_name ().length;
+	return result;
+}
 
-		private string get_reason () {
-			// var c = get_reset_code();
-			var sig = stacktrace.sig;
-
-			var color = get_highlight_code ();
-			if (sig == ProcessSignal.TRAP) {
-				return "The reason is likely %san uncaught error%s".printf (
-					color, get_reset_code ());
-			}
-			if (sig == ProcessSignal.ABRT) {
-				return "The reason is likely %sa failed assertion (assert...)%s".printf (
-					color, get_reset_code ());
-			}
-			if (sig == ProcessSignal.SEGV) {
-				return "The reason is likely %sa null reference being used%s".printf (
-					color, get_reset_code ());
-			}
-			return "Unknown reason";
-		}
+private string get_reason () {
+	// var c = get_reset_code();
+	var sig = stacktrace.sig;
+
+	var color = get_highlight_code ();
+	if (sig == ProcessSignal.TRAP) {
+		return "The reason is likely %san uncaught error%s".printf (
+			color, get_reset_code ());
+	}
+	if (sig == ProcessSignal.ABRT) {
+		return "The reason is likely %sa failed assertion (assert...)%s".printf (
+			color, get_reset_code ());
+	}
+	if (sig == ProcessSignal.SEGV) {
+		return "The reason is likely %sa null reference being used%s".printf (
+			color, get_reset_code ());
+	}
+	return "Unknown reason";
+}
 
-		/**
-		 * Print the stacktrace to ``stdout``
-		 *
-		 * @param trace the stacktrace
-		 *
-		 */
-		public virtual void print (Stacktrace trace) {
-			this.stacktrace = trace;
-			background_color = stacktrace.error_background;
-			var header = "%s%s\n".printf (get_printable_title (),
-										  get_reset_code ());
-			var first_vala = trace.first_vala;
-
-			if (trace.first_vala != null) {
-				header = "%s in %s, line %s in %s\n".printf (
-					get_printable_title (),
-					get_printable_file_short_path (first_vala, false),
-					get_printable_line_number (first_vala, false),
-					get_printable_function (first_vala) + get_reset_code ());
-				title_length += first_vala.line_number.length +
-								first_vala.function.length +
-								first_vala.file_short_path.length;
-			}
-			stdout.printf (header);
-			background_color = Color.BLACK;
-			if( !stacktrace.is_custom) {
-				var reason = get_reason ();
-				stdout.printf ("   %s.\n", reason);
-			}
-			var is_all_file_name_blank = stacktrace.is_all_file_name_blank;
+/**
+ * Print the stacktrace to ``stdout``
+ *
+ * @param trace the stacktrace
+ *
+ */
+public virtual void print (Stacktrace trace) {
+	this.stacktrace = trace;
+	background_color = stacktrace.error_background;
+	var header = "%s%s\n".printf (get_printable_title (),
+	                              get_reset_code ());
+	var first_vala = trace.first_vala;
+
+	if (trace.first_vala != null) {
+		header = "%s in %s, line %s in %s\n".printf (
+			get_printable_title (),
+			get_printable_file_short_path (first_vala, false),
+			get_printable_line_number (first_vala, false),
+			get_printable_function (first_vala) + get_reset_code ());
+		title_length += first_vala.line_number.length +
+		                first_vala.function.length +
+		                first_vala.file_short_path.length;
+	}
+	stdout.printf (header);
+	background_color = Color.BLACK;
+	if( !stacktrace.is_custom) {
+		var reason = get_reason ();
+		stdout.printf ("   %s.\n", reason);
+	}
+	var is_all_file_name_blank = stacktrace.is_all_file_name_blank;
 
-			// Has the user forgot to compile with -g -X -rdynamic flag ?
-			if (is_all_file_name_blank) {
-				var advice = "   %sNote%s: no file path and line numbers can be retrieved. Are you sure %syou added -g -X -rdynamic%s to valac command line?\n";
-				var color = get_highlight_code ();
-				stdout.printf (advice, color, get_reset_code (), color, get_reset_code ());
-			}
+	// Has the user forgot to compile with -g -X -rdynamic flag ?
+	if (is_all_file_name_blank) {
+		var advice = "   %sNote%s: no file path and line numbers can be retrieved. Are you sure %syou added -g -X -rdynamic%s to valac command line?\n";
+		var color = get_highlight_code ();
+		stdout.printf (advice, color, get_reset_code (), color, get_reset_code ());
+	}
 
-			// Has the user forgot to compile with rdynamic flag ?
-			if (stacktrace.is_all_function_name_blank && !is_all_file_name_blank) {
-				var advice = "   %sNote%s: no vala function name can be retrieved. Are you sure %syou added -X -rdynamic%s to valac command line?\n";
-				var color = get_highlight_code ();
-				stdout.printf (advice, color, get_reset_code (), color, get_reset_code ());
-			}
+	// Has the user forgot to compile with rdynamic flag ?
+	if (stacktrace.is_all_function_name_blank && !is_all_file_name_blank) {
+		var advice = "   %sNote%s: no vala function name can be retrieved. Are you sure %syou added -X -rdynamic%s to valac command line?\n";
+		var color = get_highlight_code ();
+		stdout.printf (advice, color, get_reset_code (), color, get_reset_code ());
+	}
 
-			stdout.printf ("\n");
-			int i = 1;
-			bool has_displayed_first_vala = false;
-			foreach (var frame in trace.frames) {
-				var show_frame = frame.function != "" || frame.file_path.has_suffix (".vala") || frame.file_path.has_suffix (".c");
-				if (Stacktrace.hide_installed_libraries && has_displayed_first_vala)
-					show_frame = show_frame && frame.file_short_path != "";
-
-				// Ignore glib tracing code if displayed before the first vala frame
-				if ((frame.function == "g_logv" || frame.function == "g_log") && !has_displayed_first_vala)
-					show_frame = false;
-				if (show_frame) {
-					// #2  ./OtherModule.c      line 80      in 'other_module_do_it'
-					// at /home/cran/Projects/noise/noise-perf-instant-search/tests/errors/module/OtherModule.vala:10
-					var str = " %s  #%d  %s    line %s in %s\n";
-					background_color = Color.BLACK;
-					var lead = " ";
-					var function_padding = 0;
-					if (frame == first_vala) {
-						has_displayed_first_vala = true;
-						lead = "*";
-						background_color = stacktrace.error_background;
-						function_padding = 22;
-					}
-					var l_number = "";
-					if (frame.line_number == "") {
-						str = " %s  #%d  <unknown>  %s in %s\n";
-						var func_name = get_printable_function (frame);
-						var fill_len = int.max (stacktrace.max_file_name_length + stacktrace.max_line_number_length - 1, 0);
-						str = str.printf (
-							lead,
-							i,
-							string.nfill (fill_len, ' '),
-							func_name);
-					} else {
-						str = str.printf (
-							lead,
-							i,
-							get_printable_file_short_path (frame),
-							get_printable_line_number (frame),
-							get_printable_function (frame, function_padding));
-						l_number = ":" + frame.line_number;
-					}
-					stdout.printf (str);
-					str = "        at %s%s\n".printf (
-						frame.file_path, l_number);
-					stdout.printf (str);
+	stdout.printf ("\n");
+	int i = 1;
+	bool has_displayed_first_vala = false;
+	foreach (var frame in trace.frames) {
+		var show_frame = frame.function != "" || frame.file_path.has_suffix (".vala") || frame.file_path.has_suffix (".c");
+		if (Stacktrace.hide_installed_libraries && has_displayed_first_vala)
+			show_frame = show_frame && frame.file_short_path != "";
+
+		// Ignore glib tracing code if displayed before the first vala frame
+		if ((frame.function == "g_logv" || frame.function == "g_log") && !has_displayed_first_vala)
+			show_frame = false;
+		if (show_frame) {
+			// #2  ./OtherModule.c      line 80      in 'other_module_do_it'
+			// at /home/cran/Projects/noise/noise-perf-instant-search/tests/errors/module/OtherModule.vala:10
+			var str = " %s  #%d  %s    line %s in %s\n";
+			background_color = Color.BLACK;
+			var lead = " ";
+			var function_padding = 0;
+			if (frame == first_vala) {
+				has_displayed_first_vala = true;
+				lead = "*";
+				background_color = stacktrace.error_background;
+				function_padding = 22;
+			}
+			var l_number = "";
+			if (frame.line_number == "") {
+				str = " %s  #%d  <unknown>  %s in %s\n";
+				var func_name = get_printable_function (frame);
+				var fill_len = int.max (stacktrace.max_file_name_length + stacktrace.max_line_number_length - 1, 0);
+				str = str.printf (
+					lead,
+					i,
+					string.nfill (fill_len, ' '),
+					func_name);
+			} else {
+				str = str.printf (
+					lead,
+					i,
+					get_printable_file_short_path (frame),
+					get_printable_line_number (frame),
+					get_printable_function (frame, function_padding));
+				l_number = ":" + frame.line_number;
+			}
+			stdout.printf (str);
+			str = "        at %s%s\n".printf (
+				frame.file_path, l_number);
+			stdout.printf (str);
 
-					i++;
-				}
-			}
+			i++;
 		}
-
 	}
 }
+
+}
+}
diff -pruN 2.6.1-1/libraries/libIvy/Stacktrace.vala 2.7.1-1/libraries/libIvy/Stacktrace.vala
--- 2.6.1-1/libraries/libIvy/Stacktrace.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/libraries/libIvy/Stacktrace.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,388 +14,388 @@
  * limitations under the License.
  */
 
- /**
-  * Provides services to display vala stacktraces
-  */
+/**
+ * Provides services to display vala stacktraces
+ */
 namespace Ivy {
 
-	internal enum Style {
-		RESET = 0,
-		BRIGHT = 1,
-		DIM = 2,
-		UNDERLINE = 3,
-		BLINK = 4,
-		REVERSE = 7,
-		HIDDEN = 8
-	}
+internal enum Style {
+	RESET = 0,
+	BRIGHT = 1,
+	DIM = 2,
+	UNDERLINE = 3,
+	BLINK = 4,
+	REVERSE = 7,
+	HIDDEN = 8
+}
 
+/**
+ * Defines how Unix signals are processed
+ */
+public enum CriticalHandler {
 	/**
-	 * Defines how Unix signals are processed
+	 * Unix signals are ignored
 	 */
-	public enum CriticalHandler {
-		/**
-		 * Unix signals are ignored
-		 */
-		IGNORE,
-		/**
-		 * When a signal is intercepted, a stacktrace is displayed
-		 * to ``stdout`` and the execution of the application is
-		 * resumed
-		 */
-		PRINT_STACKTRACE,
-		/**
-		 * When a signal is intercepted, a stacktrace is displayed
-		 * to ``stdout`` and  the application is stopped
-		 */
-		CRASH
-	}
-
+	IGNORE,
 	/**
-	 * Colors used for displaying stacktraces
+	 * When a signal is intercepted, a stacktrace is displayed
+	 * to ``stdout`` and the execution of the application is
+	 * resumed
 	 */
-	public enum Color {
-		BLACK = 0,
-		RED = 1,
-		GREEN = 2,
-		YELLOW = 3,
-		BLUE = 4,
-		MAGENTA = 5,
-		CYAN = 6,
-		WHITE = 7
-	}
-
+	PRINT_STACKTRACE,
 	/**
-	 * A complete execution stacktrace
-	 *
-	 * Holds a collection of {@link Frame} and the basic methods to intercept Unix signals
-	 * and prints the complete stacktrace to ``stdout`` in colors.
-	 *
-	 * For more information, refer to the [[https://github.com/I-hate-farms/stacktrace|official website]].
-	 *
-	 * Here's a sample of a printed stacktrace:
-	 * {{{
-	 * An error occured (SIGSEGV) in samples/vala_file.vala, line 21 in 'this_will_crash_harder'
-	 * The reason is likely a null reference being used.
-	 *
-	 *    #1  <unknown>                                   in 'strlen'
-	 *        at /lib/x86_64-linux-gnu/libc.so.6
-	 * *  #2  samples/vala_file.vala             line  21 in 'this_will_crash_harder'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/vala_file.vala:21
-	 *    #3  samples/module/OtherModule.vala    line  11 in 'other_module_do_it'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/module/OtherModule.vala:11
-	 *    #4  samples/error_sigsegv.vala         line  19 in 'namespace_someclass_exec'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:19
-	 *    #5  samples/error_sigsegv.vala         line  29 in 'this_will_crash'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:29
-	 *    #6  samples/error_sigsegv.vala         line  39 in '_vala_main'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:39
-	 *    #7  error_sigsegv.vala.c               line 421 in 'main'
-	 *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/error_sigsegv.vala.c:421
-	 *    #8  <unknown>                                   in '__libc_start_main'
-	 *        at /lib/x86_64-linux-gnu/libc.so.6
-	 * }}}
+	 * When a signal is intercepted, a stacktrace is displayed
+	 * to ``stdout`` and  the application is stopped
 	 */
-	public class Stacktrace {
+	CRASH
+}
+
+/**
+ * Colors used for displaying stacktraces
+ */
+public enum Color {
+	BLACK = 0,
+	RED = 1,
+	GREEN = 2,
+	YELLOW = 3,
+	BLUE = 4,
+	MAGENTA = 5,
+	CYAN = 6,
+	WHITE = 7
+}
+
+/**
+ * A complete execution stacktrace
+ *
+ * Holds a collection of {@link Frame} and the basic methods to intercept Unix signals
+ * and prints the complete stacktrace to ``stdout`` in colors.
+ *
+ * For more information, refer to the [[https://github.com/I-hate-farms/stacktrace|official website]].
+ *
+ * Here's a sample of a printed stacktrace:
+ * {{{
+ * An error occured (SIGSEGV) in samples/vala_file.vala, line 21 in 'this_will_crash_harder'
+ * The reason is likely a null reference being used.
+ *
+ *    #1  <unknown>                                   in 'strlen'
+ *        at /lib/x86_64-linux-gnu/libc.so.6
+ * *  #2  samples/vala_file.vala             line  21 in 'this_will_crash_harder'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/vala_file.vala:21
+ *    #3  samples/module/OtherModule.vala    line  11 in 'other_module_do_it'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/module/OtherModule.vala:11
+ *    #4  samples/error_sigsegv.vala         line  19 in 'namespace_someclass_exec'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:19
+ *    #5  samples/error_sigsegv.vala         line  29 in 'this_will_crash'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:29
+ *    #6  samples/error_sigsegv.vala         line  39 in '_vala_main'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/samples/error_sigsegv.vala:39
+ *    #7  error_sigsegv.vala.c               line 421 in 'main'
+ *        at /home/cran/Documents/Projects/i-hate-farms/stacktrace/error_sigsegv.vala.c:421
+ *    #8  <unknown>                                   in '__libc_start_main'
+ *        at /lib/x86_64-linux-gnu/libc.so.6
+ * }}}
+ */
+public class Stacktrace {
+
+internal Frame first_vala = null;
+
+internal int max_file_name_length = 0;
+
+internal int max_line_number_length = 0;
+
+internal bool is_all_function_name_blank = true;
+
+internal bool is_all_file_name_blank = true;
+
+private Gee.List<Frame> _frames = new Gee.ArrayList<Frame>();
+
+/**
+ * Unix signal being intercepted
+ *
+ */
+public ProcessSignal sig;
+
+/**
+ * Enables the Unix signals interception
+ *
+ * Setting it to false and preventing signals interception and the collection
+ * of the complete stacktrace (that might a significant effect on performance)
+ * is useful when the application uses a library that emits a ``SIGTRAP``
+ * signal for unknown reasons.
+ *
+ * Such a case would cripple the application performance and clutter the
+ * ``stdout`` ouput for no benefit.
+ *
+ * Default is ``true``
+ */
+public static bool enabled { get; set; default = true;}
+
+/**
+ * Hides frames located in external system libraries (like ``libgc``) without
+ * code information
+ *
+ * * Default is ``true``
+ *
+ * Before
+ * {{{
+ *    An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
+ *   The reason is likely an uncaught error.
+ *
+ *    #1  <unknown>                                          in 'g_signal_handlers_disconnect_matched'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ * *  #2  ../src/Database/Core/QueryResult.vala    line  26 in 'app_center_core_query_result_finalize'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/QueryResult.vala:26
+ *    #3  <unknown>                                          in 'g_object_unref'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #4  ../src/Database/Core/Dao.vala            line  88 in 'app_center_core_dao_insert'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/Dao.vala:88
+ *    #5  ../src/Database/PackageKitSource.vala    line  18 in 'app_center_core_package_kit_source_fetch'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/PackageKitSource.vala:18
+ *    #6  ../src/MainPanel.vala                    line  68 in '__lambda19_'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/MainPanel.vala:68
+ *    #7  src/MainPanel.c                          line 297 in '___lambda19__app_center_views_browse_view_show_app_info'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/MainPanel.c:297
+ *    #8  <unknown>                                          in 'g_cclosure_marshal_VOID__STRINGv'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #9  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #10  <unknown>                                          in 'g_signal_emit_by_name'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #11  src/BrowseView.c                         line 871 in '__lambda16_'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:871
+ *    #12  src/BrowseView.c                         line 878 in '___lambda16__gtk_button_clicked'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:878
+ *    #13  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #14  <unknown>                                          in 'g_signal_emit'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #15  <unknown>                                          in 'g_closure_invoke'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #16  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #17  <unknown>                                          in 'g_signal_emit'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #18  <unknown>                                          in 'ffi_call_unix64'
+ *        at /usr/lib/x86_64-linux-gnu/libffi.so.6
+ *    #19  <unknown>                                          in 'ffi_call'
+ *        at /usr/lib/x86_64-linux-gnu/libffi.so.6
+ *    #20  <unknown>                                          in 'g_cclosure_marshal_generic_va'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #21  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #22  <unknown>                                          in 'g_signal_emit'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #23  <unknown>                                          in 'g_cclosure_marshal_VOID__BOXEDv'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #24  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #25  <unknown>                                          in 'g_signal_emit'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #26  <unknown>                                          in 'gtk_event_controller_handle_event'
+ *        at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
+ *    #27  <unknown>                                          in 'g_signal_emit_valist'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #28  <unknown>                                          in 'g_signal_emit'
+ *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *    #29  <unknown>                                          in 'gtk_main_do_event'
+ *        at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
+ *    #30  <unknown>                                          in 'g_main_context_dispatch'
+ *        at /lib/x86_64-linux-gnu/libglib-2.0.so.0
+ *    #31  <unknown>                                          in 'g_main_context_iteration'
+ *        at /lib/x86_64-linux-gnu/libglib-2.0.so.0
+ *    #32  <unknown>                                          in 'g_application_run'
+ *        at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
+ *    #33  <unknown>                                          in 'granite_application_run'
+ *        at /usr/lib/x86_64-linux-gnu/libgranite.so.2
+ *    #34  ../src/Application.vala                  line  54 in 'app_center_main'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Application.vala:54
+ *    #35  src/Application.c                        line 296 in 'main'
+ *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/Application.c:296
+ *    #36  <unknown>                                          in '__libc_start_main'
+ *        at /lib/x86_64-linux-gnu/libc.so.6
+ *
+ * }}}
+ *
+ * After :
+ * {{{
+ * An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
+ *    The reason is likely an uncaught error.
+ *
+ *     #1  <unknown>                                         in 'g_signal_handlers_disconnect_matched'
+ *         at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
+ *  *  #2  ../src/Database/Core/QueryResult.vala    line  26 in 'app_center_core_query_result_finalize'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/QueryResult.vala:26
+ *     #3  ../src/Database/Core/Dao.vala            line  88 in 'app_center_core_dao_insert'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/Dao.vala:88
+ *     #4  ../src/Database/PackageKitSource.vala    line  18 in 'app_center_core_package_kit_source_fetch'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/PackageKitSource.vala:18
+ *     #5  ../src/MainPanel.vala                    line  68 in '__lambda19_'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/MainPanel.vala:68
+ *     #6  src/MainPanel.c                          line 297 in '___lambda19__app_center_views_browse_view_show_app_info'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/MainPanel.c:297
+ *     #7  src/BrowseView.c                         line 871 in '__lambda16_'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:871
+ *     #8  src/BrowseView.c                         line 878 in '___lambda16__gtk_button_clicked'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:878
+ *     #9  ../src/Application.vala                  line  55 in 'app_center_main'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Application.vala:55
+ *     #10  src/Application.c                       line 304 in 'main'
+ *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/Application.c:304
+ * }}}
+ */
+public static bool hide_installed_libraries { get; set; default = true;}
 
-		internal Frame first_vala = null;
+/**
+ * Sets the default higlighted text color for stacktrace that are created
+ * via Unix signals interception
+ *
+ * Default is ``Color.WHITE``
+ */
+public static Color default_highlight_color { get; set; default = Color.WHITE;}
 
-		internal int max_file_name_length = 0;
+/**
+ * Sets the default background color for stacktrace that are created
+ * via Unix signals interception
+ *
+ * Default is ``Color.RED``
+ */
+public static Color default_error_background { get; set; default = Color.RED;}
 
-		internal int max_line_number_length = 0;
+/**
+ * Sets the stacktrace higlighted text color when printed on ``stdout``
+ *
+ * Default is ``Color.WHITE``
+ */
+public Color highlight_color { get; set; default = Color.WHITE;}
 
-		internal bool is_all_function_name_blank = true;
-
-		internal bool is_all_file_name_blank = true;
-
-		private Gee.List<Frame> _frames = new Gee.ArrayList<Frame>();
-
-		/**
-		 * Unix signal being intercepted
-		 *
-		 */
-		public ProcessSignal sig;
-
-		/**
-		 * Enables the Unix signals interception
-		 *
-		 * Setting it to false and preventing signals interception and the collection
-		 * of the complete stacktrace (that might a significant effect on performance)
-		 * is useful when the application uses a library that emits a ``SIGTRAP``
-		 * signal for unknown reasons.
-		 *
-		 * Such a case would cripple the application performance and clutter the
-		 * ``stdout`` ouput for no benefit.
-		 *
-		 * Default is ``true``
-		 */
-		public static bool enabled { get;set;default = true;}
-
-		/**
-		 * Hides frames located in external system libraries (like ``libgc``) without
-		 * code information
-		 *
-		 * * Default is ``true``
-		 *
-		 * Before
-		 * {{{
-		 *    An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
-		 *   The reason is likely an uncaught error.
-		 *
-		 *    #1  <unknown>                                          in 'g_signal_handlers_disconnect_matched'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 * *  #2  ../src/Database/Core/QueryResult.vala    line  26 in 'app_center_core_query_result_finalize'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/QueryResult.vala:26
-		 *    #3  <unknown>                                          in 'g_object_unref'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #4  ../src/Database/Core/Dao.vala            line  88 in 'app_center_core_dao_insert'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/Dao.vala:88
-		 *    #5  ../src/Database/PackageKitSource.vala    line  18 in 'app_center_core_package_kit_source_fetch'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/PackageKitSource.vala:18
-		 *    #6  ../src/MainPanel.vala                    line  68 in '__lambda19_'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/MainPanel.vala:68
-		 *    #7  src/MainPanel.c                          line 297 in '___lambda19__app_center_views_browse_view_show_app_info'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/MainPanel.c:297
-		 *    #8  <unknown>                                          in 'g_cclosure_marshal_VOID__STRINGv'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #9  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #10  <unknown>                                          in 'g_signal_emit_by_name'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #11  src/BrowseView.c                         line 871 in '__lambda16_'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:871
-		 *    #12  src/BrowseView.c                         line 878 in '___lambda16__gtk_button_clicked'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:878
-		 *    #13  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #14  <unknown>                                          in 'g_signal_emit'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #15  <unknown>                                          in 'g_closure_invoke'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #16  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #17  <unknown>                                          in 'g_signal_emit'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #18  <unknown>                                          in 'ffi_call_unix64'
-		 *        at /usr/lib/x86_64-linux-gnu/libffi.so.6
-		 *    #19  <unknown>                                          in 'ffi_call'
-		 *        at /usr/lib/x86_64-linux-gnu/libffi.so.6
-		 *    #20  <unknown>                                          in 'g_cclosure_marshal_generic_va'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #21  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #22  <unknown>                                          in 'g_signal_emit'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #23  <unknown>                                          in 'g_cclosure_marshal_VOID__BOXEDv'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #24  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #25  <unknown>                                          in 'g_signal_emit'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #26  <unknown>                                          in 'gtk_event_controller_handle_event'
-		 *        at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
-		 *    #27  <unknown>                                          in 'g_signal_emit_valist'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #28  <unknown>                                          in 'g_signal_emit'
-		 *        at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *    #29  <unknown>                                          in 'gtk_main_do_event'
-		 *        at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
-		 *    #30  <unknown>                                          in 'g_main_context_dispatch'
-		 *        at /lib/x86_64-linux-gnu/libglib-2.0.so.0
-		 *    #31  <unknown>                                          in 'g_main_context_iteration'
-		 *        at /lib/x86_64-linux-gnu/libglib-2.0.so.0
-		 *    #32  <unknown>                                          in 'g_application_run'
-		 *        at /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0
-		 *    #33  <unknown>                                          in 'granite_application_run'
-		 *        at /usr/lib/x86_64-linux-gnu/libgranite.so.2
-		 *    #34  ../src/Application.vala                  line  54 in 'app_center_main'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Application.vala:54
-		 *    #35  src/Application.c                        line 296 in 'main'
-		 *        at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/Application.c:296
-		 *    #36  <unknown>                                          in '__libc_start_main'
-		 *        at /lib/x86_64-linux-gnu/libc.so.6
-		 *
-		 * }}}
-		 *
-		 * After :
-		 * {{{
-		 * An error occured (SIGTRAP) in ../src/Database/Core/QueryResult.vala, line 26 in 'app_center_core_query_result_finalize'
-		 *    The reason is likely an uncaught error.
-		 *
-		 *     #1  <unknown>                                         in 'g_signal_handlers_disconnect_matched'
-		 *         at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
-		 *  *  #2  ../src/Database/Core/QueryResult.vala    line  26 in 'app_center_core_query_result_finalize'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/QueryResult.vala:26
-		 *     #3  ../src/Database/Core/Dao.vala            line  88 in 'app_center_core_dao_insert'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/Core/Dao.vala:88
-		 *     #4  ../src/Database/PackageKitSource.vala    line  18 in 'app_center_core_package_kit_source_fetch'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Database/PackageKitSource.vala:18
-		 *     #5  ../src/MainPanel.vala                    line  68 in '__lambda19_'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/MainPanel.vala:68
-		 *     #6  src/MainPanel.c                          line 297 in '___lambda19__app_center_views_browse_view_show_app_info'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/MainPanel.c:297
-		 *     #7  src/BrowseView.c                         line 871 in '__lambda16_'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:871
-		 *     #8  src/BrowseView.c                         line 878 in '___lambda16__gtk_button_clicked'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/BrowseView.c:878
-		 *     #9  ../src/Application.vala                  line  55 in 'app_center_main'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/src/Application.vala:55
-		 *     #10  src/Application.c                       line 304 in 'main'
-		 *         at /home/cran/Documents/Projects/i-hate-farms/app/exocron/build/src/Application.c:304
-		 * }}}
-		 */
-		public static bool hide_installed_libraries { get;set;default = true;}
-
-		/**
-		 * Sets the default higlighted text color for stacktrace that are created
-		 * via Unix signals interception
-		 *
-		 * Default is ``Color.WHITE``
-		 */
-		public static Color default_highlight_color { get;set;default = Color.WHITE;}
-
-		/**
-		 * Sets the default background color for stacktrace that are created
-		 * via Unix signals interception
-		 *
-		 * Default is ``Color.RED``
-		 */
-		 public static Color default_error_background { get;set;default = Color.RED;}
-
-		/**
-		 * Sets the stacktrace higlighted text color when printed on ``stdout``
-		 *
-		 * Default is ``Color.WHITE``
-		 */
-		 public Color highlight_color { get;set;default = Color.WHITE;}
-
-		/**
-		 * Sets the stacktrace background color when printed on ``stdout``
-		 *
-		 * Default is ``Color.RED``
-		 */
-		public Color error_background { get;set;default = Color.RED;}
-
-		/**
-		 * Collection of frames
-		 *
-		 */
-		public Gee.List<Frame> frames {
-			get {
-				return _frames;
-			}
-		}
-
-		private Printer printer = new Printer ();
-		private Extractor extractor = new Extractor ();
-
-		public Stacktrace (GLib.ProcessSignal sig = GLib.ProcessSignal.TTOU) {
-			this.sig = sig;
-			// The stacktrace is used likely to understand the inner
-			// working of the app so we displays everything.
-			if (is_custom) {
-				hide_installed_libraries = false;
-				error_background = Color.BLUE;
-			} else {
-				error_background = default_error_background;
-				highlight_color = default_highlight_color;
-			}
-			extractor.create_stacktrace (this);
-		}
-
-		/**
-		 * Returns true if the stacktrace is "custom"
-		 *
-		 * A custom stacktrace has been created via code as
-		 * opposed to created via Unix signal interception.
-		 *
-		 * Custom stacktrace are displayed with a different color scheme (default ``Color.GREEN``) that
-		 * can be set via {@link highlight_color} and {@link error_background}
-		 *
-		 * Here's how to create a custom stacktrace:
-		 * {{{
-		 *
-		 *   int my_function (string arg) {
-		 *      var custom_stracktrace = new Stacktrace ();
-		 *      custom_stracktrace.print ();
-		 *      return 0;
-		 *   }
-		 * }}}
-		 */
-		public bool is_custom {
-			get {
-				return sig == ProcessSignal.TTOU;
-			}
-		}
-
-		/**
-		 * Prints the stacktrace to ``stdout`` with colors
-		 *
-		 */
-		public void print () {
-		   printer.print (this);
-		}
-
-		/**
-		 * Registers handlers to intercept Unix signals
-		 *
-		 * Calling ``register_handlers`` is required for the
-		 * library to display a stacktrace when the application encounters an error (ie raises a ``SIGABRT``,
-		 * a ``SIGSEV`` or a ``SIGTRAP`` signal).
-		 *
-		 * ''Note:'' calling ``register_handlers`` is not needed to be able to display custom stacktraces. <<BR>>
-		 * (See {@link is_custom} for more information about custom stacktraces).
-		 *
-		 * How to initialize the library so it can intercept Unix signals:
-		 * {{{
-		 *
-		 *   static int main (string[] arg) {
-		 *      Stacktrace.register_handlers ();
-		 *      // Start your application
-		 *      ...
-		 *      return 0;
-		 *   }
-		 * }}}
-		 *
-		 */
-		public static void register_handlers () {
-			//Log.set_always_fatal (LogLevelFlags.LEVEL_CRITICAL);
-			Log.set_always_fatal (LogLevelFlags.LEVEL_ERROR);
-
-			Process.@signal (ProcessSignal.SEGV, handler);
-			Process.@signal (ProcessSignal.TRAP, handler);
-			if (critical_handling != CriticalHandler.IGNORE)
-				Process.@signal (ProcessSignal.ABRT, handler);
-		}
-
-		/**
-		 * Defines how Unix signals are processed
-		 *
-		 * Default is ``CriticalHandler.PRINT_STACKTRACE``.
-		 */
-		public static CriticalHandler critical_handling  { get;set;default = CriticalHandler.PRINT_STACKTRACE;}
-
-		/*{
-			set {
-				_critical_handling = value;
-				if( value == CriticalHandler.CRASH )
-				//var variables = Environ.get ();
-				//Environ.set_variable (variables, "G_DEBUG", "fatal-criticals" );
-				Log.set_always_fatal (LogLevelFlags.LEVEL_CRITICAL);
-			}
-			get {
-			}
-
-		   }*/
-
-		private static void handler (int sig) {
-			if( !enabled)
-				return;
-			Stacktrace stack = new Stacktrace ((ProcessSignal) sig);
-			stack.print ();
-			if (sig != ProcessSignal.TRAP ||
-				(sig == ProcessSignal.TRAP && critical_handling == CriticalHandler.CRASH))
-				Process.exit (1);
-		}
+/**
+ * Sets the stacktrace background color when printed on ``stdout``
+ *
+ * Default is ``Color.RED``
+ */
+public Color error_background { get; set; default = Color.RED;}
 
+/**
+ * Collection of frames
+ *
+ */
+public Gee.List<Frame> frames {
+	get {
+		return _frames;
+	}
+}
+
+private Printer printer = new Printer ();
+private Extractor extractor = new Extractor ();
+
+public Stacktrace (GLib.ProcessSignal sig = GLib.ProcessSignal.TTOU) {
+	this.sig = sig;
+	// The stacktrace is used likely to understand the inner
+	// working of the app so we displays everything.
+	if (is_custom) {
+		hide_installed_libraries = false;
+		error_background = Color.BLUE;
+	} else {
+		error_background = default_error_background;
+		highlight_color = default_highlight_color;
+	}
+	extractor.create_stacktrace (this);
+}
+
+/**
+ * Returns true if the stacktrace is "custom"
+ *
+ * A custom stacktrace has been created via code as
+ * opposed to created via Unix signal interception.
+ *
+ * Custom stacktrace are displayed with a different color scheme (default ``Color.GREEN``) that
+ * can be set via {@link highlight_color} and {@link error_background}
+ *
+ * Here's how to create a custom stacktrace:
+ * {{{
+ *
+ *   int my_function (string arg) {
+ *      var custom_stracktrace = new Stacktrace ();
+ *      custom_stracktrace.print ();
+ *      return 0;
+ *   }
+ * }}}
+ */
+public bool is_custom {
+	get {
+		return sig == ProcessSignal.TTOU;
 	}
 }
+
+/**
+ * Prints the stacktrace to ``stdout`` with colors
+ *
+ */
+public void print () {
+	printer.print (this);
+}
+
+/**
+ * Registers handlers to intercept Unix signals
+ *
+ * Calling ``register_handlers`` is required for the
+ * library to display a stacktrace when the application encounters an error (ie raises a ``SIGABRT``,
+ * a ``SIGSEV`` or a ``SIGTRAP`` signal).
+ *
+ * ''Note:'' calling ``register_handlers`` is not needed to be able to display custom stacktraces. <<BR>>
+ * (See {@link is_custom} for more information about custom stacktraces).
+ *
+ * How to initialize the library so it can intercept Unix signals:
+ * {{{
+ *
+ *   static int main (string[] arg) {
+ *      Stacktrace.register_handlers ();
+ *      // Start your application
+ *      ...
+ *      return 0;
+ *   }
+ * }}}
+ *
+ */
+public static void register_handlers () {
+	//Log.set_always_fatal (LogLevelFlags.LEVEL_CRITICAL);
+	Log.set_always_fatal (LogLevelFlags.LEVEL_ERROR);
+
+	Process.@signal (ProcessSignal.SEGV, handler);
+	Process.@signal (ProcessSignal.TRAP, handler);
+	if (critical_handling != CriticalHandler.IGNORE)
+		Process.@signal (ProcessSignal.ABRT, handler);
+}
+
+/**
+ * Defines how Unix signals are processed
+ *
+ * Default is ``CriticalHandler.PRINT_STACKTRACE``.
+ */
+public static CriticalHandler critical_handling  { get; set; default = CriticalHandler.PRINT_STACKTRACE;}
+
+/*{
+        set {
+                _critical_handling = value;
+                if( value == CriticalHandler.CRASH )
+                //var variables = Environ.get ();
+                //Environ.set_variable (variables, "G_DEBUG", "fatal-criticals" );
+                Log.set_always_fatal (LogLevelFlags.LEVEL_CRITICAL);
+        }
+        get {
+        }
+
+   }*/
+
+private static void handler (int sig) {
+	if( !enabled)
+		return;
+	Stacktrace stack = new Stacktrace ((ProcessSignal) sig);
+	stack.print ();
+	if (sig != ProcessSignal.TRAP ||
+	    (sig == ProcessSignal.TRAP && critical_handling == CriticalHandler.CRASH))
+		Process.exit (1);
+}
+
+}
+}
diff -pruN 2.6.1-1/libraries/WebExtension/webextension.vala 2.7.1-1/libraries/WebExtension/webextension.vala
--- 2.6.1-1/libraries/WebExtension/webextension.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/libraries/WebExtension/webextension.vala	2019-02-01 19:30:50.000000000 +0000
@@ -1,175 +1,175 @@
 [DBus (name = "org.gnome.FeedReader.ArticleView")]
 public class FeedReaderWebExtension : Object {
 
-	private WebKit.DOM.Document m_doc;
-	public signal void onClick(string path, int width, int height, string url);
-	public signal void message(string message);
+private WebKit.DOM.Document m_doc;
+public signal void onClick(string path, int width, int height, string url);
+public signal void message(string message);
 
-	[DBus (visible = false)]
-	public void on_bus_aquired(DBusConnection connection)
+[DBus (visible = false)]
+public void on_bus_aquired(DBusConnection connection)
+{
+	try
 	{
-		try
-		{
-			connection.register_object("/org/gnome/FeedReader/ArticleView", this);
-		}
-		catch(GLib.IOError e)
-		{
-			warning("Could not register object");
-		}
+		connection.register_object("/org/gnome/FeedReader/ArticleView", this);
 	}
-
-	[DBus (visible = false)]
-	public void on_page_created(WebKit.WebExtension extension, WebKit.WebPage page)
+	catch(GLib.IOError e)
 	{
-		page.document_loaded.connect(() => {
+		warning("Could not register object");
+	}
+}
+
+[DBus (visible = false)]
+public void on_page_created(WebKit.WebExtension extension, WebKit.WebPage page)
+{
+	page.document_loaded.connect(() => {
 			onDocLoaded(page);
 		});
-		message("on_page_created");
-	}
+	message("on_page_created");
+}
 
-	private void onDocLoaded(WebKit.WebPage page)
-	{
-		m_doc = page.get_dom_document();
-		message("onDocLoaded");
-	}
+private void onDocLoaded(WebKit.WebPage page)
+{
+	m_doc = page.get_dom_document();
+	message("onDocLoaded");
+}
+
+public void recalculate()
+{
+	message("recalculate");
+	var images = m_doc.get_images();
+	ulong count = images.get_length();
 
-	public void recalculate()
+	for(ulong i = 0; i < count; i++)
 	{
-		message("recalculate");
-		var images = m_doc.get_images();
-		ulong count = images.get_length();
+		var image = (WebKit.DOM.HTMLImageElement)images.item(i);
 
-		for(ulong i = 0; i < count; i++)
+		// don't offer imageviewer if image isn't local
+		if(image.src.has_prefix("http"))
+			continue;
+
+		// if image was so huge it had to be replaced with a downscaled version
+		if(image.has_attribute("FR_huge"))
+		{
+			addListener(image, image.get_attribute("FR_huge"));
+			continue;
+		}
+		else if(image.has_attribute("FR_parent"))
 		{
-			var image = (WebKit.DOM.HTMLImageElement)images.item(i);
+			addListener(image, image.get_attribute("FR_parent"));
+			continue;
+		}
 
-			// don't offer imageviewer if image isn't local
-			if(image.src.has_prefix("http"))
-				continue;
-
-			// if image was so huge it had to be replaced with a downscaled version
-			if(image.has_attribute("FR_huge"))
-			{
-				addListener(image, image.get_attribute("FR_huge"));
-				continue;
-			}
-			else if(image.has_attribute("FR_parent"))
-			{
-				addListener(image, image.get_attribute("FR_parent"));
-				continue;
-			}
-
-			long nHeight = image.get_natural_height();
-			long nWidth = image.get_natural_width();
-			long height = image.get_height();
-			long width = image.get_width();
-
-			if(nHeight > 250 || nWidth > 250)
-			{
-				double hRatio = (double)height / (double)nHeight;
-				double wRatio = (double)width / (double)nWidth;
-				double threshold = 0.8;
-
-				if(hRatio <= threshold
-				|| wRatio <= threshold)
-					addListener(image, image.src);
-				else
-					removeListener(image);
-			}
+		long nHeight = image.get_natural_height();
+		long nWidth = image.get_natural_width();
+		long height = image.get_height();
+		long width = image.get_width();
+
+		if(nHeight > 250 || nWidth > 250)
+		{
+			double hRatio = (double)height / (double)nHeight;
+			double wRatio = (double)width / (double)nWidth;
+			double threshold = 0.8;
+
+			if(hRatio <= threshold
+			   || wRatio <= threshold)
+				addListener(image, image.src);
+			else
+				removeListener(image);
 		}
 	}
+}
 
-	[DBus (visible = false)]
-	private void addListener(WebKit.DOM.HTMLImageElement image, string url)
+[DBus (visible = false)]
+private void addListener(WebKit.DOM.HTMLImageElement image, string url)
+{
+	// check if url exists
+	if(GLib.FileUtils.test(url, GLib.FileTest.EXISTS))
 	{
-		// check if url exists
-		if(GLib.FileUtils.test(url, GLib.FileTest.EXISTS))
-		{
-			((WebKit.DOM.EventTarget) image).add_event_listener_with_closure("mouseover", on_enter, false);
-			((WebKit.DOM.EventTarget) image).add_event_listener_with_closure("mousemove", on_enter, false);
-			((WebKit.DOM.EventTarget) image).add_event_listener_with_closure("mouseout", on_leave, false);
-			((WebKit.DOM.EventTarget) image).add_event_listener_with_closure("click", on_click, false);
-		}
+		((WebKit.DOM.EventTarget)image).add_event_listener_with_closure("mouseover", on_enter, false);
+		((WebKit.DOM.EventTarget)image).add_event_listener_with_closure("mousemove", on_enter, false);
+		((WebKit.DOM.EventTarget)image).add_event_listener_with_closure("mouseout", on_leave, false);
+		((WebKit.DOM.EventTarget)image).add_event_listener_with_closure("click", on_click, false);
 	}
+}
 
-	[DBus (visible = false)]
-	private void removeListener(WebKit.DOM.HTMLImageElement image)
-	{
-		((WebKit.DOM.EventTarget) image).remove_event_listener_with_closure("mouseover", on_enter, false);
-		((WebKit.DOM.EventTarget) image).remove_event_listener_with_closure("mousemove", on_enter, false);
-		((WebKit.DOM.EventTarget) image).remove_event_listener_with_closure("mouseout", on_leave, false);
-		((WebKit.DOM.EventTarget) image).remove_event_listener_with_closure("click", on_click, false);
+[DBus (visible = false)]
+private void removeListener(WebKit.DOM.HTMLImageElement image)
+{
+	((WebKit.DOM.EventTarget)image).remove_event_listener_with_closure("mouseover", on_enter, false);
+	((WebKit.DOM.EventTarget)image).remove_event_listener_with_closure("mousemove", on_enter, false);
+	((WebKit.DOM.EventTarget)image).remove_event_listener_with_closure("mouseout", on_leave, false);
+	((WebKit.DOM.EventTarget)image).remove_event_listener_with_closure("click", on_click, false);
 
-		try
-		{
-			image.set_attribute("class", "");
-		}
-		catch(GLib.Error e)
-		{
-			stderr.printf("WebExtension.recalculate: %s", e.message);
-		}
+	try
+	{
+		image.set_attribute("class", "");
 	}
-
-	[DBus (visible = false)]
-	private void on_enter(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+	catch(GLib.Error e)
 	{
-		try
-		{
-			var image = (WebKit.DOM.HTMLImageElement)target;
-			image.set_attribute("class", "clickable-img-hover");
-		}
-		catch(GLib.Error e)
-		{
-
-		}
+		stderr.printf("WebExtension.recalculate: %s", e.message);
 	}
+}
 
-	[DBus (visible = false)]
-	private void on_leave(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+[DBus (visible = false)]
+private void on_enter(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+{
+	try
+	{
+		var image = (WebKit.DOM.HTMLImageElement)target;
+		image.set_attribute("class", "clickable-img-hover");
+	}
+	catch(GLib.Error e)
 	{
-		try
-		{
-			var image = (WebKit.DOM.HTMLImageElement)target;
-			image.set_attribute("class", "");
-		}
-		catch(GLib.Error e)
-		{
 
-		}
 	}
+}
 
-	[DBus (visible = false)]
-	public void on_click(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+[DBus (visible = false)]
+private void on_leave(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+{
+	try
 	{
-		event.prevent_default();
 		var image = (WebKit.DOM.HTMLImageElement)target;
+		image.set_attribute("class", "");
+	}
+	catch(GLib.Error e)
+	{
 
-		string url = "";
-		var parent = image.get_parent_element();
-		if(parent.tag_name == "A")
-			url = parent.get_attribute("href");
+	}
+}
 
+[DBus (visible = false)]
+public void on_click(WebKit.DOM.EventTarget target, WebKit.DOM.Event event)
+{
+	event.prevent_default();
+	var image = (WebKit.DOM.HTMLImageElement)target;
 
-		int height = (int)image.natural_height;
-		int width = (int)image.natural_width;
-		string src = image.src;
-		string pref = "file://";
-		if(src.has_prefix(pref))
-			src = src.substring(pref.length);
+	string url = "";
+	var parent = image.get_parent_element();
+	if(parent.tag_name == "A")
+		url = parent.get_attribute("href");
 
-		if(image.has_attribute("FR_huge"))
-		{
-			src = image.get_attribute("FR_huge");
-			Gdk.Pixbuf.get_file_info(src, out width, out height);
-		}
-		else if(image.has_attribute("FR_parent"))
-		{
-			src = image.get_attribute("FR_parent");
-			Gdk.Pixbuf.get_file_info(src, out width, out height);
-		}
 
-		onClick(src, width, height, url);
+	int height = (int)image.natural_height;
+	int width = (int)image.natural_width;
+	string src = image.src;
+	string pref = "file://";
+	if(src.has_prefix(pref))
+		src = src.substring(pref.length);
+
+	if(image.has_attribute("FR_huge"))
+	{
+		src = image.get_attribute("FR_huge");
+		Gdk.Pixbuf.get_file_info(src, out width, out height);
 	}
+	else if(image.has_attribute("FR_parent"))
+	{
+		src = image.get_attribute("FR_parent");
+		Gdk.Pixbuf.get_file_info(src, out width, out height);
+	}
+
+	onClick(src, width, height, url);
+}
 }
 
 [DBus (name = "org.gnome.FeedReader.ArticleView")]
@@ -184,5 +184,5 @@ public void webkit_web_extension_initial
 	var server = new FeedReaderWebExtension();
 	extension.page_created.connect(server.on_page_created);
 	Bus.own_name(BusType.SESSION, "org.gnome.FeedReader.ArticleView", BusNameOwnerFlags.NONE,
-		server.on_bus_aquired, null, () => { warning("Could not aquire name"); });
+	             server.on_bus_aquired, null, () => { warning("Could not aquire name"); });
 }
diff -pruN 2.6.1-1/meson.build 2.7.1-1/meson.build
--- 2.6.1-1/meson.build	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/meson.build	2019-02-01 19:30:50.000000000 +0000
@@ -1,5 +1,5 @@
 project('feedreader', ['vala', 'c'],
-  version: '2.6.0',
+  version: '2.7.1',
   meson_version: '>= 0.44.1',
   license: 'GPL-3.0',
   default_options: ['prefix=/usr']
@@ -46,7 +46,7 @@ gstreamer_pbutils   = dependency('gstrea
 gtk                 = dependency('gtk+-3.0', version: '>=3.22')
 gumbo               = dependency('gumbo')
 json_glib           = dependency('json-glib-1.0')
-libcurl             = c_compiler.find_library('libcurl')
+libcurl             = c_compiler.find_library('curl')
 libnotify           = dependency('libnotify')
 libpeas             = dependency('libpeas-1.0')
 libsecret           = dependency('libsecret-1')
diff -pruN 2.6.1-1/org.gnome.FeedReader.json 2.7.1-1/org.gnome.FeedReader.json
--- 2.6.1-1/org.gnome.FeedReader.json	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/org.gnome.FeedReader.json	2019-02-01 19:30:50.000000000 +0000
@@ -22,7 +22,10 @@
     "--talk-name=org.gnome.OnlineAccounts",
     "--own-name=org.gnome.FeedReader.ArticleView",
     "--talk-name=org.freedesktop.Notifications",
-    "--talk-name=org.freedesktop.secrets"
+    "--talk-name=org.freedesktop.secrets",
+    /* Access to DecSync directory */
+    "--env=DECSYNC_DIR=.local/share/decsync",
+    "--filesystem=~/.local/share/decsync"
   ],
   "modules": [{
       "name": "libgee",
diff -pruN 2.6.1-1/plugins/backend/bazqux/bazquxAPI.vala 2.7.1-1/plugins/backend/bazqux/bazquxAPI.vala
--- 2.6.1-1/plugins/backend/bazqux/bazquxAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/bazqux/bazquxAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,460 +15,460 @@
 
 public class FeedReader.bazquxAPI : GLib.Object {
 
-	public enum bazquxSubscriptionAction {
-		EDIT,
-		SUBSCRIBE,
-		UNSUBSCRIBE
-	}
+public enum bazquxSubscriptionAction {
+	EDIT,
+	SUBSCRIBE,
+	UNSUBSCRIBE
+}
 
-	private bazquxConnection m_connection;
-	private bazquxUtils m_utils;
-	private string m_userID;
-	private DataBaseReadOnly m_db;
+private bazquxConnection m_connection;
+private bazquxUtils m_utils;
+private string m_userID;
+
+public bazquxAPI(bazquxUtils utils)
+{
+	m_utils = utils;
+	m_connection = new bazquxConnection(utils);
+}
 
-	public bazquxAPI(bazquxUtils utils, DataBaseReadOnly db)
-	{
-		m_db = db;
-		m_utils = utils;
-		m_connection = new bazquxConnection(utils);
+public LoginResponse login()
+{
+	if(m_utils.getAccessToken() == "")
+	{
+		var result = m_connection.getToken();
+		if(getUserID())
+			return result;
 	}
+	else if(getUserID())
+		return LoginResponse.SUCCESS;
 
-	public LoginResponse login()
-	{
-		if(m_utils.getAccessToken() == "")
-		{
-			var result = m_connection.getToken();
-			if(getUserID())
-				return result;
-		}
-		else if(getUserID())
-			return LoginResponse.SUCCESS;
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-		return LoginResponse.UNKNOWN_ERROR;
-	}
+public bool ping()
+{
+	return m_connection.ping();
+}
+
+private bool getUserID()
+{
+	Logger.debug("getUserID: getting user info");
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("user-info", msg.get());
+
+	if(response.status != 200)
+		return false;
 
-	public bool ping()
+	var parser = new Json.Parser();
+	try
 	{
-		return m_connection.ping();
+		parser.load_from_data(response.data, -1);
 	}
-
-	private bool getUserID()
+	catch(Error e)
+	{
+		Logger.error("getUserID: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	if(root.has_member("userId"))
 	{
-		Logger.debug("getUserID: getting user info");
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("user-info", msg.get());
+		m_userID = root.get_string_member("userId");
+		m_utils.setUserID(m_userID);
+		Logger.info("bazqux: userID = " + m_userID);
 
-		if(response.status != 200)
-			return false;
+		return true;
+	}
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getUserID: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		if(root.has_member("userId"))
-		{
-			m_userID = root.get_string_member("userId");
-			m_utils.setUserID(m_userID);
-			Logger.info("bazqux: userID = " + m_userID);
+	return false;
+}
 
-			return true;
-		}
+public bool getFeeds(Gee.List<Feed> feeds)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("subscription/list", msg.get());
 
+	if(response.status != 200)
 		return false;
-	}
 
-	public bool getFeeds(Gee.List<Feed> feeds)
+	Logger.debug(response.data);
+	var parser = new Json.Parser();
+	try
 	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("subscription/list", msg.get());
-
-		if(response.status != 200)
-			return false;
-
-		Logger.debug(response.data);
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getFeeds: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("subscriptions");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-
-			string feedID = object.get_string_member("id");
-			string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
-			string? icon_url = object.get_string_member("iconUrl");
-
-			uint catCount = object.get_array_member("categories").get_length();
-			var categories = new Gee.ArrayList<string>();
-			for(uint j = 0; j < catCount; ++j)
-			{
-				categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
-			}
-			feeds.add(
-				new Feed(
-						feedID,
-						object.get_string_member("title"),
-						url,
-						0,
-						categories,
-						icon_url
-					)
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getFeeds: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("subscriptions");
+	uint length = array.get_length();
+
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+
+		string feedID = object.get_string_member("id");
+		string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+		string? icon_url = object.get_string_member("iconUrl");
+
+		uint catCount = object.get_array_member("categories").get_length();
+		var categories = new Gee.ArrayList<string>();
+		for(uint j = 0; j < catCount; ++j)
+		{
+			categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+		}
+		feeds.add(
+			new Feed(
+				feedID,
+				object.get_string_member("title"),
+				url,
+				0,
+				categories,
+				icon_url
+				)
 			);
-		}
-		return true;
 	}
+	return true;
+}
 
-	public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("tag/list", msg.get());
+public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("tag/list", msg.get());
 
-		if(response.status != 200)
-			return false;
+	if(response.status != 200)
+		return false;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("tags");
-		uint length = array.get_length();
-		int orderID = 0;
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("tags");
+	uint length = array.get_length();
+	int orderID = 0;
+
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		int start = id.last_index_of_char('/') + 1;
+		string title = id.substring(start);
 
-		for (uint i = 0; i < length; i++)
+		if(id.contains("/label/"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			int start = id.last_index_of_char('/') + 1;
-			string title = id.substring(start);
-
-			if(id.contains("/label/"))
+			if(m_utils.tagIsCat(id, feeds))
 			{
-				if(m_utils.tagIsCat(id, feeds))
-				{
-					categories.add(
-						new Category(
-							id,
-							title,
-							0,
-							orderID,
-							CategoryID.MASTER.to_string(),
-							1
+				categories.add(
+					new Category(
+						id,
+						title,
+						0,
+						orderID,
+						CategoryID.MASTER.to_string(),
+						1
 						)
 					);
-					++orderID;
-				}
-				else
-				{
-					tags.add(
-						new Tag(
-							id,
-							title,
-							m_db.getTagColor()
+				++orderID;
+			}
+			else
+			{
+				tags.add(
+					new Tag(
+						id,
+						title,
+						db.getTagColor()
 						)
 					);
-				}
 			}
 		}
-		return true;
 	}
+	return true;
+}
 
 
-	public int getTotalUnread()
+public int getTotalUnread()
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("unread-count", msg.get());
+
+	if(response.status != 200)
+		return 0;
+
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
 	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("unread-count", msg.get());
+		Logger.error("getTotalUnread: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		if(response.status != 200)
-			return 0;
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("unreadcounts");
+	uint length = array.get_length();
+	int count = 0;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		if(object.get_string_member("id").has_prefix("feed/"))
 		{
-			Logger.error("getTotalUnread: Could not load message response");
-			Logger.error(e.message);
+			count += (int)object.get_int_member("count");
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("unreadcounts");
-		uint length = array.get_length();
-		int count = 0;
+	}
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			if(object.get_string_member("id").has_prefix("feed/"))
-			{
-				count += (int)object.get_int_member("count");
-			}
+	Logger.debug("getTotalUnread %i".printf(count));
+	return count;
+}
 
-		}
 
-		Logger.debug("getTotalUnread %i".printf(count));
-		return count;
-	}
+public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	msg.add("n", count.to_string());
+	msg.add("xt", "user/-/state/com.google/read");
+	if(continuation != null)
+		msg.add("c", continuation);
 
+	var response = m_connection.send_get_request("stream/items/ids", msg.get());
+
+	if(response.status != 200)
+		return null;
 
-	public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+	var parser = new Json.Parser();
+	try
 	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		msg.add("n", count.to_string());
-		msg.add("xt", "user/-/state/com.google/read");
-		if(continuation != null)
-			msg.add("c", continuation);
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("updateArticles: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		var response = m_connection.send_get_request("stream/items/ids", msg.get());
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("itemRefs");
+	uint length = array.get_length();
 
-		if(response.status != 200)
-			return null;
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		ids.add(object.get_string_member("id"));
+	}
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("updateArticles: Could not load message response");
-			Logger.error(e.message);
-		}
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("itemRefs");
-		uint length = array.get_length();
+	return null;
+}
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			ids.add(object.get_string_member("id"));
-		}
+public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	msg.add("n", count.to_string());
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
+	if(whatToGet == ArticleStatus.UNREAD)
+		msg.add("xt", "user/-/state/com.google/read");
+	if(whatToGet == ArticleStatus.READ)
+		msg.add("s", "user/-/state/com.google/read");
+	else if(whatToGet == ArticleStatus.MARKED)
+		msg.add("s", "user/-/state/com.google/starred");
+
+	if( continuation != null )
+		msg.add("c", continuation);
+
+	string api_endpoint = "stream/contents";
+	if(feed_id != null)
+		api_endpoint += "/" + feed_id;
+	else if(tagID != null)
+		api_endpoint += "/" + tagID;
+	var response = m_connection.send_get_request(api_endpoint, msg.get());
 
+	if(response.status != 200)
 		return null;
-	}
 
-	public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
 	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		msg.add("n", count.to_string());
-
-		if(whatToGet == ArticleStatus.UNREAD)
-			msg.add("xt", "user/-/state/com.google/read");
-		if(whatToGet == ArticleStatus.READ)
-			msg.add("s", "user/-/state/com.google/read");
-		else if(whatToGet == ArticleStatus.MARKED)
-			msg.add("s", "user/-/state/com.google/starred");
-
-		if( continuation != null )
-			msg.add("c", continuation);
-
-		string api_endpoint = "stream/contents";
-		if(feed_id != null)
-			api_endpoint += "/" + feed_id;
-		else if(tagID != null)
-			api_endpoint += "/" + tagID;
-		var response = m_connection.send_get_request(api_endpoint, msg.get());
+		Logger.error("getArticles: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		if(response.status != 200)
-			return null;
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("items");
+	uint length = array.get_length();
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		id = id.substring(id.last_index_of_char('/') + 1);
+		bool marked = false;
+		bool read = false;
+		var cats = object.get_array_member("categories");
+		uint cat_length = cats.get_length();
+
+		var tags = new Gee.ArrayList<string>();
+		for (uint j = 0; j < cat_length; j++)
 		{
-			Logger.error("getArticles: Could not load message response");
-			Logger.error(e.message);
+			string cat = cats.get_string_element(j);
+			if(cat.has_suffix("com.google/starred"))
+				marked = true;
+			else if(cat.has_suffix("com.google/read"))
+				read = true;
+			else if(cat.contains("/label/") && db.getTagName(cat) != null)
+				tags.add(cat);
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("items");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			id = id.substring(id.last_index_of_char('/') + 1);
-			bool marked = false;
-			bool read = false;
-			var cats = object.get_array_member("categories");
-			uint cat_length = cats.get_length();
+			var attachments = object.get_array_member("enclosure");
 
-			var tags = new Gee.ArrayList<string>();
-			for (uint j = 0; j < cat_length; j++)
-			{
-				string cat = cats.get_string_element(j);
-				if(cat.has_suffix("com.google/starred"))
-					marked = true;
-				else if(cat.has_suffix("com.google/read"))
-					read = true;
-				else if(cat.contains("/label/") && m_db.getTagName(cat) != null)
-					tags.add(cat);
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
+				var attachment = attachments.get_object_element(j);
 
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(attachment.get_string_member("type")))
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(attachment.get_string_member("type")))
 					);
-				}
 			}
-
-			articles.add(new Article(
-									id,
-									object.get_string_member("title"),
-									object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
-									object.get_object_member("origin").get_string_member("streamId"),
-									read ? ArticleStatus.READ : ArticleStatus.UNREAD,
-									marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-									object.get_object_member("summary").get_string_member("content"),
-									"",
-									object.get_string_member("author"),
-									new DateTime.from_unix_local(object.get_int_member("published")),
-									-1,
-									tags,
-									enclosures
-							)
-						);
 		}
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
-
-		return null;
+		articles.add(new Article(
+				     id,
+				     object.get_string_member("title"),
+				     object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+				     object.get_object_member("origin").get_string_member("streamId"),
+				     read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+				     marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				     object.get_object_member("summary").get_string_member("content"),
+				     "",
+				     object.get_string_member("author"),
+				     new DateTime.from_unix_local(object.get_int_member("published")),
+				     -1,
+				     tags,
+				     enclosures
+				     )
+		             );
 	}
 
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-	public void edidTag(string articleID, string tagID, bool add = true)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
+	return null;
+}
 
-		if(add)
-			msg.add("a", tagID);
-		else
-			msg.add("r", tagID);
 
-		msg.add("i", "tag:google.com,2005:reader/item/" + articleID);
-		m_connection.send_post_request("edit-tag", msg.get());
-	}
+public void edidTag(string articleID, string tagID, bool add = true)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+
+	if(add)
+		msg.add("a", tagID);
+	else
+		msg.add("r", tagID);
 
-	public void markAsRead(string? streamID = null)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		msg.add("s", streamID);
-		msg.add("ts", "%i000000".printf(Settings.state().get_int("last-sync")));
-		m_connection.send_post_request("mark-all-as-read", msg.get());
-	}
+	msg.add("i", "tag:google.com,2005:reader/item/" + articleID);
+	m_connection.send_post_request("edit-tag", msg.get());
+}
 
-	public string composeTagID(string tagName)
-	{
-		return "user/%s/label/%s".printf(m_userID, tagName);
-	}
+public void markAsRead(string? streamID = null)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	msg.add("s", streamID);
+	msg.add("ts", "%i000000".printf(Settings.state().get_int("last-sync")));
+	m_connection.send_post_request("mark-all-as-read", msg.get());
+}
 
-	public void deleteTag(string tagID)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		msg.add("s", tagID);
-		m_connection.send_post_request("disable-tag", msg.get());
-	}
+public string composeTagID(string tagName)
+{
+	return "user/%s/label/%s".printf(m_userID, tagName);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
-		msg.add("s", tagID);
-		msg.add("dest", composeTagID(title));
-		m_connection.send_post_request("rename-tag", msg.get());
-	}
+public void deleteTag(string tagID)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	msg.add("s", tagID);
+	m_connection.send_post_request("disable-tag", msg.get());
+}
 
-	public bool editSubscription(bazquxSubscriptionAction action, string feedID, string? title = null, string? add = null, string? remove = null)
-	{
-		var msg = new bazquxMessage();
-		msg.add("output", "json");
+public void renameTag(string tagID, string title)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+	msg.add("s", tagID);
+	msg.add("dest", composeTagID(title));
+	m_connection.send_post_request("rename-tag", msg.get());
+}
 
-		switch(action)
-		{
-			case bazquxSubscriptionAction.EDIT:
-				msg.add("ac", "edit");
-				break;
-			case bazquxSubscriptionAction.SUBSCRIBE:
-				msg.add("ac", "subscribe");
-				break;
-			case bazquxSubscriptionAction.UNSUBSCRIBE:
-				msg.add("ac", "unsubscribe");
-				break;
-		}
+public bool editSubscription(bazquxSubscriptionAction action, string feedID, string? title = null, string? add = null, string? remove = null)
+{
+	var msg = new bazquxMessage();
+	msg.add("output", "json");
+
+	switch(action)
+	{
+	case bazquxSubscriptionAction.EDIT:
+		msg.add("ac", "edit");
+		break;
+	case bazquxSubscriptionAction.SUBSCRIBE:
+		msg.add("ac", "subscribe");
+		break;
+	case bazquxSubscriptionAction.UNSUBSCRIBE:
+		msg.add("ac", "unsubscribe");
+		break;
+	}
 
-		msg.add("s", feedID);
+	msg.add("s", feedID);
 
-		if(title != null)
-			msg.add("t", title);
+	if(title != null)
+		msg.add("t", title);
 
-		if(add != null)
-			msg.add("a", add);
+	if(add != null)
+		msg.add("a", add);
 
-		if(remove != null)
-			msg.add("r", remove);
+	if(remove != null)
+		msg.add("r", remove);
 
 
-		var response = m_connection.send_post_request("subscription/edit", msg.get());
+	var response = m_connection.send_post_request("subscription/edit", msg.get());
 
-		return response.status == 200;
-	}
+	return response.status == 200;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/bazqux/bazquxConnection.vala 2.7.1-1/plugins/backend/bazqux/bazquxConnection.vala
--- 2.6.1-1/plugins/backend/bazqux/bazquxConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/bazqux/bazquxConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,129 +14,129 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 public class FeedReader.bazquxConnection {
-	private string m_username;
-	private string m_api_code;
-	private string m_passwd;
-	private bazquxUtils m_utils;
-	private Soup.Session m_session;
-
-	public bazquxConnection(bazquxUtils utils)
-	{
-		m_utils = utils;
-		m_username = m_utils.getUser();
-		m_api_code = m_utils.getAccessToken();
-		m_passwd = m_utils.getPasswd();
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-	}
-
-	public LoginResponse getToken()
-	{
-		Logger.debug("bazqux Connection: getToken()");
+private string m_username;
+private string m_api_code;
+private string m_passwd;
+private bazquxUtils m_utils;
+private Soup.Session m_session;
+
+public bazquxConnection(bazquxUtils utils)
+{
+	m_utils = utils;
+	m_username = m_utils.getUser();
+	m_api_code = m_utils.getAccessToken();
+	m_passwd = m_utils.getPasswd();
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+}
 
-		if(m_username == "" && m_passwd == "")
-			return LoginResponse.ALL_EMPTY;
-		if(m_username == "")
-			return LoginResponse.MISSING_USER;
-		if(m_passwd == "")
-			return LoginResponse.MISSING_PASSWD;
+public LoginResponse getToken()
+{
+	Logger.debug("bazqux Connection: getToken()");
+
+	if(m_username == "" && m_passwd == "")
+		return LoginResponse.ALL_EMPTY;
+	if(m_username == "")
+		return LoginResponse.MISSING_USER;
+	if(m_passwd == "")
+		return LoginResponse.MISSING_PASSWD;
+
+	var message = new Soup.Message("POST", "https://bazqux.com/accounts/ClientLogin/");
+	string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
+	string response = (string)message.response_body.flatten().data;
+	try{
 
-		var message = new Soup.Message("POST", "https://bazqux.com/accounts/ClientLogin/");
-		string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
-		string response = (string)message.response_body.flatten().data;
-		try{
-
-			var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
-			if(regex.match(response))
-			{
-				Logger.error("Regex bazqux - %s".printf(response));
-				string split = regex.replace( response, -1,0,"");
-				Logger.error("authcode"+split);
-				m_utils.setAccessToken(split.strip());
-				return LoginResponse.SUCCESS;
-			}
-			else
-			{
-				Logger.debug(response);
-				return LoginResponse.WRONG_LOGIN;
-			}
+		var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+		if(regex.match(response))
+		{
+			Logger.error("Regex bazqux - %s".printf(response));
+			string split = regex.replace( response, -1,0,"");
+			Logger.error("authcode"+split);
+			m_utils.setAccessToken(split.strip());
+			return LoginResponse.SUCCESS;
 		}
-		catch(Error e)
+		else
 		{
-			Logger.error("bazquxConnection - getToken: Could not load message response");
-			Logger.error(e.message);
-			return LoginResponse.UNKNOWN_ERROR;
+			Logger.debug(response);
+			return LoginResponse.WRONG_LOGIN;
 		}
 	}
-
-	public Response send_get_request(string path, string? message_string = null)
+	catch(Error e)
 	{
-		return send_request(path, "GET", message_string);
+		Logger.error("bazquxConnection - getToken: Could not load message response");
+		Logger.error(e.message);
+		return LoginResponse.UNKNOWN_ERROR;
 	}
+}
 
-	public Response send_post_request(string path, string? message_string = null)
-	{
-		return send_request(path, "POST", message_string);
-	}
+public Response send_get_request(string path, string? message_string = null)
+{
+	return send_request(path, "GET", message_string);
+}
 
-	private Response send_request(string path, string type, string? message_string = null)
-	{
+public Response send_post_request(string path, string? message_string = null)
+{
+	return send_request(path, "POST", message_string);
+}
 
-		var message = new Soup.Message(type, bazquxSecret.base_uri + path);
+private Response send_request(string path, string type, string? message_string = null)
+{
 
-		string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", oldauth);
+	var message = new Soup.Message(type, bazquxSecret.base_uri + path);
 
-		if(message_string != null)
-			message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", oldauth);
 
-		m_session.send_message(message);
+	if(message_string != null)
+		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
-	}
+	m_session.send_message(message);
 
-	public bool ping()
-	{
-		var message = new Soup.Message("GET", "https://www.bazqux.com/reader/ping");
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 
-		string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", oldauth);
-		m_session.send_message(message);
+public bool ping()
+{
+	var message = new Soup.Message("GET", "https://www.bazqux.com/reader/ping");
+
+	string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", oldauth);
+	m_session.send_message(message);
 
-		if((string)message.response_body.data == "OK")
-			return true;
+	if((string)message.response_body.data == "OK")
+		return true;
 
-		return false;
-	}
+	return false;
+}
 
 }
 
 public class FeedReader.bazquxMessage {
 
-	string request = "";
-
-	public bazquxMessage()
-	{
+string request = "";
 
-	}
+public bazquxMessage()
+{
 
-	public void add(string parameter, string val)
-	{
-		if(request != "")
-			request += "&";
+}
 
-		request += parameter;
-		request += "=";
-		request += GLib.Uri.escape_string(val);
-	}
+public void add(string parameter, string val)
+{
+	if(request != "")
+		request += "&";
+
+	request += parameter;
+	request += "=";
+	request += GLib.Uri.escape_string(val);
+}
 
-	public string get()
-	{
-		return request;
-	}
+public string get()
+{
+	return request;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/bazqux/bazquxInterface.vala 2.7.1-1/plugins/backend/bazqux/bazquxInterface.vala
--- 2.6.1-1/plugins/backend/bazqux/bazquxInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/bazqux/bazquxInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,423 +15,395 @@
 
 public class FeedReader.bazquxInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private bazquxAPI m_api;
-	private bazquxUtils m_utils;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
-
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new bazquxUtils(settings_backend, secrets);
-		m_api = new bazquxAPI(m_utils, db);
-	}
+private bazquxAPI m_api;
+private bazquxUtils m_utils;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new bazquxUtils(settings_backend, secrets);
+	m_api = new bazquxAPI(m_utils);
+}
 
-	public string getWebsite()
-	{
-		return "https://bazqux.com/";
-	}
+public string getWebsite()
+{
+	return "https://bazqux.com/";
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
+}
 
-	public string getID()
-	{
-		return "bazqux";
-	}
+public string getID()
+{
+	return "bazqux";
+}
 
-	public string iconName()
-	{
-		return "feed-service-bazqux";
-	}
+public string iconName()
+{
+	return "feed-service-bazqux";
+}
 
-	public string serviceName()
-	{
-		return "BazQux";
-	}
+public string serviceName()
+{
+	return "BazQux";
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public Gtk.Box? getWidget()
-	{
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
+public Gtk.Box? getWidget()
+{
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_userEntry.activate.connect(() => { tryLogin(); });
+	m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+	m_passwordEntry.set_invisible_char('*');
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(user_label, 0, 0, 1, 1);
+	grid.attach(m_userEntry, 1, 0, 1, 1);
+	grid.attach(password_label, 0, 1, 1, 1);
+	grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-bazqux", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
 
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
+	return box;
+}
 
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_userEntry.activate.connect(() => { tryLogin(); });
-		m_passwordEntry.activate.connect(() => { tryLogin(); });
-
-		m_passwordEntry.set_invisible_char('*');
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(user_label, 0, 0, 1, 1);
-		grid.attach(m_userEntry, 1, 0, 1, 1);
-		grid.attach(password_label, 0, 1, 1, 1);
-		grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-bazqux", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
+public void showHtAccess()
+{
 
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+}
 
-		return box;
-	}
+public void writeData()
+{
+	m_utils.setUser(m_userEntry.get_text());
+	m_utils.setPassword(m_passwordEntry.get_text());
+}
 
-	public void showHtAccess()
-	{
+public string buildLoginURL()
+{
+	return "";
+}
 
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public void writeData()
-	{
-		m_utils.setUser(m_userEntry.get_text());
-		m_utils.setPassword(m_passwordEntry.get_text());
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public bool supportTags()
+{
+	return true;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public bool supportTags()
-	{
-		return true;
-	}
+public string symbolicIcon()
+{
+	return "feed-service-bazqux-symbolic";
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string getServerURL()
+{
+	return "https://bazqux.com/";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-bazqux-symbolic";
-	}
+public string uncategorizedID()
+{
+	return "";
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public bool supportCategories()
+{
+	return true;
+}
+public bool hideCategoryWhenEmpty(string cadID)
+{
+	return false;
+}
 
-	public string getServerURL()
-	{
-		return "https://bazqux.com/";
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public string uncategorizedID()
-	{
-		return "";
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
-	public bool hideCategoryWhenEmpty(string cadID)
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return true;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	if(read == ArticleStatus.READ)
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+	else
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
+		m_api.edidTag(articleID, "user/-/state/com.google/starred");
+	else
+		m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		if(read == ArticleStatus.READ)
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read");
-		else
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.markAsRead(feedID);
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		if(marked == ArticleStatus.MARKED)
-			m_api.edidTag(articleID, "user/-/state/com.google/starred");
-		else
-			m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markAsRead(catID);
+}
 
-	public bool alwaysSetReadByID()
+public void markAllItemsRead()
+{
+	var db = DataBase.readOnly();
+	var categories = db.read_categories();
+	foreach(Category cat in categories)
 	{
-		return false;
+		m_api.markAsRead(cat.getCatID());
 	}
 
-	public void setFeedRead(string feedID)
+	var feeds = db.read_feeds_without_cat();
+	foreach(Feed feed in feeds)
 	{
-		m_api.markAsRead(feedID);
+		m_api.markAsRead(feed.getFeedID());
 	}
+	m_api.markAsRead();
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markAsRead(catID);
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, true);
+}
 
-	public void markAllItemsRead()
-	{
-		var categories = m_db.read_categories();
-		foreach(Category cat in categories)
-		{
-			m_api.markAsRead(cat.getCatID());
-		}
+public void removeArticleTag(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, false);
+}
 
-		var feeds = m_db.read_feeds_without_cat();
-		foreach(Feed feed in feeds)
-		{
-			m_api.markAsRead(feed.getFeedID());
-		}
-		m_api.markAsRead();
-	}
+public string createTag(string caption)
+{
+	return m_api.composeTagID(caption);
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		m_api.edidTag(articleID, tagID, true);
-	}
+public void deleteTag(string tagID)
+{
+	m_api.deleteTag(tagID);
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		m_api.edidTag(articleID, tagID, false);
-	}
+public void renameTag(string tagID, string title)
+{
+	m_api.renameTag(tagID, title);
+}
 
-	public string createTag(string caption)
-	{
-		return m_api.composeTagID(caption);
-	}
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
 
-	public void deleteTag(string tagID)
-	{
-		m_api.deleteTag(tagID);
-	}
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	feedID = "feed/" + feedURL;
+	bool success = false;
+	errmsg = "";
 
-	public void renameTag(string tagID, string title)
+	if(catID == null && newCatName != null)
 	{
-		m_api.renameTag(tagID, title);
+		string newCatID = m_api.composeTagID(newCatName);
+		success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, newCatID);
 	}
-
-	public bool serverAvailable()
+	else
 	{
-		return m_api.ping();
+		success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, catID);
 	}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		feedID = "feed/" + feedURL;
-		bool success = false;
-		errmsg = "";
+	if(!success)
+		errmsg = @"bazqux could not subscribe to $feedURL";
 
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.composeTagID(newCatName);
-			success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, newCatID);
-		}
-		else
-		{
-			success = m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.SUBSCRIBE, "feed/"+feedURL, null, catID);
-		}
+	return success;
+}
 
-		if(!success)
-			errmsg = @"bazqux could not subscribe to $feedURL";
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	//FIXME
+}
 
-		return success;
-	}
+public void removeFeed(string feedID)
+{
+	m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.UNSUBSCRIBE, feedID);
+}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		//FIXME
-	}
+public void renameFeed(string feedID, string title)
+{
+	m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, title);
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.UNSUBSCRIBE, feedID);
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, null, newCatID, currentCatID);
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, title);
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.composeTagID(title);
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.editSubscription(bazquxAPI.bazquxSubscriptionAction.EDIT, feedID, null, newCatID, currentCatID);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameTag(catID, title);
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.composeTagID(title);
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameTag(catID, title);
-	}
+public void deleteCategory(string catID)
+{
+	m_api.deleteTag(catID);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.deleteTag(catID);
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getFeeds(feeds))
 	{
-		return;
-	}
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
+		if(m_api.getCategoriesAndTags(feeds, categories, tags))
+			return true;
 	}
+	return false;
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		if(m_api.getFeeds(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
-
-			if(m_api.getCategoriesAndTags(feeds, categories, tags))
-				return true;
-		}
-		return false;
-	}
+public int getUnreadCount()
+{
+	return m_api.getTotalUnread();
+}
 
-	public int getUnreadCount()
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	if(whatToGet == ArticleStatus.READ)
 	{
-		return m_api.getTotalUnread();
+		return;
 	}
-
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+	else if(whatToGet == ArticleStatus.ALL)
 	{
-		if(whatToGet == ArticleStatus.READ)
-		{
-			return;
-		}
-		else if(whatToGet == ArticleStatus.ALL)
-		{
-			var unreadIDs = new Gee.LinkedList<string>();
-			string? continuation = null;
-			int left = 4*count;
-
-			while(left > 0)
-			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
-
-				if(left > 1000)
-				{
-					continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
-					left -= 1000;
-				}
-				else
-				{
-					m_api.updateArticles(unreadIDs, left, continuation);
-					left = 0;
-				}
-			}
-			m_db_write.updateArticlesByID(unreadIDs, "unread");
-		}
-
-		var articles = new Gee.LinkedList<Article>();
+		var unreadIDs = new Gee.LinkedList<string>();
 		string? continuation = null;
-		int left = count;
-		string? bazqux_feedID = (isTagID) ? null : feedID;
-		string? bazqux_tagID = (isTagID) ? feedID : null;
+		int left = 4*count;
 
 		while(left > 0)
 		{
@@ -440,18 +412,43 @@ public class FeedReader.bazquxInterface
 
 			if(left > 1000)
 			{
-				continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+				continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
 				left -= 1000;
 			}
 			else
 			{
-				continuation = m_api.getArticles(articles, left, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+				m_api.updateArticles(unreadIDs, left, continuation);
 				left = 0;
 			}
 		}
-		writeArticles(articles);
+		DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
 	}
 
+	var articles = new Gee.LinkedList<Article>();
+	string? continuation = null;
+	int left = count;
+	string? bazqux_feedID = (isTagID) ? null : feedID;
+	string? bazqux_tagID = (isTagID) ? feedID : null;
+
+	while(left > 0)
+	{
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
+
+		if(left > 1000)
+		{
+			continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+			left -= 1000;
+		}
+		else
+		{
+			continuation = m_api.getArticles(articles, left, whatToGet, continuation, bazqux_tagID, bazqux_feedID);
+			left = 0;
+		}
+	}
+	writeArticles(articles);
+}
+
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/bazqux/bazquxUtils.vala 2.7.1-1/plugins/backend/bazqux/bazquxUtils.vala
--- 2.6.1-1/plugins/backend/bazqux/bazquxUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/bazqux/bazquxUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,87 +14,87 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.bazquxSecret {
-	 const string base_uri        = "https://www.bazqux.com/reader/api/0/";
+const string base_uri        = "https://www.bazqux.com/reader/api/0/";
 }
 
 public class FeedReader.bazquxUtils : GLib.Object {
 
-	private GLib.Settings m_settings;
-	private Password m_password;
+private GLib.Settings m_settings;
+private Password m_password;
 
-	public bazquxUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.bazqux", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.bazqux");
-
-		var password_schema = new Secret.Schema ("org.gnome.feedreader.bazqux", Secret.SchemaFlags.NONE,
-							    			     "type", Secret.SchemaAttributeType.STRING,
-										         "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, password_schema, "Feedserver login", () => {
+public bazquxUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.bazqux", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.bazqux");
+
+	var password_schema = new Secret.Schema ("org.gnome.feedreader.bazqux", Secret.SchemaFlags.NONE,
+	                                         "type", Secret.SchemaAttributeType.STRING,
+	                                         "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, password_schema, "Feedserver login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["type"] = "BazQux";
 			attributes["Username"] = getUser();
 			return attributes;
 		});
-	}
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getAccessToken()
-	{
-		return Utils.gsettingReadString(m_settings, "access-token");
-	}
+public string getAccessToken()
+{
+	return Utils.gsettingReadString(m_settings, "access-token");
+}
 
-	public void setAccessToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "access-token", token);
-	}
+public void setAccessToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "access-token", token);
+}
 
-	public string getUserID()
-	{
-		return Utils.gsettingReadString(m_settings, "user-id");
-	}
+public string getUserID()
+{
+	return Utils.gsettingReadString(m_settings, "user-id");
+}
 
-	public void setUserID(string id)
-	{
-		Utils.gsettingWriteString(m_settings, "user-id", id);
-	}
+public void setUserID(string id)
+{
+	Utils.gsettingWriteString(m_settings, "user-id", id);
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-	}
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+}
 
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
+public string getPasswd()
+{
+	return m_password.get_password();
+}
 
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 
-	public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+{
+	foreach(Feed feed in feeds)
 	{
-		foreach(Feed feed in feeds)
+		if(feed.hasCat(tagID))
 		{
-			if(feed.hasCat(tagID))
-			{
-				return true;
-			}
+			return true;
 		}
-		return false;
 	}
+	return false;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/decsync/decsyncInterface.vala 2.7.1-1/plugins/backend/decsync/decsyncInterface.vala
--- 2.6.1-1/plugins/backend/decsync/decsyncInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/decsyncInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,515 +15,514 @@
 
 public class FeedReader.decsyncInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	internal DecsyncUtils m_utils;
-	private Soup.Session m_session;
-	internal Decsync<Unit> m_sync;
-	private string m_loginDir;
-	private Gtk.Button loginButton;
-	private Gtk.Spinner waitingSpinner;
-	private Gtk.Stack loginStack;
-	internal DataBaseReadOnly m_db;
-	internal DataBase m_db_write;
-
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new DecsyncUtils(settings_backend);
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_session.timeout = 5;
-	}
+internal DecsyncUtils m_utils;
+private Soup.Session m_session;
+internal Decsync<Unit> m_sync;
+private string m_loginDir;
+private Gtk.Button loginButton;
+private Gtk.Spinner waitingSpinner;
+private Gtk.Stack loginStack;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new DecsyncUtils(settings_backend);
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_session.timeout = 5;
+}
 
-	private bool initDecsync()
+private bool initDecsync()
+{
+	var decsyncDir = m_utils.getDecsyncDir();
+	if (decsyncDir == "")
 	{
-		var decsyncDir = m_utils.getDecsyncDir();
-		if (decsyncDir == "")
-		{
-			return false;
-		}
-		var dir = getDecsyncSubdir(decsyncDir, "rss");
-		var ownAppId = getAppId("FeedReader");
-		var listeners = new Gee.ArrayList<OnEntryUpdateListener>();
-		listeners.add(new DecsyncListeners.ReadMarkListener(true, this));
-		listeners.add(new DecsyncListeners.ReadMarkListener(false, this));
-		listeners.add(new DecsyncListeners.SubscriptionsListener(this));
-		listeners.add(new DecsyncListeners.FeedNamesListener(this));
-		listeners.add(new DecsyncListeners.CategoriesListener(this));
-		listeners.add(new DecsyncListeners.CategoryNamesListener(this));
-		listeners.add(new DecsyncListeners.CategoryParentsListener(this));
-		m_sync = new Decsync<Unit>(dir, ownAppId, listeners);
-		m_sync.syncComplete.connect((extra) => {
+		return false;
+	}
+	var dir = getDecsyncSubdir(decsyncDir, "rss");
+	var ownAppId = getAppId("FeedReader");
+	var listeners = new Gee.ArrayList<OnEntryUpdateListener>();
+	listeners.add(new DecsyncListeners.ReadMarkListener(true, this));
+	listeners.add(new DecsyncListeners.ReadMarkListener(false, this));
+	listeners.add(new DecsyncListeners.SubscriptionsListener(this));
+	listeners.add(new DecsyncListeners.FeedNamesListener(this));
+	listeners.add(new DecsyncListeners.CategoriesListener(this));
+	listeners.add(new DecsyncListeners.CategoryNamesListener(this));
+	listeners.add(new DecsyncListeners.CategoryParentsListener(this));
+	m_sync = new Decsync<Unit>(dir, ownAppId, listeners);
+	m_sync.syncComplete.connect((extra) => {
 			FeedReaderBackend.get_default().updateBadge();
 			refreshFeedListCounter();
 			newFeedList();
 			updateArticleList();
 		});
-		m_sync.initMonitor(new Unit());
-		return true;
-	}
+	m_sync.initMonitor(new Unit());
+	return true;
+}
 
-	public string getWebsite()
-	{
-		return "https://github.com/39aldo39/DecSync";
-	}
+public string getWebsite()
+{
+	return "https://github.com/39aldo39/DecSync";
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+}
 
-	public string getID()
-	{
-		return "decsync";
-	}
+public string getID()
+{
+	return "decsync";
+}
 
-	public string iconName()
-	{
-		return "feed-service-decsync";
-	}
+public string iconName()
+{
+	return "feed-service-decsync";
+}
 
-	public string serviceName()
-	{
-		return "DecSync";
-	}
+public string serviceName()
+{
+	return "DecSync";
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public Gtk.Box? getWidget()
+public Gtk.Box? getWidget()
+{
+	var doneLabel = new Gtk.Label(_("Done"));
+	var waitingLabel = new Gtk.Label(_("Adding Feeds"));
+	waitingSpinner = new Gtk.Spinner();
+	var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+	waitingBox.pack_start(waitingSpinner, false, false, 0);
+	waitingBox.pack_start(waitingLabel, true, false, 0);
+	loginStack = new Gtk.Stack();
+	loginStack.add_named(doneLabel, "label");
+	loginStack.add_named(waitingBox, "waiting");
+	var dirLabel = new Gtk.Label(_("DecSync directory:"));
+	dirLabel.set_alignment(1.0f, 0.5f);
+	dirLabel.set_hexpand(true);
+	m_loginDir = m_utils.getDecsyncDir();
+	var buttonLabel = m_loginDir;
+	if (buttonLabel == "")
 	{
-		var doneLabel = new Gtk.Label(_("Done"));
-		var waitingLabel = new Gtk.Label(_("Adding Feeds"));
-		waitingSpinner = new Gtk.Spinner();
-		var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
-		waitingBox.pack_start(waitingSpinner, false, false, 0);
-		waitingBox.pack_start(waitingLabel, true, false, 0);
-		loginStack = new Gtk.Stack();
-		loginStack.add_named(doneLabel, "label");
-		loginStack.add_named(waitingBox, "waiting");
-		var dirLabel = new Gtk.Label(_("DecSync directory:"));
-		dirLabel.set_alignment(1.0f, 0.5f);
-		dirLabel.set_hexpand(true);
-		m_loginDir = m_utils.getDecsyncDir();
-		var buttonLabel = m_loginDir;
-		if (buttonLabel == "")
-		{
-			buttonLabel = _("Select...");
-		}
-		var dirButton = new Gtk.Button.with_label(buttonLabel);
-		dirButton.clicked.connect(() => {
+		buttonLabel = _("Select...");
+	}
+	var dirButton = new Gtk.Button.with_label(buttonLabel);
+	dirButton.clicked.connect(() => {
 			var chooser = new Gtk.FileChooserDialog("Select Directory",
-                                      null,
-                                      Gtk.FileChooserAction.SELECT_FOLDER,
-                                      _("_Cancel"),
-                                      Gtk.ResponseType.CANCEL,
-                                      _("_Select"),
-                                      Gtk.ResponseType.ACCEPT);
+			                                        null,
+			                                        Gtk.FileChooserAction.SELECT_FOLDER,
+			                                        _("_Cancel"),
+			                                        Gtk.ResponseType.CANCEL,
+			                                        _("_Select"),
+			                                        Gtk.ResponseType.ACCEPT);
 			chooser.set_show_hidden(true);
 			chooser.set_current_folder(m_utils.getDecsyncDir());
 			if (chooser.run() == Gtk.ResponseType.ACCEPT)
 			{
-				m_loginDir = chooser.get_filename();
-				dirButton.set_label(m_loginDir);
+			        m_loginDir = chooser.get_filename();
+			        dirButton.set_label(m_loginDir);
 			}
 			chooser.close();
 		});
 
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(dirLabel, 0, 0, 1, 1);
-		grid.attach(dirButton, 1, 0, 1, 1);
-
-		//---------------------------------------------------------------------
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(dirLabel, 0, 0, 1, 1);
+	grid.attach(dirButton, 1, 0, 1, 1);
+
+	//---------------------------------------------------------------------
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-decsync", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please select your DecSync directory and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	loginButton = new Gtk.Button();
+	loginButton.add(loginStack);
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
 
-		var logo = new Gtk.Image.from_icon_name("feed-service-decsync", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please select your DecSync directory and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		loginButton = new Gtk.Button();
-		loginButton.add(loginStack);
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
-
-		return box;
-	}
+	return box;
+}
 
-	public void showHtAccess()
-	{
-		return;
-	}
+public void showHtAccess()
+{
+	return;
+}
 
-	public void writeData()
-	{
-		m_utils.setDecsyncDir(m_loginDir);
-	}
+public void writeData()
+{
+	m_utils.setDecsyncDir(m_loginDir);
+}
 
-	public async void postLoginAction()
-	{
-		loginButton.set_sensitive(false);
-		waitingSpinner.start();
-		loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginStack.set_visible_child_name("waiting");
-		SourceFunc callback = postLoginAction.callback;
-		new GLib.Thread<void*>(null, () => {
+public async void postLoginAction()
+{
+	loginButton.set_sensitive(false);
+	waitingSpinner.start();
+	loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginStack.set_visible_child_name("waiting");
+	SourceFunc callback = postLoginAction.callback;
+	new Thread<void*>(null, () => {
 			m_sync.initStoredEntries();
 			m_sync.executeStoredEntries({"feeds", "subscriptions"}, new Unit());
 			Idle.add((owned) callback);
 			return null;
 		});
-		yield;
-	}
+	yield;
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public bool doInitSync()
-	{
-		return false;
-	}
+public bool doInitSync()
+{
+	return false;
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-decsync-symbolic";
-	}
+public string symbolicIcon()
+{
+	return "feed-service-decsync-symbolic";
+}
 
-	public string accountName()
-	{
-		return "DecSync";
-	}
+public string accountName()
+{
+	return "DecSync";
+}
 
-	public string getServerURL()
-	{
-		return "http://localhost/";
-	}
+public string getServerURL()
+{
+	return "http://localhost/";
+}
 
-	public string uncategorizedID()
-	{
-		return "0";
-	}
+public string uncategorizedID()
+{
+	return "0";
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return false;
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return false;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return true;
-	}
+public bool supportMultiLevelCategories()
+{
+	return true;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return false;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return false;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return false;
+}
 
-	public void resetAccount()
-	{
-		return;
-	}
+public void resetAccount()
+{
+	return;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public LoginResponse login()
+public LoginResponse login()
+{
+	if (initDecsync())
 	{
-		if (initDecsync())
-		{
-			return LoginResponse.SUCCESS;
-		}
-		else
-		{
-			return LoginResponse.ALL_EMPTY;
-		}
+		return LoginResponse.SUCCESS;
 	}
-
-	public bool logout()
+	else
 	{
-		return true;
+		return LoginResponse.ALL_EMPTY;
 	}
+}
 
-	public bool serverAvailable()
-	{
-		return Utils.ping("https://duckduckgo.com/");
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus readStatus)
-	{
-		var read = readStatus == ArticleStatus.READ;
-		Logger.debug("Mark " + articleIDs + " as " + (read ? "read" : "unread"));
-		var entries = new Gee.ArrayList<Decsync.EntryWithPath>();
-		foreach (var articleID in articleIDs.split(","))
-		{
-			Article? article = m_db.read_article(articleID);
-			if (article != null)
-			{
-				var path = articleToPath(article, "read");
-				var key = stringToNode(article.getArticleID());
-				entries.add(new Decsync.EntryWithPath.now(path, key, boolToNode(read)));
-			}
-		}
-		m_sync.setEntries(entries);
-	}
+public bool serverAvailable()
+{
+	return Utils.ping("https://duckduckgo.com/");
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus markedStatus)
+public void setArticleIsRead(string articleIDs, ArticleStatus readStatus)
+{
+	var read = readStatus == ArticleStatus.READ;
+	Logger.debug("Mark " + articleIDs + " as " + (read ? "read" : "unread"));
+	var entries = new Gee.ArrayList<Decsync.EntryWithPath>();
+	var db = DataBase.readOnly();
+	foreach (var articleID in articleIDs.split(","))
 	{
-		var marked = markedStatus == ArticleStatus.MARKED;
-		Logger.debug("Mark " + articleID + " as " + (marked ? "marked" : "unmarked"));
-		Article? article = m_db.read_article(articleID);
+		Article? article = db.read_article(articleID);
 		if (article != null)
 		{
-			var path = articleToPath(article, "marked");
+			var path = articleToPath(article, "read");
 			var key = stringToNode(article.getArticleID());
-			m_sync.setEntry(path, key, boolToNode(marked));
+			entries.add(new Decsync.EntryWithPath.now(path, key, boolToNode(read)));
 		}
 	}
+	m_sync.setEntries(entries);
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return true;
+public void setArticleIsMarked(string articleID, ArticleStatus markedStatus)
+{
+	var marked = markedStatus == ArticleStatus.MARKED;
+	Logger.debug("Mark " + articleID + " as " + (marked ? "marked" : "unmarked"));
+	Article? article = DataBase.readOnly().read_article(articleID);
+	if (article != null)
+	{
+		var path = articleToPath(article, "marked");
+		var key = stringToNode(article.getArticleID());
+		m_sync.setEntry(path, key, boolToNode(marked));
 	}
+}
 
-	public void setFeedRead(string feedID)
-	{
-		return;
-	}
+public bool alwaysSetReadByID()
+{
+	return true;
+}
 
-	public void setCategoryRead(string catID)
-	{
-		return;
-	}
+public void setFeedRead(string feedID)
+{
+	return;
+}
 
-	public void markAllItemsRead()
-	{
-		return;
-	}
+public void setCategoryRead(string catID)
+{
+	return;
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		return;
-	}
+public void markAllItemsRead()
+{
+	return;
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		return;
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	return;
+}
 
-	public string createTag(string caption)
-	{
-		return "";
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	return;
+}
 
-	public void deleteTag(string tagID)
-	{
-		return;
-	}
+public string createTag(string caption)
+{
+	return "";
+}
+
+public void deleteTag(string tagID)
+{
+	return;
+}
+
+public void renameTag(string tagID, string title)
+{
+	return;
+}
+
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	return addFeedWithDecsync(feedURL, catID, newCatName, out feedID, out errmsg);
+}
 
-	public void renameTag(string tagID, string title)
+public bool addFeedWithDecsync(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg, bool updateDecsync = true)
+{
+	var db = DataBase.writeAccess();
+	var catIDs = new Gee.ArrayList<string>();
+	if(catID == null && newCatName != null)
 	{
-		return;
+		string cID = createCategory(newCatName, null);
+		var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
+		db.write_categories(ListUtils.single(cat));
+		catIDs.add(cID);
 	}
-
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+	else if(catID != null && newCatName == null)
 	{
-		return addFeedWithDecsync(feedURL, catID, newCatName, out feedID, out errmsg);
+		catIDs.add(catID);
 	}
-
-	public bool addFeedWithDecsync(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg, bool updateDecsync = true)
+	else
 	{
-	 	var catIDs = new Gee.ArrayList<string>();
-		if(catID == null && newCatName != null)
-		{
-			string cID = createCategory(newCatName, null);
-			var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
-			m_db_write.write_categories(ListUtils.single(cat));
-			catIDs.add(cID);
-		}
-		else if(catID != null && newCatName == null)
-		{
-			catIDs.add(catID);
-		}
-		else
-		{
-			catIDs.add(uncategorizedID());
-		}
-
-		feedID = feedURL;
+		catIDs.add(uncategorizedID());
+	}
 
-		Logger.info(@"addFeed: ID = $feedID");
-		Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
+	feedID = feedURL;
 
-		if(feed != null)
-		{
-			if(!m_db.feed_exists(feed.getURL())) {
-				m_db_write.write_feeds(ListUtils.single(feed));
+	Logger.info(@"addFeed: ID = $feedID");
+	Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
 
-				if (updateDecsync)
-				{
-					m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(true));
-					renameFeed(feedID, feed.getTitle());
-					moveFeed(feedID, feed.getCatString(), null);
-				}
+	if(feed != null)
+	{
+		if(!db.feed_exists(feed.getURL())) {
+			db.write_feeds(ListUtils.single(feed));
 
-				m_sync.executeStoredEntries({"feeds", "names"}, new Unit(),
-					stringEquals(feedID)
-				);
-				m_sync.executeStoredEntries({"feeds", "categories"}, new Unit(),
-					stringEquals(feedID)
-				);
-				return true;
+			if (updateDecsync)
+			{
+				m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(true));
+				renameFeed(feedID, feed.getTitle());
+				moveFeed(feedID, feed.getCatString(), null);
 			}
-		}
-
-		return false;
-	}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		string feedID, errmsg;
-		foreach(Feed feed in feeds)
-		{
-			var catString = feed.getCatString();
-			addFeed(feed.getXmlUrl(), catString != "" ? catString : null, null, out feedID, out errmsg);
+			m_sync.executeStoredEntries({"feeds", "names"}, new Unit(),
+			                            stringEquals(feedID)
+			                            );
+			m_sync.executeStoredEntries({"feeds", "categories"}, new Unit(),
+			                            stringEquals(feedID)
+			                            );
+			return true;
 		}
 	}
 
-	public void removeFeed(string feedID)
-	{
-		m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(false));
-	}
+	return false;
+}
 
-	public void renameFeed(string feedID, string title)
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	string feedID, errmsg;
+	foreach(Feed feed in feeds)
 	{
-		m_sync.setEntry({"feeds", "names"}, stringToNode(feedID), stringToNode(title));
+		var catString = feed.getCatString();
+		addFeed(feed.getXmlUrl(), catString != "" ? catString : null, null, out feedID, out errmsg);
 	}
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		string? value = newCatID == uncategorizedID() ? null : newCatID;
-		m_sync.setEntry({"feeds", "categories"}, stringToNode(feedID), stringToNode(value));
-	}
+public void removeFeed(string feedID)
+{
+	m_sync.setEntry({"feeds", "subscriptions"}, stringToNode(feedID), boolToNode(false));
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		string? catID = m_db.getCategoryID(title);
-		while (catID == null || m_db.read_category(catID) != null)
-		{
-			catID = "catID%05d".printf(Random.int_range(0, 100000));
-		}
-		renameCategory(catID, title);
-		moveCategory(catID, parentID ?? CategoryID.MASTER.to_string());
-		Logger.info("createCategory: ID = " + catID);
-		return catID;
-	}
+public void renameFeed(string feedID, string title)
+{
+	m_sync.setEntry({"feeds", "names"}, stringToNode(feedID), stringToNode(title));
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_sync.setEntry({"categories", "names"}, stringToNode(catID), stringToNode(title));
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	string? value = newCatID == uncategorizedID() ? null : newCatID;
+	m_sync.setEntry({"feeds", "categories"}, stringToNode(feedID), stringToNode(value));
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		string? value = newParentID == CategoryID.MASTER.to_string() ? null : newParentID;
-		m_sync.setEntry({"categories", "parents"}, stringToNode(catID), stringToNode(value));
-	}
+public string createCategory(string title, string? parentID)
+{
+	var db = DataBase.readOnly();
+	string? catID = db.getCategoryID(title);
+	while (catID == null || db.read_category(catID) != null)
+	{
+		catID = "catID%05d".printf(Random.int_range(0, 100000));
+	}
+	renameCategory(catID, title);
+	moveCategory(catID, parentID ?? CategoryID.MASTER.to_string());
+	Logger.info("createCategory: ID = " + catID);
+	return catID;
+}
 
-	public void deleteCategory(string catID)
-	{
-		Logger.info("Delete category " + catID);
-		var feedIDs = m_db.getFeedIDofCategorie(catID);
-		foreach (var feedID in feedIDs)
-		{
-			moveFeed(feedID, uncategorizedID(), catID);
-		}
-	}
+public void renameCategory(string catID, string title)
+{
+	m_sync.setEntry({"categories", "names"}, stringToNode(catID), stringToNode(title));
+}
+
+public void moveCategory(string catID, string newParentID)
+{
+	string? value = newParentID == CategoryID.MASTER.to_string() ? null : newParentID;
+	m_sync.setEntry({"categories", "parents"}, stringToNode(catID), stringToNode(value));
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
+public void deleteCategory(string catID)
+{
+	Logger.info("Delete category " + catID);
+	var feedIDs = DataBase.readOnly().getFeedIDofCategorie(catID);
+	foreach (var feedID in feedIDs)
 	{
 		moveFeed(feedID, uncategorizedID(), catID);
 	}
+}
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	moveFeed(feedID, uncategorizedID(), catID);
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		return true;
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public int getUnreadCount()
-	{
-		return 0;
-	}
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	return true;
+}
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-	{
-		var feeds = m_db.read_feeds();
-		var articles = new Gee.ArrayList<Article>();
-		GLib.Mutex mutex = GLib.Mutex();
-		var now = new GLib.DateTime.now_local();
-		int? weeks = ((DropArticles)Settings.general().get_enum("drop-articles-after")).to_weeks();
-		var dropDate = weeks == null ? null : now.add_weeks(-(int)weeks);
+public int getUnreadCount()
+{
+	return 0;
+}
 
-		try
-		{
-			var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	var feeds = DataBase.readOnly().read_feeds();
+	var articles = new Gee.ArrayList<Article>();
+	GLib.Mutex mutex = GLib.Mutex();
+	var now = new GLib.DateTime.now_local();
+	int? weeks = ((DropArticles)Settings.general().get_enum("drop-articles-after")).to_weeks();
+	var dropDate = weeks == null ? null : now.add_weeks(-(int)weeks);
+
+	try
+	{
+		var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
 				if(cancellable != null && cancellable.is_cancelled())
 					return;
 
@@ -532,8 +531,8 @@ public class FeedReader.decsyncInterface
 
 				if(url == null || url == "" || GLib.Uri.parse_scheme(url) == null)
 				{
-					Logger.error("no valid URL");
-					return;
+				        Logger.error("no valid URL");
+				        return;
 				}
 
 				var msg = new Soup.Message("GET", url);
@@ -547,177 +546,178 @@ public class FeedReader.decsyncInterface
 				Rss.Parser parser = new Rss.Parser();
 				try
 				{
-					parser.load_from_data(xml, xml.length);
+				        parser.load_from_data(xml, xml.length);
 				}
 				catch(GLib.Error e)
 				{
-					Logger.error("decsyncInterface.getArticles: %s".printf(e.message));
-					return;
+				        Logger.error("decsyncInterface.getArticles: %s".printf(e.message));
+				        return;
 				}
 				var doc = parser.get_document();
 
 				string? locale = null;
 				if(doc.encoding != null
-				&& doc.encoding != "")
+				   && doc.encoding != "")
 				{
-					locale = doc.encoding;
+				        locale = doc.encoding;
 				}
 
 				Logger.debug("Got %u articles".printf(doc.get_items().length()));
 				var newArticles = new Gee.ArrayList<Article>();
+				var db = DataBase.readOnly();
 				foreach(Rss.Item item in doc.get_items())
 				{
-					string? articleID = item.guid;
+				        string? articleID = item.guid;
 
-					if(articleID == null)
-					{
-						if(item.link == null)
-						{
-							Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
-							continue;
+				        if(articleID == null)
+				        {
+				                if(item.link == null)
+				                {
+				                        Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
+				                        continue;
 						}
 
-						articleID = item.link;
+				                articleID = item.link;
 					}
 
-					if (m_db.read_article(articleID) != null)
+					if (db.read_article(articleID) != null)
 					{
 						continue;
 					}
 
-					var date = Rfc822.parseDate(item.pub_date);
-					if (date != null)
-					{
-						Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
+				        var date = Rfc822.parseDate(item.pub_date);
+				        if (date != null)
+				        {
+				                Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
 					}
-					else
-					{
-						if (item.pub_date != null)
+				        else
+				        {
+				                if (item.pub_date != null)
 							Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
-						date = new DateTime.now_local();
+				                date = new DateTime.now_local();
 					}
 
-					if (dropDate != null && date.compare(dropDate) == -1)
-					{
-						continue;
+				        if (dropDate != null && date.compare(dropDate) == -1)
+				        {
+				                continue;
 					}
 
-					//Logger.info("Got content: " + item.description);
-					string? content = m_utils.convert(item.description, locale);
-					//Logger.info("Converted to: " + item.description);
-					if(content == null)
+				        //Logger.info("Got content: " + item.description);
+				        string? content = m_utils.convert(item.description, locale);
+				        //Logger.info("Converted to: " + item.description);
+				        if(content == null)
 						content = _("Nothing to read here.");
 
-					var enclosures = new Gee.ArrayList<Enclosure>();
+				        var enclosures = new Gee.ArrayList<Enclosure>();
 
-					if(item.enclosure_url != null)
-					{
-						// FIXME: check what type of media we actually got
-						enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
+				        if(item.enclosure_url != null)
+				        {
+				                // FIXME: check what type of media we actually got
+				                enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
 					}
 
-					string articleURL = item.link;
-					if(articleURL.has_prefix("/"))
+				        string articleURL = item.link;
+				        if(articleURL.has_prefix("/"))
 						articleURL = feed.getURL() + articleURL.substring(1);
 
-					var article = new Article(
-										articleID,
-										(item.title != null) ? m_utils.convert(item.title, locale) : null,
-										articleURL,
-										feed.getFeedID(),
-										ArticleStatus.UNREAD,
-										ArticleStatus.UNMARKED,
-										content,
-										content,
-										m_utils.convert(item.author, locale),
-										date,
-										0,
-										null,
-										enclosures
-					);
+				        var article = new Article(
+						articleID,
+						(item.title != null) ? m_utils.convert(item.title, locale) : null,
+						articleURL,
+						feed.getFeedID(),
+						ArticleStatus.UNREAD,
+						ArticleStatus.UNMARKED,
+						content,
+						content,
+						m_utils.convert(item.author, locale),
+						date,
+						0,
+						null,
+						enclosures
+						);
 
-					Logger.debug("Got new article: " + article.getTitle());
+				        Logger.debug("Got new article: " + article.getTitle());
 
-					newArticles.add(article);
+				        newArticles.add(article);
 				}
 				mutex.lock();
 				articles.add_all(newArticles);
 				mutex.unlock();
 			}, (int)GLib.get_num_processors(), true);
 
-			foreach(Feed feed in feeds)
+		foreach(Feed feed in feeds)
+		{
+			try
 			{
-				try
-				{
-					threads.add(feed);
-				}
-				catch(GLib.Error e)
-				{
-					Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
-				}
+				threads.add(feed);
+			}
+			catch(GLib.Error e)
+			{
+				Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
 			}
-
-			bool immediate = false; // allow to queue up additional tasks
-			bool wait = true; // function will block until all tasks are done
-			ThreadPool.free((owned)threads, immediate, wait);
-		}
-		catch(Error e)
-		{
-			Logger.error("Error creating threads to download Feeds: " + e.message);
 		}
 
-		articles.sort((a, b) => {
+		bool immediate = false;         // allow to queue up additional tasks
+		bool wait = true;         // function will block until all tasks are done
+		ThreadPool.free((owned)threads, immediate, wait);
+	}
+	catch(Error e)
+	{
+		Logger.error("Error creating threads to download Feeds: " + e.message);
+	}
+
+	articles.sort((a, b) => {
 			return strcmp(a.getArticleID(), b.getArticleID());
 		});
 
-		if(articles.size > 0)
-		{
-			m_db_write.write_articles(articles);
-			Logger.debug("decsyncInterface: %i articles written".printf(articles.size));
+	if(articles.size > 0)
+	{
+		DataBase.writeAccess().write_articles(articles);
+		Logger.debug("decsyncInterface: %i articles written".printf(articles.size));
 
-			var multiMap = groupBy<Article, Gee.List<string>, Article>(
-				articles,
-				article => { return articleToBasePath(article); }
+		var multiMap = groupBy<Article, Gee.List<string>, Article>(
+			articles,
+			article => { return articleToBasePath(article); }
 			);
-			multiMap.get_keys().@foreach(basePath => {
+		multiMap.get_keys().@foreach(basePath => {
 				var articleIDs = multiMap.@get(basePath).map<Json.Node>(article => {
 					return stringToNode(article.getArticleID());
 				});
 				foreach (var type in toList({"read","marked"}))
 				{
-					m_sync.executeStoredEntries(basePathToPath(basePath, type), new Unit(),
-						key => { return articleIDs.any_match(articleID => { return articleID.equal(key); }); }
-					);
+				        m_sync.executeStoredEntries(basePathToPath(basePath, type), new Unit(),
+				                                    key => { return articleIDs.any_match(articleID => { return articleID.equal(key); }); }
+				                                    );
 				}
 				return true;
 			});
-		}
-
-		m_sync.executeAllNewEntries(new Unit());
 	}
 
-	public string[] articleToPath(Article article, string type)
-	{
-		return basePathToPath(articleToBasePath(article), type);
-	}
+	m_sync.executeAllNewEntries(new Unit());
+}
 
-	public string[] basePathToPath(Gee.List<string> basePath, string type)
-	{
-		var path = new Gee.ArrayList<string>();
-		path.add("articles");
-		path.add(type);
-		path.add_all(basePath);
-		return path.to_array();
-	}
+public string[] articleToPath(Article article, string type)
+{
+	return basePathToPath(articleToBasePath(article), type);
+}
 
-	public Gee.List<string> articleToBasePath(Article article)
-	{
-		var datetime = article.getDate().to_utc();
-		var year = datetime.format("%Y");
-		var month = datetime.format("%m");
-		var day = datetime.format("%d");
-		return toList({year, month, day});
-	}
+public string[] basePathToPath(Gee.List<string> basePath, string type)
+{
+	var path = new Gee.ArrayList<string>();
+	path.add("articles");
+	path.add(type);
+	path.add_all(basePath);
+	return path.to_array();
+}
+
+public Gee.List<string> articleToBasePath(Article article)
+{
+	var datetime = article.getDate().to_utc();
+	var year = datetime.format("%Y");
+	var month = datetime.format("%m");
+	var day = datetime.format("%d");
+	return toList({year, month, day});
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/decsync/decsyncListeners.vala 2.7.1-1/plugins/backend/decsync/decsyncListeners.vala
--- 2.6.1-1/plugins/backend/decsync/decsyncListeners.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/decsyncListeners.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,269 +15,271 @@
 
 public class FeedReader.DecsyncListeners : GLib.Object {
 
-	public class ReadMarkListener : OnSubdirEntryUpdateListener<Unit> {
+public class ReadMarkListener : OnSubdirEntryUpdateListener<Unit> {
 
-		private Gee.List<string> m_subdir;
-		private bool m_is_read_entry;
-		private decsyncInterface m_plugin;
-
-		public ReadMarkListener(bool is_read_entry, decsyncInterface plugin)
-		{
-			this.m_subdir = toList({"articles", is_read_entry ? "read" : "marked"});
-			this.m_is_read_entry = is_read_entry;
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subdir()
-		{
-			return m_subdir;
-		}
-
-		public override void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, Unit extra)
-		{
-			var articleID = entry.key.get_string();
-			if (articleID == null)
-			{
-				Logger.warning("Invalid articleID " + Json.to_string(entry.key, false));
-				return;
-			}
-			var added = entry.value.get_boolean();
-			if (m_is_read_entry)
-			{
-				Logger.debug((added ? "read " : "unread ") + articleID);
-			}
-			else
-			{
-				Logger.debug((added ? "mark " : "unmark ") + articleID);
-			}
-			Article? article = m_plugin.m_db.read_article(articleID);
-			if (article == null)
-			{
-				Logger.info("Unkown article " + articleID);
-				return;
-			}
-			if (m_is_read_entry)
-			{
-				article.setUnread(added ? ArticleStatus.READ : ArticleStatus.UNREAD);
-			}
-			else
-			{
-				article.setMarked(added ? ArticleStatus.MARKED : ArticleStatus.UNMARKED);
-			}
-			m_plugin.m_db_write.update_article(article);
-		}
-	}
-
-	public class SubscriptionsListener : OnSubfileEntryUpdateListener<Unit> {
-
-		private Gee.List<string> m_subfile;
-		private decsyncInterface m_plugin;
-
-		public SubscriptionsListener(decsyncInterface plugin)
-		{
-			this.m_subfile = toList({"feeds", "subscriptions"});
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subfile()
-		{
-			return m_subfile;
-		}
-
-		public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-		{
-			var feedID = entry.key.get_string();
-			if (feedID == null)
-			{
-				Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
-				return;
-			}
-			var subscribed = entry.value.get_boolean();
-			if (subscribed)
-			{
-				string outFeedID, errmsg;
-				m_plugin.addFeedWithDecsync(feedID, null, null, out outFeedID, out errmsg, false);
-			}
-			else
-			{
-				m_plugin.m_db_write.delete_feed(feedID);
-			}
-		}
-	}
-
-	public class FeedNamesListener : OnSubfileEntryUpdateListener<Unit> {
-
-		private Gee.List<string> m_subfile;
-		private decsyncInterface m_plugin;
-
-		public FeedNamesListener(decsyncInterface plugin)
-		{
-			this.m_subfile = toList({"feeds", "names"});
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subfile()
-		{
-			return m_subfile;
-		}
-
-		public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-		{
-			var feedID = entry.key.get_string();
-			if (feedID == null)
-			{
-				Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
-				return;
-			}
-			var name = entry.value.get_string();
-			if (name == null)
-			{
-				Logger.warning("Invalid name " + Json.to_string(entry.value, false));
-				return;
-			}
-			m_plugin.m_db_write.rename_feed(feedID, name);
-		}
-	}
-
-	public class CategoriesListener : OnSubfileEntryUpdateListener<Unit> {
-
-		private Gee.List<string> m_subfile;
-		private decsyncInterface m_plugin;
-
-		public CategoriesListener(decsyncInterface plugin)
-		{
-			this.m_subfile = toList({"feeds", "categories"});
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subfile()
-		{
-			return m_subfile;
-		}
-
-		public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-		{
-			var feedID = entry.key.get_string();
-			if (feedID == null)
-			{
-				Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
-				return;
-			}
-			var feed = m_plugin.m_db.read_feed(feedID);
-			if (feed == null) return;
-			var currentCatID = feed.getCatString();
-			string newCatID;
-			if (entry.value.is_null())
-			{
-				newCatID = m_plugin.uncategorizedID();
-			}
-			else
-			{
-				newCatID = entry.value.get_string();
-			}
-			if (newCatID == null)
-			{
-				Logger.warning("Invalid catID " + Json.to_string(entry.value, false));
-				return;
-			}
-			addCategory(m_plugin, newCatID);
-			m_plugin.m_db_write.move_feed(feedID, currentCatID, newCatID);
-		}
-	}
-
-	public class CategoryNamesListener : OnSubfileEntryUpdateListener<Unit> {
-
-		private Gee.List<string> m_subfile;
-		private decsyncInterface m_plugin;
-
-		public CategoryNamesListener(decsyncInterface plugin)
-		{
-			this.m_subfile = toList({"categories", "names"});
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subfile()
-		{
-			return m_subfile;
-		}
-
-		public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-		{
-			var catID = entry.key.get_string();
-			if (catID == null)
-			{
-				Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
-				return;
-			}
-			var name = entry.value.get_string();
-			if (name == null)
-			{
-				Logger.warning("Invalid name " + Json.to_string(entry.value, false));
-				return;
-			}
-			m_plugin.m_db_write.rename_category(catID, name);
-			Logger.debug("Renamed category " + catID + " to " + name);
-		}
-	}
-
-	public class CategoryParentsListener : OnSubfileEntryUpdateListener<Unit> {
-
-		private Gee.List<string> m_subfile;
-		private decsyncInterface m_plugin;
-
-		public CategoryParentsListener(decsyncInterface plugin)
-		{
-			this.m_subfile = toList({"categories", "parents"});
-			this.m_plugin = plugin;
-		}
-
-		public override Gee.List<string> subfile()
-		{
-			return m_subfile;
-		}
-
-		public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
-		{
-			var catID = entry.key.get_string();
-			if (catID == null)
-			{
-				Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
-				return;
-			}
-			string parentID;
-			if (entry.value.is_null())
-			{
-				parentID = CategoryID.MASTER.to_string();
-			}
-			else
-			{
-				parentID = entry.value.get_string();
-			}
-			if (parentID == null)
-			{
-				Logger.warning("Invalid parentID " + Json.to_string(entry.value, false));
-				return;
-			}
-			addCategory(m_plugin, parentID);
-			m_plugin.m_db_write.move_category(catID, parentID);
-			Logger.debug("Moved category " + catID + " to " + parentID);
-		}
-	}
-
-	private static void addCategory(decsyncInterface plugin, string catID)
-	{
-		if (catID == plugin.uncategorizedID() || catID == CategoryID.MASTER.to_string() || plugin.m_db.read_category(catID) != null)
-		{
-			return;
-		}
-		var cat = new Category(catID, catID, 0, 99, CategoryID.MASTER.to_string(), 1);
-		plugin.m_db_write.write_categories(ListUtils.single(cat));
-		plugin.m_sync.executeStoredEntries({"categories", "names"}, new Unit(),
-			stringEquals(catID)
-		);
-		plugin.m_sync.executeStoredEntries({"categories", "parents"}, new Unit(),
-			stringEquals(catID)
-		);
-		Logger.debug("Added category " + catID);
+private Gee.List<string> m_subdir;
+private bool m_is_read_entry;
+private decsyncInterface m_plugin;
+
+public ReadMarkListener(bool is_read_entry, decsyncInterface plugin)
+{
+	this.m_subdir = toList({"articles", is_read_entry ? "read" : "marked"});
+	this.m_is_read_entry = is_read_entry;
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subdir()
+{
+	return m_subdir;
+}
+
+public override void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, Unit extra)
+{
+	var articleID = entry.key.get_string();
+	if (articleID == null)
+	{
+		Logger.warning("Invalid articleID " + Json.to_string(entry.key, false));
+		return;
+	}
+	var added = entry.value.get_boolean();
+	if (m_is_read_entry)
+	{
+		Logger.debug((added ? "read " : "unread ") + articleID);
+	}
+	else
+	{
+		Logger.debug((added ? "mark " : "unmark ") + articleID);
+	}
+	var db = DataBase.writeAccess();
+	Article? article = db.read_article(articleID);
+	if (article == null)
+	{
+		Logger.info("Unkown article " + articleID);
+		return;
+	}
+	if (m_is_read_entry)
+	{
+		article.setUnread(added ? ArticleStatus.READ : ArticleStatus.UNREAD);
+	}
+	else
+	{
+		article.setMarked(added ? ArticleStatus.MARKED : ArticleStatus.UNMARKED);
+	}
+	db.update_article(article);
+}
+}
+
+public class SubscriptionsListener : OnSubfileEntryUpdateListener<Unit> {
+
+private Gee.List<string> m_subfile;
+private decsyncInterface m_plugin;
+
+public SubscriptionsListener(decsyncInterface plugin)
+{
+	this.m_subfile = toList({"feeds", "subscriptions"});
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subfile()
+{
+	return m_subfile;
+}
+
+public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+{
+	var feedID = entry.key.get_string();
+	if (feedID == null)
+	{
+		Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+		return;
+	}
+	var subscribed = entry.value.get_boolean();
+	if (subscribed)
+	{
+		string outFeedID, errmsg;
+		m_plugin.addFeedWithDecsync(feedID, null, null, out outFeedID, out errmsg, false);
+	}
+	else
+	{
+		DataBase.writeAccess().delete_feed(feedID);
+	}
+}
+}
+
+public class FeedNamesListener : OnSubfileEntryUpdateListener<Unit> {
+
+private Gee.List<string> m_subfile;
+private decsyncInterface m_plugin;
+
+public FeedNamesListener(decsyncInterface plugin)
+{
+	this.m_subfile = toList({"feeds", "names"});
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subfile()
+{
+	return m_subfile;
+}
+
+public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+{
+	var feedID = entry.key.get_string();
+	if (feedID == null)
+	{
+		Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+		return;
+	}
+	var name = entry.value.get_string();
+	if (name == null)
+	{
+		Logger.warning("Invalid name " + Json.to_string(entry.value, false));
+		return;
+	}
+	DataBase.writeAccess().rename_feed(feedID, name);
+}
+}
+
+public class CategoriesListener : OnSubfileEntryUpdateListener<Unit> {
+
+private Gee.List<string> m_subfile;
+private decsyncInterface m_plugin;
+
+public CategoriesListener(decsyncInterface plugin)
+{
+	this.m_subfile = toList({"feeds", "categories"});
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subfile()
+{
+	return m_subfile;
+}
+
+public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+{
+	var feedID = entry.key.get_string();
+	if (feedID == null)
+	{
+		Logger.warning("Invalid feedID " + Json.to_string(entry.key, false));
+		return;
+	}
+	var db = DataBase.writeAccess();
+	var feed = db.read_feed(feedID);
+	if (feed == null) return;
+	var currentCatID = feed.getCatString();
+	string newCatID;
+	if (entry.value.is_null())
+	{
+		newCatID = m_plugin.uncategorizedID();
+	}
+	else
+	{
+		newCatID = entry.value.get_string();
+	}
+	if (newCatID == null)
+	{
+		Logger.warning("Invalid catID " + Json.to_string(entry.value, false));
+		return;
+	}
+	addCategory(m_plugin, newCatID);
+	db.move_feed(feedID, currentCatID, newCatID);
+}
+}
+
+public class CategoryNamesListener : OnSubfileEntryUpdateListener<Unit> {
+
+private Gee.List<string> m_subfile;
+private decsyncInterface m_plugin;
+
+public CategoryNamesListener(decsyncInterface plugin)
+{
+	this.m_subfile = toList({"categories", "names"});
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subfile()
+{
+	return m_subfile;
+}
+
+public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+{
+	var catID = entry.key.get_string();
+	if (catID == null)
+	{
+		Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
+		return;
+	}
+	var name = entry.value.get_string();
+	if (name == null)
+	{
+		Logger.warning("Invalid name " + Json.to_string(entry.value, false));
+		return;
+	}
+	DataBase.writeAccess().rename_category(catID, name);
+	Logger.debug("Renamed category " + catID + " to " + name);
+}
+}
+
+public class CategoryParentsListener : OnSubfileEntryUpdateListener<Unit> {
+
+private Gee.List<string> m_subfile;
+private decsyncInterface m_plugin;
+
+public CategoryParentsListener(decsyncInterface plugin)
+{
+	this.m_subfile = toList({"categories", "parents"});
+	this.m_plugin = plugin;
+}
+
+public override Gee.List<string> subfile()
+{
+	return m_subfile;
+}
+
+public override void onSubfileEntryUpdate(Decsync.Entry entry, Unit extra)
+{
+	var catID = entry.key.get_string();
+	if (catID == null)
+	{
+		Logger.warning("Invalid catID " + Json.to_string(entry.key, false));
+		return;
 	}
+	string parentID;
+	if (entry.value.is_null())
+	{
+		parentID = CategoryID.MASTER.to_string();
+	}
+	else
+	{
+		parentID = entry.value.get_string();
+	}
+	if (parentID == null)
+	{
+		Logger.warning("Invalid parentID " + Json.to_string(entry.value, false));
+		return;
+	}
+	addCategory(m_plugin, parentID);
+	DataBase.writeAccess().move_category(catID, parentID);
+	Logger.debug("Moved category " + catID + " to " + parentID);
+}
+}
+
+private static void addCategory(decsyncInterface plugin, string catID)
+{
+	if (catID == plugin.uncategorizedID() || catID == CategoryID.MASTER.to_string() || DataBase.readOnly().read_category(catID) != null)
+	{
+		return;
+	}
+	var cat = new Category(catID, catID, 0, 99, CategoryID.MASTER.to_string(), 1);
+	DataBase.writeAccess().write_categories(ListUtils.single(cat));
+	plugin.m_sync.executeStoredEntries({"categories", "names"}, new Unit(),
+	                                   stringEquals(catID)
+	                                   );
+	plugin.m_sync.executeStoredEntries({"categories", "parents"}, new Unit(),
+	                                   stringEquals(catID)
+	                                   );
+	Logger.debug("Added category " + catID);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/decsync/decsyncUtils.vala 2.7.1-1/plugins/backend/decsync/decsyncUtils.vala
--- 2.6.1-1/plugins/backend/decsync/decsyncUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/decsyncUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,106 +15,106 @@
 
 public class FeedReader.DecsyncUtils : GLib.Object {
 
-	GLib.Settings m_settings;
+GLib.Settings m_settings;
 
-	public DecsyncUtils(GLib.SettingsBackend? settings_backend)
+public DecsyncUtils(GLib.SettingsBackend? settings_backend)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.decsync", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.decsync");
+}
+
+public string getDecsyncDir()
+{
+	var dir = Utils.gsettingReadString(m_settings, "decsync-dir");
+	if (dir == "")
+	{
+		return GLib.Environment.get_variable("DECSYNC_DIR") ?? getDefaultDecsyncBaseDir();
+	}
+	else
+	{
+		return dir;
+	}
+}
+
+public void setDecsyncDir(string decsyncDir)
+{
+	Utils.gsettingWriteString(m_settings, "decsync-dir", decsyncDir);
+}
+
+public Feed? downloadFeed(Soup.Session session, string xmlURL, string feedID, Gee.List<string> catIDs, out string errmsg)
+{
+	errmsg = "";
+
+	// download
+	//Logger.debug(@"Requesting: $xmlURL");
+	var msg = new Soup.Message("GET", xmlURL);
+	if (msg == null)
+	{
+		errmsg = @"Couldn't parse feed URL: $xmlURL";
+		Logger.warning(errmsg);
+		return null;
+	}
+	uint status = session.send_message(msg);
+	if(status != 200)
+	{
+		errmsg = "Could not download feed";
+		Logger.warning(errmsg);
+		return null;
+	}
+	string xml = (string)msg.response_body.flatten().data;
+	string? url = null;
+
+	// parse
+	Rss.Parser parser = new Rss.Parser();
+
+	try
+	{
+		parser.load_from_data(xml, xml.length);
+	}
+	catch(Error e)
 	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.decsync", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.decsync");
-	}
-
-	public string getDecsyncDir()
-	{
-		var dir = Utils.gsettingReadString(m_settings, "decsync-dir");
-		if (dir == "")
-		{
-			return getDefaultDecsyncBaseDir();
-		}
-		else
-		{
-			return dir;
-		}
-	}
-
-	public void setDecsyncDir(string decsyncDir)
-	{
-		Utils.gsettingWriteString(m_settings, "decsync-dir", decsyncDir);
-	}
-
-	public Feed? downloadFeed(Soup.Session session, string xmlURL, string feedID, Gee.List<string> catIDs, out string errmsg)
-	{
-		errmsg = "";
-
-		// download
-		//Logger.debug(@"Requesting: $xmlURL");
-		var msg = new Soup.Message("GET", xmlURL);
-		if (msg == null)
-		{
-			errmsg = @"Couldn't parse feed URL: $xmlURL";
-			Logger.warning(errmsg);
-			return null;
-		}
-		uint status = session.send_message(msg);
-		if(status != 200)
-		{
-			errmsg = "Could not download feed";
-			Logger.warning(errmsg);
-			return null;
-		}
-		string xml = (string)msg.response_body.flatten().data;
-		string? url = null;
-
-		// parse
-		Rss.Parser parser = new Rss.Parser();
-
-		try
-		{
-			parser.load_from_data(xml, xml.length);
-		}
-		catch(Error e)
-		{
-			errmsg = "Could not parse feed";
-			Logger.warning(errmsg);
-			return null;
-		}
-
-		var doc = parser.get_document();
-
-		if(doc.link != null
-		&& doc.link != "")
-			url = doc.link;
-
-		var Feed = new Feed(
-					feedID,
-					doc.title,
-					url,
-					0,
-					catIDs,
-					doc.image_url,
-					xmlURL);
-
-		return Feed;
-	}
-
-	public string? convert(string? text, string? locale)
-	{
-		if(text == null)
-			return null;
-
-		if(locale == null)
-			return text;
-
-		try
-		{
-			return GLib.convert(text, -1, "utf-8", locale);
-		}
-		catch(ConvertError e)
-		{
-			Logger.error(e.message);
-		}
+		errmsg = "Could not parse feed";
+		Logger.warning(errmsg);
+		return null;
+	}
+
+	var doc = parser.get_document();
+
+	if(doc.link != null
+	   && doc.link != "")
+		url = doc.link;
+
+	var Feed = new Feed(
+		feedID,
+		doc.title,
+		url,
+		0,
+		catIDs,
+		doc.image_url,
+		xmlURL);
+
+	return Feed;
+}
 
-		return "";
+public string? convert(string? text, string? locale)
+{
+	if(text == null)
+		return null;
+
+	if(locale == null)
+		return text;
+
+	try
+	{
+		return GLib.convert(text, -1, "utf-8", locale);
 	}
+	catch(ConvertError e)
+	{
+		Logger.error(e.message);
+	}
+
+	return "";
+}
 }
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/Decsync.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/Decsync.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/Decsync.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/Decsync.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,7 +16,9 @@
  * along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
 
-public class Unit { public Unit() {} }
+public class Unit { public Unit() {
+		    }
+}
 
 /**
  * The `DecSync` class represents an interface to synchronized key-value mappings stored on the file
@@ -66,559 +68,559 @@ public class Unit { public Unit() {} }
  */
 public class Decsync<T> : GLib.Object {
 
-	string dir;
-	string ownAppId;
-	string ownAppIdEncoded;
-	Gee.Iterable<OnEntryUpdateListener<T>> listeners;
-	DirectoryMonitor? monitor = null;
-
-	/**
-	 * Signal which is called when a sync is complete. For example, it can be used to update the UI.
-	 */
-	public signal void syncComplete(T extra);
+string dir;
+string ownAppId;
+string ownAppIdEncoded;
+Gee.Iterable<OnEntryUpdateListener<T>> listeners;
+DirectoryMonitor? monitor = null;
 
-	public Decsync(string dir, string ownAppId, Gee.Iterable<OnEntryUpdateListener<T>> listeners)
-	{
-		this.dir = dir;
-		this.ownAppId = ownAppId;
-		this.ownAppIdEncoded = FileUtils.urlencode(ownAppId);
-		this.listeners = listeners;
-	}
-
-	/**
-	 * Represents an [Entry] with its path.
-	 */
-	public class EntryWithPath {
-		public Gee.List<string> path;
-		public Entry entry;
-
-		public EntryWithPath(string[] path, Entry entry)
-		{
-			this.path = toList(path);
-			this.entry = entry;
-		}
-
-		public EntryWithPath.now(string[] path, Json.Node key, Json.Node value)
-		{
-			this.path = toList(path);
-			this.entry = new Entry.now(key, value);
-		}
-	}
+/**
+ * Signal which is called when a sync is complete. For example, it can be used to update the UI.
+ */
+public signal void syncComplete(T extra);
 
-	/**
-	 * Represents a key/value pair stored by DecSync. Additionally, it has a datetime property
-	 * indicating the most recent update. It does not store its path, see [EntryWithPath].
-	 */
-	public class Entry {
-		internal string datetime;
-		public Json.Node key;
-		public Json.Node value;
-
-		public Entry(string datetime, Json.Node key, Json.Node value)
-		{
-			this.datetime = datetime;
-			this.key = key;
-			this.value = value;
-		}
-
-		public Entry.now(Json.Node key, Json.Node value)
-		{
-			this.datetime = new GLib.DateTime.now_utc().format("%FT%T");
-			this.key = key;
-			this.value = value;
-		}
-
-		internal string toLine()
-		{
-			var json = new Json.Node(Json.NodeType.ARRAY);
-			var array = new Json.Array();
-			array.add_string_element(this.datetime);
-			array.add_element(this.key);
-			array.add_element(this.value);
-			json.set_array(array);
-			return Json.to_string(json, false);
-		}
+public Decsync(string dir, string ownAppId, Gee.Iterable<OnEntryUpdateListener<T>> listeners)
+{
+	this.dir = dir;
+	this.ownAppId = ownAppId;
+	this.ownAppIdEncoded = FileUtils.urlencode(ownAppId);
+	this.listeners = listeners;
+}
 
-		internal static Entry? fromLine(string line)
-		{
-			try {
-				var json = Json.from_string(line);
-				var array = json.get_array();
-				if (array == null || array.get_length() != 3) {
-					Log.w("Invalid entry " + line);
-					return null;
-				}
-				var datetime = array.get_string_element(0);
-				if (datetime == null) {
-					Log.w("Invalid entry " + line);
-					return null;
-				}
-				var key = array.get_element(1);
-				var value = array.get_element(2);
-				return new Entry(datetime, key, value);
-			} catch (GLib.Error e) {
-				Log.w("Invalid JSON: " + line + "\n" + e.message);
-				return null;
-			}
-		}
-	}
+/**
+ * Represents an [Entry] with its path.
+ */
+public class EntryWithPath {
+public Gee.List<string> path;
+public Entry entry;
+
+public EntryWithPath(string[] path, Entry entry)
+{
+	this.path = toList(path);
+	this.entry = entry;
+}
 
-	private class EntriesLocation {
-		public Gee.List<string> path;
-		public File newEntriesFile;
-		public File? storedEntriesFile;
-		public File? readBytesFile;
+public EntryWithPath.now(string[] path, Json.Node key, Json.Node value)
+{
+	this.path = toList(path);
+	this.entry = new Entry.now(key, value);
+}
+}
 
-		public EntriesLocation.getNewEntriesLocation(Decsync decsync, Gee.List<string> path, string appId)
-		{
-			var pathString = FileUtils.pathToString(path);
-			var appIdEncoded = FileUtils.urlencode(appId);
-			this.path = path;
-			this.newEntriesFile = File.new_for_path(decsync.dir + "/new-entries/" + appIdEncoded + "/" + pathString);
-			this.storedEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
-			this.readBytesFile = File.new_for_path(decsync.dir + "/read-bytes/" + decsync.ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
-		}
+/**
+ * Represents a key/value pair stored by DecSync. Additionally, it has a datetime property
+ * indicating the most recent update. It does not store its path, see [EntryWithPath].
+ */
+public class Entry {
+internal string datetime;
+public Json.Node key;
+public Json.Node value;
+
+public Entry(string datetime, Json.Node key, Json.Node value)
+{
+	this.datetime = datetime;
+	this.key = key;
+	this.value = value;
+}
 
-		public EntriesLocation.getStoredEntriesLocation(Decsync decsync, Gee.List<string> path)
-		{
-			var pathString = FileUtils.pathToString(path);
-			this.path = path;
-			this.newEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
-			this.storedEntriesFile = null;
-			this.readBytesFile = null;
-		}
-	}
+public Entry.now(Json.Node key, Json.Node value)
+{
+	this.datetime = new GLib.DateTime.now_utc().format("%FT%T");
+	this.key = key;
+	this.value = value;
+}
 
-	/**
-	 * Associates the given [value] with the given [key] in the map corresponding to the given
-	 * [path]. This update is sent to synchronized devices.
-	 */
-	public void setEntry(string[] pathArray, Json.Node key, Json.Node value)
-	{
-		var entries = new Gee.ArrayList<Entry>();
-		entries.add(new Entry.now(key, value));
-		setEntriesForPath(toList(pathArray), entries);
+internal string toLine()
+{
+	var json = new Json.Node(Json.NodeType.ARRAY);
+	var array = new Json.Array();
+	array.add_string_element(this.datetime);
+	array.add_element(this.key);
+	array.add_element(this.value);
+	json.set_array(array);
+	return Json.to_string(json, false);
+}
+
+internal static Entry? fromLine(string line)
+{
+	try {
+		var json = Json.from_string(line);
+		var array = json.get_array();
+		if (array == null || array.get_length() != 3) {
+			Log.w("Invalid entry " + line);
+			return null;
+		}
+		var datetime = array.get_string_element(0);
+		if (datetime == null) {
+			Log.w("Invalid entry " + line);
+			return null;
+		}
+		var key = array.get_element(1);
+		var value = array.get_element(2);
+		return new Entry(datetime, key, value);
+	} catch (GLib.Error e) {
+		Log.w("Invalid JSON: " + line + "\n" + e.message);
+		return null;
 	}
+}
+}
 
-	/**
-	 * Like [setEntry], but allows multiple entries to be set. This is more efficient if multiple
-	 * entries share the same path.
-	 *
-	 * @param entriesWithPath entries with path which are inserted.
-	 */
-	public void setEntries(Gee.Collection<EntryWithPath> entriesWithPath)
-	{
-		var multiMap = groupBy<EntryWithPath, Gee.List<string>, Entry>(
-			entriesWithPath,
-			entryWithPath => { return entryWithPath.path; },
-			entryWithPath => { return entryWithPath.entry; }
+private class EntriesLocation {
+public Gee.List<string> path;
+public File newEntriesFile;
+public File? storedEntriesFile;
+public File? readBytesFile;
+
+public EntriesLocation.getNewEntriesLocation(Decsync decsync, Gee.List<string> path, string appId)
+{
+	var pathString = FileUtils.pathToString(path);
+	var appIdEncoded = FileUtils.urlencode(appId);
+	this.path = path;
+	this.newEntriesFile = File.new_for_path(decsync.dir + "/new-entries/" + appIdEncoded + "/" + pathString);
+	this.storedEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
+	this.readBytesFile = File.new_for_path(decsync.dir + "/read-bytes/" + decsync.ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
+}
+
+public EntriesLocation.getStoredEntriesLocation(Decsync decsync, Gee.List<string> path)
+{
+	var pathString = FileUtils.pathToString(path);
+	this.path = path;
+	this.newEntriesFile = File.new_for_path(decsync.dir + "/stored-entries/" + decsync.ownAppIdEncoded + "/" + pathString);
+	this.storedEntriesFile = null;
+	this.readBytesFile = null;
+}
+}
+
+/**
+ * Associates the given [value] with the given [key] in the map corresponding to the given
+ * [path]. This update is sent to synchronized devices.
+ */
+public void setEntry(string[] pathArray, Json.Node key, Json.Node value)
+{
+	var entries = new Gee.ArrayList<Entry>();
+	entries.add(new Entry.now(key, value));
+	setEntriesForPath(toList(pathArray), entries);
+}
+
+/**
+ * Like [setEntry], but allows multiple entries to be set. This is more efficient if multiple
+ * entries share the same path.
+ *
+ * @param entriesWithPath entries with path which are inserted.
+ */
+public void setEntries(Gee.Collection<EntryWithPath> entriesWithPath)
+{
+	var multiMap = groupBy<EntryWithPath, Gee.List<string>, Entry>(
+		entriesWithPath,
+		entryWithPath => { return entryWithPath.path; },
+		entryWithPath => { return entryWithPath.entry; }
 		);
-		multiMap.get_keys().@foreach(path => {
+	multiMap.get_keys().@foreach(path => {
 			setEntriesForPath(path, multiMap.@get(path));
 			return true;
 		});
-	}
-
-	/**
-	 * Like [setEntries], but only allows the entries to have the same path. Consequently, it can
-	 * be slightly more convenient since the path has to be specified just once.
-	 *
-	 * @param path path to the map in which the entries are inserted.
-	 * @param entries entries which are inserted.
-	 */
-	public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entries)
-	{
-		Log.d("Write to path " + FileUtils.pathToString(path));
-		var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId);
+}
 
-		// Write new entries
-		var builder = new StringBuilder();
-		foreach (var entry in entries) {
-			builder.append(entry.toLine() + "\n");
+/**
+ * Like [setEntries], but only allows the entries to have the same path. Consequently, it can
+ * be slightly more convenient since the path has to be specified just once.
+ *
+ * @param path path to the map in which the entries are inserted.
+ * @param entries entries which are inserted.
+ */
+public void setEntriesForPath(Gee.List<string> path, Gee.Collection<Entry> entries)
+{
+	Log.d("Write to path " + FileUtils.pathToString(path));
+	var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId);
+
+	// Write new entries
+	var builder = new StringBuilder();
+	foreach (var entry in entries) {
+		builder.append(entry.toLine() + "\n");
+	}
+	try {
+		FileUtils.writeFile(entriesLocation.newEntriesFile, builder.str, true);
+	} catch (Error e) {
+		Log.w(e.message);
+	}
+
+	// Update .decsync-sequence files
+	while (!path.is_empty) {
+		path.remove_at(path.size - 1);
+		var dir = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId).newEntriesFile;
+		var file = dir.get_child(".decsync-sequence");
+
+		// Get the old version
+		int64 version = 0;
+		if (file.query_exists()) {
+			try {
+				var stream = new DataInputStream(file.read());
+				version = int64.parse(stream.read_line());         // Defaults to 0
+			} catch (GLib.Error e) {
+				Log.w(e.message);
+			}
 		}
+
+		// Write the new version
 		try {
-			FileUtils.writeFile(entriesLocation.newEntriesFile, builder.str, true);
+			FileUtils.writeFile(file, (version + 1).to_string());
 		} catch (Error e) {
 			Log.w(e.message);
 		}
+	}
 
-		// Update .decsync-sequence files
-		while (!path.is_empty) {
-			path.remove_at(path.size - 1);
-			var dir = new EntriesLocation.getNewEntriesLocation(this, path, ownAppId).newEntriesFile;
-			var file = dir.get_child(".decsync-sequence");
-
-			// Get the old version
-			int64 version = 0;
-			if (file.query_exists()) {
-				try {
-					var stream = new DataInputStream(file.read());
-					version = int64.parse(stream.read_line()); // Defaults to 0
-				} catch (GLib.Error e) {
-					Log.w(e.message);
-				}
-			}
+	// Update stored entries
+	updateStoredEntries(entriesLocation, entries);
+}
 
-			// Write the new version
-			try {
-				FileUtils.writeFile(file, (version + 1).to_string());
-			} catch (Error e) {
-				Log.w(e.message);
-			}
+/**
+ * Initializes the monitor which watches the filesystem for updated entries and executes the
+ * corresponding actions.
+ *
+ * @param extra extra data passed to the [listeners].
+ */
+public void initMonitor(T extra)
+{
+	try {
+		var newEntriesDir = File.new_for_path(dir + "/new-entries");
+		var parent = newEntriesDir.get_parent();
+		if (!parent.query_exists()) {
+			parent.make_directory_with_parents();
 		}
-
-		// Update stored entries
-		updateStoredEntries(entriesLocation, entries);
-	}
-
-	/**
-	 * Initializes the monitor which watches the filesystem for updated entries and executes the
-	 * corresponding actions.
-	 *
-	 * @param extra extra data passed to the [listeners].
-	 */
-	public void initMonitor(T extra)
-	{
-		try {
-			var newEntriesDir = File.new_for_path(dir + "/new-entries");
-			var parent = newEntriesDir.get_parent();
-			if (!parent.query_exists()) {
-				parent.make_directory_with_parents();
-			}
-			monitor = new DirectoryMonitor(newEntriesDir);
-			monitor.changed.connect(pathString => {
+		monitor = new DirectoryMonitor(newEntriesDir);
+		monitor.changed.connect(pathString => {
 				var pathEncoded = new Gee.ArrayList<string>.wrap(pathString.split("/"));
 				pathEncoded.remove("");
 				if (pathEncoded.is_empty || pathEncoded.last()[0] == '.') {
-					return;
+				        return;
 				}
 				var path = new Gee.ArrayList<string>();
 				path.add_all_iterator(pathEncoded.map<string>(part => { return FileUtils.urldecode(part); }));
 				if (path.any_match(part => { return part == null; })) {
-					Log.w("Cannot decode path " + pathString);
-					return;
+				        Log.w("Cannot decode path " + pathString);
+				        return;
 				}
 				var appId = path.first();
 				path.remove_at(0);
 				var entriesLocation = new EntriesLocation.getNewEntriesLocation(this, path, appId);
 				if (appId != ownAppId && entriesLocation.newEntriesFile.query_file_type(FileQueryInfoFlags.NONE) == FileType.REGULAR) {
-					executeEntriesLocation(entriesLocation, extra);
-					Log.d("Sync complete");
-					syncComplete(extra);
+				        executeEntriesLocation(entriesLocation, extra);
+				        Log.d("Sync complete");
+				        syncComplete(extra);
 				}
 			});
-			Log.d("Initialized folder monitor for " + dir + "/new-entries");
+		Log.d("Initialized folder monitor for " + dir + "/new-entries");
+	} catch (GLib.Error e) {
+		Log.w(e.message);
+	}
+}
+
+/**
+ * Gets all updated entries and executes the corresponding actions.
+ *
+ * @param extra extra data passed to the [listeners].
+ */
+public void executeAllNewEntries(T extra)
+{
+	Log.d("Execute all new entries in " + dir);
+	var newEntriesDir = File.new_for_path(dir + "/new-entries");
+	var readBytesDir = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded);
+	Gee.Predicate<Gee.List<string>> pathPred = path => { return path.is_empty || path.first() != ownAppId; };
+	FileUtils.listFilesRecursiveRelative(newEntriesDir, readBytesDir, pathPred)
+	.map<EntriesLocation>(path => { return new EntriesLocation.getNewEntriesLocation(this, path.slice(1, path.size), path.first()); })
+	.@foreach (entriesLocation => {
+			executeEntriesLocation(entriesLocation, extra);
+			return true;
+		});
+	Log.d("Sync complete");
+	syncComplete(extra);
+}
+
+private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Gee.Predicate<Json.Node>? keyPred = null, Gee.Predicate<Json.Node>? valuePred = null)
+{
+	// Get the number of read bytes
+	int64 readBytes = 0;
+	if (entriesLocation.readBytesFile != null && entriesLocation.readBytesFile.query_exists()) {
+		try {
+			var stream = new DataInputStream(entriesLocation.readBytesFile.read());
+			readBytes = int64.parse(stream.read_line());         // Defaults to 0
 		} catch (GLib.Error e) {
 			Log.w(e.message);
 		}
 	}
 
-	/**
-	 * Gets all updated entries and executes the corresponding actions.
-	 *
-	 * @param extra extra data passed to the [listeners].
-	 */
-	public void executeAllNewEntries(T extra)
-	{
-		Log.d("Execute all new entries in " + dir);
-		var newEntriesDir = File.new_for_path(dir + "/new-entries");
-		var readBytesDir = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded);
-		Gee.Predicate<Gee.List<string>> pathPred = path => { return path.is_empty || path.first() != ownAppId; };
-		FileUtils.listFilesRecursiveRelative(newEntriesDir, readBytesDir, pathPred)
-			.map<EntriesLocation>(path => { return new EntriesLocation.getNewEntriesLocation(this, path.slice(1, path.size), path.first()); })
-			.@foreach (entriesLocation => {
-				executeEntriesLocation(entriesLocation, extra);
-				return true;
-			});
-		Log.d("Sync complete");
-		syncComplete(extra);
+	// Write the new number of read bytes (= size of the entry file)
+	if (entriesLocation.readBytesFile != null) {
+		try {
+			var size = entriesLocation.newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
+			if (readBytes >= size) return;
+			FileUtils.writeFile(entriesLocation.readBytesFile, size.to_string());
+		} catch (GLib.Error e) {
+			Log.w(e.message);
+		}
 	}
 
-	private void executeEntriesLocation(EntriesLocation entriesLocation, T extra, Gee.Predicate<Json.Node>? keyPred = null, Gee.Predicate<Json.Node>? valuePred = null)
-	{
-		// Get the number of read bytes
-		int64 readBytes = 0;
-		if (entriesLocation.readBytesFile != null && entriesLocation.readBytesFile.query_exists()) {
-			try {
-				var stream = new DataInputStream(entriesLocation.readBytesFile.read());
-				readBytes = int64.parse(stream.read_line()); // Defaults to 0
-			} catch (GLib.Error e) {
-				Log.w(e.message);
-			}
-		}
+	Log.d("Execute entries of " + entriesLocation.newEntriesFile.get_path());
 
-		// Write the new number of read bytes (= size of the entry file)
-		if (entriesLocation.readBytesFile != null) {
-			try {
-				var size = entriesLocation.newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
-				if (readBytes >= size) return;
-				FileUtils.writeFile(entriesLocation.readBytesFile, size.to_string());
-			} catch (GLib.Error e) {
-				Log.w(e.message);
+	// Execute the entries
+	var entriesMap = new Gee.HashMap<Json.Node, Entry>(
+		a => { return a.hash(); },
+		(a, b) => { return a.equal(b); }
+		);
+	try {
+		var stream = new DataInputStream(entriesLocation.newEntriesFile.read());
+		stream.seek(readBytes, SeekType.SET);
+		string line;
+		while ((line = stream.read_line(null)) != null) {
+			var entryLine = Entry.fromLine(line);
+			if (entryLine == null) {
+				continue;
+			}
+			if ((keyPred == null || keyPred(entryLine.key)) &&
+			    (valuePred == null || valuePred(entryLine.value))) {
+				var key = entryLine.key;
+				var entry = entriesMap.@get(key);
+				if (entry == null || entryLine.datetime > entry.datetime) {
+					entriesMap.@set(key, entryLine);
+				}
 			}
 		}
+	} catch (GLib.Error e) {
+		Log.w(e.message);
+	}
+	var entries = new Gee.ArrayList<Entry>();
+	entries.add_all(entriesMap.values);
+	executeEntries(entriesLocation, entries, extra);
+}
 
-		Log.d("Execute entries of " + entriesLocation.newEntriesFile.get_path());
+private void executeEntries(EntriesLocation entriesLocation, Gee.Collection<Entry> entries, T extra)
+{
+	updateStoredEntries(entriesLocation, entries);
 
-		// Execute the entries
-		var entriesMap = new Gee.HashMap<Json.Node, Entry>(
-			a => { return a.hash(); },
-			(a, b) => { return a.equal(b); }
-		);
-		try {
-			var stream = new DataInputStream(entriesLocation.newEntriesFile.read());
-			stream.seek(readBytes, SeekType.SET);
+	var listener = getListener(entriesLocation.path);
+	if (listener == null) {
+		Log.e("Unknown action for path " + FileUtils.pathToString(entriesLocation.path));
+		return;
+	}
+
+	listener.onEntriesUpdate(entriesLocation.path, entries, extra);
+}
+
+private void updateStoredEntries(EntriesLocation entriesLocation, Gee.Collection<Entry> entries)
+{
+	if (entriesLocation.storedEntriesFile == null) {
+		return;
+	}
+
+	try {
+		var haveToFilterFile = false;
+		if (entriesLocation.storedEntriesFile.query_exists()) {
+			var stream = new DataInputStream(entriesLocation.storedEntriesFile.read());
 			string line;
 			while ((line = stream.read_line(null)) != null) {
 				var entryLine = Entry.fromLine(line);
 				if (entryLine == null) {
 					continue;
 				}
-				if ((keyPred == null || keyPred(entryLine.key)) &&
-						(valuePred == null || valuePred(entryLine.value))) {
-					var key = entryLine.key;
-					var entry = entriesMap.@get(key);
-					if (entry == null || entryLine.datetime > entry.datetime) {
-						entriesMap.@set(key, entryLine);
-					}
-				}
-			}
-		} catch (GLib.Error e) {
-			Log.w(e.message);
-		}
-		var entries = new Gee.ArrayList<Entry>();
-		entries.add_all(entriesMap.values);
-		executeEntries(entriesLocation, entries, extra);
-	}
-
-	private void executeEntries(EntriesLocation entriesLocation, Gee.Collection<Entry> entries, T extra)
-	{
-		updateStoredEntries(entriesLocation, entries);
-
-		var listener = getListener(entriesLocation.path);
-		if (listener == null) {
-			Log.e("Unknown action for path " + FileUtils.pathToString(entriesLocation.path));
-			return;
-		}
-
-		listener.onEntriesUpdate(entriesLocation.path, entries, extra);
-	}
-
-	private void updateStoredEntries(EntriesLocation entriesLocation, Gee.Collection<Entry> entries)
-	{
-		if (entriesLocation.storedEntriesFile == null) {
-			return;
-		}
-
-		try {
-			var haveToFilterFile = false;
-			if (entriesLocation.storedEntriesFile.query_exists()) {
-				var stream = new DataInputStream(entriesLocation.storedEntriesFile.read());
-				string line;
-				while ((line = stream.read_line(null)) != null) {
-					var entryLine = Entry.fromLine(line);
-					if (entryLine == null) {
-						continue;
-					}
-					var entriesIterator = entries.iterator();
-					while (entriesIterator.has_next()) {
-						entriesIterator.next();
-						var entry = entriesIterator.get();
-						if (entry.key.equal(entryLine.key)) {
-							if (entry.datetime > entryLine.datetime) {
-								haveToFilterFile = true;
-							} else {
-								entriesIterator.remove();
-							}
+				var entriesIterator = entries.iterator();
+				while (entriesIterator.has_next()) {
+					entriesIterator.next();
+					var entry = entriesIterator.get();
+					if (entry.key.equal(entryLine.key)) {
+						if (entry.datetime > entryLine.datetime) {
+							haveToFilterFile = true;
+						} else {
+							entriesIterator.remove();
 						}
 					}
 				}
 			}
+		}
 
-			if (haveToFilterFile) {
-				FileUtils.filterFile(entriesLocation.storedEntriesFile, line => {
+		if (haveToFilterFile) {
+			FileUtils.filterFile(entriesLocation.storedEntriesFile, line => {
 					var entryLine = Entry.fromLine(line);
 					if (entryLine == null) {
-						return false;
+					        return false;
 					}
 					return !entries.any_match(entry => { return entry.key.equal(entryLine.key); });
 				});
-			}
+		}
 
-			var builder = new StringBuilder();
-			entries.@foreach(entry => {
+		var builder = new StringBuilder();
+		entries.@foreach(entry => {
 				builder.append(entry.toLine() + "\n");
 				return true;
 			});
-			FileUtils.writeFile(entriesLocation.storedEntriesFile, builder.str, true);
-		}
-		catch (GLib.Error e)
-		{
-			Log.w(e.message);
-		}
+		FileUtils.writeFile(entriesLocation.storedEntriesFile, builder.str, true);
 	}
-
-	/**
-	 * Gets all stored entries satisfying the predicates and executes the corresponding actions.
-	 *
-	 * @param executePath path to the entries to executes. This can be either a file or a directory.
-	 * If it specifies a file, the entries in that file are executed. If it specifies a directory,
-	 * all entries in all subfiles are executed.
-	 * @param extra extra data passed to the [listeners].
-	 * @param keyPred optional predicate on the keys. The key has to satisfy this predicate to be
-	 * executed.
-	 * @param valuePred optional predicate on the values. The value has to satisfy this predicate to
-	 * be executed.
-	 * @param pathPred optional predicate on the subpaths. Each subpath has to satisfy this
-	 * predicate to be executed. This holds for directories as well. Furthermore, the path of
-	 * specified in [executePath] is not part of the argument.
-	 */
-	public void executeStoredEntries(string[] executePathArray, T extra,
-		Gee.Predicate<Json.Node>? keyPred = null,
-		Gee.Predicate<Json.Node>? valuePred = null,
-		Gee.Predicate<Gee.List<string>>? pathPred = null)
+	catch (GLib.Error e)
 	{
-		var executePath = toList(executePathArray);
-		var executePathString = FileUtils.pathToString(executePath);
-		var executeDir = File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded + "/" + executePathString);
-		FileUtils.listFilesRecursiveRelative(executeDir, null, pathPred)
-			.@foreach(path => {
-				path.insert_all(0, executePath);
-				var entriesLocation = new EntriesLocation.getStoredEntriesLocation(this, path);
-				executeEntriesLocation(entriesLocation, extra, keyPred, valuePred);
-				return true;
-			});
+		Log.w(e.message);
 	}
+}
 
-	/**
-	 * Initializes the stored entries. This method does not execute any actions. This is often
-	 * followed with a call to [executeStoredEntries].
-	 */
-	public void initStoredEntries()
-	{
-		// Get the most up-to-date appId
-		string? appId = null;
-		string? maxDatetime = null;
-		FileUtils.listFilesRecursiveRelative(File.new_for_path(dir + "/stored-entries"))
-			.filter(path => { return !path.is_empty; })
-			.@foreach(path => {
-				var pathString = FileUtils.pathToString(path);
-				try {
-					var file = File.new_for_path(dir + "/stored-entries/" + pathString);
-					var stream = new DataInputStream(file.read());
-					string line;
-					while ((line = stream.read_line(null)) != null) {
-						var entry = Entry.fromLine(line);
-						if (entry == null) {
-							continue;
-						}
-						if (maxDatetime == null || entry.datetime > maxDatetime ||
-								path.first() == ownAppId && entry.datetime == maxDatetime) { // Prefer own appId
-							maxDatetime = entry.datetime;
-							appId = path.first();
-						}
-					}
-				} catch (GLib.Error e) {
-					Log.w(e.message);
-				}
-				return true;
-			});
-		if (appId == null) {
-			Log.i("No appId found for initialization");
-			return;
-		}
-
-		// Copy the stored files and update the read bytes
-		if (appId != ownAppId) {
-			var appIdEncoded = FileUtils.urlencode(appId);
+/**
+ * Gets all stored entries satisfying the predicates and executes the corresponding actions.
+ *
+ * @param executePath path to the entries to executes. This can be either a file or a directory.
+ * If it specifies a file, the entries in that file are executed. If it specifies a directory,
+ * all entries in all subfiles are executed.
+ * @param extra extra data passed to the [listeners].
+ * @param keyPred optional predicate on the keys. The key has to satisfy this predicate to be
+ * executed.
+ * @param valuePred optional predicate on the values. The value has to satisfy this predicate to
+ * be executed.
+ * @param pathPred optional predicate on the subpaths. Each subpath has to satisfy this
+ * predicate to be executed. This holds for directories as well. Furthermore, the path of
+ * specified in [executePath] is not part of the argument.
+ */
+public void executeStoredEntries(string[] executePathArray, T extra,
+                                 Gee.Predicate<Json.Node>? keyPred = null,
+                                 Gee.Predicate<Json.Node>? valuePred = null,
+                                 Gee.Predicate<Gee.List<string>>? pathPred = null)
+{
+	var executePath = toList(executePathArray);
+	var executePathString = FileUtils.pathToString(executePath);
+	var executeDir = File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded + "/" + executePathString);
+	FileUtils.listFilesRecursiveRelative(executeDir, null, pathPred)
+	.@foreach(path => {
+			path.insert_all(0, executePath);
+			var entriesLocation = new EntriesLocation.getStoredEntriesLocation(this, path);
+			executeEntriesLocation(entriesLocation, extra, keyPred, valuePred);
+			return true;
+		});
+}
 
+/**
+ * Initializes the stored entries. This method does not execute any actions. This is often
+ * followed with a call to [executeStoredEntries].
+ */
+public void initStoredEntries()
+{
+	// Get the most up-to-date appId
+	string? appId = null;
+	string? maxDatetime = null;
+	FileUtils.listFilesRecursiveRelative(File.new_for_path(dir + "/stored-entries"))
+	.filter(path => { return !path.is_empty; })
+	.@foreach(path => {
+			var pathString = FileUtils.pathToString(path);
 			try {
-				FileUtils.@delete(File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
-				FileUtils.copy(File.new_for_path(dir + "/stored-entries/" + appIdEncoded), File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
+			        var file = File.new_for_path(dir + "/stored-entries/" + pathString);
+			        var stream = new DataInputStream(file.read());
+			        string line;
+			        while ((line = stream.read_line(null)) != null) {
+			                var entry = Entry.fromLine(line);
+			                if (entry == null) {
+			                        continue;
+					}
+			                if (maxDatetime == null || entry.datetime > maxDatetime ||
+			                    path.first() == ownAppId && entry.datetime == maxDatetime) {                     // Prefer own appId
+			                        maxDatetime = entry.datetime;
+			                        appId = path.first();
+					}
+				}
 			} catch (GLib.Error e) {
-				Log.w(e.message);
+			        Log.w(e.message);
 			}
+			return true;
+		});
+	if (appId == null) {
+		Log.i("No appId found for initialization");
+		return;
+	}
 
-			try {
-				FileUtils.@delete(File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
-				FileUtils.copy(File.new_for_path(dir + "/read-bytes/" + appIdEncoded), File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
-			} catch (GLib.Error e) {
-				Log.w(e.message);
-			}
-			var newEntriesDir = File.new_for_path(dir + "/new-entries/" + appIdEncoded);
-			var ownReadBytesDir = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded);
-			FileUtils.listFilesRecursiveRelative(newEntriesDir, ownReadBytesDir).@foreach(path => {
+	// Copy the stored files and update the read bytes
+	if (appId != ownAppId) {
+		var appIdEncoded = FileUtils.urlencode(appId);
+
+		try {
+			FileUtils.@delete(File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
+			FileUtils.copy(File.new_for_path(dir + "/stored-entries/" + appIdEncoded), File.new_for_path(dir + "/stored-entries/" + ownAppIdEncoded));
+		} catch (GLib.Error e) {
+			Log.w(e.message);
+		}
+
+		try {
+			FileUtils.@delete(File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
+			FileUtils.copy(File.new_for_path(dir + "/read-bytes/" + appIdEncoded), File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded));
+		} catch (GLib.Error e) {
+			Log.w(e.message);
+		}
+		var newEntriesDir = File.new_for_path(dir + "/new-entries/" + appIdEncoded);
+		var ownReadBytesDir = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded);
+		FileUtils.listFilesRecursiveRelative(newEntriesDir, ownReadBytesDir).@foreach(path => {
 				var pathString = FileUtils.pathToString(path);
 				try {
-					var newEntriesFile = File.new_for_path(dir + "/new-entries/" + appIdEncoded + "/" + pathString);
-					var size = newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
-					var readBytesFile = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
-					FileUtils.writeFile(readBytesFile, size.to_string());
+				        var newEntriesFile = File.new_for_path(dir + "/new-entries/" + appIdEncoded + "/" + pathString);
+				        var size = newEntriesFile.query_info("standard::size", FileQueryInfoFlags.NONE).get_size();
+				        var readBytesFile = File.new_for_path(dir + "/read-bytes/" + ownAppIdEncoded + "/" + appIdEncoded + "/" + pathString);
+				        FileUtils.writeFile(readBytesFile, size.to_string());
 				} catch (GLib.Error e) {
-					Log.w(e.message);
+				        Log.w(e.message);
 				}
 				return true;
 			});
-		}
-    }
+	}
+}
 
-	/**
-	 * Returns the value of the given [key] in the map of the given [path], and in the given
-	 * [DecSync directory][decsyncDir] without specifying an appId, or `null` if there is no
-	 * such value. The use of this method is discouraged. It is recommended to use the method
-	 * [executeStoredEntries] when possible.
-	 */
-	public static Json.Node? getStoredStaticValue(string decsyncDir, string[] pathArray, Json.Node key)
-	{
-		Log.d("Get value for key " + Json.to_string(key, false) + " for path " + string.joinv("/", pathArray) + " in " + decsyncDir);
-		var path = toList(pathArray);
-		var pathString = FileUtils.pathToString(path);
-		Json.Node? result = null;
-		string? maxDatetime = null;
-		var storedEntriesDir = File.new_for_path(decsyncDir + "/stored-entries");
-		try {
-			var enumerator = storedEntriesDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
-			FileInfo info;
-			while ((info = enumerator.next_file(null)) != null) {
-				if (info.get_name()[0] == '.') {
-					continue;
-				}
+/**
+ * Returns the value of the given [key] in the map of the given [path], and in the given
+ * [DecSync directory][decsyncDir] without specifying an appId, or `null` if there is no
+ * such value. The use of this method is discouraged. It is recommended to use the method
+ * [executeStoredEntries] when possible.
+ */
+public static Json.Node? getStoredStaticValue(string decsyncDir, string[] pathArray, Json.Node key)
+{
+	Log.d("Get value for key " + Json.to_string(key, false) + " for path " + string.joinv("/", pathArray) + " in " + decsyncDir);
+	var path = toList(pathArray);
+	var pathString = FileUtils.pathToString(path);
+	Json.Node? result = null;
+	string? maxDatetime = null;
+	var storedEntriesDir = File.new_for_path(decsyncDir + "/stored-entries");
+	try {
+		var enumerator = storedEntriesDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
+		FileInfo info;
+		while ((info = enumerator.next_file(null)) != null) {
+			if (info.get_name()[0] == '.') {
+				continue;
+			}
+
+			var appIdEncoded = info.get_name();
+			var file = File.new_for_path(decsyncDir + "/stored-entries/" + appIdEncoded + "/" + pathString);
+			if (!file.query_exists() || file.query_file_type(FileQueryInfoFlags.NONE) != FileType.REGULAR) {
+				continue;
+			}
 
-				var appIdEncoded = info.get_name();
-				var file = File.new_for_path(decsyncDir + "/stored-entries/" + appIdEncoded + "/" + pathString);
-				if (!file.query_exists() || file.query_file_type(FileQueryInfoFlags.NONE) != FileType.REGULAR) {
+			var stream = new DataInputStream(file.read());
+			string line;
+			while ((line = stream.read_line(null)) != null) {
+				var entry = Entry.fromLine(line);
+				if (entry == null) {
 					continue;
 				}
-
-				var stream = new DataInputStream(file.read());
-				string line;
-				while ((line = stream.read_line(null)) != null) {
-					var entry = Entry.fromLine(line);
-					if (entry == null) {
-						continue;
-					}
-					if (entry.key.equal(key) && (maxDatetime == null || entry.datetime > maxDatetime)) {
-						maxDatetime = entry.datetime;
-						result = entry.value;
-					}
+				if (entry.key.equal(key) && (maxDatetime == null || entry.datetime > maxDatetime)) {
+					maxDatetime = entry.datetime;
+					result = entry.value;
 				}
 			}
-		} catch (GLib.Error e) {
-			Log.w(e.message);
 		}
-
-		return result;
+	} catch (GLib.Error e) {
+		Log.w(e.message);
 	}
 
-	private OnEntryUpdateListener<T>? getListener(Gee.List<string> path)
-	{
-		foreach (var listener in listeners) {
-			if (listener.matchesPath(path)) {
-				return listener;
-			}
+	return result;
+}
+
+private OnEntryUpdateListener<T>? getListener(Gee.List<string> path)
+{
+	foreach (var listener in listeners) {
+		if (listener.matchesPath(path)) {
+			return listener;
 		}
-		return null;
 	}
+	return null;
+}
 }
 
 /**
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/DirectoryMonitor.vala	2019-02-01 19:30:50.000000000 +0000
@@ -18,73 +18,73 @@
 
 public class DirectoryMonitor : GLib.Object {
 
-	private File mDir;
-	private string mPath;
-	private FileMonitor mMonitor;
-	private Gee.ArrayList<DirectoryMonitor> mChilds = new Gee.ArrayList<DirectoryMonitor>();
-
-	public signal void changed(string path);
-
-	public DirectoryMonitor(File dir) throws GLib.Error
-	{
-		this.withPath(dir, "");
-	}
+private File mDir;
+private string mPath;
+private FileMonitor mMonitor;
+private Gee.ArrayList<DirectoryMonitor> mChilds = new Gee.ArrayList<DirectoryMonitor>();
+
+public signal void changed(string path);
+
+public DirectoryMonitor(File dir) throws GLib.Error
+{
+	this.withPath(dir, "");
+}
 
-	private DirectoryMonitor.withPath(File dir, string path) throws GLib.Error
-	{
-		mDir = dir;
-		mPath = path;
-		var currentDir = File.new_for_path(dir.get_path() + path);
-		mMonitor = currentDir.monitor_directory(FileMonitorFlags.NONE);
-		mMonitor.changed.connect((file, otherFile, event) => {
+private DirectoryMonitor.withPath(File dir, string path) throws GLib.Error
+{
+	mDir = dir;
+	mPath = path;
+	var currentDir = File.new_for_path(dir.get_path() + path);
+	mMonitor = currentDir.monitor_directory(FileMonitorFlags.NONE);
+	mMonitor.changed.connect((file, otherFile, event) => {
 			if (file.get_path() != mDir.get_path() + path) {
-				onEvent(path + "/" + file.get_basename(), event);
+			        onEvent(path + "/" + file.get_basename(), event);
 			}
 		});
-		Log.d("Monitor created for " + currentDir.get_path() + " (folder " + dir.get_path() + ")");
+	Log.d("Monitor created for " + currentDir.get_path() + " (folder " + dir.get_path() + ")");
 
-		var enumerator = currentDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
-		FileInfo info = null;
-		while (((info = enumerator.next_file(null)) != null)) {
-			if (info.get_file_type() == FileType.DIRECTORY) {
-				var childMonitor = new DirectoryMonitor.withPath(mDir, path + "/" + info.get_name());
-				childMonitor.changed.connect((path) => {
+	var enumerator = currentDir.enumerate_children("standard::*", FileQueryInfoFlags.NONE);
+	FileInfo info = null;
+	while (((info = enumerator.next_file(null)) != null)) {
+		if (info.get_file_type() == FileType.DIRECTORY) {
+			var childMonitor = new DirectoryMonitor.withPath(mDir, path + "/" + info.get_name());
+			childMonitor.changed.connect((path) => {
 					changed(path);
 				});
-				mChilds.add(childMonitor);
-			}
+			mChilds.add(childMonitor);
 		}
 	}
+}
 
-	private void onEvent(string path, FileMonitorEvent event)
-	{
-	    Log.d("Received inotify event " + event.to_string() + " at " + mDir.get_path() + "/" + path);
-		switch (event) {
-			case FileMonitorEvent.DELETED:
-				foreach (var c in mChilds) {
-					if (c.mPath == path) {
-						mChilds.remove(c);
-						break;
-					}
-				}
+private void onEvent(string path, FileMonitorEvent event)
+{
+	Log.d("Received inotify event " + event.to_string() + " at " + mDir.get_path() + "/" + path);
+	switch (event) {
+	case FileMonitorEvent.DELETED:
+		foreach (var c in mChilds) {
+			if (c.mPath == path) {
+				mChilds.remove(c);
 				break;
-			case FileMonitorEvent.CREATED:
-			case FileMonitorEvent.CHANGED:
-				var file = File.new_for_path(mDir.get_path() + path);
-				if (file.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY) {
-					try {
-						var childMonitor = new DirectoryMonitor.withPath(mDir, path);
-						childMonitor.changed.connect((path) => {
-							changed(path);
-						});
-						mChilds.add(childMonitor);
-					} catch (GLib.Error e) {
-						Log.w(e.message);
-					}
-				} else {
-					changed(path);
-				}
-			break;
+			}
+		}
+		break;
+	case FileMonitorEvent.CREATED:
+	case FileMonitorEvent.CHANGED:
+		var file = File.new_for_path(mDir.get_path() + path);
+		if (file.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY) {
+			try {
+				var childMonitor = new DirectoryMonitor.withPath(mDir, path);
+				childMonitor.changed.connect((path) => {
+						changed(path);
+					});
+				mChilds.add(childMonitor);
+			} catch (GLib.Error e) {
+				Log.w(e.message);
+			}
+		} else {
+			changed(path);
 		}
+		break;
 	}
 }
+}
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/FileUtils.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/FileUtils.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/FileUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/FileUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -18,200 +18,200 @@
 
 public class FileUtils : GLib.Object {
 
-	public static void writeFile(File file, string content, bool append = false) throws GLib.Error
-	{
-		var parent = file.get_parent();
+public static void writeFile(File file, string content, bool append = false) throws GLib.Error
+{
+	var parent = file.get_parent();
+	if (!parent.query_exists()) {
+		parent.make_directory_with_parents();
+	}
+
+	GLib.FileOutputStream stream;
+	if (append) {
+		stream = file.append_to(FileCreateFlags.NONE);
+	} else {
+		if (file.query_exists()) {
+			file.@delete();
+		}
+		stream = file.create(FileCreateFlags.REPLACE_DESTINATION);
+	}
+	stream.write(content.data);
+}
+
+public static void @delete(File src) throws GLib.Error
+{
+	if (!src.query_exists()) {
+		return;
+	}
+	if (src.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY) {
+		var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
+		FileInfo info;
+		while ((info = enumerator.next_file(null)) != null) {
+			var name = info.get_name();
+			@delete(src.get_child(name));
+		}
+	}
+	src.@delete();
+}
+
+public static void copy(File src, File dst, bool overwrite = false) throws GLib.Error
+{
+	switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
+	case FileType.REGULAR:
+		var parent = dst.get_parent();
 		if (!parent.query_exists()) {
 			parent.make_directory_with_parents();
 		}
+		src.copy(dst, overwrite ? FileCopyFlags.OVERWRITE : FileCopyFlags.NONE);
+		return;
+	case FileType.DIRECTORY:
+		dst.make_directory_with_parents();
+		var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
+		FileInfo info;
+		while ((info = enumerator.next_file(null)) != null) {
+			var name = info.get_name();
+			copy(src.get_child(name), dst.get_child(name), overwrite);
+		}
+		return;
+	}
+}
 
-		GLib.FileOutputStream stream;
-		if (append) {
-			stream = file.append_to(FileCreateFlags.NONE);
-		} else {
-			if (file.query_exists()) {
-				file.@delete();
-			}
-			stream = file.create(FileCreateFlags.REPLACE_DESTINATION);
+public static void filterFile(File file, Gee.Predicate<string> linePred) throws GLib.Error
+{
+	var tempFile = File.new_for_path(file.get_parent().get_path() + "." + file.get_basename() + ".tmp");
+	var instream = new DataInputStream(file.read());
+	var outstream = new DataOutputStream(tempFile.create(FileCreateFlags.NONE));
+	string line;
+	while ((line = instream.read_line(null)) != null) {
+		if (linePred(line)) {
+			outstream.put_string(line + "\n");
 		}
-		stream.write(content.data);
+	}
+	tempFile.move(file, FileCopyFlags.OVERWRITE);
+}
+
+public static Gee.ArrayList<Gee.ArrayList<string>> listFilesRecursiveRelative(File src, File? readBytesSrc = null, Gee.Predicate<Gee.List<string>>? pathPred = null)
+{
+	if (src.get_basename()[0] == '.') {
+		return new Gee.ArrayList<Gee.ArrayList<string>>();
+	}
+	if (pathPred != null && !pathPred(new Gee.ArrayList<string>())) {
+		return new Gee.ArrayList<Gee.ArrayList<string>>();
 	}
 
-	public static void @delete(File src) throws GLib.Error
-	{
-		if (!src.query_exists()) {
-			return;
+	switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
+	case FileType.REGULAR:
+		var result = new Gee.ArrayList<Gee.ArrayList<string>>();
+		result.add(new Gee.ArrayList<string>());
+		return result;
+	case FileType.DIRECTORY:
+		// Skip same versions
+		if (readBytesSrc != null) {
+			var file = src.get_child(".decsync-sequence");
+			string? version = null;
+			if (file.query_exists()) {
+				try {
+					version = new DataInputStream(file.read()).read_line();
+				} catch (GLib.Error e) {
+					Log.w(e.message);
+				}
+			}
+			var readBytesFile = readBytesSrc.get_child(".decsync-sequence");
+			string? readBytesVersion = null;
+			if (readBytesFile.query_exists()) {
+				try {
+					readBytesVersion = new DataInputStream(readBytesFile.read()).read_line();
+				} catch (GLib.Error e) {
+					Log.w(e.message);
+				}
+			}
+			if (version != null) {
+				if (version == readBytesVersion) {
+					return new Gee.ArrayList<Gee.ArrayList<string>>();
+				} else {
+					try {
+						copy(file, readBytesFile, true);
+					} catch (GLib.Error e) {
+						Log.w(e.message);
+					}
+				}
+			}
 		}
-		if (src.query_file_type(FileQueryInfoFlags.NONE) == FileType.DIRECTORY) {
+
+		var result = new Gee.ArrayList<Gee.ArrayList<string>>();
+		try {
 			var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
 			FileInfo info;
 			while ((info = enumerator.next_file(null)) != null) {
-				var name = info.get_name();
-				@delete(src.get_child(name));
+				string name = info.get_name();
+				string? nameDecoded = urldecode(name);
+				if (nameDecoded == null) {
+					Log.w("Cannot decode name " + name);
+					continue;
+				}
+
+				var newReadBytesSrc = readBytesSrc == null ? null : readBytesSrc.get_child(name);
+				Gee.Predicate<Gee.List<string>>? newPathPred = null;
+				if (pathPred != null) {
+					newPathPred = path => { path.insert(0, nameDecoded); return pathPred(path); };
+				}
+				var paths = listFilesRecursiveRelative(src.get_child(name), newReadBytesSrc, newPathPred);
+				foreach (var path in paths) {
+					path.insert(0, nameDecoded);
+				}
+				result.add_all(paths);
 			}
+		} catch (GLib.Error e) {
+			Log.w(e.message);
 		}
-		src.@delete();
+		return result;
+	default:
+		return new Gee.ArrayList<Gee.ArrayList<string>>();
 	}
+}
 
-	public static void copy(File src, File dst, bool overwrite = false) throws GLib.Error
-	{
-		switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
-			case FileType.REGULAR:
-				var parent = dst.get_parent();
-				if (!parent.query_exists()) {
-					parent.make_directory_with_parents();
-				}
-				src.copy(dst, overwrite ? FileCopyFlags.OVERWRITE : FileCopyFlags.NONE);
-				return;
-			case FileType.DIRECTORY:
-				dst.make_directory_with_parents();
-				var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
-				FileInfo info;
-				while ((info = enumerator.next_file(null)) != null) {
-					var name = info.get_name();
-					copy(src.get_child(name), dst.get_child(name), overwrite);
-				}
-				return;
+public static string pathToString(Gee.List<string> path)
+{
+	var encodedPath = new Gee.ArrayList<string>();
+	encodedPath.add_all_iterator(path.map<string>(part => { return urlencode(part); }));
+	return string.joinv("/", encodedPath.to_array());
+}
+
+public static string urlencode(string input)
+{
+	var builder = new StringBuilder();
+	for (int i = 0; i < input.length; i++) {
+		char byte = input[i];
+		if (byte.isalnum() || "-_.~".contains(byte.to_string())) {
+			builder.append_c(byte);
+		} else {
+			builder.append("%%%2X".printf(byte));
 		}
 	}
+	var output = builder.str;
 
-	public static void filterFile(File file, Gee.Predicate<string> linePred) throws GLib.Error
-	{
-		var tempFile = File.new_for_path(file.get_parent().get_path() + "." + file.get_basename() + ".tmp");
-		var instream = new DataInputStream(file.read());
-		var outstream = new DataOutputStream(tempFile.create(FileCreateFlags.NONE));
-		string line;
-		while ((line = instream.read_line(null)) != null) {
-			if (linePred(line)) {
-				outstream.put_string(line + "\n");
-			}
-		}
-		tempFile.move(file, FileCopyFlags.OVERWRITE);
+	if (output != "" && output[0] == '.') {
+		output = "%2E" + output.substring(1);
 	}
 
-	public static Gee.ArrayList<Gee.ArrayList<string>> listFilesRecursiveRelative(File src, File? readBytesSrc = null, Gee.Predicate<Gee.List<string>>? pathPred = null)
-	{
-		if (src.get_basename()[0] == '.') {
-			return new Gee.ArrayList<Gee.ArrayList<string>>();
-		}
-		if (pathPred != null && !pathPred(new Gee.ArrayList<string>())) {
-			return new Gee.ArrayList<Gee.ArrayList<string>>();
-		}
-
-		switch (src.query_file_type(FileQueryInfoFlags.NONE)) {
-			case FileType.REGULAR:
-				var result = new Gee.ArrayList<Gee.ArrayList<string>>();
-				result.add(new Gee.ArrayList<string>());
-				return result;
-			case FileType.DIRECTORY:
-				// Skip same versions
-				if (readBytesSrc != null) {
-					var file = src.get_child(".decsync-sequence");
-					string? version = null;
-					if (file.query_exists()) {
-						try {
-							version = new DataInputStream(file.read()).read_line();
-						} catch (GLib.Error e) {
-							Log.w(e.message);
-						}
-					}
-					var readBytesFile = readBytesSrc.get_child(".decsync-sequence");
-					string? readBytesVersion = null;
-					if (readBytesFile.query_exists()) {
-						try {
-							readBytesVersion = new DataInputStream(readBytesFile.read()).read_line();
-						} catch (GLib.Error e) {
-							Log.w(e.message);
-						}
-					}
-					if (version != null) {
-						if (version == readBytesVersion) {
-							return new Gee.ArrayList<Gee.ArrayList<string>>();
-						} else {
-							try {
-								copy(file, readBytesFile, true);
-							} catch (GLib.Error e) {
-								Log.w(e.message);
-							}
-						}
-					}
-				}
+	return output;
+}
 
-				var result = new Gee.ArrayList<Gee.ArrayList<string>>();
-				try {
-					var enumerator = src.enumerate_children("standard::name", FileQueryInfoFlags.NONE);
-					FileInfo info;
-					while ((info = enumerator.next_file(null)) != null) {
-						string name = info.get_name();
-						string? nameDecoded = urldecode(name);
-						if (nameDecoded == null) {
-							Log.w("Cannot decode name " + name);
-							continue;
-						}
-
-						var newReadBytesSrc = readBytesSrc == null ? null : readBytesSrc.get_child(name);
-						Gee.Predicate<Gee.List<string>>? newPathPred = null;
-						if (pathPred != null) {
-							newPathPred = path => { path.insert(0, nameDecoded); return pathPred(path); };
-						}
-						var paths = listFilesRecursiveRelative(src.get_child(name), newReadBytesSrc, newPathPred);
-						foreach (var path in paths) {
-							path.insert(0, nameDecoded);
-						}
-						result.add_all(paths);
-					}
-				} catch (GLib.Error e) {
-					Log.w(e.message);
-				}
-				return result;
-			default:
-				return new Gee.ArrayList<Gee.ArrayList<string>>();
+public static string? urldecode(string input)
+{
+	var builder = new StringBuilder();
+	for (int i = 0; i < input.length; i++) {
+		char byte = input[i];
+		if (byte != '%') {
+			builder.append_c(byte);
+		} else {
+			if (i + 2 >= input.length) return null;
+			if (!input[i+1].isxdigit() || !input[i+2].isxdigit()) return null;
+			char value1 = (char)input[i+1].xdigit_value();
+			char value2 = (char)input[i+2].xdigit_value();
+			builder.append_c(16 * value1 + value2);
+			i += 2;
 		}
 	}
-
-    public static string pathToString(Gee.List<string> path)
-    {
-        var encodedPath = new Gee.ArrayList<string>();
-        encodedPath.add_all_iterator(path.map<string>(part => { return urlencode(part); }));
-        return string.joinv("/", encodedPath.to_array());
-    }
-
-    public static string urlencode(string input)
-    {
-	    var builder = new StringBuilder();
-	    for (int i = 0; i < input.length; i++) {
-		    char byte = input[i];
-		    if (byte.isalnum() || "-_.~".contains(byte.to_string())) {
-			    builder.append_c(byte);
-		    } else {
-			    builder.append("%%%2X".printf(byte));
-		    }
-	    }
-	    var output = builder.str;
-
-	    if (output != "" && output[0] == '.') {
-		    output = "%2E" + output.substring(1);
-	    }
-
-	    return output;
-    }
-
-    public static string? urldecode(string input)
-    {
-	    var builder = new StringBuilder();
-	    for (int i = 0; i < input.length; i++) {
-		    char byte = input[i];
-		    if (byte != '%') {
-			    builder.append_c(byte);
-		    } else {
-			    if (i + 2 >= input.length) return null;
-			    if (!input[i+1].isxdigit() || !input[i+2].isxdigit()) return null;
-			    char value1 = (char)input[i+1].xdigit_value();
-			    char value2 = (char)input[i+2].xdigit_value();
-			    builder.append_c(16 * value1 + value2);
-			    i += 2;
-		    }
-	    }
-	    return builder.str;
-    }
+	return builder.str;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/Log.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/Log.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/Log.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/Log.vala	2019-02-01 19:30:50.000000000 +0000
@@ -17,30 +17,30 @@
  */
 
 public class Log : GLib.Object {
-	const string TAG = "DecSync";
+const string TAG = "DecSync";
 
-	private static void log(LogLevelFlags level, string message)
-	{
-		GLib.log_structured(TAG, level, "MESSAGE", "%s", message);
-	}
-
-	public static void e(string message)
-	{
-		log(GLib.LogLevelFlags.LEVEL_CRITICAL, message);
-	}
-
-	public static void w(string message)
-	{
-		log(GLib.LogLevelFlags.LEVEL_WARNING, message);
-	}
-
-	public static void i(string message)
-	{
-		log(GLib.LogLevelFlags.LEVEL_INFO, message);
-	}
-
-	public static void d(string message)
-	{
-		log(GLib.LogLevelFlags.LEVEL_DEBUG, message);
-	}
+private static void log(LogLevelFlags level, string message)
+{
+	GLib.log_structured(TAG, level, "MESSAGE", "%s", message);
+}
+
+public static void e(string message)
+{
+	log(GLib.LogLevelFlags.LEVEL_CRITICAL, message);
+}
+
+public static void w(string message)
+{
+	log(GLib.LogLevelFlags.LEVEL_WARNING, message);
+}
+
+public static void i(string message)
+{
+	log(GLib.LogLevelFlags.LEVEL_INFO, message);
+}
+
+public static void d(string message)
+{
+	log(GLib.LogLevelFlags.LEVEL_DEBUG, message);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/OnEntryUpdateListener.vala	2019-02-01 19:30:50.000000000 +0000
@@ -17,50 +17,50 @@
  */
 
 public interface OnEntryUpdateListener<T> : GLib.Object {
-	public abstract bool matchesPath(Gee.List<string> path);
-	public abstract void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra);
+public abstract bool matchesPath(Gee.List<string> path);
+public abstract void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra);
 }
 
 public abstract class OnSubdirEntryUpdateListener<T> : GLib.Object, OnEntryUpdateListener<T> {
 
-	public abstract Gee.List<string> subdir();
-	public abstract void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, T extra);
+public abstract Gee.List<string> subdir();
+public abstract void onSubdirEntryUpdate(Gee.List<string> path, Decsync.Entry entry, T extra);
 
-	public bool matchesPath(Gee.List<string> path)
-	{
-		return path.size >= subdir().size && pathEquals(path.slice(0, subdir().size), subdir());
-	}
+public bool matchesPath(Gee.List<string> path)
+{
+	return path.size >= subdir().size && pathEquals(path.slice(0, subdir().size), subdir());
+}
 
-	public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
-	{
-		foreach (var entry in entries) {
-			onSubdirEntryUpdate(convertPath(path), entry, extra);
-		}
+public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
+{
+	foreach (var entry in entries) {
+		onSubdirEntryUpdate(convertPath(path), entry, extra);
 	}
+}
 
-	private Gee.List<string> convertPath(Gee.List<string> path)
-	{
-		return path.slice(subdir().size, path.size);
-	}
+private Gee.List<string> convertPath(Gee.List<string> path)
+{
+	return path.slice(subdir().size, path.size);
+}
 }
 
 public abstract class OnSubfileEntryUpdateListener<T> : GLib.Object, OnEntryUpdateListener<T> {
 
-	public abstract Gee.List<string> subfile();
-	public abstract void onSubfileEntryUpdate(Decsync.Entry entry, T extra);
+public abstract Gee.List<string> subfile();
+public abstract void onSubfileEntryUpdate(Decsync.Entry entry, T extra);
 
-	public bool matchesPath(Gee.List<string> path)
-	{
-		return pathEquals(path, subfile());
-	}
+public bool matchesPath(Gee.List<string> path)
+{
+	return pathEquals(path, subfile());
+}
 
-	public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
-	{
-		foreach (var entry in entries) {
-			onSubfileEntryUpdate(entry, extra);
-		}
+public void onEntriesUpdate(Gee.List<string> path, Gee.Collection<Decsync.Entry> entries, T extra)
+{
+	foreach (var entry in entries) {
+		onSubfileEntryUpdate(entry, extra);
 	}
 }
+}
 
 private bool pathEquals(Gee.List<string> path1, Gee.List<string> path2)
 {
diff -pruN 2.6.1-1/plugins/backend/decsync/libdecsync/src/Utils.vala 2.7.1-1/plugins/backend/decsync/libdecsync/src/Utils.vala
--- 2.6.1-1/plugins/backend/decsync/libdecsync/src/Utils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/decsync/libdecsync/src/Utils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -23,9 +23,9 @@ public Gee.List<string> toList(string[]
 
 public Gee.Predicate<Json.Node> stringEquals(string input)
 {
-    return json => {
-        return json.get_string() == input;
-    };
+	return json => {
+		       return json.get_string() == input;
+	};
 }
 
 public Json.Node boolToNode(bool input)
diff -pruN 2.6.1-1/plugins/backend/demo/demoInterface.vala 2.7.1-1/plugins/backend/demo/demoInterface.vala
--- 2.6.1-1/plugins/backend/demo/demoInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/demo/demoInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -6,590 +6,590 @@
 
 public class FeedReader.demoInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	//--------------------------------------------------------------------------------------
-	// This method gets executed right after the plugin is loaded. Do everything
-	// you need to set up the plugin here.
-	//--------------------------------------------------------------------------------------
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
+//--------------------------------------------------------------------------------------
+// This method gets executed right after the plugin is loaded. Do everything
+// you need to set up the plugin here.
+//--------------------------------------------------------------------------------------
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Return the the website/homepage of the project
-	//--------------------------------------------------------------------------------------
-	public string getWebsite()
-	{
+//--------------------------------------------------------------------------------------
+// Return the the website/homepage of the project
+//--------------------------------------------------------------------------------------
+public string getWebsite()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return an unique id for the backend. Basically a short form of the name:
-	// Tiny Tiny RSS -> "ttrss"
-	// Local Backend -> "local"
-	//--------------------------------------------------------------------------------------
-	public string getID()
-	{
+//--------------------------------------------------------------------------------------
+// Return an unique id for the backend. Basically a short form of the name:
+// Tiny Tiny RSS -> "ttrss"
+// Local Backend -> "local"
+//--------------------------------------------------------------------------------------
+public string getID()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return flags describing the type of Service
-	// - LOCAL
-	// - HOSTED
-	// - SELF_HOSTED
-	// - FREE_SOFTWARE
-	// - PROPRIETARY
-	// - FREE
-	// - PAID_PREMIUM
-	// - PAID
-	//--------------------------------------------------------------------------------------
-	public BackendFlags getFlags()
-	{
+//--------------------------------------------------------------------------------------
+// Return flags describing the type of Service
+// - LOCAL
+// - HOSTED
+// - SELF_HOSTED
+// - FREE_SOFTWARE
+// - PROPRIETARY
+// - FREE
+// - PAID_PREMIUM
+// - PAID
+//--------------------------------------------------------------------------------------
+public BackendFlags getFlags()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return the login UI inside a Gtk.Box (username- and password-entries)
-	// Return 'null' if use web-login
-	//--------------------------------------------------------------------------------------
-	public Gtk.Box? getWidget()
-	{
+//--------------------------------------------------------------------------------------
+// Return the login UI inside a Gtk.Box (username- and password-entries)
+// Return 'null' if use web-login
+//--------------------------------------------------------------------------------------
+public Gtk.Box? getWidget()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return the name of the service-icon (non-symbolic).
-	//--------------------------------------------------------------------------------------
-	public string iconName()
-	{
+//--------------------------------------------------------------------------------------
+// Return the name of the service-icon (non-symbolic).
+//--------------------------------------------------------------------------------------
+public string iconName()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return the name of the service as displayed to the user
-	//--------------------------------------------------------------------------------------
-	public string serviceName()
-	{
+//--------------------------------------------------------------------------------------
+// Return the name of the service as displayed to the user
+//--------------------------------------------------------------------------------------
+public string serviceName()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return wheather the plugin needs a webview to log in via oauth.
-	//--------------------------------------------------------------------------------------
-	public bool needWebLogin()
-	{
+//--------------------------------------------------------------------------------------
+// Return wheather the plugin needs a webview to log in via oauth.
+//--------------------------------------------------------------------------------------
+public bool needWebLogin()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Only important for self-hosted services.
-	// If the server is secured by htaccess and a second username and password
-	// is required, show the UI to enter those in this methode.
-	// If htaccess won't be needed do nothing here.
-	//--------------------------------------------------------------------------------------
-	public void showHtAccess()
-	{
+//--------------------------------------------------------------------------------------
+// Only important for self-hosted services.
+// If the server is secured by htaccess and a second username and password
+// is required, show the UI to enter those in this methode.
+// If htaccess won't be needed do nothing here.
+//--------------------------------------------------------------------------------------
+public void showHtAccess()
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Methode gets executed before logging in. Write all the data gathered
-	// into gsettings (password, username, access-key).
-	//--------------------------------------------------------------------------------------
-	public void writeData()
-	{
+//--------------------------------------------------------------------------------------
+// Methode gets executed before logging in. Write all the data gathered
+// into gsettings (password, username, access-key).
+//--------------------------------------------------------------------------------------
+public void writeData()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Do stuff after a successful login
-	//--------------------------------------------------------------------------------------
-	public async void postLoginAction()
-	{
+//--------------------------------------------------------------------------------------
+// Do stuff after a successful login
+//--------------------------------------------------------------------------------------
+public async void postLoginAction()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Only needed if "needWebLogin()" retruned true. Return URL that should be
-	// loaded to log in via website.
-	//--------------------------------------------------------------------------------------
-	public string buildLoginURL()
-	{
+//--------------------------------------------------------------------------------------
+// Only needed if "needWebLogin()" retruned true. Return URL that should be
+// loaded to log in via website.
+//--------------------------------------------------------------------------------------
+public string buildLoginURL()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Extract access-key from redirect-URL from webview after loggin in with
-	// the webview.
-	// Return "true" if extracted sucessfuly, "false" otherwise.
-	//--------------------------------------------------------------------------------------
-	public bool extractCode(string redirectURL)
-	{
+//--------------------------------------------------------------------------------------
+// Extract access-key from redirect-URL from webview after loggin in with
+// the webview.
+// Return "true" if extracted sucessfuly, "false" otherwise.
+//--------------------------------------------------------------------------------------
+public bool extractCode(string redirectURL)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Does the service you are implementing support tags?
-	// If so return "true", otherwise return "false".
-	//--------------------------------------------------------------------------------------
-	public bool supportTags()
-	{
+//--------------------------------------------------------------------------------------
+// Does the service you are implementing support tags?
+// If so return "true", otherwise return "false".
+//--------------------------------------------------------------------------------------
+public bool supportTags()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// If the daemon should to an initial sync after logging in.
-	// For all online services: true
-	// Only for local backend: false
-	//--------------------------------------------------------------------------------------
-	public bool doInitSync()
-	{
+//--------------------------------------------------------------------------------------
+// If the daemon should to an initial sync after logging in.
+// For all online services: true
+// Only for local backend: false
+//--------------------------------------------------------------------------------------
+public bool doInitSync()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// What is the symbolic icon-name of the service-logo?
-	// Return a string with the name, not the complete path.
-	// For example: "feed-service-demo-symbolic"
-	//--------------------------------------------------------------------------------------
-	public string symbolicIcon()
-	{
+//--------------------------------------------------------------------------------------
+// What is the symbolic icon-name of the service-logo?
+// Return a string with the name, not the complete path.
+// For example: "feed-service-demo-symbolic"
+//--------------------------------------------------------------------------------------
+public string symbolicIcon()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return a name the account of the user can be identified with.
-	// This can be the real name of the user, the email-address
-	// or any other personal information that identifies the account.
-	//--------------------------------------------------------------------------------------
-	public string accountName()
-	{
+//--------------------------------------------------------------------------------------
+// Return a name the account of the user can be identified with.
+// This can be the real name of the user, the email-address
+// or any other personal information that identifies the account.
+//--------------------------------------------------------------------------------------
+public string accountName()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// If the service can be self-hosted or has multiple providers
-	// you can return the URL of the server here. Preferably without "http://www."
-	//--------------------------------------------------------------------------------------
-	public string getServerURL()
-	{
+//--------------------------------------------------------------------------------------
+// If the service can be self-hosted or has multiple providers
+// you can return the URL of the server here. Preferably without "http://www."
+//--------------------------------------------------------------------------------------
+public string getServerURL()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Many services have different ways of telling if a feed is uncategorized.
-	// OwnCloud-News and Tiny Tiny RSS use the id "0", while feedly and InoReader
-	// use an empty string ("").
-	// Return what this service uses to indicate that the feed does not belong
-	// to any category.
-	//--------------------------------------------------------------------------------------
-	public string uncategorizedID()
-	{
+//--------------------------------------------------------------------------------------
+// Many services have different ways of telling if a feed is uncategorized.
+// OwnCloud-News and Tiny Tiny RSS use the id "0", while feedly and InoReader
+// use an empty string ("").
+// Return what this service uses to indicate that the feed does not belong
+// to any category.
+//--------------------------------------------------------------------------------------
+public string uncategorizedID()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Sone services have special categories that should not be visible when empty
-	// e.g. feedly has a category called "Must Read".
-	// Argument: ID of a category
-	// Return: wheather the category should be visible when empty
-	//--------------------------------------------------------------------------------------
-	public bool hideCategoryWhenEmpty(string catID)
-	{
+//--------------------------------------------------------------------------------------
+// Sone services have special categories that should not be visible when empty
+// e.g. feedly has a category called "Must Read".
+// Argument: ID of a category
+// Return: wheather the category should be visible when empty
+//--------------------------------------------------------------------------------------
+public bool hideCategoryWhenEmpty(string catID)
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Does the service support categories at all? (feedbin is weird :P)
-	//--------------------------------------------------------------------------------------
-	public bool supportCategories()
-	{
+//--------------------------------------------------------------------------------------
+// Does the service support categories at all? (feedbin is weird :P)
+//--------------------------------------------------------------------------------------
+public bool supportCategories()
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Does the service support add/remove/rename of categories and feeds?
-	//--------------------------------------------------------------------------------------
-	public bool supportFeedManipulation()
-	{
+//--------------------------------------------------------------------------------------
+// Does the service support add/remove/rename of categories and feeds?
+//--------------------------------------------------------------------------------------
+public bool supportFeedManipulation()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Does the service allow categories as children of other categories?
-	// If so return "true", otherwise return "false".
-	//--------------------------------------------------------------------------------------
-	public bool supportMultiLevelCategories()
-	{
+//--------------------------------------------------------------------------------------
+// Does the service allow categories as children of other categories?
+// If so return "true", otherwise return "false".
+//--------------------------------------------------------------------------------------
+public bool supportMultiLevelCategories()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Can one feed be part of more than one category?
-	// If so return "true", otherwise return "false".
-	//--------------------------------------------------------------------------------------
-	public bool supportMultiCategoriesPerFeed()
-	{
+//--------------------------------------------------------------------------------------
+// Can one feed be part of more than one category?
+// If so return "true", otherwise return "false".
+//--------------------------------------------------------------------------------------
+public bool supportMultiCategoriesPerFeed()
+{
 
-	}
+}
 
-	public bool syncFeedsAndCategories()
-	{
+public bool syncFeedsAndCategories()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Does changing the name of a tag also change it's ID?
-	// InoReader tagID's for example look like this:
-	// "user/1005921515/label/tagName"
-	// So if the name changes the ID changes accordingly. This needs special treatment.
-	// Return "true" if this is the case, otherwise return "false".
-	//--------------------------------------------------------------------------------------
-	public bool tagIDaffectedByNameChange()
-	{
+//--------------------------------------------------------------------------------------
+// Does changing the name of a tag also change it's ID?
+// InoReader tagID's for example look like this:
+// "user/1005921515/label/tagName"
+// So if the name changes the ID changes accordingly. This needs special treatment.
+// Return "true" if this is the case, otherwise return "false".
+//--------------------------------------------------------------------------------------
+public bool tagIDaffectedByNameChange()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Delete all passwords, keys and user-information.
-	// Do not delete feeds or articles from the data-base.
-	//--------------------------------------------------------------------------------------
-	public void resetAccount()
-	{
+//--------------------------------------------------------------------------------------
+// Delete all passwords, keys and user-information.
+// Do not delete feeds or articles from the data-base.
+//--------------------------------------------------------------------------------------
+public void resetAccount()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// State wheater the service syncs articles based on a maximum count
-	// or uses something else (OwnCloud uses the last synced articleID)
-	//--------------------------------------------------------------------------------------
-	public bool useMaxArticles()
-	{
+//--------------------------------------------------------------------------------------
+// State wheater the service syncs articles based on a maximum count
+// or uses something else (OwnCloud uses the last synced articleID)
+//--------------------------------------------------------------------------------------
+public bool useMaxArticles()
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Log in to the account of the service. If there is no need or API to sign in,
-	// check all passwords or keys and make sure the service is reachable and works.
-	// Possible return values are:
-	// - SUCCESS
-	// - MISSING_USER
-	// - MISSING_PASSWD
-	// - MISSING_URL
-	// - ALL_EMPTY
-	// - UNKNOWN_ERROR
-	// - FIRST_TRY
-	// - NO_BACKEND
-	// - WRONG_LOGIN
-	// - NO_CONNECTION
-	// - NO_API_ACCESS
-	// - UNAUTHORIZED
-	// - CA_ERROR
-	// - PLUGIN_NEEDED
-	//--------------------------------------------------------------------------------------
-	public LoginResponse login()
-	{
+//--------------------------------------------------------------------------------------
+// Log in to the account of the service. If there is no need or API to sign in,
+// check all passwords or keys and make sure the service is reachable and works.
+// Possible return values are:
+// - SUCCESS
+// - MISSING_USER
+// - MISSING_PASSWD
+// - MISSING_URL
+// - ALL_EMPTY
+// - UNKNOWN_ERROR
+// - FIRST_TRY
+// - NO_BACKEND
+// - WRONG_LOGIN
+// - NO_CONNECTION
+// - NO_API_ACCESS
+// - UNAUTHORIZED
+// - CA_ERROR
+// - PLUGIN_NEEDED
+//--------------------------------------------------------------------------------------
+public LoginResponse login()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// If it is possible to log out of the account of the service, do so here.
-	// If not, do nothing and return "true".
-	//--------------------------------------------------------------------------------------
-	public bool logout()
-	{
+//--------------------------------------------------------------------------------------
+// If it is possible to log out of the account of the service, do so here.
+// If not, do nothing and return "true".
+//--------------------------------------------------------------------------------------
+public bool logout()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Check if the service is reachable.
-	// You can use the method Utils.ping() if the service doesn't provide anything.
-	//--------------------------------------------------------------------------------------
-	public bool serverAvailable()
-	{
+//--------------------------------------------------------------------------------------
+// Check if the service is reachable.
+// You can use the method Utils.ping() if the service doesn't provide anything.
+//--------------------------------------------------------------------------------------
+public bool serverAvailable()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Method to set the state of articles to read or unread
-	// "articleIDs": comma separated string of articleIDs e.g. "id1,id2,id3"
-	// "read": the state to apply. ArticleStatus.READ or ArticleStatus.UNREAD
-	//--------------------------------------------------------------------------------------
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
+//--------------------------------------------------------------------------------------
+// Method to set the state of articles to read or unread
+// "articleIDs": comma separated string of articleIDs e.g. "id1,id2,id3"
+// "read": the state to apply. ArticleStatus.READ or ArticleStatus.UNREAD
+//--------------------------------------------------------------------------------------
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Method to set the state of articles to marked or unmarked
-	// "articleID": single articleID
-	// "read": the state to apply. ArticleStatus.MARKED or ArticleStatus.UNMARKED
-	//--------------------------------------------------------------------------------------
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
+//--------------------------------------------------------------------------------------
+// Method to set the state of articles to marked or unmarked
+// "articleID": single articleID
+// "read": the state to apply. ArticleStatus.MARKED or ArticleStatus.UNMARKED
+//--------------------------------------------------------------------------------------
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
 
-	}
+}
 
-	//--------------------------------------------------------------------------------------
-	// Should setArticleIsRead always be used instead of setFeedRead, setCategoryRead or
-	// markAllItemsRead?
-	// By using IDs as identifier, the articles are known, but it may be less efficient.
-	// If "true", the methods setFeedRead/setCategoryRead/markAllItemsRead never get called.
-	//--------------------------------------------------------------------------------------
-	public bool alwaysSetReadByID()
-	{
+//--------------------------------------------------------------------------------------
+// Should setArticleIsRead always be used instead of setFeedRead, setCategoryRead or
+// markAllItemsRead?
+// By using IDs as identifier, the articles are known, but it may be less efficient.
+// If "true", the methods setFeedRead/setCategoryRead/markAllItemsRead never get called.
+//--------------------------------------------------------------------------------------
+public bool alwaysSetReadByID()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Mark all articles of the feed as read
-	//--------------------------------------------------------------------------------------
-	public void setFeedRead(string feedID)
-	{
+//--------------------------------------------------------------------------------------
+// Mark all articles of the feed as read
+//--------------------------------------------------------------------------------------
+public void setFeedRead(string feedID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Mark all articles of the feeds that are part of the category as read
-	//--------------------------------------------------------------------------------------
-	public void setCategoryRead(string catID)
-	{
+//--------------------------------------------------------------------------------------
+// Mark all articles of the feeds that are part of the category as read
+//--------------------------------------------------------------------------------------
+public void setCategoryRead(string catID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Mark ALL articles as read
-	//--------------------------------------------------------------------------------------
-	public void markAllItemsRead()
-	{
+//--------------------------------------------------------------------------------------
+// Mark ALL articles as read
+//--------------------------------------------------------------------------------------
+public void markAllItemsRead()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Add an existing tag to the article
-	//--------------------------------------------------------------------------------------
-	public void tagArticle(string articleID, string tagID)
-	{
+//--------------------------------------------------------------------------------------
+// Add an existing tag to the article
+//--------------------------------------------------------------------------------------
+public void tagArticle(string articleID, string tagID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Remove an existing tag from the article
-	//--------------------------------------------------------------------------------------
-	public void removeArticleTag(string articleID, string tagID)
-	{
+//--------------------------------------------------------------------------------------
+// Remove an existing tag from the article
+//--------------------------------------------------------------------------------------
+public void removeArticleTag(string articleID, string tagID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Create a new tag with the title of "caption" and return the id of the
-	// newly added tag.
-	// Hint: some services don't have API to create tags, but instead create them
-	// on the fly when tagging articles. In this case just compose the tagID
-	// following the schema tha service uses and return it.
-	//--------------------------------------------------------------------------------------
-	public string createTag(string caption)
-	{
+//--------------------------------------------------------------------------------------
+// Create a new tag with the title of "caption" and return the id of the
+// newly added tag.
+// Hint: some services don't have API to create tags, but instead create them
+// on the fly when tagging articles. In this case just compose the tagID
+// following the schema tha service uses and return it.
+//--------------------------------------------------------------------------------------
+public string createTag(string caption)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Delete a tag completely
-	//--------------------------------------------------------------------------------------
-	public void deleteTag(string tagID)
-	{
+//--------------------------------------------------------------------------------------
+// Delete a tag completely
+//--------------------------------------------------------------------------------------
+public void deleteTag(string tagID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Rename the tag with the id "tagID" to the new name "title"
-	//--------------------------------------------------------------------------------------
-	public void renameTag(string tagID, string title)
-	{
+//--------------------------------------------------------------------------------------
+// Rename the tag with the id "tagID" to the new name "title"
+//--------------------------------------------------------------------------------------
+public void renameTag(string tagID, string title)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Subscribe to the URL "feedURL"
-	// "catID": the category the feed should be placed into, "null" otherwise
-	// "newCatName": the name of a new category the feed should be put in, "null" otherwise
-	//--------------------------------------------------------------------------------------
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
+//--------------------------------------------------------------------------------------
+// Subscribe to the URL "feedURL"
+// "catID": the category the feed should be placed into, "null" otherwise
+// "newCatName": the name of a new category the feed should be put in, "null" otherwise
+//--------------------------------------------------------------------------------------
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Remove the feed with the id "feedID" completely
-	//--------------------------------------------------------------------------------------
-	public void removeFeed(string feedID)
-	{
+//--------------------------------------------------------------------------------------
+// Remove the feed with the id "feedID" completely
+//--------------------------------------------------------------------------------------
+public void removeFeed(string feedID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Rename the feed with the id "feedID" to "title"
-	//--------------------------------------------------------------------------------------
-	public void renameFeed(string feedID, string title)
-	{
+//--------------------------------------------------------------------------------------
+// Rename the feed with the id "feedID" to "title"
+//--------------------------------------------------------------------------------------
+public void renameFeed(string feedID, string title)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Move the feed with the id "feedID" from its current category
-	// to any other category. "currentCatID" is only needed if the
-	// feed can be part of multiple categories at once.
-	//--------------------------------------------------------------------------------------
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
+//--------------------------------------------------------------------------------------
+// Move the feed with the id "feedID" from its current category
+// to any other category. "currentCatID" is only needed if the
+// feed can be part of multiple categories at once.
+//--------------------------------------------------------------------------------------
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Create a new category
-	// "title": title of the new category
-	// "parentID": only needed if multi-level-categories are supported
-	// Hint: some services don't have API to create categories, but instead create them
-	// on the fly when movin feeds over to them. In this case just compose the categoryID
-	// following the schema tha service uses and return it.
-	//--------------------------------------------------------------------------------------
-	public string createCategory(string title, string? parentID)
-	{
+//--------------------------------------------------------------------------------------
+// Create a new category
+// "title": title of the new category
+// "parentID": only needed if multi-level-categories are supported
+// Hint: some services don't have API to create categories, but instead create them
+// on the fly when movin feeds over to them. In this case just compose the categoryID
+// following the schema tha service uses and return it.
+//--------------------------------------------------------------------------------------
+public string createCategory(string title, string? parentID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Rename the category with the id "catID" to "title"
-	//--------------------------------------------------------------------------------------
-	public void renameCategory(string catID, string title)
-	{
+//--------------------------------------------------------------------------------------
+// Rename the category with the id "catID" to "title"
+//--------------------------------------------------------------------------------------
+public void renameCategory(string catID, string title)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Move the category with the id "catID" into another category
-	// with the id "newParentID"
-	// This method is only used if multi-level-categories are supported
-	//--------------------------------------------------------------------------------------
-	public void moveCategory(string catID, string newParentID)
-	{
+//--------------------------------------------------------------------------------------
+// Move the category with the id "catID" into another category
+// with the id "newParentID"
+// This method is only used if multi-level-categories are supported
+//--------------------------------------------------------------------------------------
+public void moveCategory(string catID, string newParentID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Delete the category with the id "catID"
-	//--------------------------------------------------------------------------------------
-	public void deleteCategory(string catID)
-	{
+//--------------------------------------------------------------------------------------
+// Delete the category with the id "catID"
+//--------------------------------------------------------------------------------------
+public void deleteCategory(string catID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Rename the feed with the id "feedID" from the category with the id "catID"
-	// Don't delete the feed entirely, just remove it from the category.
-	// Only useful if feed can be part of multiple categories.
-	//--------------------------------------------------------------------------------------
-	public void removeCatFromFeed(string feedID, string catID)
-	{
+//--------------------------------------------------------------------------------------
+// Rename the feed with the id "feedID" from the category with the id "catID"
+// Don't delete the feed entirely, just remove it from the category.
+// Only useful if feed can be part of multiple categories.
+//--------------------------------------------------------------------------------------
+public void removeCatFromFeed(string feedID, string catID)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Import the content of "opml"
-	// If the service doesn't provide API to import OPML you can use the
-	// OPMLparser-class
-	//--------------------------------------------------------------------------------------
-	public void importOPML(string opml)
-	{
+//--------------------------------------------------------------------------------------
+// Import the content of "opml"
+// If the service doesn't provide API to import OPML you can use the
+// OPMLparser-class
+//--------------------------------------------------------------------------------------
+public void importOPML(string opml)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Get all feeds, categories and tags from the service
-	// Fill up the emtpy LinkedList's that are provided with instances of the
-	// model-classes category, feed and article
-	//--------------------------------------------------------------------------------------
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
+//--------------------------------------------------------------------------------------
+// Get all feeds, categories and tags from the service
+// Fill up the emtpy LinkedList's that are provided with instances of the
+// model-classes category, feed and article
+//--------------------------------------------------------------------------------------
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Return the total count of unread articles on the server
-	//--------------------------------------------------------------------------------------
-	public int getUnreadCount()
-	{
+//--------------------------------------------------------------------------------------
+// Return the total count of unread articles on the server
+//--------------------------------------------------------------------------------------
+public int getUnreadCount()
+{
 
-	}
+}
 
 
-	//--------------------------------------------------------------------------------------
-	// Get the requested articles and write them to the data-base
-	//
-	// "count":		the number of articles to get
-	// "whatToGet":	the kind of articles to get (all/unread/marked/etc.)
-	// "since":     how far back to sync articles (null = no limit)
-	// "feedID":	get only articles of a secific feed or tag
-	// "isTagID":	false if "feedID" is a feed-ID, true if "feedID" is a tag-ID
-	//
-	// It is recommended after getting the articles from the server to use the signal
-	// "writeArticles(Gee.List<Article> articles)"
-	// to automatically process them in the content-grabber, write them to the
-	// data-base and send all the signals to the UI to update accordingly.
-	// But if the API suggests a different approach you can everything on your
-	// own (see ttrss-backend).
-	//--------------------------------------------------------------------------------------
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-	{
+//--------------------------------------------------------------------------------------
+// Get the requested articles and write them to the data-base
+//
+// "count":		the number of articles to get
+// "whatToGet":	the kind of articles to get (all/unread/marked/etc.)
+// "since":     how far back to sync articles (null = no limit)
+// "feedID":	get only articles of a secific feed or tag
+// "isTagID":	false if "feedID" is a feed-ID, true if "feedID" is a tag-ID
+//
+// It is recommended after getting the articles from the server to use the signal
+// "writeArticles(Gee.List<Article> articles)"
+// to automatically process them in the content-grabber, write them to the
+// data-base and send all the signals to the UI to update accordingly.
+// But if the API suggests a different approach you can everything on your
+// own (see ttrss-backend).
+//--------------------------------------------------------------------------------------
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
 
-	}
+}
 
 }
 
diff -pruN 2.6.1-1/plugins/backend/feedbin/feedbinAPI.vala 2.7.1-1/plugins/backend/feedbin/feedbinAPI.vala
--- 2.6.1-1/plugins/backend/feedbin/feedbinAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedbin/feedbinAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -24,425 +24,425 @@ public errordomain FeedbinError {
 }
 
 public class FeedbinAPI : Object {
-	private const string BASE_URI_FORMAT = "%s/v2/";
+private const string BASE_URI_FORMAT = "%s/v2/";
 
-	private Soup.Session m_session;
-	private string m_base_uri;
-	public string username { get ; set; }
-	public string password { get ; set; }
+private Soup.Session m_session;
+private string m_base_uri;
+public string username { get; set; }
+public string password { get; set; }
+
+public FeedbinAPI(string username, string password, string? user_agent = null, string? host = "https://api.feedbin.com")
+{
+	this.username = username;
+	this.password = password;
+	m_base_uri = BASE_URI_FORMAT.printf(host);
+	m_session = new Soup.Session();
 
-	public FeedbinAPI(string username, string password, string? user_agent = null, string? host = "https://api.feedbin.com")
-	{
-		this.username = username;
-		this.password = password;
-		m_base_uri = BASE_URI_FORMAT.printf(host);
-		m_session = new Soup.Session();
+	if(user_agent != null)
+		m_session.user_agent = user_agent;
 
-		if(user_agent != null)
-			m_session.user_agent = user_agent;
+	m_session.authenticate.connect(authenticate);
+}
 
-		m_session.authenticate.connect(authenticate);
-	}
+~FeedbinAPI()
+{
+	m_session.authenticate.disconnect(authenticate);
+}
 
-	~FeedbinAPI()
-	{
-		m_session.authenticate.disconnect(authenticate);
-	}
+private void authenticate(Soup.Message msg, Soup.Auth auth, bool retrying)
+{
+	if(!retrying)
+		auth.authenticate(this.username, this.password);
+}
 
-	private void authenticate(Soup.Message msg, Soup.Auth auth, bool retrying)
-	{
-		if(!retrying)
-			auth.authenticate(this.username, this.password);
+private Soup.Message request(string method, string last_part, string? input = null) throws FeedbinError
+requires (method == "DELETE" || method == "GET" || method == "POST")
+requires (input == null || method != "GET")
+ensures (result.status_code >= 200)
+ensures (result.status_code < 400)
+{
+	var path = m_base_uri + last_part;
+	var message = new Soup.Message(method, path);
+
+	if(method == "POST")
+		message.request_headers.append("Content-Type", "application/json; charset=utf-8");
+
+	if(input != null)
+		message.request_body.append_take(input.data);
+
+	m_session.send_message(message);
+	var status = message.status_code;
+	if(status < 200 || status >= 400)
+	{
+		switch(status)
+		{
+		case Soup.Status.CANT_RESOLVE:
+		case Soup.Status.CANT_RESOLVE_PROXY:
+		case Soup.Status.CANT_CONNECT:
+		case Soup.Status.CANT_CONNECT_PROXY:
+			throw new FeedbinError.NO_CONNECTION(@"Connection to $m_base_uri failed");
+		case Soup.Status.UNAUTHORIZED:
+			throw new FeedbinError.NOT_AUTHORIZED(@"Not authorized to $method $path");
+		case Soup.Status.NOT_FOUND:
+			throw new FeedbinError.NOT_FOUND(@"$method $path not found");
+		}
+		string phrase = Soup.Status.get_phrase(status);
+		throw new FeedbinError.UNKNOWN_ERROR(@"Unexpected status $status ($phrase) for $method $path");
 	}
+	return message;
+}
 
-	private Soup.Message request(string method, string last_part, string? input = null) throws FeedbinError
-	requires (method == "DELETE" || method == "GET" || method == "POST")
-	requires (input == null || method != "GET")
-	ensures (result.status_code >= 200)
-	ensures (result.status_code < 400)
-	{
-		var path = m_base_uri + last_part;
-		var message = new Soup.Message(method, path);
+// TODO: Move to DateUtils
+private static DateTime string_to_datetime(string s) throws FeedbinError
+{
+	var time = TimeVal();
+	if(!time.from_iso8601(s))
+		throw new FeedbinError.INVALID_FORMAT(@"Expected date but got $s");
+	return new DateTime.from_timeval_utc(time);
+}
 
-		if(method == "POST")
-			message.request_headers.append("Content-Type", "application/json; charset=utf-8");
+// TODO: JSON utils?
+private static DateTime get_datetime_member(Json.Object obj, string name) throws FeedbinError
+requires (name != "")
+{
+	var s = obj.get_string_member(name);
+	return string_to_datetime(s);
+}
 
-		if(input != null)
-			message.request_body.append_take(input.data);
+private Soup.Message post_request(string path, string input) throws FeedbinError
+requires (input != "")
+{
+	return request("POST", path, input);
+}
 
-		m_session.send_message(message);
-		var status = message.status_code;
-		if(status < 200 || status >= 400)
-		{
-			switch(status)
-			{
-			case Soup.Status.CANT_RESOLVE:
-			case Soup.Status.CANT_RESOLVE_PROXY:
-			case Soup.Status.CANT_CONNECT:
-			case Soup.Status.CANT_CONNECT_PROXY:
-				throw new FeedbinError.NO_CONNECTION(@"Connection to $m_base_uri failed");
-			case Soup.Status.UNAUTHORIZED:
-				throw new FeedbinError.NOT_AUTHORIZED(@"Not authorized to $method $path");
-			case Soup.Status.NOT_FOUND:
-				throw new FeedbinError.NOT_FOUND(@"$method $path not found");
-			}
-			string phrase = Soup.Status.get_phrase(status);
-			throw new FeedbinError.UNKNOWN_ERROR(@"Unexpected status $status ($phrase) for $method $path");
-		}
-		return message;
-	}
+private Soup.Message delete_request(string path) throws FeedbinError
+{
+	return request("DELETE", path);
+}
 
-	// TODO: Move to DateUtils
-	private static DateTime string_to_datetime(string s) throws FeedbinError
-	{
-		var time = TimeVal();
-		if(!time.from_iso8601(s))
-			throw new FeedbinError.INVALID_FORMAT(@"Expected date but got $s");
-		return new DateTime.from_timeval_utc(time);
-	}
+private Soup.Message get_request(string path) throws FeedbinError
+{
+	return request("GET", path);
+}
 
-	// TODO: JSON utils?
-	private static DateTime get_datetime_member(Json.Object obj, string name) throws FeedbinError
-	requires (name != "")
+private static Json.Node parse_json(Soup.Message response) throws FeedbinError
+{
+	var method = response.method;
+	var uri = response.uri.to_string(false);
+	string content = (string)response.response_body.flatten().data;
+	if(content == null)
 	{
-		var s = obj.get_string_member(name);
-		return string_to_datetime(s);
+		throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned no content but expected JSON");
 	}
 
-	private Soup.Message post_request(string path, string input) throws FeedbinError
-	requires (input != "")
+	var parser = new Json.Parser();
+	try
 	{
-		return request("POST", path, input);
+		parser.load_from_data(content, -1);
 	}
-
-	private Soup.Message delete_request(string path) throws FeedbinError
+	catch (Error e)
 	{
-		return request("DELETE", path);
+		throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned invalid JSON: " + e.message + "\nContent is: $content");
 	}
+	return parser.get_root();
+}
 
-	private Soup.Message get_request(string path) throws FeedbinError
-	{
-		return request("GET", path);
-	}
+private Json.Node get_json(string path) throws FeedbinError
+requires (path != "")
+{
+	var response = get_request(path);
+	return parse_json(response);
+}
 
-	private static Json.Node parse_json(Soup.Message response) throws FeedbinError
-	{
-		var method = response.method;
-		var uri = response.uri.to_string(false);
-		string content = (string)response.response_body.flatten().data;
-		if(content == null)
-		{
-			throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned no content but expected JSON");
-		}
+private Soup.Message post_json_object(string path, Json.Object obj) throws FeedbinError
+{
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(obj);
+
+	var gen = new Json.Generator();
+	gen.set_root(root);
+	var data = gen.to_data(null);
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(content, -1);
-		}
-		catch (Error e)
-		{
-			throw new FeedbinError.INVALID_FORMAT(@"$method $uri returned invalid JSON: " + e.message + "\nContent is: $content");
-		}
-		return parser.get_root();
-	}
+	return post_request(path, data);
+}
 
-	private Json.Node get_json(string path) throws FeedbinError
-	requires (path != "")
+public bool login() throws FeedbinError
+{
+	try
 	{
-		var response = get_request(path);
-		return parse_json(response);
+		var res = get_request("authentication.json");
+		return res.status_code == Soup.Status.OK;
 	}
-
-	private Soup.Message post_json_object(string path, Json.Object obj) throws FeedbinError
+	catch(FeedbinError.NOT_AUTHORIZED e)
 	{
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(obj);
-
-		var gen = new Json.Generator();
-		gen.set_root(root);
-		var data = gen.to_data(null);
+		return false;
+	}
+}
 
-		return post_request(path, data);
+public struct Subscription {
+	int64 id;
+	DateTime created_at;
+	int64 feed_id;
+	string? title;
+	string? feed_url;
+	string? site_url;
+
+	public Subscription.from_json(Json.Object object) throws FeedbinError
+	{
+		id = object.get_int_member("id");
+		created_at = get_datetime_member(object, "created_at");
+		feed_id = object.get_int_member("feed_id");
+		title = object.get_string_member("title");
+		feed_url = object.get_string_member("feed_url");
+		site_url = object.get_string_member("site_url");
 	}
+}
+
+public Subscription get_subscription(int64 subscription_id) throws FeedbinError
+{
+	var root = get_json(@"subscriptions/$subscription_id.json");
+	return Subscription.from_json(root.get_object());
+}
 
-	public bool login() throws FeedbinError
+public Gee.List<Subscription?> get_subscriptions() throws FeedbinError
+ensures (!result.contains(null))
+{
+	var root = get_json("subscriptions.json");
+	var subscriptions = new Gee.ArrayList<Subscription?>();
+	var array = root.get_array();
+	for(var i = 0; i < array.get_length(); ++i)
 	{
-		try
-		{
-			var res = get_request("authentication.json");
-			return res.status_code == Soup.Status.OK;
-		}
-		catch(FeedbinError.NOT_AUTHORIZED e)
-		{
-			return false;
-		}
+		var node = array.get_object_element(i);
+		subscriptions.add(Subscription.from_json(node));
 	}
+	return subscriptions;
+}
 
-	public struct Subscription {
-		int64 id;
-		DateTime created_at;
-		int64 feed_id;
-		string? title;
-		string? feed_url;
-		string? site_url;
+public void delete_subscription(int64 subscription_id) throws FeedbinError
+{
+	delete_request(@"subscriptions/$subscription_id.json");
+}
 
-		public Subscription.from_json(Json.Object object) throws FeedbinError
-		{
-			id = object.get_int_member("id");
-			created_at = get_datetime_member(object, "created_at");
-			feed_id = object.get_int_member("feed_id");
-			title = object.get_string_member("title");
-			feed_url = object.get_string_member("feed_url");
-			site_url = object.get_string_member("site_url");
-		}
-	}
+public Subscription? add_subscription(string url) throws FeedbinError
+{
+	Json.Object object = new Json.Object();
+	object.set_string_member("feed_url", url);
+
+	try
+	{
+		var response = post_json_object("subscriptions.json", object);
+		if(response.status_code == 300)
+			throw new FeedbinError.MULTIPLE_CHOICES("Site $url has multiple feeds to subscribe to");
 
-	public Subscription get_subscription(int64 subscription_id) throws FeedbinError
-	{
-		var root = get_json(@"subscriptions/$subscription_id.json");
+		var root = parse_json(response);
 		return Subscription.from_json(root.get_object());
 	}
-
-	public Gee.List<Subscription?> get_subscriptions() throws FeedbinError
-	ensures (!result.contains(null))
+	catch (FeedbinError.NOT_FOUND e)
 	{
-		var root = get_json("subscriptions.json");
-		var subscriptions = new Gee.ArrayList<Subscription?>();
-		var array = root.get_array();
-		for(var i = 0; i < array.get_length(); ++i)
-		{
-			var node = array.get_object_element(i);
-			subscriptions.add(Subscription.from_json(node));
-		}
-		return subscriptions;
+		return null;
 	}
+}
 
-	public void delete_subscription(int64 subscription_id) throws FeedbinError
-	{
-		delete_request(@"subscriptions/$subscription_id.json");
+public void rename_subscription(int64 subscription_id, string title) throws FeedbinError
+{
+	Json.Object object = new Json.Object();
+	object.set_string_member("title", title);
+	post_json_object(@"subscriptions/$subscription_id/update.json", object);
+}
+
+public struct Tagging
+{
+	int64 id;
+	int64 feed_id;
+	string name;
+
+	public Tagging.from_json(Json.Object object)
+	{
+		id = object.get_int_member("id");
+		feed_id = object.get_int_member("feed_id");
+		name = object.get_string_member("name");
 	}
+}
 
-	public Subscription? add_subscription(string url) throws FeedbinError
-	{
-		Json.Object object = new Json.Object();
-		object.set_string_member("feed_url", url);
+public void add_tagging(int64 feed_id, string tag_name) throws FeedbinError
+{
+	Json.Object object = new Json.Object();
+	object.set_int_member("feed_id", feed_id);
+	object.set_string_member("name", tag_name);
 
-		try
-		{
-			var response = post_json_object("subscriptions.json", object);
-			if(response.status_code == 300)
-				throw new FeedbinError.MULTIPLE_CHOICES("Site $url has multiple feeds to subscribe to");
+	post_json_object("taggings.json", object);
+	// TODO: Return id
+}
 
-			var root = parse_json(response);
-			return Subscription.from_json(root.get_object());
-		}
-		catch (FeedbinError.NOT_FOUND e)
-		{
-			return null;
-		}
-	}
+public void delete_tagging(int64 tagging_id) throws FeedbinError
+{
+	delete_request(@"taggings/$tagging_id.json");
+}
 
-	public void rename_subscription(int64 subscription_id, string title) throws FeedbinError
+public Gee.List<Tagging?> get_taggings() throws FeedbinError
+ensures (!result.contains(null))
+{
+	var root = get_json("taggings.json");
+	var taggings = new Gee.ArrayList<Tagging?>();
+	var array = root.get_array();
+	for(var i = 0; i < array.get_length(); ++i)
 	{
-		Json.Object object = new Json.Object();
-		object.set_string_member("title", title);
-		post_json_object(@"subscriptions/$subscription_id/update.json", object);
+		var object = array.get_object_element(i);
+		taggings.add(Tagging.from_json(object));
 	}
+	return taggings;
+}
 
-	public struct Tagging
-	{
-		int64 id;
-		int64 feed_id;
-		string name;
+public struct Entry
+{
+	int64 id;
+	int64 feed_id;
+	string? title;
+	string? url;
+	string? author;
+	string? content;
+	string? summary;
+	DateTime published;
+	DateTime created_at;
+
+	public Entry.from_json(Json.Object object) throws FeedbinError
+	{
+		id = object.get_int_member("id");
+		feed_id = object.get_int_member("feed_id");
+		title = object.get_string_member("title");
+		url = object.get_string_member("url");
+		author = object.get_string_member("author");
+		content = object.get_string_member("content");
+		summary = object.get_string_member("summary");
+		published = get_datetime_member(object, "published");
+		created_at = get_datetime_member(object, "created_at");
+	}
+}
 
-		public Tagging.from_json(Json.Object object)
+public Gee.List<Entry?> get_entries(int page, bool only_starred, DateTime? since, int64? feed_id = null) throws FeedbinError
+requires (page >= 0)
+ensures (!result.contains(null))
+{
+	string starred = only_starred ? "true" : "false";
+	string path = @"entries.json?per_page=100&page=$page&starred=$starred&include_enclosure=true";
+	if(since != null)
+	{
+		var t = GLib.TimeVal();
+		if(since.to_timeval(out t))
 		{
-			id = object.get_int_member("id");
-			feed_id = object.get_int_member("feed_id");
-			name = object.get_string_member("name");
+			path += "&since=" + t.to_iso8601();
 		}
 	}
 
-	public void add_tagging(int64 feed_id, string tag_name) throws FeedbinError
-	{
-		Json.Object object = new Json.Object();
-		object.set_int_member("feed_id", feed_id);
-		object.set_string_member("name", tag_name);
+	if(feed_id != null)
+		path = @"feeds/$feed_id/$path";
 
-		post_json_object("taggings.json", object);
-		// TODO: Return id
+	Json.Node root;
+	try
+	{
+		root = get_json(path);
 	}
-
-	public void delete_tagging(int64 tagging_id) throws FeedbinError
+	catch(FeedbinError.NOT_FOUND e)
 	{
-		delete_request(@"taggings/$tagging_id.json");
+		return Gee.List.empty<Entry?>();
 	}
 
-	public Gee.List<Tagging?> get_taggings() throws FeedbinError
-	ensures (!result.contains(null))
+	var entries = new Gee.ArrayList<Entry?>();
+	var array = root.get_array();
+	for(var i = 0; i < array.get_length(); ++i)
 	{
-		var root = get_json("taggings.json");
-		var taggings = new Gee.ArrayList<Tagging?>();
-		var array = root.get_array();
-		for(var i = 0; i < array.get_length(); ++i)
-		{
-			var object = array.get_object_element(i);
-			taggings.add(Tagging.from_json(object));
-		}
-		return taggings;
+		var object = array.get_object_element(i);
+		entries.add(Entry.from_json(object));
 	}
+	return entries;
+}
 
-	public struct Entry
+private Gee.Set<int64?> get_x_entries(string path) throws FeedbinError
+{
+	var root = get_json(path);
+	var array = root.get_array();
+	// We have to set the hash function here manually or contains() won't
+	// work right -- presumably because it's trying to do pointer comparisons?
+	var ids = new Gee.HashSet<int64?>(
+		(n) => { return int64_hash(n); },
+		(a, b) => { return int64_equal(a, b); });
+	for(var i = 0; i < array.get_length(); ++i)
 	{
-		int64 id;
-		int64 feed_id;
-		string? title;
-		string? url;
-		string? author;
-		string? content;
-		string? summary;
-		DateTime published;
-		DateTime created_at;
-
-		public Entry.from_json(Json.Object object) throws FeedbinError
-		{
-			id = object.get_int_member("id");
-			feed_id = object.get_int_member("feed_id");
-			title = object.get_string_member("title");
-			url = object.get_string_member("url");
-			author = object.get_string_member("author");
-			content = object.get_string_member("content");
-			summary = object.get_string_member("summary");
-			published = get_datetime_member(object, "published");
-			created_at = get_datetime_member(object, "created_at");
-		}
+		ids.add(array.get_int_element(i));
 	}
+	return ids;
+}
 
-	public Gee.List<Entry?> get_entries(int page, bool only_starred, DateTime? since, int64? feed_id = null) throws FeedbinError
-	requires (page >= 0)
-	ensures (!result.contains(null))
-	{
-		string starred = only_starred ? "true" : "false";
-		string path = @"entries.json?per_page=100&page=$page&starred=$starred&include_enclosure=true";
-		if(since != null)
-		{
-			var t = GLib.TimeVal();
-			if(since.to_timeval(out t))
-			{
-				path += "&since=" + t.to_iso8601();
-			}
-		}
-
-		if(feed_id != null)
-			path = @"feeds/$feed_id/$path";
-
-		Json.Node root;
-		try
-		{
-			root = get_json(path);
-		}
-		catch(FeedbinError.NOT_FOUND e)
-		{
-			return Gee.List.empty<Entry?>();
-		}
-
-		var entries = new Gee.ArrayList<Entry?>();
-		var array = root.get_array();
-		for(var i = 0; i < array.get_length(); ++i)
-		{
-			var object = array.get_object_element(i);
-			entries.add(Entry.from_json(object));
-		}
-		return entries;
-	}
+public Gee.Set<int64?> get_unread_entries() throws FeedbinError
+{
+	return get_x_entries("unread_entries.json");
+}
 
-	private Gee.Set<int64?> get_x_entries(string path) throws FeedbinError
-	{
-		var root = get_json(path);
-		var array = root.get_array();
-		// We have to set the hash function here manually or contains() won't
-		// work right -- presumably because it's trying to do pointer comparisons?
-		var ids = new Gee.HashSet<int64?>(
-			(n) => { return int64_hash(n); },
-			(a, b) => { return int64_equal(a, b); });
-		for(var i = 0; i < array.get_length(); ++i)
-		{
-			ids.add(array.get_int_element(i));
-		}
-		return ids;
-	}
+public Gee.Set<int64?> get_starred_entries() throws FeedbinError
+{
+	return get_x_entries("starred_entries.json");
+}
 
-	public Gee.Set<int64?> get_unread_entries() throws FeedbinError
+private void set_entries_status(string type, Gee.Collection<int64?> entry_ids, bool create) throws FeedbinError
+requires (!entry_ids.contains(null))
+{
+	Json.Array array = new Json.Array();
+	foreach(var id in entry_ids)
 	{
-		return get_x_entries("unread_entries.json");
+		array.add_int_element(id);
 	}
 
-	public Gee.Set<int64?> get_starred_entries() throws FeedbinError
-	{
-		return get_x_entries("starred_entries.json");
-	}
+	Json.Object object = new Json.Object();
+	object.set_array_member(type, array);
 
-	private void set_entries_status(string type, Gee.Collection<int64?> entry_ids, bool create) throws FeedbinError
-	requires (!entry_ids.contains(null))
-	{
-		Json.Array array = new Json.Array();
-		foreach(var id in entry_ids)
-		{
-			array.add_int_element(id);
-		}
+	string path = create ? @"$type.json" : @"$type/delete.json";
+	post_json_object(path, object);
+}
 
-		Json.Object object = new Json.Object();
-		object.set_array_member(type, array);
+public void set_entries_read(Gee.Collection<int64?> entry_ids, bool read) throws FeedbinError
+requires (!entry_ids.contains(null))
+{
+	set_entries_status("unread_entries", entry_ids, !read);
+}
 
-		string path = create ? @"$type.json" : @"$type/delete.json";
-		post_json_object(path, object);
-	}
+public void set_entries_starred(Gee.Collection<int64?> entry_ids, bool starred) throws FeedbinError
+requires (!entry_ids.contains(null))
+{
+	set_entries_status("starred_entries", entry_ids, starred);
+}
 
-	public void set_entries_read(Gee.Collection<int64?> entry_ids, bool read) throws FeedbinError
-	requires (!entry_ids.contains(null))
+public Gee.Map<string, Bytes?> get_favicons() throws FeedbinError
+{
+	// The favicon API isn't public right now; make sure to handle it
+	// suddenly changing or disappearing
+	try
 	{
-		set_entries_status("unread_entries", entry_ids, !read);
-	}
+		var root = get_json("favicons.json");
+		if(root == null)
+			return Gee.Map.empty<string, Bytes?>();
 
-	public void set_entries_starred(Gee.Collection<int64?> entry_ids, bool starred) throws FeedbinError
-	requires (!entry_ids.contains(null))
-	{
-		set_entries_status("starred_entries", entry_ids, starred);
-	}
+		var array = root.get_array();
+		if(array == null)
+			return Gee.Map.empty<string, Bytes?>();
 
-	public Gee.Map<string, Bytes?> get_favicons() throws FeedbinError
-	{
-		// The favicon API isn't public right now; make sure to handle it
-		// suddenly changing or disappearing
-		try
-		{
-			var root = get_json("favicons.json");
-			if(root == null)
-				return Gee.Map.empty<string, Bytes?>();
-
-			var array = root.get_array();
-			if(array == null)
-				return Gee.Map.empty<string, Bytes?>();
-
-			var favicons = new Gee.HashMap<string, Bytes?>();
-			for(var i = 0; i < array.get_length(); ++i)
-			{
-				var obj = array.get_object_element(i);
-				string host = obj.get_string_member("host");
-				if(host == null)
-					continue;
-				var favicon_encoded = obj.get_string_member("favicon");
-				if(favicon_encoded == null)
-					continue;
-				var favicon = new Bytes.take(Base64.decode(favicon_encoded));
-				favicons.set(host, favicon);
-			}
-			return favicons;
-		}
-		catch(Error e)
+		var favicons = new Gee.HashMap<string, Bytes?>();
+		for(var i = 0; i < array.get_length(); ++i)
 		{
-			return Gee.Map.empty<string, Bytes?>();
+			var obj = array.get_object_element(i);
+			string host = obj.get_string_member("host");
+			if(host == null)
+				continue;
+			var favicon_encoded = obj.get_string_member("favicon");
+			if(favicon_encoded == null)
+				continue;
+			var favicon = new Bytes.take(Base64.decode(favicon_encoded));
+			favicons.set(host, favicon);
 		}
+		return favicons;
+	}
+	catch(Error e)
+	{
+		return Gee.Map.empty<string, Bytes?>();
 	}
 }
+}
diff -pruN 2.6.1-1/plugins/backend/feedbin/feedbinInterface.vala 2.7.1-1/plugins/backend/feedbin/feedbinInterface.vala
--- 2.6.1-1/plugins/backend/feedbin/feedbinInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedbin/feedbinInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,742 +15,740 @@
 
 public class FeedReader.FeedbinInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private FeedbinAPI m_api;
-	private FeedbinUtils m_utils;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
-
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new FeedbinUtils(settings_backend, secrets);
-		m_api = new FeedbinAPI(m_utils.getUser(), m_utils.getPassword(), Constants.USER_AGENT);
-	}
-
-	public string getWebsite()
-	{
-		return "https://feedbin.com/";
-	}
-
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.PAID);
-	}
-
-	public string getID()
-	{
-		return "feedbin";
-	}
+private FeedbinAPI m_api;
+private FeedbinUtils m_utils;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new FeedbinUtils(settings_backend, secrets);
+	m_api = new FeedbinAPI(m_utils.getUser(), m_utils.getPassword(), Constants.USER_AGENT);
+}
 
-	public string iconName()
-	{
-		return "feed-service-feedbin";
-	}
+public string getWebsite()
+{
+	return "https://feedbin.com/";
+}
 
-	public string serviceName()
-	{
-		return "Feedbin";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.PAID);
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public string getID()
+{
+	return "feedbin";
+}
 
-	public Gtk.Box? getWidget()
-	ensures (result != null)
-	{
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
+public string iconName()
+{
+	return "feed-service-feedbin";
+}
 
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
+public string serviceName()
+{
+	return "Feedbin";
+}
 
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
+public bool needWebLogin()
+{
+	return false;
+}
 
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-		var loginButton = new Gtk.Button.with_label(_("Login"));
+public Gtk.Box? getWidget()
+ensures (result != null)
+{
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+	var loginButton = new Gtk.Button.with_label(_("Login"));
 
-		m_userEntry.activate.connect(() => {
+	m_userEntry.activate.connect(() => {
 			loginButton.activate();
 		});
-		m_passwordEntry.activate.connect(() => {
+	m_passwordEntry.activate.connect(() => {
 			loginButton.activate();
 		});
 
-		m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passwordEntry.set_visibility(false);
+	m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passwordEntry.set_visibility(false);
 
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(user_label, 0, 0, 1, 1);
-		grid.attach(m_userEntry, 1, 0, 1, 1);
-		grid.attach(password_label, 0, 1, 1, 1);
-		grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-feedbin", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to Feedbin to enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => {
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(user_label, 0, 0, 1, 1);
+	grid.attach(m_userEntry, 1, 0, 1, 1);
+	grid.attach(password_label, 0, 1, 1, 1);
+	grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-feedbin", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to Feedbin to enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => {
 			tryLogin();
 		});
 
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
 
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPassword());
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPassword());
 
-		return box;
-	}
+	return box;
+}
 
-	public void showHtAccess()
-	{
-	}
+public void showHtAccess()
+{
+}
 
-	public void writeData()
-	{
-		m_api.username = m_userEntry.get_text().strip();
-		m_utils.setUser(m_api.username);
+public void writeData()
+{
+	m_api.username = m_userEntry.get_text().strip();
+	m_utils.setUser(m_api.username);
 
-		m_api.password = m_passwordEntry.get_text().strip();
-		m_utils.setPassword(m_api.password);
-	}
+	m_api.password = m_passwordEntry.get_text().strip();
+	m_utils.setPassword(m_api.password);
+}
 
-	public async void postLoginAction()
-	{
-	}
+public async void postLoginAction()
+{
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-feedbin-symbolic";
-	}
+public string symbolicIcon()
+{
+	return "feed-service-feedbin-symbolic";
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public string getServerURL()
-	{
-		return "https://feedbin.com/";
-	}
+public string getServerURL()
+{
+	return "https://feedbin.com/";
+}
 
-	public string uncategorizedID()
-	{
-		return "0";
-	}
+public string uncategorizedID()
+{
+	return "0";
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return false;
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return false;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
+
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
+
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
+
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public bool syncFeedsAndCategories()
+public bool useMaxArticles()
+{
+	return true;
+}
+
+public LoginResponse login()
+{
+	try
 	{
-		return true;
+		if(m_api.login())
+			return LoginResponse.SUCCESS;
+		else
+			return LoginResponse.WRONG_LOGIN;
 	}
-
-	public bool tagIDaffectedByNameChange()
+	catch(FeedbinError.NO_CONNECTION e)
 	{
-		return true;
+		return LoginResponse.NO_CONNECTION;
 	}
-
-	public void resetAccount()
+	catch(Error e)
 	{
-		m_utils.resetAccount();
+		Logger.error("Feedbin login: " + e.message);
+		return LoginResponse.UNKNOWN_ERROR;
 	}
+}
+
+public bool logout()
+{
+	return true;
+}
+
+public bool serverAvailable()
+{
+	return login() != LoginResponse.NO_CONNECTION;
+}
 
-	public bool useMaxArticles()
+public void setArticleIsRead(string article_id, ArticleStatus status)
+{
+	var entry_id = int64.parse(article_id);
+	var entry_ids = ListUtils.single<int64?>(entry_id);
+	try
 	{
-		return true;
+		m_api.set_entries_read(entry_ids, status == ArticleStatus.READ);
 	}
-
-	public LoginResponse login()
+	catch(Error e)
 	{
-		try
-		{
-			if(m_api.login())
-				return LoginResponse.SUCCESS;
-			else
-				return LoginResponse.WRONG_LOGIN;
-		}
-		catch(FeedbinError.NO_CONNECTION e)
-		{
-			return LoginResponse.NO_CONNECTION;
-		}
-		catch(Error e)
-		{
-			Logger.error("Feedbin login: " + e.message);
-			return LoginResponse.UNKNOWN_ERROR;
-		}
+		Logger.error(@"FeedbinInterface.setArticleIsRead: " + e.message);
 	}
+}
 
-	public bool logout()
+public void setArticleIsMarked(string article_id, ArticleStatus status)
+{
+	var entry_id = int64.parse(article_id);
+	var entry_ids = ListUtils.single<int64?>(entry_id);
+	try
 	{
-		return true;
+		m_api.set_entries_starred(entry_ids, status == ArticleStatus.MARKED);
 	}
-
-	public bool serverAvailable()
+	catch(Error e)
 	{
-		return login() != LoginResponse.NO_CONNECTION;
+		Logger.error(@"FeedbinInterface.setArticleIsMarked: " + e.message);
 	}
+}
 
-	public void setArticleIsRead(string article_id, ArticleStatus status)
+private void setRead(string id, FeedListType type)
+{
+	const int count = 1000;
+	int num_articles = 1;         // set to any value > 0
+	var db = DataBase.readOnly();
+	for(var offset = 0; num_articles > 0; offset += count)
 	{
-		var entry_id = int64.parse(article_id);
-		var entry_ids = ListUtils.single<int64?>(entry_id);
-		try
-		{
-			m_api.set_entries_read(entry_ids, status == ArticleStatus.READ);
-		}
-		catch(Error e)
+		var articles = db.read_articles(id, type, ArticleListState.ALL, "", count, offset);
+		var entry_ids = new Gee.ArrayList<int64?>();
+		foreach(var article in articles)
 		{
-			Logger.error(@"FeedbinInterface.setArticleIsRead: " + e.message);
+			entry_ids.add(int64.parse(article.getArticleID()));
 		}
-	}
-
-	public void setArticleIsMarked(string article_id, ArticleStatus status)
-	{
-		var entry_id = int64.parse(article_id);
-		var entry_ids = ListUtils.single<int64?>(entry_id);
 		try
 		{
-			m_api.set_entries_starred(entry_ids, status == ArticleStatus.MARKED);
+			m_api.set_entries_read(entry_ids, true);
 		}
 		catch(Error e)
 		{
-			Logger.error(@"FeedbinInterface.setArticleIsMarked: " + e.message);
-		}
-	}
-
-	private void setRead(string id, FeedListType type)
-	{
-		const int count = 1000;
-		int num_articles = 1; // set to any value > 0
-		for(var offset = 0; num_articles > 0; offset += count)
-		{
-			var articles = m_db.read_articles(id, type, ArticleListState.ALL, "", count, offset);
-			var entry_ids = new Gee.ArrayList<int64?>();
-			foreach(var article in articles)
-			{
-				entry_ids.add(int64.parse(article.getArticleID()));
-			}
-			try
-			{
-				m_api.set_entries_read(entry_ids, true);
-			}
-			catch(Error e)
-			{
-				Logger.error(@"FeedbinInterface.setRead: " + e.message);
-				break;
-			}
+			Logger.error(@"FeedbinInterface.setRead: " + e.message);
+			break;
 		}
 	}
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public void setFeedRead(string feed_id)
-	{
-		setRead(feed_id, FeedListType.FEED);
-	}
+public void setFeedRead(string feed_id)
+{
+	setRead(feed_id, FeedListType.FEED);
+}
 
-	public void setCategoryRead(string category_id)
-	{
-		setRead(category_id, FeedListType.CATEGORY);
-	}
+public void setCategoryRead(string category_id)
+{
+	setRead(category_id, FeedListType.CATEGORY);
+}
 
-	public void markAllItemsRead()
-	{
-		setRead(FeedID.ALL.to_string(), FeedListType.FEED);
-	}
+public void markAllItemsRead()
+{
+	setRead(FeedID.ALL.to_string(), FeedListType.FEED);
+}
 
-	public void tagArticle(string article_id, string tag_id)
-	{
-		return;
-	}
+public void tagArticle(string article_id, string tag_id)
+{
+	return;
+}
 
-	public void removeArticleTag(string article_id, string tag_id)
-	{
-		return;
-	}
+public void removeArticleTag(string article_id, string tag_id)
+{
+	return;
+}
 
-	public string createTag(string caption)
-	{
-		return "";
-	}
+public string createTag(string caption)
+{
+	return "";
+}
 
-	public void deleteTag(string tag_id)
-	{
-		return;
-	}
+public void deleteTag(string tag_id)
+{
+	return;
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		return;
-	}
+public void renameTag(string tagID, string title)
+{
+	return;
+}
 
-	public bool addFeed(string feed_url, string? cat_id, string? category_name, out string feed_id, out string errmsg)
+public bool addFeed(string feed_url, string? cat_id, string? category_name, out string feed_id, out string errmsg)
+{
+	feed_id = "";
+	try
 	{
-		feed_id = "";
-		try
+		var subscription = m_api.add_subscription(feed_url);
+		if (subscription == null)
 		{
-			var subscription = m_api.add_subscription(feed_url);
-			if (subscription == null)
-			{
-				errmsg = @"Feedbin could not find a feed at $(feed_url)";
-				return false;
-			}
-			feed_id = subscription.feed_id.to_string();
-
-			if(category_name != null)
-				m_api.add_tagging(subscription.feed_id, category_name);
-
-			errmsg = "";
-			return true;
-		}
-		catch(Error e)
-		{
-			errmsg = e.message;
-			Logger.error(@"FeedbinInterface.addFeed: $errmsg");
+			errmsg = @"Feedbin could not find a feed at $(feed_url)";
 			return false;
 		}
-	}
+		feed_id = subscription.feed_id.to_string();
 
-	public void addFeeds(Gee.List<Feed> feeds)
+		if(category_name != null)
+			m_api.add_tagging(subscription.feed_id, category_name);
+
+		errmsg = "";
+		return true;
+	}
+	catch(Error e)
 	{
-		return;
+		errmsg = e.message;
+		Logger.error(@"FeedbinInterface.addFeed: $errmsg");
+		return false;
 	}
+}
 
-	private FeedbinAPI.Subscription subscription_for_feed(string feed_id_str) throws FeedbinError
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	return;
+}
+
+private FeedbinAPI.Subscription subscription_for_feed(string feed_id_str) throws FeedbinError
+{
+	var feed_id = int64.parse(feed_id_str);
+	var subscriptions = m_api.get_subscriptions();
+	foreach(var subscription in subscriptions)
 	{
-		var feed_id = int64.parse(feed_id_str);
-		var subscriptions = m_api.get_subscriptions();
-		foreach(var subscription in subscriptions)
-		{
-			if(subscription.feed_id == feed_id)
-				return subscription;
-		}
-		throw new FeedbinError.NOT_FOUND("No subscription found for feed $feed_id");
+		if(subscription.feed_id == feed_id)
+			return subscription;
 	}
+	throw new FeedbinError.NOT_FOUND("No subscription found for feed $feed_id");
+}
 
-	public void removeFeed(string feed_id_str)
+public void removeFeed(string feed_id_str)
+{
+	try
 	{
-		try
-		{
-			var subscription = subscription_for_feed(feed_id_str);
-			m_api.delete_subscription(subscription.id);
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.removeFeed: " + e.message);
-		}
+		var subscription = subscription_for_feed(feed_id_str);
+		m_api.delete_subscription(subscription.id);
 	}
-
-	public void renameFeed(string feed_id_str, string title)
+	catch(Error e)
 	{
-		try
-		{
-			var subscription = subscription_for_feed(feed_id_str);
-			m_api.rename_subscription(subscription.id, title);
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.renameFeed: " + e.message);
-		}
+		Logger.error(@"FeedbinInterface.removeFeed: " + e.message);
 	}
+}
 
-	public void moveFeed(string feed_id_str, string new_category, string? old_category)
+public void renameFeed(string feed_id_str, string title)
+{
+	try
 	{
-		Logger.debug(@"moveFeed: $feed_id_str from $old_category to $new_category");
-		try
-		{
-			var subscription = subscription_for_feed(feed_id_str);
-			var feed_id = subscription.feed_id;
-			if(old_category != null)
-			{
-				var taggings = m_api.get_taggings();
-				foreach(var tagging in taggings)
-				{
-					if(tagging.name != old_category || tagging.feed_id != feed_id)
-						continue;
-					Logger.debug(@"moveFeed: Deleting tag $old_category from $feed_id");
-					m_api.delete_tagging(tagging.id);
-					break;
-				}
-			}
-			Logger.debug(@"moveFeed: Adding tag $new_category to $feed_id");
-			m_api.add_tagging(feed_id, new_category);
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.moveFeed: " + e.message);
-		}
+		var subscription = subscription_for_feed(feed_id_str);
+		m_api.rename_subscription(subscription.id, title);
 	}
-
-	public void renameCategory(string old_category, string new_category)
+	catch(Error e)
 	{
-		Logger.debug(@"renameCategory: From $old_category to $new_category");
-		try
+		Logger.error(@"FeedbinInterface.renameFeed: " + e.message);
+	}
+}
+
+public void moveFeed(string feed_id_str, string new_category, string? old_category)
+{
+	Logger.debug(@"moveFeed: $feed_id_str from $old_category to $new_category");
+	try
+	{
+		var subscription = subscription_for_feed(feed_id_str);
+		var feed_id = subscription.feed_id;
+		if(old_category != null)
 		{
 			var taggings = m_api.get_taggings();
 			foreach(var tagging in taggings)
 			{
-				if(tagging.name != old_category)
+				if(tagging.name != old_category || tagging.feed_id != feed_id)
 					continue;
-				var feed_id = tagging.feed_id;
-				Logger.debug(@"renameCategory: Tagging $feed_id with $new_category");
+				Logger.debug(@"moveFeed: Deleting tag $old_category from $feed_id");
 				m_api.delete_tagging(tagging.id);
-				m_api.add_tagging(feed_id, new_category);
+				break;
 			}
 		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.renameCategory: " + e.message);
-		}
+		Logger.debug(@"moveFeed: Adding tag $new_category to $feed_id");
+		m_api.add_tagging(feed_id, new_category);
 	}
-
-	public void moveCategory(string category_id, string new_parent_id)
+	catch(Error e)
 	{
-		// Feedbin doesn't have multi-level categories
+		Logger.error(@"FeedbinInterface.moveFeed: " + e.message);
 	}
+}
 
-	public string createCategory(string title, string? parent_id)
-	ensures (result == title)
+public void renameCategory(string old_category, string new_category)
+{
+	Logger.debug(@"renameCategory: From $old_category to $new_category");
+	try
+	{
+		var taggings = m_api.get_taggings();
+		foreach(var tagging in taggings)
+		{
+			if(tagging.name != old_category)
+				continue;
+			var feed_id = tagging.feed_id;
+			Logger.debug(@"renameCategory: Tagging $feed_id with $new_category");
+			m_api.delete_tagging(tagging.id);
+			m_api.add_tagging(feed_id, new_category);
+		}
+	}
+	catch(Error e)
 	{
-		// Categories are created and destroyed based on feeds having them.
-		// There are no empty categories in Feedbin
-		return title;
+		Logger.error(@"FeedbinInterface.renameCategory: " + e.message);
 	}
+}
+
+public void moveCategory(string category_id, string new_parent_id)
+{
+	// Feedbin doesn't have multi-level categories
+}
+
+public string createCategory(string title, string? parent_id)
+ensures (result == title)
+{
+	// Categories are created and destroyed based on feeds having them.
+	// There are no empty categories in Feedbin
+	return title;
+}
 
-	public void deleteCategory(string category)
+public void deleteCategory(string category)
+{
+	Logger.debug(@"deleteCategory: $category");
+	try
 	{
-		Logger.debug(@"deleteCategory: $category");
-		try
-		{
-			var taggings = m_api.get_taggings();
-			foreach(var tagging in taggings)
-			{
-				if(tagging.name != category)
-					continue;
-				var feed_id = tagging.feed_id;
-				Logger.debug(@"deleteCategory: Deleting category $category from feed $feed_id");
-				m_api.delete_tagging(tagging.id);
-			}
-		}
-		catch(Error e)
+		var taggings = m_api.get_taggings();
+		foreach(var tagging in taggings)
 		{
-			Logger.error(@"FeedbinInterface.deleteCategory: " + e.message);
+			if(tagging.name != category)
+				continue;
+			var feed_id = tagging.feed_id;
+			Logger.debug(@"deleteCategory: Deleting category $category from feed $feed_id");
+			m_api.delete_tagging(tagging.id);
 		}
 	}
+	catch(Error e)
+	{
+		Logger.error(@"FeedbinInterface.deleteCategory: " + e.message);
+	}
+}
 
-	public void removeCatFromFeed(string feed_id_str, string category)
+public void removeCatFromFeed(string feed_id_str, string category)
+{
+	Logger.debug(@"removeCatFromFeed: Feed $feed_id_str, category $category");
+	try
 	{
-		Logger.debug(@"removeCatFromFeed: Feed $feed_id_str, category $category");
-		try
+		var feed_id = int64.parse(feed_id_str);
+		var taggings = m_api.get_taggings();
+		foreach(var tagging in taggings)
 		{
-			var feed_id = int64.parse(feed_id_str);
-			var taggings = m_api.get_taggings();
-			foreach(var tagging in taggings)
-			{
-				if(tagging.feed_id != feed_id || tagging.name != category)
-					continue;
+			if(tagging.feed_id != feed_id || tagging.name != category)
+				continue;
 
-				Logger.debug(@"removeCatFromFeed: Deleting category $category from feed $feed_id");
-				m_api.delete_tagging(tagging.id);
-				break;
-			}
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.removeCatFromFeed: " + e.message);
+			Logger.debug(@"removeCatFromFeed: Deleting category $category from feed $feed_id");
+			m_api.delete_tagging(tagging.id);
+			break;
 		}
 	}
-
-	public void importOPML(string opml)
+	catch(Error e)
 	{
+		Logger.error(@"FeedbinInterface.removeCatFromFeed: " + e.message);
 	}
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		try
-		{
-			var taggings = m_api.get_taggings();
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
+public void importOPML(string opml)
+{
+}
 
-			var favicons = m_api.get_favicons();
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	try
+	{
+		var taggings = m_api.get_taggings();
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-			// It's easier to rebuild the category list than to update it
-			var category_names = new Gee.HashSet<string>();
-			foreach(var tagging in taggings)
-			{
-				category_names.add(tagging.name);
-			}
-			Logger.debug("getFeedsAndCats: Got %d categories: %s".printf(category_names.size, StringUtils.join(category_names, ", ")));
+		var favicons = m_api.get_favicons();
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-			categories.clear();
-			var top_category = CategoryID.MASTER.to_string();
-			foreach(string name in category_names)
-			{
-				// Note: Feedbin categories *are* case sensitive, so we don't need
-				// to change the case here. "articles" and "Articles" are different
-				// tags.
-				categories.add(
-					new Category (
-						name,
-						name,
-						0,
-						0,
-						top_category,
-						1
+		// It's easier to rebuild the category list than to update it
+		var category_names = new Gee.HashSet<string>();
+		foreach(var tagging in taggings)
+		{
+			category_names.add(tagging.name);
+		}
+		Logger.debug("getFeedsAndCats: Got %d categories: %s".printf(category_names.size, StringUtils.join(category_names, ", ")));
+
+		categories.clear();
+		var top_category = CategoryID.MASTER.to_string();
+		foreach(string name in category_names)
+		{
+			// Note: Feedbin categories *are* case sensitive, so we don't need
+			// to change the case here. "articles" and "Articles" are different
+			// tags.
+			categories.add(
+				new Category (
+					name,
+					name,
+					0,
+					0,
+					top_category,
+					1
 					)
 				);
-			}
+		}
 
-			var tag_map = new Gee.HashMultiMap<string, string>();
-			foreach(var tagging in taggings)
-			{
-				tag_map.set(tagging.feed_id.to_string(), tagging.name);
-			}
+		var tag_map = new Gee.HashMultiMap<string, string>();
+		foreach(var tagging in taggings)
+		{
+			tag_map.set(tagging.feed_id.to_string(), tagging.name);
+		}
 
-			var subscriptions = m_api.get_subscriptions();
-			feeds.clear();
+		var subscriptions = m_api.get_subscriptions();
+		feeds.clear();
 
-			foreach(var subscription in subscriptions)
-			{
-				var feed_id = subscription.feed_id.to_string();
-				Gee.List<string> feed_categories = new Gee.ArrayList<string>();
+		foreach(var subscription in subscriptions)
+		{
+			var feed_id = subscription.feed_id.to_string();
+			Gee.List<string> feed_categories = new Gee.ArrayList<string>();
 
-				if(tag_map.contains(feed_id))
-					feed_categories.add_all(tag_map.get(feed_id));
-				else
-					feed_categories.add(uncategorizedID());
+			if(tag_map.contains(feed_id))
+				feed_categories.add_all(tag_map.get(feed_id));
+			else
+				feed_categories.add(uncategorizedID());
 
-				string? favicon_uri = null;
-				if(subscription.site_url != null)
+			string? favicon_uri = null;
+			if(subscription.site_url != null)
+			{
+				var uri = new Soup.URI(subscription.site_url);
+				if(uri != null)
 				{
-					var uri = new Soup.URI(subscription.site_url);
-					if(uri != null)
+					var favicon = favicons.get(uri.host);
+					if(favicon != null)
 					{
-						var favicon = favicons.get(uri.host);
-						if(favicon != null)
-						{
-							string base64 = Base64.encode(favicon.get_data());
-							favicon_uri = @"data:application/octet-stream;base64,$base64";
-						}
+						string base64 = Base64.encode(favicon.get_data());
+						favicon_uri = @"data:application/octet-stream;base64,$base64";
 					}
 				}
+			}
 
-				feeds.add(
-					new Feed(
-						feed_id,
-						subscription.title,
-						subscription.site_url,
-						0,
-						feed_categories,
-						favicon_uri,
-						subscription.feed_url)
+			feeds.add(
+				new Feed(
+					feed_id,
+					subscription.title,
+					subscription.site_url,
+					0,
+					feed_categories,
+					favicon_uri,
+					subscription.feed_url)
 				);
-			}
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.getFeedsAndCats: " + e.message);
-			return false;
 		}
-		return true;
 	}
+	catch(Error e)
+	{
+		Logger.error(@"FeedbinInterface.getFeedsAndCats: " + e.message);
+		return false;
+	}
+	return true;
+}
 
-	public int getUnreadCount()
-	ensures (result >= 0)
+public int getUnreadCount()
+ensures (result >= 0)
+{
+	try
 	{
-		try
-		{
-			return m_api.get_unread_entries().size;
-		}
-		catch(Error e)
-		{
-			Logger.error(@"FeedbinInterface.getUnreadCount: " + e.message);
-			return 0;
-		}
+		return m_api.get_unread_entries().size;
 	}
+	catch(Error e)
+	{
+		Logger.error(@"FeedbinInterface.getUnreadCount: " + e.message);
+		return 0;
+	}
+}
 
-	public void getArticles(int count, ArticleStatus what_to_get, DateTime? since, string? feed_id_str, bool is_tag_id, GLib.Cancellable? cancellable = null)
-	requires (count >= 0)
+public void getArticles(int count, ArticleStatus what_to_get, DateTime? since, string? feed_id_str, bool is_tag_id, GLib.Cancellable? cancellable = null)
+requires (count >= 0)
+{
+	try
 	{
-		try
-		{
-			int64? feed_id = null;
-			if(!is_tag_id && feed_id_str != null)
-				feed_id = int64.parse(feed_id_str);
-			bool only_starred = what_to_get == ArticleStatus.MARKED;
+		var db = DataBase.readOnly();
+		int64? feed_id = null;
+		if(!is_tag_id && feed_id_str != null)
+			feed_id = int64.parse(feed_id_str);
+		bool only_starred = what_to_get == ArticleStatus.MARKED;
 
-			if(cancellable != null && cancellable.is_cancelled())
-				return;
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
 
-			// The Feedbin API doesn't include read/unread/starred status in the entries.json
-			// so look them up.
-			var unread_ids = m_api.get_unread_entries();
-			if(cancellable != null && cancellable.is_cancelled())
-				return;
+		// The Feedbin API doesn't include read/unread/starred status in the entries.json
+		// so look them up.
+		var unread_ids = m_api.get_unread_entries();
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
 
-			var starred_ids = m_api.get_starred_entries();
+		var starred_ids = m_api.get_starred_entries();
 
+		{
+			// Update read/unread status of existing entries
+			string search_feed_id;
+			FeedListType search_type;
+			if(feed_id == null)
 			{
-				// Update read/unread status of existing entries
-				string search_feed_id;
-				FeedListType search_type;
-				if(feed_id == null)
-				{
-					search_feed_id = FeedID.ALL.to_string();
-					search_type = FeedListType.ALL_FEEDS;
-				}
-				else if(is_tag_id)
-				{
-					search_feed_id = feed_id_str;
-					search_type = FeedListType.TAG;
-				}
-				else
-				{
-					search_feed_id = feed_id_str;
-					search_type = FeedListType.FEED;
-				}
-
-				Logger.debug(@"Checking if any articles in $search_type $search_feed_id changed state");
-				for(var offset = 0, c = 1000; ; offset += c)
-				{
-					var articles = new Gee.ArrayList<Article>();
-					var existing_articles = m_db.read_articles(search_feed_id, search_type, ArticleListState.ALL, "", c, offset);
-					if(existing_articles.size == 0)
-						break;
-
-					foreach(var article in existing_articles)
-					{
-						var id = int64.parse(article.getArticleID());
-						var marked = starred_ids.contains(id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
-						var unread = unread_ids.contains(id) ? ArticleStatus.UNREAD : ArticleStatus.READ;
-						var changed = false;
-						if(article.getMarked() != marked)
-						{
-							article.setMarked(marked);
-							changed = true;
-						}
-						if(article.getUnread() != unread)
-						{
-							article.setUnread(unread);
-							changed = true;
-						}
-						articles.add(article);
-					}
-					writeArticles(articles);
-				}
+				search_feed_id = FeedID.ALL.to_string();
+				search_type = FeedListType.ALL_FEEDS;
 			}
-
-			// Add new articles
-			for(int page = 1; ; ++page)
+			else if(is_tag_id)
 			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
+				search_feed_id = feed_id_str;
+				search_type = FeedListType.TAG;
+			}
+			else
+			{
+				search_feed_id = feed_id_str;
+				search_type = FeedListType.FEED;
+			}
 
-				var entries = m_api.get_entries(page, only_starred, since, feed_id);
-				if(entries.size == 0)
+			Logger.debug(@"Checking if any articles in $search_type $search_feed_id changed state");
+			for(var offset = 0, c = 1000; ; offset += c)
+			{
+				var articles = new Gee.ArrayList<Article>();
+				var existing_articles = db.read_articles(search_feed_id, search_type, ArticleListState.ALL, "", c, offset);
+				if(existing_articles.size == 0)
 					break;
 
-				var articles = new Gee.ArrayList<Article>();
-				foreach(var entry in entries)
+				foreach(var article in existing_articles)
 				{
-					articles.add(
-						new Article(
-							entry.id.to_string(),
-							entry.title,
-							entry.url,
-							entry.feed_id.to_string(),
-							unread_ids.contains(entry.id) ? ArticleStatus.UNREAD : ArticleStatus.READ,
-							starred_ids.contains(entry.id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-							entry.content,
-							entry.summary,
-							entry.author,
-							entry.published != null ? entry.published : entry.created_at,
-							-1,
-							null,
-							null)
-					);
+					var id = int64.parse(article.getArticleID());
+					var marked = starred_ids.contains(id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+					var unread = unread_ids.contains(id) ? ArticleStatus.UNREAD : ArticleStatus.READ;
+					var changed = false;
+					if(article.getMarked() != marked)
+					{
+						article.setMarked(marked);
+						changed = true;
+					}
+					if(article.getUnread() != unread)
+					{
+						article.setUnread(unread);
+						changed = true;
+					}
+					articles.add(article);
 				}
 				writeArticles(articles);
 			}
 		}
-		catch(Error e)
+
+		// Add new articles
+		for(int page = 1; ; ++page)
 		{
-			Logger.error(@"FeedbinInterface.getArticles: " + e.message);
+			if(cancellable != null && cancellable.is_cancelled())
+				return;
+
+			var entries = m_api.get_entries(page, only_starred, since, feed_id);
+			if(entries.size == 0)
+				break;
+
+			var articles = new Gee.ArrayList<Article>();
+			foreach(var entry in entries)
+			{
+				articles.add(
+					new Article(
+						entry.id.to_string(),
+						entry.title,
+						entry.url,
+						entry.feed_id.to_string(),
+						unread_ids.contains(entry.id) ? ArticleStatus.UNREAD : ArticleStatus.READ,
+						starred_ids.contains(entry.id) ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+						entry.content,
+						entry.summary,
+						entry.author,
+						entry.published != null ? entry.published : entry.created_at,
+						-1,
+						null,
+						null)
+					);
+			}
+			writeArticles(articles);
 		}
 	}
+	catch(Error e)
+	{
+		Logger.error(@"FeedbinInterface.getArticles: " + e.message);
+	}
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/feedbin/feedbinUtils.vala 2.7.1-1/plugins/backend/feedbin/feedbinUtils.vala
--- 2.6.1-1/plugins/backend/feedbin/feedbinUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedbin/feedbinUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,51 +15,51 @@
 
 public class FeedReader.FeedbinUtils : GLib.Object {
 
-	GLib.Settings m_settings;
-	Password m_password;
+GLib.Settings m_settings;
+Password m_password;
 
-	public FeedbinUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedbin", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.feedbin");
-
-		var password_schema =
-			new Secret.Schema("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-							  "URL", Secret.SchemaAttributeType.STRING,
-							  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, password_schema, "FeedReader: feedbin login", () => {
+public FeedbinUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedbin", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.feedbin");
+
+	var password_schema =
+		new Secret.Schema("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+		                  "URL", Secret.SchemaAttributeType.STRING,
+		                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, password_schema, "FeedReader: feedbin login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = "feedbin.com";
 			attributes["Username"] = getUser();
 			return attributes;
 		});
-	}
+}
+
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
+
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
-
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
-
-	public string getPassword(Cancellable? cancellable = null)
-	{
-		return m_password.get_password(cancellable);
-	}
-
-	public void setPassword(string password, Cancellable? cancellable = null)
-	{
-		m_password.set_password(password, cancellable);
-	}
-
-	public void resetAccount(Cancellable? cancellable = null)
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password(cancellable);
-	}
+public string getPassword(Cancellable? cancellable = null)
+{
+	return m_password.get_password(cancellable);
+}
+
+public void setPassword(string password, Cancellable? cancellable = null)
+{
+	m_password.set_password(password, cancellable);
+}
+
+public void resetAccount(Cancellable? cancellable = null)
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password(cancellable);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedbin/TestFeedbin.vala 2.7.1-1/plugins/backend/feedbin/TestFeedbin.vala
--- 2.6.1-1/plugins/backend/feedbin/TestFeedbin.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedbin/TestFeedbin.vala	2019-02-01 19:30:50.000000000 +0000
@@ -4,215 +4,215 @@ const string password_env = "FEEDBIN_TES
 
 void delete_subscription(FeedbinAPI api, string url)
 {
-    var subscriptions = api.get_subscriptions();
-    foreach(var subscription in subscriptions)
-    {
-        if(subscription.feed_url != url)
-            continue;
-        api.delete_subscription(subscription.id);
-        break;
-    }
+	var subscriptions = api.get_subscriptions();
+	foreach(var subscription in subscriptions)
+	{
+		if(subscription.feed_url != url)
+			continue;
+		api.delete_subscription(subscription.id);
+		break;
+	}
 }
 
 void add_login_tests(string host)
 {
-    string? username = Environment.get_variable(user_env);
-    string? password = Environment.get_variable(password_env);
-    if(username == null || password == null)
+	string? username = Environment.get_variable(user_env);
+	string? password = Environment.get_variable(password_env);
+	if(username == null || password == null)
 		return;
 
 	// Stick a random number at the end of Feed URL's to ensure that they're
 	// unique, even if we run two tests against the same account
 	uint nonce = Random.next_int();
 
-    Test.add_data_func ("/feedbinapi/login", () => {
+	Test.add_data_func ("/feedbinapi/login", () => {
+
+		var api = new FeedbinAPI(username, password, null, host);
+		assert(api.login());
+
+		api = new FeedbinAPI("wrong", "password", null, host);
+		assert(!api.login());
+
+		api.username = username;
+		assert(!api.login());
+
+		api.password = password;
+		assert(api.login());
+	});
+
+	Test.add_data_func ("/feedbinapi/subscription", () => {
+		if(username == null || password == null)
+		{
+		        Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+		        return;
+		}
+
+		var api = new FeedbinAPI(username, password, null, host);
+
+		var url = "https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-subscribe-$(nonce)";
+		delete_subscription(api, url);
+
+		var subscription = api.add_subscription(url);
+		assert(subscription.id != 0);
+
+		{
+		        var got_subscription = api.get_subscription(subscription.id);
+		        assert(got_subscription.id == subscription.id);
+		}
+
+		bool found_subscription = false;
+		foreach(var got_subscription in api.get_subscriptions())
+		{
+		        if(got_subscription.id == subscription.id)
+		        {
+		                assert(got_subscription.feed_id == subscription.feed_id);
+		                assert(got_subscription.feed_url == subscription.feed_url);
+		                assert(got_subscription.site_url == subscription.site_url);
+		                assert(got_subscription.title == subscription.title);
+		                found_subscription = true;
+			}
+		}
+		assert(found_subscription);
 
-        var api = new FeedbinAPI(username, password, null, host);
-        assert(api.login());
+		string title = "Rename test";
+		api.rename_subscription(subscription.id, title);
+		var renamed_subscription = api.get_subscription(subscription.id);
+		assert(renamed_subscription.title == title);
 
-        api = new FeedbinAPI("wrong", "password", null, host);
-        assert(!api.login());
+		api.delete_subscription(subscription.id);
+		foreach(var got_subscription in api.get_subscriptions())
+		{
+		        assert(got_subscription.id != subscription.id);
+		        assert(got_subscription.feed_url != url);
+		}
+	});
 
-        api.username = username;
-        assert(!api.login());
-
-        api.password = password;
-        assert(api.login());
-    });
-
-    Test.add_data_func ("/feedbinapi/subscription", () => {
-        if(username == null || password == null)
-        {
-            Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
-            return;
-        }
-
-        var api = new FeedbinAPI(username, password, null, host);
-
-        var url = "https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-subscribe-$(nonce)";
-        delete_subscription(api, url);
-
-        var subscription = api.add_subscription(url);
-        assert(subscription.id != 0);
-
-		{
-			var got_subscription = api.get_subscription(subscription.id);
-			assert(got_subscription.id == subscription.id);
-		}
-
-        bool found_subscription = false;
-        foreach(var got_subscription in api.get_subscriptions())
-        {
-            if(got_subscription.id == subscription.id)
-            {
-				assert(got_subscription.feed_id == subscription.feed_id);
-				assert(got_subscription.feed_url == subscription.feed_url);
-				assert(got_subscription.site_url == subscription.site_url);
-				assert(got_subscription.title == subscription.title);
-                found_subscription = true;
-            }
-        }
-        assert(found_subscription);
-
-        string title = "Rename test";
-        api.rename_subscription(subscription.id, title);
-        var renamed_subscription = api.get_subscription(subscription.id);
-        assert(renamed_subscription.title == title);
-
-        api.delete_subscription(subscription.id);
-        foreach(var got_subscription in api.get_subscriptions())
-        {
-            assert(got_subscription.id != subscription.id);
-            assert(got_subscription.feed_url != url);
-        }
-    });
-
-    Test.add_data_func ("/feedbinapi/taggings", () => {
-        if(username == null || password == null)
-        {
-            Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
-            return;
-        }
-
-        var api = new FeedbinAPI(username, password, null, host);
-
-        var url = @"https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-taggings-$(nonce)";
-        delete_subscription(api, url);
-
-        var subscription = api.add_subscription(url);
-
-        // The subscription is new so it shouldn't have any taggings
-        var taggings = api.get_taggings();
-        foreach(var tagging in taggings)
-        {
-            assert(tagging.feed_id != subscription.feed_id);
-        }
-
-        string category = "Taggings Test";
-        api.add_tagging(subscription.feed_id, category);
-
-        // Check taggings
-        int64? tagging_id = null;
-        foreach(var tagging in api.get_taggings())
-        {
-            if(tagging.feed_id == subscription.feed_id)
-            {
-                assert(tagging.name == category);
-                tagging_id = tagging.id;
-                break;
-            }
-        }
-        assert(tagging_id != null);
-
-        // Delete the tag and verify that it's gone
-        api.delete_tagging(tagging_id);
-        foreach(var tagging in api.get_taggings())
-        {
-            assert(tagging.feed_id != subscription.feed_id);
+	Test.add_data_func ("/feedbinapi/taggings", () => {
+		if(username == null || password == null)
+		{
+		        Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+		        return;
+		}
+
+		var api = new FeedbinAPI(username, password, null, host);
+
+		var url = @"https://www.brendanlong.com/feeds/all.atom.xml?feedreader-test-taggings-$(nonce)";
+		delete_subscription(api, url);
+
+		var subscription = api.add_subscription(url);
+
+		// The subscription is new so it shouldn't have any taggings
+		var taggings = api.get_taggings();
+		foreach(var tagging in taggings)
+		{
+		        assert(tagging.feed_id != subscription.feed_id);
+		}
+
+		string category = "Taggings Test";
+		api.add_tagging(subscription.feed_id, category);
+
+		// Check taggings
+		int64? tagging_id = null;
+		foreach(var tagging in api.get_taggings())
+		{
+		        if(tagging.feed_id == subscription.feed_id)
+		        {
+		                assert(tagging.name == category);
+		                tagging_id = tagging.id;
+		                break;
+			}
+		}
+		assert(tagging_id != null);
+
+		// Delete the tag and verify that it's gone
+		api.delete_tagging(tagging_id);
+		foreach(var tagging in api.get_taggings())
+		{
+		        assert(tagging.feed_id != subscription.feed_id);
 		}
 
 		// cleanup
 		api.delete_subscription(subscription.id);
-    });
+	});
 
-    Test.add_data_func ("/feedbinapi/entries", () => {
-        if(username == null || password == null)
-        {
-            Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
-            return;
-        }
+	Test.add_data_func ("/feedbinapi/entries", () => {
+		if(username == null || password == null)
+		{
+		        Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+		        return;
+		}
 
-        var api = new FeedbinAPI(username, password, null, host);
+		var api = new FeedbinAPI(username, password, null, host);
 
 		// Note: This one shouldn't be deleted or recreated, since we want the entries to be available
-        var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-entries";
+		var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-entries";
 
-        var subscription = api.add_subscription(url);
+		var subscription = api.add_subscription(url);
 
-        /* FIXME: Figure out why this next line is failing
-        var entries = api.get_entries(1, false, null, subscription.feed_id);
-        foreach(var entry in entries)
-        {
-            assert(entry.feed_id == subscription.feed_id);
-        }
-
-		assert(entries.size > 0);
-		int i = Random.int_range(0, entries.size);
-        var entry = entries.to_array()[i];
-        var entry_ids = new Gee.ArrayList<int64?>();
-        entry_ids.add(entry.id);
-
-        // read status
-        api.set_entries_read(entry_ids, true);
-        var unread_entries = api.get_unread_entries();
-        assert(!unread_entries.contains(entry.id));
-
-        api.set_entries_read(entry_ids, false);
-        unread_entries = api.get_unread_entries();
-        assert(unread_entries.contains(entry.id));
-
-        api.set_entries_read(entry_ids, true);
-        unread_entries = api.get_unread_entries();
-        assert(!unread_entries.contains(entry.id));
-
-        // starred status
-        api.set_entries_starred(entry_ids, true);
-        var starred_entries = api.get_starred_entries();
-        assert(starred_entries.contains(entry.id));
-
-        api.set_entries_starred(entry_ids, false);
-        starred_entries = api.get_starred_entries();
-        assert(!starred_entries.contains(entry.id));
-
-        api.set_entries_starred(entry_ids, true);
-        starred_entries = api.get_starred_entries();
-        assert(starred_entries.contains(entry.id));
-        */
-    });
-
-    Test.add_data_func ("/feedbinapi/favicons", () => {
-        if(username == null || password == null)
-        {
-            Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
-            return;
+		/* FIXME: Figure out why this next line is failing
+		   var entries = api.get_entries(1, false, null, subscription.feed_id);
+		   foreach(var entry in entries)
+		   {
+		    assert(entry.feed_id == subscription.feed_id);
+		   }
+
+		        assert(entries.size > 0);
+		        int i = Random.int_range(0, entries.size);
+		   var entry = entries.to_array()[i];
+		   var entry_ids = new Gee.ArrayList<int64?>();
+		   entry_ids.add(entry.id);
+
+		   // read status
+		   api.set_entries_read(entry_ids, true);
+		   var unread_entries = api.get_unread_entries();
+		   assert(!unread_entries.contains(entry.id));
+
+		   api.set_entries_read(entry_ids, false);
+		   unread_entries = api.get_unread_entries();
+		   assert(unread_entries.contains(entry.id));
+
+		   api.set_entries_read(entry_ids, true);
+		   unread_entries = api.get_unread_entries();
+		   assert(!unread_entries.contains(entry.id));
+
+		   // starred status
+		   api.set_entries_starred(entry_ids, true);
+		   var starred_entries = api.get_starred_entries();
+		   assert(starred_entries.contains(entry.id));
+
+		   api.set_entries_starred(entry_ids, false);
+		   starred_entries = api.get_starred_entries();
+		   assert(!starred_entries.contains(entry.id));
+
+		   api.set_entries_starred(entry_ids, true);
+		   starred_entries = api.get_starred_entries();
+		   assert(starred_entries.contains(entry.id));
+		 */
+	});
+
+	Test.add_data_func ("/feedbinapi/favicons", () => {
+		if(username == null || password == null)
+		{
+		        Test.skip(@"Need $user_env and $password_env set to run Feedbin tests");
+		        return;
 		}
 
-        var api = new FeedbinAPI(username, password, null, host);
+		var api = new FeedbinAPI(username, password, null, host);
 
 		// Note: This one shouldn't be deleted or recreated, since we want the entries to be available
-        var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-favicons";
+		var url = "https://www.brendanlong.com/feeds/all.atom.xml?feed-reader-test-favicons";
 
 		var subscription = api.add_subscription(url);
 		var favicons = api.get_favicons();
 		bool found_favicon = false;
 		foreach(var i in favicons.entries)
 		{
-			if(i.key != "www.brendanlong.com")
+		        if(i.key != "www.brendanlong.com")
 				continue;
-			// Don't check the contents of the Favicon because Feedbin doesn't
-			// seem to neccessarily return the exact icon we gave it
-			found_favicon = true;
-			break;
+		        // Don't check the contents of the Favicon because Feedbin doesn't
+		        // seem to neccessarily return the exact icon we gave it
+		        found_favicon = true;
+		        break;
 		}
 		// FIXME: We don't download icons on the test server because favicon downloading
 		// is handled by a different service
@@ -228,19 +228,19 @@ void main(string[] args)
 	if(host == null)
 		host = "https://api.feedbin.com";
 
-    // Tests that don't need a login
-    Test.add_data_func ("/feedbinapi/construct", () => {
-        var api = new FeedbinAPI("user", "password", null, host);
-        assert(api != null);
-    });
+	// Tests that don't need a login
+	Test.add_data_func ("/feedbinapi/construct", () => {
+		var api = new FeedbinAPI("user", "password", null, host);
+		assert(api != null);
+	});
 
-    Test.add_data_func ("/feedbinapi/bad login", () => {
-        var api = new FeedbinAPI("user", "password", null, host);
+	Test.add_data_func ("/feedbinapi/bad login", () => {
+		var api = new FeedbinAPI("user", "password", null, host);
 
-        assert(!api.login());
-    });
+		assert(!api.login());
+	});
 
-    add_login_tests(host);
+	add_login_tests(host);
 
-    Test.run ();
+	Test.run ();
 }
diff -pruN 2.6.1-1/plugins/backend/feedhq/feedhqAPI.vala 2.7.1-1/plugins/backend/feedhq/feedhqAPI.vala
--- 2.6.1-1/plugins/backend/feedhq/feedhqAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedhq/feedhqAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,458 +15,458 @@
 
 public class FeedReader.FeedHQAPI : GLib.Object {
 
-	public enum FeedHQSubscriptionAction {
-		EDIT,
-		SUBSCRIBE,
-		UNSUBSCRIBE
-	}
+public enum FeedHQSubscriptionAction {
+	EDIT,
+	SUBSCRIBE,
+	UNSUBSCRIBE
+}
+
+private FeedHQConnection m_connection;
+private FeedHQUtils m_utils;
+private string m_userID;
+
+public FeedHQAPI (FeedHQUtils utils)
+{
+	m_utils = utils;
+	m_connection = new FeedHQConnection(m_utils);
+}
+
 
-	private FeedHQConnection m_connection;
-	private FeedHQUtils m_utils;
-	private string m_userID;
+public LoginResponse login()
+{
+	Logger.debug("FeedHQ Login");
 
-	public FeedHQAPI (FeedHQUtils utils)
+	if(m_utils.getAccessToken() == "")
 	{
-		m_utils = utils;
-		m_connection = new FeedHQConnection(m_utils);
+		var result = m_connection.getToken();
+		if(m_connection.postToken() && getUserID())
+			return result;
 	}
+	else if(getUserID())
+		return LoginResponse.SUCCESS;
 
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-	public LoginResponse login()
-	{
-		Logger.debug("FeedHQ Login");
+public bool ping()
+{
+	return Utils.ping("https://feedhq.org");
+}
 
-		if(m_utils.getAccessToken() == "")
-		{
-			var result = m_connection.getToken();
-			if(m_connection.postToken() && getUserID())
-				return result;
-		}
-		else if(getUserID())
-			return LoginResponse.SUCCESS;
+private bool getUserID()
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("user-info?" + msg.get());
 
-		return LoginResponse.UNKNOWN_ERROR;
-	}
+	if(response.status != 200)
+		return false;
 
-	public bool ping()
-	{
-		return Utils.ping("https://feedhq.org");
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e) {
+		Logger.error("getUserID: Could not load message response");
+		Logger.error(e.message);
+		return false;
 	}
+	var root = parser.get_root().get_object();
 
-	private bool getUserID()
+	if(root.has_member("userId"))
 	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("user-info?" + msg.get());
+		m_userID = root.get_string_member("userId");
+		m_utils.setUserID(m_userID);
+		Logger.info("FeedHQ: userID = " + m_userID);
 
-		if(response.status != 200)
-			return false;
+		if(root.has_member("userName"))
+			m_utils.setUser(root.get_string_member("userName"));
+		return true;
+	}
 
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getUserID: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
+	return false;
+}
 
-		if(root.has_member("userId"))
-		{
-			m_userID = root.get_string_member("userId");
-			m_utils.setUserID(m_userID);
-			Logger.info("FeedHQ: userID = " + m_userID);
-
-			if(root.has_member("userName"))
-				m_utils.setUser(root.get_string_member("userName"));
-			return true;
-		}
+public bool getFeeds(Gee.List<Feed> feeds)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("subscription/list?" + msg.get());
 
+	if(response.status != 200)
 		return false;
-	}
 
-	public bool getFeeds(Gee.List<Feed> feeds)
+	var parser = new Json.Parser();
+	try
 	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("subscription/list?" + msg.get());
-
-		if(response.status != 200)
-			return false;
-
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getFeeds: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("subscriptions");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getFeeds: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("subscriptions");
+	uint length = array.get_length();
+
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+
+		string feedID = object.get_string_member("id");
+		string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+		string? icon_url = object.has_member("iconUrl") ? "https:" + object.get_string_member("iconUrl") : null;
+
+		uint catCount = object.get_array_member("categories").get_length();
+
+		var categories = new Gee.ArrayList<string>();
+		for(uint j = 0; j < catCount; ++j)
+		{
+			categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
+		}
+		feeds.add(
+			new Feed(
+				feedID,
+				object.get_string_member("title"),
+				url,
+				0,
+				categories,
+				icon_url
+				)
+			);
+	}
+	return true;
+}
 
-			string feedID = object.get_string_member("id");
-			string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
-			string? icon_url = object.has_member("iconUrl") ? "https:" + object.get_string_member("iconUrl") : null;
+public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("tag/list?" + msg.get());
 
-			uint catCount = object.get_array_member("categories").get_length();
+	if(response.status != 200)
+		return false;
 
-			var categories = new Gee.ArrayList<string>();
-			for(uint j = 0; j < catCount; ++j)
-			{
-				categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
-			}
-			feeds.add(
-				new Feed(
-						feedID,
-						object.get_string_member("title"),
-						url,
-						0,
-						categories,
-						icon_url
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("tags");
+	uint length = array.get_length();
+	int orderID = 0;
+
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		int start = id.last_index_of_char('/') + 1;
+		string title = id.substring(start);
+
+		if(id.contains("/label/"))
+		{
+			categories.add(
+				new Category(
+					id,
+					title,
+					0,
+					orderID,
+					CategoryID.MASTER.to_string(),
+					1
 					)
-			);
+				);
+			++orderID;
 		}
-		return true;
 	}
+	return true;
+}
 
-	public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("tag/list?" + msg.get());
 
-		if(response.status != 200)
-			return false;
+public int getTotalUnread()
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	var response = m_connection.send_get_request("unread-count?" + msg.get());
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("tags");
-		uint length = array.get_length();
-		int orderID = 0;
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e) {
+		Logger.error("getTotalUnread: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			int start = id.last_index_of_char('/') + 1;
-			string title = id.substring(start);
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("unreadcounts");
+	uint length = array.get_length();
+	int count = 0;
 
-			if(id.contains("/label/"))
-			{
-					categories.add(
-						new Category(
-							id,
-							title,
-							0,
-							orderID,
-							CategoryID.MASTER.to_string(),
-							1
-						)
-					);
-				++orderID;
-			}
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		if(object.get_string_member("id").has_prefix("feed/"))
+		{
+			count += (int)object.get_int_member("count");
 		}
-		return true;
+
 	}
 
+	Logger.debug("getTotalUnread %i".printf(count));
+	return count;
+}
 
-	public int getTotalUnread()
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		var response = m_connection.send_get_request("unread-count?" + msg.get());
-
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getTotalUnread: Could not load message response");
-			Logger.error(e.message);
-		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("unreadcounts");
-		uint length = array.get_length();
-		int count = 0;
+public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	msg.add("n", count.to_string());
+	msg.add("s", "user/-/state/com.google/read");
+	if(continuation != null)
+		msg.add("c", continuation);
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			if(object.get_string_member("id").has_prefix("feed/"))
-			{
-				count += (int)object.get_int_member("count");
-			}
+	var response = m_connection.send_get_request("stream/items/ids?" + msg.get());
 
-		}
+	if(response.status != 200)
+		return null;
 
-		Logger.debug("getTotalUnread %i".printf(count));
-		return count;
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("updateArticles: Could not load message response");
+		Logger.error(e.message);
 	}
 
+	var root = parser.get_root().get_object();
 
-	public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+	if(!root.has_member("itemRefs"))
 	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		msg.add("n", count.to_string());
-		msg.add("s", "user/-/state/com.google/read");
-		if(continuation != null)
-			msg.add("c", continuation);
-
-		var response = m_connection.send_get_request("stream/items/ids?" + msg.get());
+		Logger.error("updateArticles: wrong response?");
+		return null;
+	}
 
-		if(response.status != 200)
-			return null;
+	var array = root.get_array_member("itemRefs");
+	uint length = array.get_length();
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("updateArticles: Could not load message response");
-			Logger.error(e.message);
-		}
+	for(uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		ids.add(object.get_string_member("id"));
+	}
 
-		var root = parser.get_root().get_object();
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-		if(!root.has_member("itemRefs"))
-		{
-			Logger.error("updateArticles: wrong response?");
-			return null;
-		}
+	return null;
+}
 
-		var array = root.get_array_member("itemRefs");
-		uint length = array.get_length();
+public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	msg.add("n", count.to_string());
+
+	if(whatToGet == ArticleStatus.UNREAD)
+		msg.add("xt", "user/-/state/com.google/read");
+	if(whatToGet == ArticleStatus.READ)
+		msg.add("s", "user/-/state/com.google/read");
+	else if(whatToGet == ArticleStatus.MARKED)
+		msg.add("s", "user/-/state/com.google/starred");
 
-		for(uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			ids.add(object.get_string_member("id"));
-		}
+	if(continuation != null)
+		msg.add("c", continuation);
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
+	string api_endpoint = "stream/contents";
+	if(feed_id != null)
+		api_endpoint += "/" + feed_id;
+	else if(tagID != null)
+		api_endpoint += "/" + tagID;
+	var response = m_connection.send_get_request(api_endpoint + "?" + msg.get());
 
+	if(response.status != 200)
 		return null;
+
+	Logger.debug(api_endpoint + "?" + msg.get());
+
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
 	}
+	catch (Error e) {
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+	}
+
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("items");
+	uint length = array.get_length();
 
-	public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+	for (uint i = 0; i < length; i++)
 	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		msg.add("n", count.to_string());
-
-		if(whatToGet == ArticleStatus.UNREAD)
-			msg.add("xt", "user/-/state/com.google/read");
-		if(whatToGet == ArticleStatus.READ)
-			msg.add("s", "user/-/state/com.google/read");
-		else if(whatToGet == ArticleStatus.MARKED)
-			msg.add("s", "user/-/state/com.google/starred");
-
-		if(continuation != null)
-			msg.add("c", continuation);
-
-		string api_endpoint = "stream/contents";
-		if(feed_id != null)
-			api_endpoint += "/" + feed_id;
-		else if(tagID != null)
-			api_endpoint += "/" + tagID;
-		var response = m_connection.send_get_request(api_endpoint + "?" + msg.get());
-
-		if(response.status != 200)
-			return null;
-
-		Logger.debug(api_endpoint + "?" + msg.get());
-
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
-		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("items");
-		uint length = array.get_length();
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		bool marked = false;
+		bool read = false;
+		var cats = object.get_array_member("categories");
+		uint cat_length = cats.get_length();
 
-		for (uint i = 0; i < length; i++)
+		var tags = new Gee.ArrayList<string>();
+		for (uint j = 0; j < cat_length; j++)
 		{
+			string cat = cats.get_string_element(j);
+			if(cat.has_suffix("com.google/starred"))
+				marked = true;
+			else if(cat.has_suffix("com.google/read"))
+				read = true;
+			else if(cat.contains("/label/"))
+				tags.add(cat);
+		}
 
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			bool marked = false;
-			bool read = false;
-			var cats = object.get_array_member("categories");
-			uint cat_length = cats.get_length();
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
+		{
+			var attachments = object.get_array_member("enclosure");
 
-			var tags = new Gee.ArrayList<string>();
-			for (uint j = 0; j < cat_length; j++)
-			{
-				string cat = cats.get_string_element(j);
-				if(cat.has_suffix("com.google/starred"))
-					marked = true;
-				else if(cat.has_suffix("com.google/read"))
-					read = true;
-				else if(cat.contains("/label/"))
-					tags.add(cat);
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
-
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(attachment.get_string_member("type")))
+				var attachment = attachments.get_object_element(j);
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(attachment.get_string_member("type")))
 					);
-				}
 			}
-
-			articles.add(new Article(
-									id,
-									object.get_string_member("title"),
-									object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
-									object.get_object_member("origin").get_string_member("streamId"),
-									read ? ArticleStatus.READ : ArticleStatus.UNREAD,
-									marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-									null,
-									null,
-									null,
-									new DateTime.from_unix_local(object.get_int_member("published")),
-									-1,
-									tags,
-									enclosures
-							)
-						);
 		}
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
-
-		return null;
+		articles.add(new Article(
+				     id,
+				     object.get_string_member("title"),
+				     object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+				     object.get_object_member("origin").get_string_member("streamId"),
+				     read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+				     marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				     null,
+				     null,
+				     null,
+				     new DateTime.from_unix_local(object.get_int_member("published")),
+				     -1,
+				     tags,
+				     enclosures
+				     )
+		             );
 	}
 
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-	public void edidTag(string articleID, string tagID, bool add = true)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
+	return null;
+}
 
-		if(add)
-			msg.add("a", tagID);
-		else
-			msg.add("r", tagID);
 
-		msg.add("i", articleID);
-		m_connection.send_post_request("edit-tag", msg.get());
-	}
+public void edidTag(string articleID, string tagID, bool add = true)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+
+	if(add)
+		msg.add("a", tagID);
+	else
+		msg.add("r", tagID);
 
-	public void markAsRead(string streamID)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		msg.add("s", streamID);
-		msg.add("ts", "%i000000".printf(Settings.state().get_int("last-sync")));
-		Logger.debug(msg.get());
-		m_connection.send_post_request("mark-all-as-read", msg.get());
-	}
+	msg.add("i", articleID);
+	m_connection.send_post_request("edit-tag", msg.get());
+}
 
-	public string composeTagID(string tagName)
-	{
-		return "user/%s/label/%s".printf(m_userID, tagName);
-	}
+public void markAsRead(string streamID)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	msg.add("s", streamID);
+	msg.add("ts", "%i000000".printf(Settings.state().get_int("last-sync")));
+	Logger.debug(msg.get());
+	m_connection.send_post_request("mark-all-as-read", msg.get());
+}
 
-	public void deleteTag(string tagID)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		msg.add("s", tagID);
-		m_connection.send_post_request("disable-tag", msg.get());
-	}
+public string composeTagID(string tagName)
+{
+	return "user/%s/label/%s".printf(m_userID, tagName);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
-		msg.add("s", tagID);
-		msg.add("dest", composeTagID(title));
-		m_connection.send_post_request("rename-tag", msg.get());
-	}
+public void deleteTag(string tagID)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	msg.add("s", tagID);
+	m_connection.send_post_request("disable-tag", msg.get());
+}
 
-	public bool editSubscription(FeedHQSubscriptionAction action, string[] feedID, string? title = null, string? add = null, string? remove = null)
-	{
-		var msg = new feedhqMessage();
-		msg.add("output", "json");
+public void renameTag(string tagID, string title)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
+	msg.add("s", tagID);
+	msg.add("dest", composeTagID(title));
+	m_connection.send_post_request("rename-tag", msg.get());
+}
 
-		switch(action)
-		{
-			case FeedHQSubscriptionAction.EDIT:
-				msg.add("ac", "edit");
-				break;
-			case FeedHQSubscriptionAction.SUBSCRIBE:
-				msg.add("ac", "subscribe");
-				break;
-			case FeedHQSubscriptionAction.UNSUBSCRIBE:
-				msg.add("ac", "unsubscribe");
-				break;
-		}
+public bool editSubscription(FeedHQSubscriptionAction action, string[] feedID, string? title = null, string? add = null, string? remove = null)
+{
+	var msg = new feedhqMessage();
+	msg.add("output", "json");
 
-		foreach(string s in feedID)
-			msg.add("s", s);
+	switch(action)
+	{
+	case FeedHQSubscriptionAction.EDIT:
+		msg.add("ac", "edit");
+		break;
+	case FeedHQSubscriptionAction.SUBSCRIBE:
+		msg.add("ac", "subscribe");
+		break;
+	case FeedHQSubscriptionAction.UNSUBSCRIBE:
+		msg.add("ac", "unsubscribe");
+		break;
+	}
 
-		if(title != null)
-			msg.add("t", title);
+	foreach(string s in feedID)
+		msg.add("s", s);
 
-		if(add != null && add != "")
-			msg.add("a", add);
+	if(title != null)
+		msg.add("t", title);
 
+	if(add != null && add != "")
+		msg.add("a", add);
 
-		if(remove != null && remove != "")
-			msg.add("r", remove);
 
-		Logger.debug(msg.get());
-		var response = m_connection.send_post_request("subscription/edit", msg.get());
+	if(remove != null && remove != "")
+		msg.add("r", remove);
 
-		return response.status == 200;
-	}
+	Logger.debug(msg.get());
+	var response = m_connection.send_post_request("subscription/edit", msg.get());
 
-	public void import(string opml)
-	{
-		var response = m_connection.send_post_request("subscription/import", opml);
-		Logger.debug("feedhq.import: " + response.data);
-	}
+	return response.status == 200;
+}
+
+public void import(string opml)
+{
+	var response = m_connection.send_post_request("subscription/import", opml);
+	Logger.debug("feedhq.import: " + response.data);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedhq/feedhqConnection.vala 2.7.1-1/plugins/backend/feedhq/feedhqConnection.vala
--- 2.6.1-1/plugins/backend/feedhq/feedhqConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedhq/feedhqConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,152 +14,152 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 public class FeedReader.FeedHQConnection {
-	private string m_username;
-	private string m_api_code;
-	private string m_passwd;
-	private FeedHQUtils m_utils;
-	private Soup.Session m_session;
-
-	public FeedHQConnection(FeedHQUtils utils)
-	{
-		m_utils = utils;
-		m_username = m_utils.getUser();
-		m_api_code = m_utils.getAccessToken();
-		m_passwd = m_utils.getPasswd();
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-	}
+private string m_username;
+private string m_api_code;
+private string m_passwd;
+private FeedHQUtils m_utils;
+private Soup.Session m_session;
+
+public FeedHQConnection(FeedHQUtils utils)
+{
+	m_utils = utils;
+	m_username = m_utils.getUser();
+	m_api_code = m_utils.getAccessToken();
+	m_passwd = m_utils.getPasswd();
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+}
 
-	public LoginResponse getToken()
-	{
-		Logger.debug("FeedHQ Connection: getToken()");
+public LoginResponse getToken()
+{
+	Logger.debug("FeedHQ Connection: getToken()");
+
+	if(m_username == "" && m_passwd == "")
+		return LoginResponse.ALL_EMPTY;
+	if(m_username == "")
+		return LoginResponse.MISSING_USER;
+	if(m_passwd == "")
+		return LoginResponse.MISSING_PASSWD;
+
+	var message = new Soup.Message("POST", "https://feedhq.org/accounts/ClientLogin");
+	string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
+	string response = (string)message.response_body.flatten().data;
+	try{
 
-		if(m_username == "" && m_passwd == "")
-			return LoginResponse.ALL_EMPTY;
-		if(m_username == "")
-			return LoginResponse.MISSING_USER;
-		if(m_passwd == "")
-			return LoginResponse.MISSING_PASSWD;
-
-		var message = new Soup.Message("POST", "https://feedhq.org/accounts/ClientLogin");
-		string message_string = "Email=" + m_username + "&Passwd=" + m_passwd;
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
-		string response = (string)message.response_body.flatten().data;
-		try{
-
-			var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
-			if(regex.match(response))
-			{
-				string split = regex.replace(response, -1,0,"");
-				Logger.debug("FeedHQ Authcode : " + split);
-				m_utils.setAccessToken(split.strip());
-				return LoginResponse.SUCCESS;
-			}
-			else
-			{
-				Logger.debug(response);
-				return LoginResponse.WRONG_LOGIN;
-			}
+		var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+		if(regex.match(response))
+		{
+			string split = regex.replace(response, -1,0,"");
+			Logger.debug("FeedHQ Authcode : " + split);
+			m_utils.setAccessToken(split.strip());
+			return LoginResponse.SUCCESS;
 		}
-		catch(Error e)
+		else
 		{
-			Logger.error("FeedHQConnection - getToken: Could not load message response");
-			Logger.error(e.message);
-			return LoginResponse.UNKNOWN_ERROR;
+			Logger.debug(response);
+			return LoginResponse.WRONG_LOGIN;
 		}
 	}
-
-
-	public bool postToken()
+	catch(Error e)
 	{
-		Logger.debug("FeedHQ Connection: postToken()");
+		Logger.error("FeedHQConnection - getToken: Could not load message response");
+		Logger.error(e.message);
+		return LoginResponse.UNKNOWN_ERROR;
+	}
+}
 
-		var message = new Soup.Message("GET", FeedHQSecret.base_uri + "token?output=json");
 
-		string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", oldauth);
-		m_session.send_message(message);
+public bool postToken()
+{
+	Logger.debug("FeedHQ Connection: postToken()");
 
-		if(message.status_code != 200)
-		{
-			Logger.debug("FeedHQ post token failed");
-			return false;
-		}
-
-		string response = (string)message.response_body.data;
-		Logger.debug("FeedHQ post token : " + response);
-		m_utils.setPostToken(response);
+	var message = new Soup.Message("GET", FeedHQSecret.base_uri + "token?output=json");
 
-		return true;
+	string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", oldauth);
+	m_session.send_message(message);
 
-	}
-	public Response send_get_request(string path, string? message_string = null)
+	if(message.status_code != 200)
 	{
-		return send_request(path, "GET", message_string);
+		Logger.debug("FeedHQ post token failed");
+		return false;
 	}
 
-	public Response send_post_request(string path, string? message_string = null)
-	{
-		return send_request(path, "POST", message_string);
-	}
+	string response = (string)message.response_body.data;
+	Logger.debug("FeedHQ post token : " + response);
+	m_utils.setPostToken(response);
 
+	return true;
 
+}
+public Response send_get_request(string path, string? message_string = null)
+{
+	return send_request(path, "GET", message_string);
+}
 
-	private Response send_request(string path, string type, string? message_string = null)
-	{
-		var message = new Soup.Message(type, FeedHQSecret.base_uri + path);
+public Response send_post_request(string path, string? message_string = null)
+{
+	return send_request(path, "POST", message_string);
+}
 
-		string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", oldauth);
-		var message_string_post = message_string + "&T=" + m_utils.getPostToken();
-		if(message_string != null)
-			message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string_post.data);
 
-		m_session.send_message(message);
 
-		if(message.status_code != 200)
-		{
-			Logger.warning(@"feedHQConnection: message unexpected response - $message_string");
-		}
+private Response send_request(string path, string type, string? message_string = null)
+{
+	var message = new Soup.Message(type, FeedHQSecret.base_uri + path);
 
-		if((uint)message.status_code == 401)
-		{
-			Logger.debug("FeedHQ Post Token Expired");
-			postToken();
-			return send_request(path, type, message_string);
-		}
+	string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", oldauth);
+	var message_string_post = message_string + "&T=" + m_utils.getPostToken();
+	if(message_string != null)
+		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string_post.data);
+
+	m_session.send_message(message);
+
+	if(message.status_code != 200)
+	{
+		Logger.warning(@"feedHQConnection: message unexpected response - $message_string");
+	}
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
+	if((uint)message.status_code == 401)
+	{
+		Logger.debug("FeedHQ Post Token Expired");
+		postToken();
+		return send_request(path, type, message_string);
 	}
 
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
 }
 
+}
 
-public class FeedReader.feedhqMessage {
 
-	string request = "";
+public class FeedReader.feedhqMessage {
 
-	public feedhqMessage()
-	{
+string request = "";
 
-	}
+public feedhqMessage()
+{
 
-	public void add(string parameter, string val)
-	{
-		if(request != "")
-			request += "&";
+}
 
-		request += parameter;
-		request += "=";
-		request += GLib.Uri.escape_string(val);
-	}
+public void add(string parameter, string val)
+{
+	if(request != "")
+		request += "&";
+
+	request += parameter;
+	request += "=";
+	request += GLib.Uri.escape_string(val);
+}
 
-	public string get()
-	{
-		return request;
-	}
+public string get()
+{
+	return request;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedhq/feedhqInterface.vala 2.7.1-1/plugins/backend/feedhq/feedhqInterface.vala
--- 2.6.1-1/plugins/backend/feedhq/feedhqInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedhq/feedhqInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,428 +15,425 @@
 
 public class FeedReader.FeedHQInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private FeedHQAPI m_api;
-	private FeedHQUtils m_utils;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
-
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new FeedHQUtils(settings_backend, secrets);
-		m_api = new FeedHQAPI(m_utils);
-	}
+private FeedHQAPI m_api;
+private FeedHQUtils m_utils;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new FeedHQUtils(settings_backend, secrets);
+	m_api = new FeedHQAPI(m_utils);
+}
 
-	public string getWebsite()
-	{
-		return "https://feedhq.org/";
-	}
+public string getWebsite()
+{
+	return "https://feedhq.org/";
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID);
+}
 
-	public string getID()
-	{
-		return "feedhq";
-	}
+public string getID()
+{
+	return "feedhq";
+}
 
-	public string iconName()
-	{
-		return "feed-service-feedhq";
-	}
+public string iconName()
+{
+	return "feed-service-feedhq";
+}
 
-	public string serviceName()
-	{
-		return "FeedHQ";
-	}
+public string serviceName()
+{
+	return "FeedHQ";
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public Gtk.Box? getWidget()
-	{
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
+public Gtk.Box? getWidget()
+{
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_userEntry.activate.connect(() => { tryLogin(); });
+	m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+	m_passwordEntry.set_invisible_char('*');
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(user_label, 0, 0, 1, 1);
+	grid.attach(m_userEntry, 1, 0, 1, 1);
+	grid.attach(password_label, 0, 1, 1, 1);
+	grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-feedhq", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
 
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
+	return box;
+}
 
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_userEntry.activate.connect(() => { tryLogin(); });
-		m_passwordEntry.activate.connect(() => { tryLogin(); });
-
-		m_passwordEntry.set_invisible_char('*');
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(user_label, 0, 0, 1, 1);
-		grid.attach(m_userEntry, 1, 0, 1, 1);
-		grid.attach(password_label, 0, 1, 1, 1);
-		grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-feedhq", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to FeedHQ and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
+public void showHtAccess()
+{
 
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+}
 
-		return box;
-	}
+public void writeData()
+{
+	m_utils.setUser(m_userEntry.get_text());
+	m_utils.setPassword(m_passwordEntry.get_text());
+}
 
-	public void showHtAccess()
-	{
 
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public void writeData()
-	{
-		m_utils.setUser(m_userEntry.get_text());
-		m_utils.setPassword(m_passwordEntry.get_text());
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public string symbolicIcon()
+{
+	return "feed-service-feedhq-symbolic";
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string getServerURL()
+{
+	return "FeedHQ.org";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-feedhq-symbolic";
-	}
+public string uncategorizedID()
+{
+	return "";
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public string getServerURL()
-	{
-		return "FeedHQ.org";
-	}
+public bool hideCategoryWhenEmpty(string cadID)
+{
+	return false;
+}
 
-	public string uncategorizedID()
-	{
-		return "";
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool hideCategoryWhenEmpty(string cadID)
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return true;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	if(read == ArticleStatus.READ)
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+	else
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
+		m_api.edidTag(articleID, "user/-/state/com.google/starred");
+	else
+		m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		if(read == ArticleStatus.READ)
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read");
-		else
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.markAsRead(feedID);
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		if(marked == ArticleStatus.MARKED)
-			m_api.edidTag(articleID, "user/-/state/com.google/starred");
-		else
-			m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markAsRead(catID);
+}
 
-	public bool alwaysSetReadByID()
+public void markAllItemsRead()
+{
+	var db = DataBase.readOnly();
+	var categories = db.read_categories();
+	foreach(Category cat in categories)
 	{
-		return false;
+		m_api.markAsRead(cat.getCatID());
 	}
 
-	public void setFeedRead(string feedID)
+	var feeds = db.read_feeds_without_cat();
+	foreach(Feed feed in feeds)
 	{
-		m_api.markAsRead(feedID);
+		m_api.markAsRead(feed.getFeedID());
 	}
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markAsRead(catID);
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	return;
+}
 
-	public void markAllItemsRead()
-	{
-		var categories = m_db.read_categories();
-		foreach(Category cat in categories)
-		{
-			m_api.markAsRead(cat.getCatID());
-		}
+public void removeArticleTag(string articleID, string tagID)
+{
+	return;
+}
 
-		var feeds = m_db.read_feeds_without_cat();
-		foreach(Feed feed in feeds)
-		{
-			m_api.markAsRead(feed.getFeedID());
-		}
-	}
+public string createTag(string caption)
+{
+	return ":(";
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		return;
-	}
+public void deleteTag(string tagID)
+{
+	return;
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		return;
-	}
+public void renameTag(string tagID, string title)
+{
+	return;
+}
 
-	public string createTag(string caption)
-	{
-		return ":(";
-	}
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
 
-	public void deleteTag(string tagID)
-	{
-		return;
-	}
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	feedID = "feed/" + feedURL;
+	bool success = false;
 
-	public void renameTag(string tagID, string title)
+	if(catID == null && newCatName != null)
 	{
-		return;
+		string newCatID = m_api.composeTagID(newCatName);
+		Logger.debug(newCatID);
+		success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
 	}
-
-	public bool serverAvailable()
+	else
 	{
-		return m_api.ping();
+		success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
 	}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		feedID = "feed/" + feedURL;
-		bool success = false;
+	if(!success)
+		errmsg = @"feedHQ could not subscribe to $feedURL";
+	else
+		errmsg = "";
 
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.composeTagID(newCatName);
-			Logger.debug(newCatID);
-			success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
-		}
-		else
-		{
-			success = m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
-		}
+	return success;
+}
 
-		if(!success)
-			errmsg = @"feedHQ could not subscribe to $feedURL";
-		else
-			errmsg = "";
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	return;
+}
 
-		return success;
-	}
+public void removeFeed(string feedID)
+{
+	m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.UNSUBSCRIBE, {feedID});
+}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		return;
-	}
+public void renameFeed(string feedID, string title)
+{
+	m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, title);
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.UNSUBSCRIBE, {feedID});
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, title);
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.composeTagID(title);
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.editSubscription(FeedHQAPI.FeedHQSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameTag(catID, title);
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.composeTagID(title);
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameTag(catID, title);
-	}
+public void deleteCategory(string catID)
+{
+	m_api.deleteTag(catID);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.deleteTag(catID);
-	}
+public void importOPML(string opml)
+{
+	m_api.import(opml);
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getFeeds(feeds))
 	{
-		return;
-	}
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-	public void importOPML(string opml)
-	{
-		m_api.import(opml);
+		if(m_api.getCategoriesAndTags(feeds, categories, tags))
+			return true;
 	}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		if(m_api.getFeeds(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
-
-			if(m_api.getCategoriesAndTags(feeds, categories, tags))
-				return true;
-		}
+	return false;
+}
 
-		return false;
-	}
+public int getUnreadCount()
+{
+	return m_api.getTotalUnread();
+}
 
-	public int getUnreadCount()
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	if(whatToGet == ArticleStatus.READ)
 	{
-		return m_api.getTotalUnread();
+		return;
 	}
-
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+	else if(whatToGet == ArticleStatus.ALL)
 	{
-		if(whatToGet == ArticleStatus.READ)
-		{
-			return;
-		}
-		else if(whatToGet == ArticleStatus.ALL)
-		{
-			var unreadIDs = new Gee.LinkedList<string>();
-			string? continuation = null;
-
-			do
-			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
-
-				continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
-			}
-			while(continuation != null);
-			m_db_write.updateArticlesByID(unreadIDs, "unread");
-		}
-
-		var articles = new Gee.LinkedList<Article>();
+		var unreadIDs = new Gee.LinkedList<string>();
 		string? continuation = null;
-		string? FeedHQ_feedID = (isTagID) ? null : feedID;
-		string? FeedHQ_tagID = (isTagID) ? feedID : null;
 
 		do
 		{
 			if(cancellable != null && cancellable.is_cancelled())
 				return;
 
-			continuation = m_api.getArticles(articles, count, whatToGet, continuation, FeedHQ_tagID, FeedHQ_feedID);
+			continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
 		}
 		while(continuation != null);
+		DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+	}
+
+	var articles = new Gee.LinkedList<Article>();
+	string? continuation = null;
+	string? FeedHQ_feedID = (isTagID) ? null : feedID;
+	string? FeedHQ_tagID = (isTagID) ? feedID : null;
 
-		writeArticles(articles);
+	do
+	{
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
+
+		continuation = m_api.getArticles(articles, count, whatToGet, continuation, FeedHQ_tagID, FeedHQ_feedID);
 	}
+	while(continuation != null);
+
+	writeArticles(articles);
+}
 
 }
 
diff -pruN 2.6.1-1/plugins/backend/feedhq/feedhqUtils.vala 2.7.1-1/plugins/backend/feedhq/feedhqUtils.vala
--- 2.6.1-1/plugins/backend/feedhq/feedhqUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedhq/feedhqUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,106 +14,106 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.FeedHQSecret {
-	 const string base_uri        = "https://feedhq.org/reader/api/0/";
+const string base_uri        = "https://feedhq.org/reader/api/0/";
 }
 
 public class FeedReader.FeedHQUtils : GLib.Object {
 
-	private GLib.Settings m_settings;
-	private Password m_password;
+private GLib.Settings m_settings;
+private Password m_password;
 
-	public FeedHQUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedhq", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.feedhq");
-
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.feedhq", Secret.SchemaFlags.NONE,
-										  "type", Secret.SchemaAttributeType.STRING,
-										  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, pwSchema, "Feedserver login", () => {
+public FeedHQUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedhq", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.feedhq");
+
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.feedhq", Secret.SchemaFlags.NONE,
+	                                  "type", Secret.SchemaAttributeType.STRING,
+	                                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, pwSchema, "Feedserver login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["type"] = "FeedHQ";
 			attributes["Username"] = getUser();
 			return attributes;
 		});
-	}
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getAccessToken()
-	{
-		return Utils.gsettingReadString(m_settings, "access-token");
-	}
+public string getAccessToken()
+{
+	return Utils.gsettingReadString(m_settings, "access-token");
+}
 
-	public void setAccessToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "access-token", token);
-	}
+public void setAccessToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "access-token", token);
+}
 
-	public string getPostToken()
-	{
-		return Utils.gsettingReadString(m_settings, "post-token");
-	}
+public string getPostToken()
+{
+	return Utils.gsettingReadString(m_settings, "post-token");
+}
 
-	public void setPostToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "post-token", token);
-	}
-	public string getUserID()
-	{
-		return Utils.gsettingReadString(m_settings, "user-id");
-	}
+public void setPostToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "post-token", token);
+}
+public string getUserID()
+{
+	return Utils.gsettingReadString(m_settings, "user-id");
+}
 
-	public void setUserID(string id)
-	{
-		Utils.gsettingWriteString(m_settings, "user-id", id);
-	}
+public void setUserID(string id)
+{
+	Utils.gsettingWriteString(m_settings, "user-id", id);
+}
 
-	public string getEmail()
-	{
-		return Utils.gsettingReadString(m_settings, "user-email");
-	}
+public string getEmail()
+{
+	return Utils.gsettingReadString(m_settings, "user-email");
+}
 
-	public void setEmail(string email)
-	{
-		Utils.gsettingWriteString(m_settings, "user-email", email);
-	}
+public void setEmail(string email)
+{
+	Utils.gsettingWriteString(m_settings, "user-email", email);
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-	}
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+}
 
-	public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+{
+	foreach(Feed feed in feeds)
 	{
-		foreach(Feed feed in feeds)
+		if(feed.hasCat(tagID))
 		{
-			if(feed.hasCat(tagID))
-			{
-				return true;
-			}
+			return true;
 		}
-		return false;
 	}
+	return false;
+}
 
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
+public string getPasswd()
+{
+	return m_password.get_password();
+}
 
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedly/feedlyAPI.vala 2.7.1-1/plugins/backend/feedly/feedlyAPI.vala
--- 2.6.1-1/plugins/backend/feedly/feedlyAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedly/feedlyAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,679 +15,680 @@
 
 public class FeedReader.FeedlyAPI : Object {
 
-	private FeedlyConnection m_connection;
-	private string m_userID;
-	private Json.Array m_unreadcounts;
-	private FeedlyUtils m_utils;
-	private DataBaseReadOnly m_db;
+private FeedlyConnection m_connection;
+private string m_userID;
+private Json.Array m_unreadcounts;
+private FeedlyUtils m_utils;
+
+public FeedlyAPI(FeedlyUtils utils) {
+	m_utils = utils;
+	m_connection = new FeedlyConnection(m_utils);
+}
 
-	public FeedlyAPI(FeedlyUtils utils, DataBaseReadOnly db) {
-		m_db = db;
-		m_utils = utils;
-		m_connection = new FeedlyConnection(m_utils);
-	}
+public string createCatID(string title)
+{
+	return "user/%s/category/%s".printf(m_userID, title);
+}
+
+public string getMarkedID()
+{
+	return "user/" + m_userID + "/tag/global.saved";
+}
+
+public LoginResponse login()
+{
+	Logger.debug("feedly backend: login");
 
-	public string createCatID(string title)
+	if(!Utils.ping("http://feedly.com/"))
+		return LoginResponse.NO_CONNECTION;
+
+	if(m_utils.getRefreshToken() == "")
 	{
-		return "user/%s/category/%s".printf(m_userID, title);
+		m_connection.getToken();
 	}
 
-	public string getMarkedID()
+	if(tokenStillValid() == ConnectionError.INVALID_SESSIONID)
 	{
-		return "user/" + m_userID + "/tag/global.saved";
+		Logger.debug("refresh token");
+		m_connection.refreshToken();
 	}
 
-	public LoginResponse login()
+	if(getUserID())
 	{
-		Logger.debug("feedly backend: login");
+		Logger.debug("feedly: login success");
+		return LoginResponse.SUCCESS;
+	}
 
-		if(!Utils.ping("http://feedly.com/"))
-			return LoginResponse.NO_CONNECTION;
+	m_utils.setAccessToken("");
+	m_utils.setRefreshToken("");
+	m_utils.setApiCode("");
 
-		if(m_utils.getRefreshToken() == "")
-		{
-			m_connection.getToken();
-		}
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-		if(tokenStillValid() == ConnectionError.INVALID_SESSIONID)
-		{
-			Logger.debug("refresh token");
-			m_connection.refreshToken();
-		}
+private bool getUserID()
+{
+	var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
 
-		if(getUserID())
-		{
-			Logger.debug("feedly: login success");
-			return LoginResponse.SUCCESS;
-		}
-
-		m_utils.setAccessToken("");
-		m_utils.setRefreshToken("");
-		m_utils.setApiCode("");
+	if(response.status != 200)
+		return false;
 
-		return LoginResponse.UNKNOWN_ERROR;
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
+	catch(Error e)
+	{
+		Logger.error("getUserID: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
 
-	private bool getUserID()
+	if(root.has_member("id"))
 	{
-		var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
+		m_userID = root.get_string_member("id");
+		Logger.info("feedly: userID = " + m_userID);
 
-		if(response.status != 200)
-			return false;
+		if(root.has_member("email"))
+			m_utils.setEmail(root.get_string_member("email"));
+		else if(root.has_member("givenName"))
+			m_utils.setEmail(root.get_string_member("givenName"));
+		else if(root.has_member("fullName"))
+			m_utils.setEmail(root.get_string_member("fullName"));
+		else if(root.has_member("google"))
+			m_utils.setEmail(root.get_string_member("google"));
+		else if(root.has_member("reader"))
+			m_utils.setEmail(root.get_string_member("reader"));
+		else if(root.has_member("twitterUserId"))
+			m_utils.setEmail(root.get_string_member("twitterUserId"));
+		else if(root.has_member("facebookUserId"))
+			m_utils.setEmail(root.get_string_member("facebookUserId"));
+		else if(root.has_member("wordPressId"))
+			m_utils.setEmail(root.get_string_member("wordPressId"));
+		else if(root.has_member("windowsLiveId"))
+			m_utils.setEmail(root.get_string_member("windowsLiveId"));
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getUserID: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
+		return true;
+	}
 
-		if(root.has_member("id"))
-		{
-			m_userID = root.get_string_member("id");
-			Logger.info("feedly: userID = " + m_userID);
+	return false;
+}
 
-			if(root.has_member("email"))
-				m_utils.setEmail(root.get_string_member("email"));
-			else if(root.has_member("givenName"))
-				m_utils.setEmail(root.get_string_member("givenName"));
-			else if(root.has_member("fullName"))
-				m_utils.setEmail(root.get_string_member("fullName"));
-			else if(root.has_member("google"))
-				m_utils.setEmail(root.get_string_member("google"));
-			else if(root.has_member("reader"))
-				m_utils.setEmail(root.get_string_member("reader"));
-			else if(root.has_member("twitterUserId"))
-				m_utils.setEmail(root.get_string_member("twitterUserId"));
-			else if(root.has_member("facebookUserId"))
-				m_utils.setEmail(root.get_string_member("facebookUserId"));
-			else if(root.has_member("wordPressId"))
-				m_utils.setEmail(root.get_string_member("wordPressId"));
-			else if(root.has_member("windowsLiveId"))
-				m_utils.setEmail(root.get_string_member("windowsLiveId"));
+private ConnectionError tokenStillValid()
+{
+	var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
 
-			return true;
-		}
+	if(response.status != 200)
+		return ConnectionError.NO_RESPONSE;
 
-		return false;
+	var parser = new Json.Parser ();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
-
-	private ConnectionError tokenStillValid()
+	catch(Error e)
 	{
-		var response = m_connection.send_get_request_to_feedly ("/v3/profile/");
-
-		if(response.status != 200)
-			return ConnectionError.NO_RESPONSE;
-
-		var parser = new Json.Parser ();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("tokenStillValid: Could not load message response");
-			Logger.error(e.message);
-			return ConnectionError.NO_RESPONSE;
-		}
-
-		var root = parser.get_root().get_object();
-
-		if(root.has_member("errorId"))
-		{
-			return ConnectionError.INVALID_SESSIONID;
-		}
-		return ConnectionError.SUCCESS;
+		Logger.error("tokenStillValid: Could not load message response");
+		Logger.error(e.message);
+		return ConnectionError.NO_RESPONSE;
 	}
 
+	var root = parser.get_root().get_object();
 
-	public bool getCategories(Gee.List<Category> categories)
+	if(root.has_member("errorId"))
 	{
-		var response = m_connection.send_get_request_to_feedly ("/v3/categories/");
+		return ConnectionError.INVALID_SESSIONID;
+	}
+	return ConnectionError.SUCCESS;
+}
 
-		if(response.status != 200)
-			return false;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e)
-		{
-			Logger.error("getCategories: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		Json.Array array = parser.get_root().get_array();
+public bool getCategories(Gee.List<Category> categories)
+{
+	var response = m_connection.send_get_request_to_feedly ("/v3/categories/");
 
-		for (int i = 0; i < array.get_length(); i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			string categorieID = object.get_string_member("id");
+	if(response.status != 200)
+		return false;
 
-			if(categorieID.has_suffix("global.all")
-			|| categorieID.has_suffix("global.uncategorized"))
-				continue;
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e)
+	{
+		Logger.error("getCategories: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	Json.Array array = parser.get_root().get_array();
 
-			categories.add(
-				new Category (
-					categorieID,
-					object.get_string_member("label"),
-					getUnreadCountforID(categorieID),
-					i+1,
-					CategoryID.MASTER.to_string(),
-					1
+	for (int i = 0; i < array.get_length(); i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string categorieID = object.get_string_member("id");
+
+		if(categorieID.has_suffix("global.all")
+		   || categorieID.has_suffix("global.uncategorized"))
+			continue;
+
+		categories.add(
+			new Category (
+				categorieID,
+				object.get_string_member("label"),
+				getUnreadCountforID(categorieID),
+				i+1,
+				CategoryID.MASTER.to_string(),
+				1
 				)
 			);
-		}
-
-		return true;
 	}
 
+	return true;
+}
 
-	public bool getFeeds(Gee.List<Feed> feeds)
-	{
-		var response = m_connection.send_get_request_to_feedly("/v3/subscriptions/");
 
-		if(response.status != 200)
-			return false;
+public bool getFeeds(Gee.List<Feed> feeds)
+{
+	var response = m_connection.send_get_request_to_feedly("/v3/subscriptions/");
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getFeeds: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		Json.Array array = parser.get_root().get_array();
-		uint length = array.get_length();
+	if(response.status != 200)
+		return false;
 
-		for (uint i = 0; i < length; i++) {
-			Json.Object object = array.get_object_element(i);
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getFeeds: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	Json.Array array = parser.get_root().get_array();
+	uint length = array.get_length();
 
-			string feedID = object.get_string_member("id");
+	for (uint i = 0; i < length; i++) {
+		Json.Object object = array.get_object_element(i);
 
-			string? icon_url = null;
-			if(object.has_member("iconUrl"))
-				icon_url = object.get_string_member("iconUrl");
-			else if(object.has_member("visualUrl"))
-				icon_url = object.get_string_member("visualUrl");
+		string feedID = object.get_string_member("id");
 
-			uint catCount = object.get_array_member("categories").get_length();
+		string? icon_url = null;
+		if(object.has_member("iconUrl"))
+			icon_url = object.get_string_member("iconUrl");
+		else if(object.has_member("visualUrl"))
+			icon_url = object.get_string_member("visualUrl");
 
-			var categories = new Gee.ArrayList<string>();
-			for(uint j = 0; j < catCount; ++j)
-			{
-				string categoryID = object.get_array_member("categories").get_object_element(j).get_string_member("id");
+		uint catCount = object.get_array_member("categories").get_length();
 
-				if(categoryID.has_suffix("global.all")
-				|| categoryID.has_suffix("global.uncategorized"))
-					continue;
+		var categories = new Gee.ArrayList<string>();
+		for(uint j = 0; j < catCount; ++j)
+		{
+			string categoryID = object.get_array_member("categories").get_object_element(j).get_string_member("id");
 
-				categories.add(categoryID);
-			}
+			if(categoryID.has_suffix("global.all")
+			   || categoryID.has_suffix("global.uncategorized"))
+				continue;
 
-			feeds.add(
-				new Feed(
-						feedID,
-						object.get_string_member("title"),
-						object.get_string_member("website"),
-						getUnreadCountforID(object.get_string_member("id")),
-						categories,
-						icon_url
-					)
-			);
+			categories.add(categoryID);
 		}
 
-		return true;
+		feeds.add(
+			new Feed(
+				feedID,
+				object.get_string_member("title"),
+				object.get_string_member("website"),
+				getUnreadCountforID(object.get_string_member("id")),
+				categories,
+				icon_url
+				)
+			);
 	}
 
+	return true;
+}
 
-	public bool getTags(Gee.List<Tag> tags)
-	{
-		var response = m_connection.send_get_request_to_feedly("/v3/tags/");
 
-		if(response.status != 200)
-			return false;
+public bool getTags(Gee.List<Tag> tags)
+{
+	var response = m_connection.send_get_request_to_feedly("/v3/tags/");
 
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getTags: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		Json.Array array = parser.get_root().get_array ();
-		uint length = array.get_length();
+	if(response.status != 200)
+		return false;
 
-		for (uint i = 0; i < length; i++) {
-			Json.Object object = array.get_object_element(i);
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e) {
+		Logger.error("getTags: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	Json.Array array = parser.get_root().get_array ();
+	uint length = array.get_length();
 
-			tags.add(
-				new Tag(
-					object.get_string_member("id"),
-					object.has_member("label") ? object.get_string_member("label") : "",
-					m_db.getTagColor()
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++) {
+		Json.Object object = array.get_object_element(i);
+
+		tags.add(
+			new Tag(
+				object.get_string_member("id"),
+				object.has_member("label") ? object.get_string_member("label") : "",
+				db.getTagColor()
 				)
 			);
-		}
-
-		return true;
 	}
 
+	return true;
+}
 
 
-	public string? getArticles(Gee.List<Article> articles, int count, string? continuation = null, ArticleStatus whatToGet = ArticleStatus.ALL, string tagID = "", string feed_id = "")
-	{
-		string steamID = "user/" + m_userID + "/category/global.all";
-		string onlyUnread = "false";
-		string marked_tag = "user/" + m_userID + "/tag/global.saved";
 
-		if(whatToGet == ArticleStatus.MARKED)
-			steamID = marked_tag;
-		else if(whatToGet == ArticleStatus.UNREAD)
-			onlyUnread = "true";
+public string? getArticles(Gee.List<Article> articles, int count, string? continuation = null, ArticleStatus whatToGet = ArticleStatus.ALL, string tagID = "", string feed_id = "")
+{
+	string steamID = "user/" + m_userID + "/category/global.all";
+	string onlyUnread = "false";
+	string marked_tag = "user/" + m_userID + "/tag/global.saved";
 
+	if(whatToGet == ArticleStatus.MARKED)
+		steamID = marked_tag;
+	else if(whatToGet == ArticleStatus.UNREAD)
+		onlyUnread = "true";
 
-		if(tagID != "" && whatToGet == ArticleStatus.ALL)
-			steamID = tagID;
 
-		if(feed_id != "" && whatToGet == ArticleStatus.ALL)
-			steamID = feed_id;
+	if(tagID != "" && whatToGet == ArticleStatus.ALL)
+		steamID = tagID;
 
-		var parser = new Json.Parser();
+	if(feed_id != "" && whatToGet == ArticleStatus.ALL)
+		steamID = feed_id;
 
-		string streamCall = "/v3/streams/ids?streamId=%s&unreadOnly=%s&count=%i&ranked=newest&continuation=%s".printf(steamID, onlyUnread, count, (continuation == null) ? "" : continuation);
-		var entry_id_response = m_connection.send_get_request_to_feedly(streamCall);
+	var parser = new Json.Parser();
 
-		if(entry_id_response.status != 200)
-			return null;
+	string streamCall = "/v3/streams/ids?streamId=%s&unreadOnly=%s&count=%i&ranked=newest&continuation=%s".printf(steamID, onlyUnread, count, (continuation == null) ? "" : continuation);
+	var entry_id_response = m_connection.send_get_request_to_feedly(streamCall);
 
-		try
-		{
-			parser.load_from_data(entry_id_response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getArticles: Could not load message response");
-			Logger.error(e.message);
-		}
+	if(entry_id_response.status != 200)
+		return null;
+
+	try
+	{
+		parser.load_from_data(entry_id_response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getArticles: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		var root = parser.get_root().get_object();
-		if(!root.has_member("continuation"))
-			return null;
+	var root = parser.get_root().get_object();
+	if(!root.has_member("continuation"))
+		return null;
 
-		string cont = root.get_string_member("continuation");
+	string cont = root.get_string_member("continuation");
 
-		var response = m_connection.send_post_string_request_to_feedly("/v3/entries/.mget", entry_id_response.data, "application/json");
+	var response = m_connection.send_post_string_request_to_feedly("/v3/entries/.mget", entry_id_response.data, "application/json");
+
+	if(response.status != 200)
+		return null;
+
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getArticles: Could not load message response");
+		Logger.error(e.message);
+	}
+	var array = parser.get_root().get_array();
 
-		if(response.status != 200)
-			return null;
+	for(int i = 0; i < array.get_length(); i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		string title = object.get_string_member("title");
+		string? author = object.get_string_member("author");
+		string summaryContent = object.has_member("summary") ? object.get_object_member("summary").get_string_member("content") : null;
+		string content = object.has_member("content") ? object.get_object_member("content").get_string_member("content") : summaryContent;
+		bool unread = object.get_boolean_member("unread");
+		string url = object.has_member("alternate") ? object.get_array_member("alternate").get_object_element(0).get_string_member("href") : null;
+		string feedID = object.get_object_member("origin").get_string_member("streamId");
 
-		try
+		DateTime date = new DateTime.now_local();
+		if(object.has_member("updated") && object.get_int_member("updated") > 0)
 		{
-			parser.load_from_data(response.data, -1);
+			date = new DateTime.from_unix_local(object.get_int_member("updated")/1000);
 		}
-		catch(Error e)
+		else if(object.has_member("published") && object.get_int_member("published") > 0)
 		{
-			Logger.error("getArticles: Could not load message response");
-			Logger.error(e.message);
+			date = new DateTime.from_unix_local(object.get_int_member("published")/1000);
 		}
-		var array = parser.get_root().get_array();
+		else if(object.has_member("crawled") && object.get_int_member("crawled") > 0)
+		{
+			date = new DateTime.from_unix_local(object.get_int_member("crawled")/1000);
+		}
+
+		var marked = ArticleStatus.UNMARKED;
 
-		for(int i = 0; i < array.get_length(); i++)
+		var tags = new Gee.ArrayList<string>();
+		if(object.has_member("tags"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			string title = object.get_string_member("title");
-			string? author = object.get_string_member("author");
-			string summaryContent = object.has_member("summary") ? object.get_object_member("summary").get_string_member("content") : null;
-			string content = object.has_member("content") ? object.get_object_member("content").get_string_member("content") : summaryContent;
-			bool unread = object.get_boolean_member("unread");
-			string url = object.has_member("alternate") ? object.get_array_member("alternate").get_object_element(0).get_string_member("href") : null;
-			string feedID = object.get_object_member("origin").get_string_member("streamId");
+			var tag_array = object.get_array_member("tags");
+			uint tagCount = tag_array.get_length();
 
-			DateTime date = new DateTime.now_local();
-			if(object.has_member("updated") && object.get_int_member("updated") > 0)
+			for(int j = 0; j < tagCount; ++j)
 			{
-				date = new DateTime.from_unix_local(object.get_int_member("updated")/1000);
-			}
-			else if(object.has_member("published") && object.get_int_member("published") > 0)
-			{
-				date = new DateTime.from_unix_local(object.get_int_member("published")/1000);
-			}
-			else if(object.has_member("crawled") && object.get_int_member("crawled") > 0)
-			{
-				date = new DateTime.from_unix_local(object.get_int_member("crawled")/1000);
+				var tag = tag_array.get_object_element(j).get_string_member("id");
+				if(tag == marked_tag)
+					marked = ArticleStatus.MARKED;
+				else if(tag.contains("global."))
+					continue;
+				else
+					tags.add(tag);
 			}
+		}
 
-			var marked = ArticleStatus.UNMARKED;
-
-			var tags = new Gee.ArrayList<string>();
-			if(object.has_member("tags"))
-			{
-				var tag_array = object.get_array_member("tags");
-				uint tagCount = tag_array.get_length();
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
+		{
+			var attachments = object.get_array_member("enclosure");
 
-				for(int j = 0; j < tagCount; ++j)
-				{
-					var tag = tag_array.get_object_element(j).get_string_member("id");
-					if(tag == marked_tag)
-						marked = ArticleStatus.MARKED;
-					else if(tag.contains("global."))
-						continue;
-					else
-						tags.add(tag);
-				}
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
-
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(attachment.get_string_member("type")))
+				var attachment = attachments.get_object_element(j);
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(attachment.get_string_member("type")))
 					);
-				}
 			}
-
-			var Article = new Article(
-								id,
-								title,
-								url,
-								feedID,
-								unread ? ArticleStatus.UNREAD : ArticleStatus.READ,
-								marked,
-								content,
-								//summaryContent,
-								null,
-								author,
-								date, // timestamp includes msecs so divide by 1000 to get rid of them
-								-1,
-								tags,
-								enclosures
-						);
-			articles.add(Article);
 		}
 
-		return cont;
+		var Article = new Article(
+			id,
+			title,
+			url,
+			feedID,
+			unread ? ArticleStatus.UNREAD : ArticleStatus.READ,
+			marked,
+			content,
+			//summaryContent,
+			null,
+			author,
+			date,                                         // timestamp includes msecs so divide by 1000 to get rid of them
+			-1,
+			tags,
+			enclosures
+			);
+		articles.add(Article);
 	}
 
-	/** Returns the number of unread articles for an ID (may be a feed, subscription, category or tag */
-	public void getUnreadCounts()
-	{
-		var response = m_connection.send_get_request_to_feedly ("/v3/markers/counts");
-
-		if(response.status != 200)
-			return;
+	return cont;
+}
 
-		var parser = new Json.Parser ();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getUnreadCounts: Could not load message response");
-			Logger.error(e.message);
-		}
+/** Returns the number of unread articles for an ID (may be a feed, subscription, category or tag */
+public void getUnreadCounts()
+{
+	var response = m_connection.send_get_request_to_feedly ("/v3/markers/counts");
 
-		var object = parser.get_root ().get_object ();
+	if(response.status != 200)
+		return;
 
-		m_unreadcounts = object.get_array_member("unreadcounts");
+	var parser = new Json.Parser ();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
-
-	private int getUnreadCountforID(string id)
+	catch(Error e)
 	{
-		int unread_count = -1;
+		Logger.error("getUnreadCounts: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		for(int i = 0; i < m_unreadcounts.get_length (); i++)
-		{
-			var unread = m_unreadcounts.get_object_element(i);
-			string unread_id = unread.get_string_member("id");
+	var object = parser.get_root ().get_object ();
 
-			if(id == unread_id)
-			{
-				unread_count = (int)unread.get_int_member("count");
-				break;
-			}
-		}
+	m_unreadcounts = object.get_array_member("unreadcounts");
+}
+
+private int getUnreadCountforID(string id)
+{
+	int unread_count = -1;
 
-		if(unread_count == -1)
+	for(int i = 0; i < m_unreadcounts.get_length (); i++)
+	{
+		var unread = m_unreadcounts.get_object_element(i);
+		string unread_id = unread.get_string_member("id");
+
+		if(id == unread_id)
 		{
-			Logger.error("Unknown id: %s".printf(id));
+			unread_count = (int)unread.get_int_member("count");
+			break;
 		}
-
-		return unread_count;
 	}
 
-	public int getTotalUnread()
+	if(unread_count == -1)
 	{
-		return getUnreadCountforID("user/" + m_userID + "/category/global.all");
+		Logger.error("Unknown id: %s".printf(id));
 	}
 
+	return unread_count;
+}
 
-	public void mark_as_read(string ids_string, string type, ArticleStatus read)
-	{
-		var id_array = ids_string.split(",");
-		Json.Object object = new Json.Object();
-
-		if(read == ArticleStatus.READ)
-			object.set_string_member ("action", "markAsRead");
-		else if(read == ArticleStatus.UNREAD)
-			object.set_string_member ("action", "keepUnread");
-		object.set_string_member ("type", type);
-
-		Json.Array ids = new Json.Array();
-		foreach(string id in id_array)
-		{
-			ids.add_string_element(id);
-		}
+public int getTotalUnread()
+{
+	return getUnreadCountforID("user/" + m_userID + "/category/global.all");
+}
 
-		string* type_id_identificator = null;
 
-		if(type == "entries")
-		{
-			type_id_identificator = "entryIds";
-		}
-		else if(type == "feeds")
-		{
-			type_id_identificator = "feedIds";
-		}
-		else if(type == "categories")
-		{
-			type_id_identificator = "categoryIds";
-		}
-		else
-		{
-			error ("Unknown type: " + type + " don't know what to do with this.");
-		}
+public void mark_as_read(string ids_string, string type, ArticleStatus read)
+{
+	var id_array = ids_string.split(",");
+	Json.Object object = new Json.Object();
 
-		object.set_array_member(type_id_identificator, ids);
+	if(read == ArticleStatus.READ)
+		object.set_string_member ("action", "markAsRead");
+	else if(read == ArticleStatus.UNREAD)
+		object.set_string_member ("action", "keepUnread");
+	object.set_string_member ("type", type);
 
-		if(type == "feeds"
-		|| type == "categories")
-		{
-			var now = new DateTime.now_local();
-			object.set_int_member("asOf", now.to_unix()*1000);
-		}
+	Json.Array ids = new Json.Array();
+	foreach(string id in id_array)
+	{
+		ids.add_string_element(id);
+	}
 
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object (object);
+	string* type_id_identificator = null;
 
-		m_connection.send_post_request_to_feedly("/v3/markers", root);
+	if(type == "entries")
+	{
+		type_id_identificator = "entryIds";
 	}
-
-	public void addArticleTag(string ids_string, string tagID)
+	else if(type == "feeds")
 	{
-		var id_array = ids_string.split(",");
-		Json.Object object = new Json.Object();
-
-		Json.Array ids = new Json.Array();
-		foreach(string id in id_array)
-		{
-			ids.add_string_element(id);
-		}
-
-		object.set_array_member("entryIds", ids);
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
-
-		m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
+		type_id_identificator = "feedIds";
 	}
-
-	public void deleteArticleTag(string ids_string, string tagID)
+	else if(type == "categories")
 	{
-		string command = GLib.Uri.escape_string(tagID) + "/" + GLib.Uri.escape_string(ids_string);
-		m_connection.send_delete_request_to_feedly("/v3/tags/" + command);
+		type_id_identificator = "categoryIds";
 	}
-
-	public string createTag(string caption)
+	else
 	{
-		string tagID = "user/" + m_userID + "/tag/" + caption;
-		Json.Object object = new Json.Object();
-		object.set_string_member("entryId", "");
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
-
-		m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
-		return tagID;
+		error ("Unknown type: " + type + " don't know what to do with this.");
 	}
 
-	public void deleteTag(string tagID)
+	object.set_array_member(type_id_identificator, ids);
+
+	if(type == "feeds"
+	   || type == "categories")
 	{
-		m_connection.send_delete_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID));
+		var now = new DateTime.now_local();
+		object.set_int_member("asOf", now.to_unix()*1000);
 	}
 
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object (object);
 
-	public bool addSubscription(string feedURL, string? title = null, string? catIDs = null)
-	{
-		Json.Object object = new Json.Object();
-		object.set_string_member("id", "feed/" + feedURL);
+	m_connection.send_post_request_to_feedly("/v3/markers", root);
+}
 
-		if(title != null)
-		{
-			object.set_string_member("title", title);
-		}
+public void addArticleTag(string ids_string, string tagID)
+{
+	var id_array = ids_string.split(",");
+	Json.Object object = new Json.Object();
 
-		if(catIDs != null)
-		{
-			var catArray = catIDs.split(",");
-			Json.Array cats = new Json.Array();
+	Json.Array ids = new Json.Array();
+	foreach(string id in id_array)
+	{
+		ids.add_string_element(id);
+	}
 
-			foreach(string catID in catArray)
-			{
-				string catName = m_db.getCategoryName(catID);
-				Json.Object catObject = new Json.Object();
-				catObject.set_string_member("id", catID);
-				catObject.set_string_member("label", catName);
-				cats.add_object_element(catObject);
-			}
+	object.set_array_member("entryIds", ids);
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
 
-			object.set_array_member("categories", cats);
-		}
+	m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
+}
 
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
+public void deleteArticleTag(string ids_string, string tagID)
+{
+	string command = GLib.Uri.escape_string(tagID) + "/" + GLib.Uri.escape_string(ids_string);
+	m_connection.send_delete_request_to_feedly("/v3/tags/" + command);
+}
 
-		var response = m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
+public string createTag(string caption)
+{
+	string tagID = "user/" + m_userID + "/tag/" + caption;
+	Json.Object object = new Json.Object();
+	object.set_string_member("entryId", "");
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
 
-		return response.status == 200;
-	}
+	m_connection.send_put_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID), root);
+	return tagID;
+}
+
+public void deleteTag(string tagID)
+{
+	m_connection.send_delete_request_to_feedly("/v3/tags/" + GLib.Uri.escape_string(tagID));
+}
 
-	public void moveSubscription(string feedID, string newCatID, string? oldCatID = null)
-	{
-		var Feed = m_db.read_feed(feedID);
 
-		Json.Object object = new Json.Object();
-		object.set_string_member("id", feedID);
-		object.set_string_member("title", Feed.getTitle());
+public bool addSubscription(string feedURL, string? title = null, string? catIDs = null)
+{
+	Json.Object object = new Json.Object();
+	object.set_string_member("id", "feed/" + feedURL);
 
+	if(title != null)
+	{
+		object.set_string_member("title", title);
+	}
 
-		var catArray = Feed.getCatIDs();
+	if(catIDs != null)
+	{
+		var catArray = catIDs.split(",");
 		Json.Array cats = new Json.Array();
 
+		var db = DataBase.readOnly();
 		foreach(string catID in catArray)
 		{
-			if(catID != oldCatID)
-			{
-				string catName = m_db.getCategoryName(catID);
-				Json.Object catObject = new Json.Object();
-				catObject.set_string_member("id", catID);
-				catObject.set_string_member("label", catName);
-				cats.add_object_element(catObject);
-			}
+			string catName = db.getCategoryName(catID);
+			Json.Object catObject = new Json.Object();
+			catObject.set_string_member("id", catID);
+			catObject.set_string_member("label", catName);
+			cats.add_object_element(catObject);
 		}
 
-		string newCatName = m_db.getCategoryName(newCatID);
-		Json.Object catObject = new Json.Object();
-		catObject.set_string_member("id", newCatID);
-		catObject.set_string_member("label", newCatName);
-		cats.add_object_element(catObject);
-
 		object.set_array_member("categories", cats);
+	}
 
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
 
-		m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
-	}
+	var response = m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
 
-	public void removeSubscription(string feedID)
-	{
-		Logger.info(@"Deleting $(feedID)");
-		m_connection.send_delete_request_to_feedly("/v3/subscriptions/" + Uri.escape_string(feedID));
-	}
+	return response.status == 200;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		Json.Object object = new Json.Object();
-		object.set_string_member("label", title);
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
+public void moveSubscription(string feedID, string newCatID, string? oldCatID = null)
+{
+	var db = DataBase.readOnly();
+	var Feed = db.read_feed(feedID);
 
-		m_connection.send_post_request_to_feedly("/v3/categories/" + Uri.escape_string(catID), root);
-	}
+	Json.Object object = new Json.Object();
+	object.set_string_member("id", feedID);
+	object.set_string_member("title", Feed.getTitle());
 
-	public void renameTag(string tagID, string title)
-	{
-		Json.Object object = new Json.Object();
-		object.set_string_member("label", title);
-		var root = new Json.Node(Json.NodeType.OBJECT);
-		root.set_object(object);
 
-		m_connection.send_post_request_to_feedly("/v3/tags/" + Uri.escape_string(tagID), root);
-	}
+	var catArray = Feed.getCatIDs();
+	Json.Array cats = new Json.Array();
 
-	public void removeCategory(string catID)
+	foreach(string catID in catArray)
 	{
-		m_connection.send_delete_request_to_feedly("/v3/categories/" + Uri.escape_string(catID));
+		if(catID != oldCatID)
+		{
+			string catName = db.getCategoryName(catID);
+			Json.Object catObject = new Json.Object();
+			catObject.set_string_member("id", catID);
+			catObject.set_string_member("label", catName);
+			cats.add_object_element(catObject);
+		}
 	}
 
-	public void importOPML(string opml)
-	{
-		m_connection.send_post_string_request_to_feedly("/v3/opml", opml, "text/xml");
-	}
+	string newCatName = db.getCategoryName(newCatID);
+	Json.Object catObject = new Json.Object();
+	catObject.set_string_member("id", newCatID);
+	catObject.set_string_member("label", newCatName);
+	cats.add_object_element(catObject);
+
+	object.set_array_member("categories", cats);
+
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
+
+	m_connection.send_post_request_to_feedly("/v3/subscriptions", root);
+}
+
+public void removeSubscription(string feedID)
+{
+	Logger.info(@"Deleting $(feedID)");
+	m_connection.send_delete_request_to_feedly("/v3/subscriptions/" + Uri.escape_string(feedID));
+}
+
+public void renameCategory(string catID, string title)
+{
+	Json.Object object = new Json.Object();
+	object.set_string_member("label", title);
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
+
+	m_connection.send_post_request_to_feedly("/v3/categories/" + Uri.escape_string(catID), root);
+}
+
+public void renameTag(string tagID, string title)
+{
+	Json.Object object = new Json.Object();
+	object.set_string_member("label", title);
+	var root = new Json.Node(Json.NodeType.OBJECT);
+	root.set_object(object);
+
+	m_connection.send_post_request_to_feedly("/v3/tags/" + Uri.escape_string(tagID), root);
+}
+
+public void removeCategory(string catID)
+{
+	m_connection.send_delete_request_to_feedly("/v3/categories/" + Uri.escape_string(catID));
+}
+
+public void importOPML(string opml)
+{
+	m_connection.send_post_string_request_to_feedly("/v3/opml", opml, "text/xml");
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedly/feedlyConnection.vala 2.7.1-1/plugins/backend/feedly/feedlyConnection.vala
--- 2.6.1-1/plugins/backend/feedly/feedlyConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedly/feedlyConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,250 +15,250 @@
 
 public class FeedReader.FeedlyConnection {
 
-	private FeedlyUtils m_utils;
-	private GLib.Settings m_settingsTweaks;
-	private Soup.Session m_session;
+private FeedlyUtils m_utils;
+private GLib.Settings m_settingsTweaks;
+private Soup.Session m_session;
+
+public FeedlyConnection(FeedlyUtils utils)
+{
+	m_utils = utils;
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+}
 
-	public FeedlyConnection(FeedlyUtils utils)
-	{
-		m_utils = utils;
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-	}
+public LoginResponse getToken()
+{
+	var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
+	string message_string = "code=" + m_utils.getApiCode()
+	                        + "&client_id=" + FeedlySecret.apiClientId
+	                        + "&client_secret=" + FeedlySecret.apiClientSecret
+	                        + "&redirect_uri=" + FeedlySecret.apiRedirectUri
+	                        + "&grant_type=authorization_code"
+	                        + "&state=getting_token";
 
-	public LoginResponse getToken()
-	{
-		var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
-		string message_string = "code=" + m_utils.getApiCode()
-								+ "&client_id=" + FeedlySecret.apiClientId
-								+ "&client_secret=" + FeedlySecret.apiClientSecret
-								+ "&redirect_uri=" + FeedlySecret.apiRedirectUri
-								+ "&grant_type=authorization_code"
-								+ "&state=getting_token";
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
 
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
+	if(message.status_code != 200)
+		return LoginResponse.NO_CONNECTION;
 
-		if(message.status_code != 200)
-			return LoginResponse.NO_CONNECTION;
+	try
+	{
+		var parser = new Json.Parser();
+		parser.load_from_data ((string)message.response_body.flatten().data);
+		var root = parser.get_root().get_object();
 
-		try
+		if(root.has_member("access_token"))
 		{
-			var parser = new Json.Parser();
-			parser.load_from_data ((string)message.response_body.flatten().data);
-			var root = parser.get_root().get_object();
-
-			if(root.has_member("access_token"))
-			{
-				string accessToken = root.get_string_member("access_token");
-				int64 expires = (int)root.get_int_member("expires_in");
-				string refreshToken = root.get_string_member("refresh_token");
-				int64 now = (new DateTime.now_local()).to_unix();
-
-				Logger.debug("access-token: " + accessToken);
-				Logger.debug("expires in: " + expires.to_string());
-				Logger.debug("refresh-token: " + refreshToken);
-				Logger.debug("now: " + now.to_string());
-
-				m_utils.setAccessToken(accessToken);
-				m_utils.setExpiration((int)(now + expires));
-				m_utils.setRefreshToken(refreshToken);
-				return LoginResponse.SUCCESS;
-			}
-			else if(root.has_member("errorCode"))
-			{
-				Logger.error("Feedly: getToken response - " + root.get_string_member("errorMessage"));
-				return LoginResponse.UNKNOWN_ERROR;
-			}
+			string accessToken = root.get_string_member("access_token");
+			int64 expires = (int)root.get_int_member("expires_in");
+			string refreshToken = root.get_string_member("refresh_token");
+			int64 now = (new DateTime.now_local()).to_unix();
+
+			Logger.debug("access-token: " + accessToken);
+			Logger.debug("expires in: " + expires.to_string());
+			Logger.debug("refresh-token: " + refreshToken);
+			Logger.debug("now: " + now.to_string());
+
+			m_utils.setAccessToken(accessToken);
+			m_utils.setExpiration((int)(now + expires));
+			m_utils.setRefreshToken(refreshToken);
+			return LoginResponse.SUCCESS;
 		}
-		catch(Error e)
+		else if(root.has_member("errorCode"))
 		{
-			Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
+			Logger.error("Feedly: getToken response - " + root.get_string_member("errorMessage"));
+			return LoginResponse.UNKNOWN_ERROR;
 		}
-
-		return LoginResponse.UNKNOWN_ERROR;
+	}
+	catch(Error e)
+	{
+		Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
 	}
 
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-	public LoginResponse refreshToken()
-	{
-		var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+public LoginResponse refreshToken()
+{
+	var message = new Soup.Message("POST", FeedlySecret.base_uri+"/v3/auth/token");
 
-		string message_string = "refresh_token=" + m_utils.getRefreshToken()
-								+ "&client_id=" + FeedlySecret.apiClientId
-								+ "&client_secret=" + FeedlySecret.apiClientSecret
-								+ "&grant_type=refresh_token";
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
+	string message_string = "refresh_token=" + m_utils.getRefreshToken()
+	                        + "&client_id=" + FeedlySecret.apiClientId
+	                        + "&client_secret=" + FeedlySecret.apiClientSecret
+	                        + "&grant_type=refresh_token";
 
-		if(message.status_code != 200)
-			return LoginResponse.NO_CONNECTION;
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
 
-		try
+	if(message.status_code != 200)
+		return LoginResponse.NO_CONNECTION;
+
+	try
+	{
+		var parser = new Json.Parser();
+		parser.load_from_data ((string)message.response_body.flatten().data);
+		var root = parser.get_root().get_object();
+
+		if(root.has_member("access_token"))
 		{
-			var parser = new Json.Parser();
-			parser.load_from_data ((string)message.response_body.flatten().data);
-			var root = parser.get_root().get_object();
-
-			if(root.has_member("access_token"))
-			{
-				string accessToken = root.get_string_member("access_token");
-				int64 expires = (int)root.get_int_member("expires_in");
-				string refreshToken = root.get_string_member("refresh_token");
-				int64 now = (new DateTime.now_local()).to_unix();
-
-				Logger.debug("access-token: " + accessToken);
-				Logger.debug("expires in: " + expires.to_string());
-				Logger.debug("refresh-token: " + refreshToken);
-				Logger.debug("now: " + now.to_string());
-
-				m_utils.setAccessToken(accessToken);
-				m_utils.setExpiration((int)(now + expires));
-				m_utils.setRefreshToken(refreshToken);
-				return LoginResponse.SUCCESS;
-			}
-			else if(root.has_member("errorCode"))
-			{
-				Logger.error("Feedly: refreshToken response - " + root.get_string_member("errorMessage"));
-				return LoginResponse.UNKNOWN_ERROR;
-			}
+			string accessToken = root.get_string_member("access_token");
+			int64 expires = (int)root.get_int_member("expires_in");
+			string refreshToken = root.get_string_member("refresh_token");
+			int64 now = (new DateTime.now_local()).to_unix();
+
+			Logger.debug("access-token: " + accessToken);
+			Logger.debug("expires in: " + expires.to_string());
+			Logger.debug("refresh-token: " + refreshToken);
+			Logger.debug("now: " + now.to_string());
+
+			m_utils.setAccessToken(accessToken);
+			m_utils.setExpiration((int)(now + expires));
+			m_utils.setRefreshToken(refreshToken);
+			return LoginResponse.SUCCESS;
 		}
-		catch(Error e)
+		else if(root.has_member("errorCode"))
 		{
-			Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
+			Logger.error("Feedly: refreshToken response - " + root.get_string_member("errorMessage"));
+			return LoginResponse.UNKNOWN_ERROR;
 		}
-
-		return LoginResponse.UNKNOWN_ERROR;
 	}
-
-
-	public Response send_get_request_to_feedly(string path)
+	catch(Error e)
 	{
-		return send_request(path, "GET");
+		Logger.error("Could not load response to Message from feedly - %s".printf(e.message));
 	}
 
-	public Response send_put_request_to_feedly(string path, Json.Node root)
-	{
-		if(!m_utils.accessTokenValid())
-			refreshToken();
+	return LoginResponse.UNKNOWN_ERROR;
+}
+
 
-		var message = new Soup.Message("PUT", FeedlySecret.base_uri+path);
+public Response send_get_request_to_feedly(string path)
+{
+	return send_request(path, "GET");
+}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+public Response send_put_request_to_feedly(string path, Json.Node root)
+{
+	if(!m_utils.accessTokenValid())
+		refreshToken();
 
-		var gen = new Json.Generator();
-		gen.set_root(root);
-		message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+	var message = new Soup.Message("PUT", FeedlySecret.base_uri+path);
 
-		size_t length;
-		string json;
-		json = gen.to_data(out length);
-		message.request_body.append_take(json.data);
-		m_session.send_message(message);
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		if(message.status_code != 200)
-		{
-			Logger.warning(@"FeedlyConnection: message unexpected response");
-		}
+	var gen = new Json.Generator();
+	gen.set_root(root);
+	message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
-	}
+	size_t length;
+	string json;
+	json = gen.to_data(out length);
+	message.request_body.append_take(json.data);
+	m_session.send_message(message);
 
-	public Response send_post_request_to_feedly(string path, Json.Node root)
+	if(message.status_code != 200)
 	{
-		if(!m_utils.accessTokenValid())
-			refreshToken();
+		Logger.warning(@"FeedlyConnection: message unexpected response");
+	}
 
-		var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+public Response send_post_request_to_feedly(string path, Json.Node root)
+{
+	if(!m_utils.accessTokenValid())
+		refreshToken();
 
-		var gen = new Json.Generator();
-		gen.set_root(root);
-		message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+	var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
 
-		size_t length;
-		string json;
-		json = gen.to_data(out length);
-		Logger.debug(json);
-		message.request_body.append_take(json.data);
-		m_session.send_message(message);
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		if(message.status_code != 200)
-		{
-			Logger.warning(@"FeedlyConnection: message unexpected response");
-			Logger.debug("Status Code: " + message.status_code.to_string());
-		}
+	var gen = new Json.Generator();
+	gen.set_root(root);
+	message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
-	}
+	size_t length;
+	string json;
+	json = gen.to_data(out length);
+	Logger.debug(json);
+	message.request_body.append_take(json.data);
+	m_session.send_message(message);
 
-	public Response send_post_string_request_to_feedly(string path, string input, string type)
+	if(message.status_code != 200)
 	{
-		if(!m_utils.accessTokenValid())
-			refreshToken();
+		Logger.warning(@"FeedlyConnection: message unexpected response");
+		Logger.debug("Status Code: " + message.status_code.to_string());
+	}
 
-		var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+public Response send_post_string_request_to_feedly(string path, string input, string type)
+{
+	if(!m_utils.accessTokenValid())
+		refreshToken();
 
-		message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
-		message.request_headers.append("Content-Type", type);
+	var message = new Soup.Message("POST", FeedlySecret.base_uri+path);
 
-		message.request_body.append_take(input.data);
-		m_session.send_message(message);
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		if(message.status_code != 200)
-		{
-			Logger.warning(@"FeedlyConnection: message unexpected response - $input");
-		}
+	message.request_headers.append("Authorization","OAuth %s".printf(m_utils.getAccessToken()));
+	message.request_headers.append("Content-Type", type);
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
-	}
+	message.request_body.append_take(input.data);
+	m_session.send_message(message);
 
-	public Response send_delete_request_to_feedly(string path)
+	if(message.status_code != 200)
 	{
-		return send_request(path, "DELETE");
+		Logger.warning(@"FeedlyConnection: message unexpected response - $input");
 	}
 
-	private Response send_request(string path, string type)
-	{
-		if(!m_utils.accessTokenValid())
-			refreshToken();
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 
-		var message = new Soup.Message(type, FeedlySecret.base_uri+path);
-		message.request_headers.append("Authorization", @"OAuth $(m_utils.getAccessToken())");
+public Response send_delete_request_to_feedly(string path)
+{
+	return send_request(path, "DELETE");
+}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-			message.request_headers.append("DNT", "1");
+private Response send_request(string path, string type)
+{
+	if(!m_utils.accessTokenValid())
+		refreshToken();
 
-		m_session.send_message(message);
+	var message = new Soup.Message(type, FeedlySecret.base_uri+path);
+	message.request_headers.append("Authorization", @"OAuth $(m_utils.getAccessToken())");
 
-		if(message.status_code != 200)
-		{
-			Logger.warning(@"FeedlyConnection: message unexpected response");
-		}
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
+
+	m_session.send_message(message);
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
+	if(message.status_code != 200)
+	{
+		Logger.warning(@"FeedlyConnection: message unexpected response");
 	}
+
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 }
diff -pruN 2.6.1-1/plugins/backend/feedly/feedlyInterface.vala 2.7.1-1/plugins/backend/feedly/feedlyInterface.vala
--- 2.6.1-1/plugins/backend/feedly/feedlyInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedly/feedlyInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,408 +15,405 @@
 
 public class FeedReader.feedlyInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private FeedlyAPI m_api;
-	private FeedlyUtils m_utils;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private FeedlyAPI m_api;
+private FeedlyUtils m_utils;
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new FeedlyUtils(settings_backend);
-		m_api = new FeedlyAPI(m_utils, db);
-	}
-
-	public string getWebsite()
-	{
-		return "http://feedly.com/";
-	}
-
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-	}
-
-	public string getID()
-	{
-		return "feedly";
-	}
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new FeedlyUtils(settings_backend);
+	m_api = new FeedlyAPI(m_utils);
+}
 
-	public string iconName()
-	{
-		return "feed-service-feedly";
-	}
+public string getWebsite()
+{
+	return "http://feedly.com/";
+}
 
-	public string serviceName()
-	{
-		return "feedly";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
+}
 
-	public bool needWebLogin()
-	{
-		return true;
-	}
+public string getID()
+{
+	return "feedly";
+}
 
-	public Gtk.Box? getWidget()
-	{
-		return null;
-	}
+public string iconName()
+{
+	return "feed-service-feedly";
+}
 
-	public void showHtAccess()
-	{
-		return;
-	}
+public string serviceName()
+{
+	return "feedly";
+}
 
-	public void writeData()
-	{
-		return;
-	}
+public bool needWebLogin()
+{
+	return true;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public Gtk.Box? getWidget()
+{
+	return null;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		if(redirectURL.has_prefix(FeedlySecret.apiRedirectUri))
-		{
-			int start = redirectURL.index_of("=")+1;
-			int end = redirectURL.index_of("&");
-			string code = redirectURL.substring(start, end-start);
-			m_utils.setApiCode(code);
-			Logger.debug("feedlyLoginWidget: set feedly-api-code: " + code);
-			GLib.Thread.usleep(500000);
-			return true;
-		}
+public void showHtAccess()
+{
+	return;
+}
 
-		return false;
-	}
+public void writeData()
+{
+	return;
+}
 
-	public string buildLoginURL()
-	{
-		return FeedlySecret.base_uri + "/v3/auth/auth" + "?client_secret=" + FeedlySecret.apiClientSecret + "&client_id=" + FeedlySecret.apiClientId
-					+ "&redirect_uri=" + FeedlySecret.apiRedirectUri + "&scope=" + FeedlySecret.apiAuthScope + "&response_type=code&state=getting_code";
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public bool supportTags()
-	{
+public bool extractCode(string redirectURL)
+{
+	if(redirectURL.has_prefix(FeedlySecret.apiRedirectUri))
+	{
+		int start = redirectURL.index_of("=")+1;
+		int end = redirectURL.index_of("&");
+		string code = redirectURL.substring(start, end-start);
+		m_utils.setApiCode(code);
+		Logger.debug("feedlyLoginWidget: set feedly-api-code: " + code);
+		GLib.Thread.usleep(500000);
 		return true;
 	}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+	return false;
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-feedly-symbolic";
-	}
+public string buildLoginURL()
+{
+	return FeedlySecret.base_uri + "/v3/auth/auth" + "?client_secret=" + FeedlySecret.apiClientSecret + "&client_id=" + FeedlySecret.apiClientId
+	       + "&redirect_uri=" + FeedlySecret.apiRedirectUri + "&scope=" + FeedlySecret.apiAuthScope + "&response_type=code&state=getting_code";
+}
 
-	public string accountName()
-	{
-		return m_utils.getEmail();
-	}
+public bool supportTags()
+{
+	return true;
+}
 
-	public string getServerURL()
-	{
-		return "http://feedly.com/";
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public string uncategorizedID()
-	{
-		return "";
-	}
+public string symbolicIcon()
+{
+	return "feed-service-feedly-symbolic";
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return catID.has_suffix("global.must");
-	}
+public string accountName()
+{
+	return m_utils.getEmail();
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public string getServerURL()
+{
+	return "http://feedly.com/";
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public string uncategorizedID()
+{
+	return "";
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return catID.has_suffix("global.must");
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return true;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return false;
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return false;
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		m_api.mark_as_read(articleIDs, "entries", read);
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		if(marked == ArticleStatus.MARKED)
-		{
-			m_api.addArticleTag(articleID, m_api.getMarkedID());
-		}
-		else if(marked == ArticleStatus.UNMARKED)
-		{
-			m_api.deleteArticleTag(articleID, m_api.getMarkedID());
-		}
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public void setFeedRead(string feedID)
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	m_api.mark_as_read(articleIDs, "entries", read);
+}
+
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
 	{
-		m_api.mark_as_read(feedID, "feeds", ArticleStatus.READ);
+		m_api.addArticleTag(articleID, m_api.getMarkedID());
 	}
-
-	public void setCategoryRead(string catID)
+	else if(marked == ArticleStatus.UNMARKED)
 	{
-		m_api.mark_as_read(catID, "categories", ArticleStatus.READ);
+		m_api.deleteArticleTag(articleID, m_api.getMarkedID());
 	}
+}
 
-	public void markAllItemsRead()
-	{
-		string catArray = "";
-		string feedArray = "";
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-		var categories = m_db.read_categories();
-		var feeds = m_db.read_feeds_without_cat();
+public void setFeedRead(string feedID)
+{
+	m_api.mark_as_read(feedID, "feeds", ArticleStatus.READ);
+}
 
-		foreach(Category cat in categories)
-		{
-			catArray += cat.getCatID() + ",";
-		}
+public void setCategoryRead(string catID)
+{
+	m_api.mark_as_read(catID, "categories", ArticleStatus.READ);
+}
 
-		foreach(Feed feed in feeds)
-		{
-			feedArray += feed.getFeedID() + ",";
-		}
+public void markAllItemsRead()
+{
+	string catArray = "";
+	string feedArray = "";
 
-		m_api.mark_as_read(catArray.substring(0, catArray.length-1), "categories", ArticleStatus.READ);
-		m_api.mark_as_read(feedArray.substring(0, feedArray.length-1), "feeds", ArticleStatus.READ);
-	}
+	var db = DataBase.readOnly();
+	var categories = db.read_categories();
+	var feeds = db.read_feeds_without_cat();
 
-	public void tagArticle(string articleID, string tagID)
+	foreach(Category cat in categories)
 	{
-		m_api.addArticleTag(articleID, tagID);
+		catArray += cat.getCatID() + ",";
 	}
 
-	public void removeArticleTag(string articleID, string tagID)
+	foreach(Feed feed in feeds)
 	{
-		m_api.deleteArticleTag(articleID, tagID);
+		feedArray += feed.getFeedID() + ",";
 	}
 
-	public string createTag(string caption)
-	{
-		return m_api.createTag(caption);
-	}
+	m_api.mark_as_read(catArray.substring(0, catArray.length-1), "categories", ArticleStatus.READ);
+	m_api.mark_as_read(feedArray.substring(0, feedArray.length-1), "feeds", ArticleStatus.READ);
+}
 
-	public void deleteTag(string tagID)
-	{
-		m_api.deleteTag(tagID);
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	m_api.addArticleTag(articleID, tagID);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		m_api.renameTag(tagID, title);
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	m_api.deleteArticleTag(articleID, tagID);
+}
 
-	public bool serverAvailable()
-	{
-		return Utils.ping("http://feedly.com/");
-	}
+public string createTag(string caption)
+{
+	return m_api.createTag(caption);
+}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		feedID = "feed/" + feedURL;
-		bool success = false;
-		errmsg = "";
+public void deleteTag(string tagID)
+{
+	m_api.deleteTag(tagID);
+}
 
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.createCatID(newCatName);
-			success = m_api.addSubscription(feedURL, null, newCatID);
-		}
-		else
-		{
-			success = m_api.addSubscription(feedURL, null, catID);
-		}
+public void renameTag(string tagID, string title)
+{
+	m_api.renameTag(tagID, title);
+}
 
-		if(!success)
-			errmsg = @"feedly could not add $feedURL";
+public bool serverAvailable()
+{
+	return Utils.ping("http://feedly.com/");
+}
 
-		return success;
-	}
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	feedID = "feed/" + feedURL;
+	bool success = false;
+	errmsg = "";
 
-	public void addFeeds(Gee.List<Feed> feeds)
+	if(catID == null && newCatName != null)
 	{
-		foreach(Feed f in feeds)
-		{
-			m_api.addSubscription(f.getXmlUrl(), null, f.getCatIDs()[0]);
-		}
+		string newCatID = m_api.createCatID(newCatName);
+		success = m_api.addSubscription(feedURL, null, newCatID);
 	}
-
-	public void removeFeed(string feedID)
+	else
 	{
-		m_api.removeSubscription(feedID);
+		success = m_api.addSubscription(feedURL, null, catID);
 	}
 
-	public void renameFeed(string feedID, string title)
-	{
-		var feed = m_db.read_feed(feedID);
-		m_api.addSubscription(feed.getFeedID(), title, feed.getCatString());
-	}
+	if(!success)
+		errmsg = @"feedly could not add $feedURL";
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID )
-	{
-		m_api.moveSubscription(feedID, newCatID, currentCatID);
-	}
+	return success;
+}
 
-	public string createCategory(string title, string? parentID)
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	foreach(Feed f in feeds)
 	{
-		return m_api.createCatID(title);
+		m_api.addSubscription(f.getXmlUrl(), null, f.getCatIDs()[0]);
 	}
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameCategory(catID, title);
-	}
+public void removeFeed(string feedID)
+{
+	m_api.removeSubscription(feedID);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void renameFeed(string feedID, string title)
+{
+	var feed = DataBase.readOnly().read_feed(feedID);
+	m_api.addSubscription(feed.getFeedID(), title, feed.getCatString());
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.removeCategory(catID);
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID )
+{
+	m_api.moveSubscription(feedID, newCatID, currentCatID);
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
-	{
-		var feed = m_db.read_feed(feedID);
-		m_api.addSubscription(feed.getFeedID(), feed.getTitle(), feed.getCatString().replace(catID + ",", ""));
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.createCatID(title);
+}
 
-	public void importOPML(string opml)
-	{
-		m_api.importOPML(opml);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameCategory(catID, title);
+}
+
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
+
+public void deleteCategory(string catID)
+{
+	m_api.removeCategory(catID);
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+public void removeCatFromFeed(string feedID, string catID)
+{
+	var feed = DataBase.readOnly().read_feed(feedID);
+	m_api.addSubscription(feed.getFeedID(), feed.getTitle(), feed.getCatString().replace(catID + ",", ""));
+}
+
+public void importOPML(string opml)
+{
+	m_api.importOPML(opml);
+}
+
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	m_api.getUnreadCounts();
+
+	if(m_api.getCategories(categories))
 	{
-		m_api.getUnreadCounts();
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-		if(m_api.getCategories(categories))
+		if(m_api.getFeeds(feeds))
 		{
 			if(cancellable != null && cancellable.is_cancelled())
 				return false;
 
-			if(m_api.getFeeds(feeds))
-			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return false;
-
-				if(m_api.getTags(tags))
-					return true;
-			}
+			if(m_api.getTags(tags))
+				return true;
 		}
-
-		return false;
 	}
 
-	public int getUnreadCount()
-	{
-		return m_api.getTotalUnread();
-	}
+	return false;
+}
+
+public int getUnreadCount()
+{
+	return m_api.getTotalUnread();
+}
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	string continuation = null;
+	string feedly_tagID = "";
+	string feedly_feedID = "";
+	if(feedID != null)
 	{
-		string continuation = null;
-		string feedly_tagID = "";
-		string feedly_feedID = "";
-		if(feedID != null)
+		if(isTagID)
 		{
-			if(isTagID)
-			{
-				feedly_tagID = feedID;
-			}
-			else
-			{
-				feedly_feedID = feedID;
-			}
+			feedly_tagID = feedID;
 		}
-
-		int skip = count;
-		int amount = 200;
-		var articles = new Gee.LinkedList<Article>();
-
-		while(skip > 0)
+		else
 		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return;
+			feedly_feedID = feedID;
+		}
+	}
 
-			if(skip >= amount)
-			{
-				skip -= amount;
-			}
-			else
-			{
-				amount = skip;
-				skip = 0;
-			}
+	int skip = count;
+	int amount = 200;
+	var articles = new Gee.LinkedList<Article>();
 
-			continuation = m_api.getArticles(articles, amount, continuation, whatToGet, feedly_tagID, feedly_feedID);
+	while(skip > 0)
+	{
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
 
-			if(continuation == null)
-				break;
+		if(skip >= amount)
+		{
+			skip -= amount;
+		}
+		else
+		{
+			amount = skip;
+			skip = 0;
 		}
 
-		writeArticles(articles);
+		continuation = m_api.getArticles(articles, amount, continuation, whatToGet, feedly_tagID, feedly_feedID);
+
+		if(continuation == null)
+			break;
 	}
+
+	writeArticles(articles);
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/feedly/feedlyUtils.vala 2.7.1-1/plugins/backend/feedly/feedlyUtils.vala
--- 2.6.1-1/plugins/backend/feedly/feedlyUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/feedly/feedlyUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,90 +14,90 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.FeedlySecret {
-	 const string base_uri        = "http://cloud.feedly.com";
-	 const string apiClientId     = "boutroue";
-	 const string apiClientSecret = "FE012EGICU4ZOBDRBEOVAJA1JZYH";
-	 const string apiRedirectUri  = "http://localhost";
-	 const string apiAuthScope    = "https://cloud.feedly.com/subscriptions";
+const string base_uri        = "http://cloud.feedly.com";
+const string apiClientId     = "boutroue";
+const string apiClientSecret = "FE012EGICU4ZOBDRBEOVAJA1JZYH";
+const string apiRedirectUri  = "http://localhost";
+const string apiAuthScope    = "https://cloud.feedly.com/subscriptions";
 }
 
 public class FeedReader.FeedlyUtils : Object {
 
-	private GLib.Settings m_settings;
+private GLib.Settings m_settings;
 
-	public FeedlyUtils(GLib.SettingsBackend? settings_backend)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedly", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.feedly");
-	}
-
-	public string getRefreshToken()
-	{
-		return Utils.gsettingReadString(m_settings, "refresh-token");
-	}
+public FeedlyUtils(GLib.SettingsBackend? settings_backend)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.feedly", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.feedly");
+}
 
-	public void setRefreshToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "refresh-token", token);
-	}
+public string getRefreshToken()
+{
+	return Utils.gsettingReadString(m_settings, "refresh-token");
+}
 
-	public string getAccessToken()
-	{
-		return Utils.gsettingReadString(m_settings, "access-token");
-	}
+public void setRefreshToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "refresh-token", token);
+}
 
-	public void setAccessToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "access-token", token);
-	}
+public string getAccessToken()
+{
+	return Utils.gsettingReadString(m_settings, "access-token");
+}
 
-	public string getApiCode()
-	{
-		return Utils.gsettingReadString(m_settings, "api-code");
-	}
+public void setAccessToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "access-token", token);
+}
 
-	public void setApiCode(string code)
-	{
-		Utils.gsettingWriteString(m_settings, "api-code", code);
-	}
+public string getApiCode()
+{
+	return Utils.gsettingReadString(m_settings, "api-code");
+}
 
-	public string getEmail()
-	{
-		return Utils.gsettingReadString(m_settings, "email");
-	}
+public void setApiCode(string code)
+{
+	Utils.gsettingWriteString(m_settings, "api-code", code);
+}
 
-	public void setEmail(string email)
-	{
-		Utils.gsettingWriteString(m_settings, "email", email);
-	}
+public string getEmail()
+{
+	return Utils.gsettingReadString(m_settings, "email");
+}
 
-	public int getExpiration()
-	{
-		return m_settings.get_int("access-token-expires");
-	}
+public void setEmail(string email)
+{
+	Utils.gsettingWriteString(m_settings, "email", email);
+}
 
-	public void setExpiration(int seconds)
-	{
-		m_settings.set_int("access-token-expires", seconds);
-	}
+public int getExpiration()
+{
+	return m_settings.get_int("access-token-expires");
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-	}
+public void setExpiration(int seconds)
+{
+	m_settings.set_int("access-token-expires", seconds);
+}
 
-	public bool accessTokenValid()
-	{
-		var now = new DateTime.now_local();
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+}
 
-		if((int)now.to_unix() >  getExpiration())
-		{
-			Logger.warning("FeedlyUtils: access token expired");
-			return false;
-		}
+public bool accessTokenValid()
+{
+	var now = new DateTime.now_local();
 
-		return true;
+	if((int)now.to_unix() >  getExpiration())
+	{
+		Logger.warning("FeedlyUtils: access token expired");
+		return false;
 	}
+
+	return true;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/fresh/freshAPI.vala 2.7.1-1/plugins/backend/fresh/freshAPI.vala
--- 2.6.1-1/plugins/backend/fresh/freshAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/fresh/freshAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,392 +15,390 @@
 
 public class FeedReader.freshAPI : Object {
 
-	private freshConnection m_connection;
-	private freshUtils m_utils;
-	private DataBaseReadOnly m_db;
+private freshConnection m_connection;
+private freshUtils m_utils;
 
-	public freshAPI(freshUtils utils, DataBaseReadOnly db)
-	{
-		m_db = db;
-		m_utils = utils;
-		m_connection = new freshConnection(m_utils);
-	}
+public freshAPI(freshUtils utils)
+{
+	m_utils = utils;
+	m_connection = new freshConnection(m_utils);
+}
 
-	public LoginResponse login()
-	{
-		Logger.debug("fresh backend: login");
+public LoginResponse login()
+{
+	Logger.debug("fresh backend: login");
 
-		if(!Utils.ping(m_utils.getUnmodifiedURL()))
-			return LoginResponse.NO_CONNECTION;
+	if(!Utils.ping(m_utils.getUnmodifiedURL()))
+		return LoginResponse.NO_CONNECTION;
 
-		return m_connection.getSID();
-	}
+	return m_connection.getSID();
+}
 
-	public bool getSubscriptionList(Gee.List<Feed> feeds)
-	{
-		var response = m_connection.getRequest("reader/api/0/subscription/list?output=json");
+public bool getSubscriptionList(Gee.List<Feed> feeds)
+{
+	var response = m_connection.getRequest("reader/api/0/subscription/list?output=json");
 
-		if(response.status != 200)
-			return false;
+	if(response.status != 200)
+		return false;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e)
-		{
-			Logger.error("getTagList: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		Json.Array array = parser.get_root().get_object().get_array_member("subscriptions");
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e)
+	{
+		Logger.error("getTagList: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	Json.Array array = parser.get_root().get_object().get_array_member("subscriptions");
 
-		for (int i = 0; i < array.get_length (); i++)
-		{
-			Json.Object object = array.get_object_element(i);
+	for (int i = 0; i < array.get_length (); i++)
+	{
+		Json.Object object = array.get_object_element(i);
 
-			string url = object.get_string_member("htmlUrl");
-			string id = object.get_string_member("id");
-			string catID = object.get_array_member("categories").get_object_element(0).get_string_member("id");
-			string xmlURL = object.get_string_member("url");
-
-			feeds.add(
-				new Feed(
-					id,
-					object.get_string_member("title"),
-					url,
-					0,
-					ListUtils.single(catID),
-					object.get_string_member("iconUrl"),
-					xmlURL)
-			);
-		}
+		string url = object.get_string_member("htmlUrl");
+		string id = object.get_string_member("id");
+		string catID = object.get_array_member("categories").get_object_element(0).get_string_member("id");
+		string xmlURL = object.get_string_member("url");
 
-		return true;
+		feeds.add(
+			new Feed(
+				id,
+				object.get_string_member("title"),
+				url,
+				0,
+				ListUtils.single(catID),
+				object.get_string_member("iconUrl"),
+				xmlURL)
+			);
 	}
 
-	public bool getTagList(Gee.List<Category> categories)
-	{
-		var response = m_connection.getRequest("reader/api/0/tag/list?output=json");
-		string prefix = "user/-/label/";
+	return true;
+}
 
-		if(response.status != 200)
-			return false;
+public bool getTagList(Gee.List<Category> categories)
+{
+	var response = m_connection.getRequest("reader/api/0/tag/list?output=json");
+	string prefix = "user/-/label/";
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e)
-		{
-			Logger.error("getTagList: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		Json.Array array = parser.get_root().get_object().get_array_member("tags");
+	if(response.status != 200)
+		return false;
 
-		for (int i = 0; i < array.get_length (); i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			string categorieID = object.get_string_member("id");
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e)
+	{
+		Logger.error("getTagList: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	Json.Array array = parser.get_root().get_object().get_array_member("tags");
+
+	for (int i = 0; i < array.get_length (); i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string categorieID = object.get_string_member("id");
 
 
-			if(!categorieID.has_prefix(prefix))
-				continue;
+		if(!categorieID.has_prefix(prefix))
+			continue;
 
-			categories.add(
-				new Category (
-					categorieID,
-					categorieID.substring(prefix.length),
-					0,
-					i+1,
-					CategoryID.MASTER.to_string(),
-					1
+		categories.add(
+			new Category (
+				categorieID,
+				categorieID.substring(prefix.length),
+				0,
+				i+1,
+				CategoryID.MASTER.to_string(),
+				1
 				)
 			);
-		}
-
-		return true;
 	}
 
-	public int getUnreadCounts()
-	{
-		var response = m_connection.getRequest("reader/api/0/unread-count?output=json");
+	return true;
+}
 
-		if(response.status != 200)
-			return 0;
+public int getUnreadCounts()
+{
+	var response = m_connection.getRequest("reader/api/0/unread-count?output=json");
 
-		int count = 0;
+	if(response.status != 200)
+		return 0;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e)
-		{
-			Logger.error("getTagList: Could not load message response");
-			Logger.error(e.message);
-		}
-		Json.Array array = parser.get_root().get_object().get_array_member("unreadcounts");
+	int count = 0;
 
-		for (int i = 0; i < array.get_length (); i++)
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e)
+	{
+		Logger.error("getTagList: Could not load message response");
+		Logger.error(e.message);
+	}
+	Json.Array array = parser.get_root().get_object().get_array_member("unreadcounts");
+
+	for (int i = 0; i < array.get_length (); i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		if(object.get_string_member("id") == "user/-/state/com.google/reading-list")
 		{
-			Json.Object object = array.get_object_element(i);
-			if(object.get_string_member("id") == "user/-/state/com.google/reading-list")
-			{
-				count = (int)object.get_int_member("count");
-			}
+			count = (int)object.get_int_member("count");
 		}
-
-		return count;
 	}
 
-	public string? getStreamContents(
-										Gee.List<Article> articles,
-										string? feedID = null,
-										string? labelID = null,
-										string? exclude = null,
-										int count = 400,
-										string order = "d",
-										string? checkpoint = null
-								)
-	{
-		var now = new DateTime.now_local();
-		string path = "reader/api/0/stream/contents";
+	return count;
+}
 
-		if(feedID != null)
-			path += "/" + feedID;
-		else if(labelID != null)
-			path += "/" + labelID;
+public string? getStreamContents(
+	Gee.List<Article> articles,
+	string? feedID = null,
+	string? labelID = null,
+	string? exclude = null,
+	int count = 400,
+	string order = "d",
+	string? checkpoint = null
+	)
+{
+	var now = new DateTime.now_local();
+	string path = "reader/api/0/stream/contents";
+
+	if(feedID != null)
+		path += "/" + feedID;
+	else if(labelID != null)
+		path += "/" + labelID;
+
+
+	var msg = new freshMessage();
+	msg.add("output", "json");
+	msg.add("r", order);
+	msg.add("n", count.to_string());
+	msg.add("client", "FeedReader");
+	msg.add("ck", now.to_unix().to_string());
+
+	if(exclude != null)
+		msg.add("xt", exclude);
 
+	if(checkpoint != null)
+		msg.add("c", checkpoint);
 
-		var msg = new freshMessage();
-		msg.add("output", "json");
-		msg.add("r", order);
-		msg.add("n", count.to_string());
-		msg.add("client", "FeedReader");
-		msg.add("ck", now.to_unix().to_string());
+	Logger.debug("getStreamContents: %s".printf(msg.get()));
 
-		if(exclude != null)
-			msg.add("xt", exclude);
+	var response = m_connection.getRequest(path + "?" + msg.get());
 
-		if(checkpoint != null)
-			msg.add("c", checkpoint);
+	if(response.status != 200)
+		return null;
 
-		Logger.debug("getStreamContents: %s".printf(msg.get()));
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getStreamContents: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		var response = m_connection.getRequest(path + "?" + msg.get());
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("items");
+	uint length = array.get_length();
 
-		if(response.status != 200)
-			return null;
+	for(uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		bool marked = false;
+		bool read = false;
+		var cats = object.get_array_member("categories");
+		uint cat_length = cats.get_length();
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+		for(uint j = 0; j < cat_length; j++)
 		{
-			Logger.error("getStreamContents: Could not load message response");
-			Logger.error(e.message);
+			string cat = cats.get_string_element(j);
+			if(cat.has_suffix("com.google/starred"))
+				marked = true;
+			else if(cat.has_suffix("com.google/read"))
+				read = true;
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("items");
-		uint length = array.get_length();
-
-		for(uint i = 0; i < length; i++)
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			bool marked = false;
-			bool read = false;
-			var cats = object.get_array_member("categories");
-			uint cat_length = cats.get_length();
+			var attachments = object.get_array_member("enclosure");
 
-			for(uint j = 0; j < cat_length; j++)
-			{
-				string cat = cats.get_string_element(j);
-				if(cat.has_suffix("com.google/starred"))
-					marked = true;
-				else if(cat.has_suffix("com.google/read"))
-					read = true;
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
+				var attachment = attachments.get_object_element(j);
+				string type = attachment.has_member("type") ? attachment.get_string_member("type") : "";
 
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-					string type = attachment.has_member("type") ? attachment.get_string_member("type") : "";
-
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(type))
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(type))
 					);
-				}
 			}
-
-			articles.add(new Article(
-									id,
-									object.get_string_member("title"),
-									object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
-									object.get_object_member("origin").get_string_member("streamId"),
-									read ? ArticleStatus.READ : ArticleStatus.UNREAD,
-									marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-									object.get_object_member("summary").get_string_member("content"),
-									null,
-									object.get_string_member("author"),
-									new DateTime.from_unix_local(object.get_int_member("published")),
-									-1,
-									null,
-									enclosures
-							)
-						);
 		}
 
-
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
-
-		return null;
+		articles.add(new Article(
+				     id,
+				     object.get_string_member("title"),
+				     object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+				     object.get_object_member("origin").get_string_member("streamId"),
+				     read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+				     marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				     object.get_object_member("summary").get_string_member("content"),
+				     null,
+				     object.get_string_member("author"),
+				     new DateTime.from_unix_local(object.get_int_member("published")),
+				     -1,
+				     null,
+				     enclosures
+				     )
+		             );
 	}
 
-	public void editTags(string articleIDs, string? addTag = null, string? removeTag = null)
-	{
-		string path = "reader/api/0/edit-tag";
-		string[] arrayID = articleIDs.split(",");
 
-		var msg = new freshMessage();
-		msg.add("T", m_connection.getToken());
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-		if(addTag != null)
-			msg.add("a", addTag);
+	return null;
+}
 
-		if(removeTag != null)
-			msg.add("r", removeTag);
+public void editTags(string articleIDs, string? addTag = null, string? removeTag = null)
+{
+	string path = "reader/api/0/edit-tag";
+	string[] arrayID = articleIDs.split(",");
 
-		foreach(string id in arrayID)
-		{
-			msg.add("i", "-/" + id);
-		}
+	var msg = new freshMessage();
+	msg.add("T", m_connection.getToken());
 
-		var response = m_connection.postRequest(path,  msg.get(), "application/x-www-form-urlencoded");
+	if(addTag != null)
+		msg.add("a", addTag);
 
-		if(response.status != 200)
-		{
-			Logger.debug(path + " " + msg.get());
-			Logger.debug(response.status.to_string());
-		}
+	if(removeTag != null)
+		msg.add("r", removeTag);
+
+	foreach(string id in arrayID)
+	{
+		msg.add("i", "-/" + id);
 	}
 
-	public void markAllAsRead(string streamID)
+	var response = m_connection.postRequest(path,  msg.get(), "application/x-www-form-urlencoded");
+
+	if(response.status != 200)
 	{
-		string path = "reader/api/0/mark-all-as-read";
+		Logger.debug(path + " " + msg.get());
+		Logger.debug(response.status.to_string());
+	}
+}
 
-		var msg = new freshMessage();
-		msg.add("T", m_connection.getToken());
-		msg.add("s", streamID);
-		msg.add("ts", m_db.getNewestArticle());
+public void markAllAsRead(string streamID)
+{
+	string path = "reader/api/0/mark-all-as-read";
 
-		var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
+	var msg = new freshMessage();
+	msg.add("T", m_connection.getToken());
+	msg.add("s", streamID);
+	msg.add("ts", DataBase.readOnly().getNewestArticle());
 
-		if(response.status != 200)
-		{
-			Logger.debug(path + " " + msg.get());
-			Logger.debug(response.status.to_string());
-		}
-	}
+	var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
 
-	public Response editStream(
-							string action,
-							string[]? streamID = null,
-							string? title = null,
-							string? add = null,
-							string? remove = null
-						)
-	{
-		string path = "reader/api/0/subscription/edit";
-
-		var msg = new freshMessage();
-		msg.add("T", m_connection.getToken());
-		msg.add("ac", action);
+	if(response.status != 200)
+	{
+		Logger.debug(path + " " + msg.get());
+		Logger.debug(response.status.to_string());
+	}
+}
 
-		if(streamID != null)
-		{
-			foreach(string s in streamID)
-				msg.add("s", s);
-		}
+public Response editStream(
+	string action,
+	string[]? streamID = null,
+	string? title = null,
+	string? add = null,
+	string? remove = null
+	)
+{
+	string path = "reader/api/0/subscription/edit";
 
-		if(title != null)
-			msg.add("t", title);
+	var msg = new freshMessage();
+	msg.add("T", m_connection.getToken());
+	msg.add("ac", action);
 
-		if(add != null)
-			msg.add("a", add);
+	if(streamID != null)
+	{
+		foreach(string s in streamID)
+			msg.add("s", s);
+	}
 
-		if(remove != null)
-			msg.add("r", remove);
+	if(title != null)
+		msg.add("t", title);
 
-		var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
+	if(add != null)
+		msg.add("a", add);
 
-		if(response.status != 200)
-		{
-			Logger.debug(path + " " + msg.get());
-			Logger.debug(response.status.to_string());
-		}
+	if(remove != null)
+		msg.add("r", remove);
 
-		return response;
-	}
+	var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
 
-	public string composeTagID(string title)
+	if(response.status != 200)
 	{
-		return "user/-/label/%s".printf(title);
+		Logger.debug(path + " " + msg.get());
+		Logger.debug(response.status.to_string());
 	}
 
-	public void renameTag(string tagID, string title)
-	{
-		string path = "reader/api/0/rename-tag";
+	return response;
+}
 
-		var msg = new freshMessage();
-		msg.add("T", m_connection.getToken());
-		msg.add("s", tagID);
-		msg.add("dest", composeTagID(title));
+public string composeTagID(string title)
+{
+	return "user/-/label/%s".printf(title);
+}
 
-		var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
+public void renameTag(string tagID, string title)
+{
+	string path = "reader/api/0/rename-tag";
 
+	var msg = new freshMessage();
+	msg.add("T", m_connection.getToken());
+	msg.add("s", tagID);
+	msg.add("dest", composeTagID(title));
+
+	var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
 
-		if(response.status != 200)
-		{
-			Logger.debug(path + " " + msg.get());
-			Logger.debug(response.status.to_string());
-		}
-	}
 
-	public void deleteTag(string tagID)
+	if(response.status != 200)
 	{
-		string path = "reader/api/0/disable-tag";
+		Logger.debug(path + " " + msg.get());
+		Logger.debug(response.status.to_string());
+	}
+}
 
-		var msg = new freshMessage();
-		msg.add("T", m_connection.getToken());
-		msg.add("s", tagID);
+public void deleteTag(string tagID)
+{
+	string path = "reader/api/0/disable-tag";
 
-		var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
+	var msg = new freshMessage();
+	msg.add("T", m_connection.getToken());
+	msg.add("s", tagID);
 
-		if(response.status != 200)
-		{
-			Logger.debug(path + " " + msg.get());
-			Logger.debug(response.status.to_string());
-		}
+	var response = m_connection.postRequest(path, msg.get(), "application/x-www-form-urlencoded");
+
+	if(response.status != 200)
+	{
+		Logger.debug(path + " " + msg.get());
+		Logger.debug(response.status.to_string());
 	}
+}
 
 }
diff -pruN 2.6.1-1/plugins/backend/fresh/freshConnection.vala 2.7.1-1/plugins/backend/fresh/freshConnection.vala
--- 2.6.1-1/plugins/backend/fresh/freshConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/fresh/freshConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,138 +15,138 @@
 
 public class FeedReader.freshConnection {
 
-	private freshUtils m_utils;
-	private GLib.Settings m_settingsTweaks;
-	private Soup.Session m_session;
-
-	public freshConnection(freshUtils utils)
-	{
-		m_utils = utils;
-		m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_session.authenticate.connect((msg, auth, retrying) => {
+private freshUtils m_utils;
+private GLib.Settings m_settingsTweaks;
+private Soup.Session m_session;
+
+public freshConnection(freshUtils utils)
+{
+	m_utils = utils;
+	m_settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_session.authenticate.connect((msg, auth, retrying) => {
 			if(m_utils.getHtaccessUser() == "")
 			{
-				Logger.error("fresh Session: need Authentication");
+			        Logger.error("fresh Session: need Authentication");
 			}
 			else if(!retrying)
 			{
-				auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+			        auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
 			}
 		});
-	}
+}
 
-	public LoginResponse getSID()
-	{
-		var message = new Soup.Message("POST", m_utils.getURL()+"accounts/ClientLogin");
+public LoginResponse getSID()
+{
+	var message = new Soup.Message("POST", m_utils.getURL()+"accounts/ClientLogin");
 
-		var msg = new freshMessage();
-		msg.add("Email", m_utils.getUser());
-		msg.add("Passwd", m_utils.getPasswd());
-
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, msg.get().data);
-		m_session.send_message(message);
-
-		if(message.status_code != 200)
-		{
-			Logger.error("No response from freshRSS to message getSID()");
-			return LoginResponse.NO_CONNECTION;
-		}
-
-		string response = (string)message.response_body.flatten().data;
-
-		if(!response.has_prefix("SID="))
-		{
-			m_utils.setToken("");
-			m_utils.setUser("");
-			m_utils.setURL("");
-			return LoginResponse.WRONG_LOGIN;
-		}
-		else
-		{
-			int start = response.index_of("=")+1;
-			int end = response.index_of("\n");
-			string token = response.substring(start, end-start);
-			Logger.debug("Token: " + token);
-			m_utils.setToken(token);
-			return LoginResponse.SUCCESS;
-		}
-	}
+	var msg = new freshMessage();
+	msg.add("Email", m_utils.getUser());
+	msg.add("Passwd", m_utils.getPasswd());
+
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, msg.get().data);
+	m_session.send_message(message);
 
-	public string getToken()
+	if(message.status_code != 200)
 	{
-		return getRequest("reader/api/0/token").data.replace("\n", "");
+		Logger.error("No response from freshRSS to message getSID()");
+		return LoginResponse.NO_CONNECTION;
 	}
 
-	public Response postRequest(string path, string input, string type)
+	string response = (string)message.response_body.flatten().data;
+
+	if(!response.has_prefix("SID="))
 	{
-		var message = new Soup.Message("POST", m_utils.getURL()+path);
+		m_utils.setToken("");
+		m_utils.setUser("");
+		m_utils.setURL("");
+		return LoginResponse.WRONG_LOGIN;
+	}
+	else
+	{
+		int start = response.index_of("=")+1;
+		int end = response.index_of("\n");
+		string token = response.substring(start, end-start);
+		Logger.debug("Token: " + token);
+		m_utils.setToken(token);
+		return LoginResponse.SUCCESS;
+	}
+}
+
+public string getToken()
+{
+	return getRequest("reader/api/0/token").data.replace("\n", "");
+}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+public Response postRequest(string path, string input, string type)
+{
+	var message = new Soup.Message("POST", m_utils.getURL()+path);
 
-		message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
-		message.request_headers.append("Content-Type", type);
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		message.request_body.append_take(input.data);
-		m_session.send_message(message);
-
-		if(message.status_code != 200)
-		{
-			Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
-		}
-
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
-	}
+	message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
+	message.request_headers.append("Content-Type", type);
 
-	public Response getRequest(string path)
+	message.request_body.append_take(input.data);
+	m_session.send_message(message);
+
+	if(message.status_code != 200)
 	{
-		var message = new Soup.Message("GET", m_utils.getURL()+path);
-		message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
+		Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
+	}
 
-		if(m_settingsTweaks.get_boolean("do-not-track"))
-				message.request_headers.append("DNT", "1");
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
+
+public Response getRequest(string path)
+{
+	var message = new Soup.Message("GET", m_utils.getURL()+path);
+	message.request_headers.append("Authorization","GoogleLogin auth=%s".printf(m_utils.getToken()));
 
-		m_session.send_message(message);
+	if(m_settingsTweaks.get_boolean("do-not-track"))
+		message.request_headers.append("DNT", "1");
 
-		if(message.status_code != 200)
-		{
-			Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
-		}
-
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
+	m_session.send_message(message);
+
+	if(message.status_code != 200)
+	{
+		Logger.warning("freshConnection: message unexpected response %u".printf(message.status_code));
 	}
+
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
 }
 
 
 public class FeedReader.freshMessage {
 
-	string request = "";
-
-	public freshMessage()
-	{
+string request = "";
 
-	}
+public freshMessage()
+{
 
-	public void add(string parameter, string val)
-	{
-		if(request != "")
-			request += "&";
+}
 
-		request += parameter;
-		request += "=";
-		request += GLib.Uri.escape_string(val, "/");
-	}
+public void add(string parameter, string val)
+{
+	if(request != "")
+		request += "&";
+
+	request += parameter;
+	request += "=";
+	request += GLib.Uri.escape_string(val, "/");
+}
 
-	public string get()
-	{
-		return request;
-	}
+public string get()
+{
+	return request;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/fresh/freshInterface.vala 2.7.1-1/plugins/backend/fresh/freshInterface.vala
--- 2.6.1-1/plugins/backend/fresh/freshInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/fresh/freshInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,497 +15,493 @@
 
 public class FeedReader.freshInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private freshAPI m_api;
-	private freshUtils m_utils;
-	private Gtk.Entry m_urlEntry;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private Gtk.Entry m_authPasswordEntry;
-	private Gtk.Entry m_authUserEntry;
-	private Gtk.Revealer m_revealer;
-	private bool m_need_htaccess = false;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private freshAPI m_api;
+private freshUtils m_utils;
+private Gtk.Entry m_urlEntry;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+private Gtk.Entry m_authPasswordEntry;
+private Gtk.Entry m_authUserEntry;
+private Gtk.Revealer m_revealer;
+private bool m_need_htaccess = false;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new freshUtils(settings_backend, secrets);
+	m_api = new freshAPI(m_utils);
+}
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new freshUtils(settings_backend, secrets);
-		m_api = new freshAPI(m_utils, db);
-	}
+public string getWebsite()
+{
+	return "https://freshrss.org/";
+}
 
-	public string getWebsite()
-	{
-		return "https://freshrss.org/";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-	}
+public string getID()
+{
+	return "fresh";
+}
 
-	public string getID()
-	{
-		return "fresh";
-	}
+public string iconName()
+{
+	return "feed-service-fresh";
+}
 
-	public string iconName()
-	{
-		return "feed-service-fresh";
-	}
+public string serviceName()
+{
+	return "freshRSS";
+}
 
-	public string serviceName()
-	{
-		return "freshRSS";
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public Gtk.Box? getWidget()
+{
+	var url_label = new Gtk.Label(_("freshRSS URL:"));
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	url_label.set_alignment(1.0f, 0.5f);
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	url_label.set_hexpand(true);
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_urlEntry = new Gtk.Entry();
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_urlEntry.activate.connect(() => { tryLogin(); });
+	m_userEntry.activate.connect(() => { tryLogin(); });
+	m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+	m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(url_label, 0, 0, 1, 1);
+	grid.attach(m_urlEntry, 1, 0, 1, 1);
+	grid.attach(user_label, 0, 1, 1, 1);
+	grid.attach(m_userEntry, 1, 1, 1, 1);
+	grid.attach(password_label, 0, 2, 1, 1);
+	grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+
+	// http auth stuff ----------------------------------------------------
+	var auth_user_label = new Gtk.Label(_("Username:"));
+	var auth_password_label = new Gtk.Label(_("Password:"));
+
+	auth_user_label.set_alignment(1.0f, 0.5f);
+	auth_password_label.set_alignment(1.0f, 0.5f);
+
+	auth_user_label.set_hexpand(true);
+	auth_password_label.set_hexpand(true);
+
+	m_authUserEntry = new Gtk.Entry();
+	m_authPasswordEntry = new Gtk.Entry();
+	m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_authPasswordEntry.set_visibility(false);
+
+	m_authUserEntry.activate.connect(() => { tryLogin(); });
+	m_authPasswordEntry.activate.connect(() => { tryLogin(); });
+
+	var authGrid = new Gtk.Grid();
+	authGrid.margin = 10;
+	authGrid.set_column_spacing(10);
+	authGrid.set_row_spacing(10);
+	authGrid.set_valign(Gtk.Align.CENTER);
+	authGrid.set_halign(Gtk.Align.CENTER);
+
+	authGrid.attach(auth_user_label, 0, 0, 1, 1);
+	authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
+	authGrid.attach(auth_password_label, 0, 1, 1, 1);
+	authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
+
+	var frame = new Gtk.Frame(_("HTTP Authorization"));
+	frame.set_halign(Gtk.Align.CENTER);
+	frame.add(authGrid);
+	m_revealer = new Gtk.Revealer();
+	m_revealer.add(frame);
+	//---------------------------------------------------------------------
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-fresh", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to your freshRSS server and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_start(m_revealer, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
+
+	m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-	public Gtk.Box? getWidget()
-	{
-		var url_label = new Gtk.Label(_("freshRSS URL:"));
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
-
-		url_label.set_alignment(1.0f, 0.5f);
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
-
-		url_label.set_hexpand(true);
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
-
-		m_urlEntry = new Gtk.Entry();
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_urlEntry.activate.connect(() => { tryLogin(); });
-		m_userEntry.activate.connect(() => { tryLogin(); });
-		m_passwordEntry.activate.connect(() => { tryLogin(); });
-
-		m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(url_label, 0, 0, 1, 1);
-		grid.attach(m_urlEntry, 1, 0, 1, 1);
-		grid.attach(user_label, 0, 1, 1, 1);
-		grid.attach(m_userEntry, 1, 1, 1, 1);
-		grid.attach(password_label, 0, 2, 1, 1);
-		grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
-
-		// http auth stuff ----------------------------------------------------
-		var auth_user_label = new Gtk.Label(_("Username:"));
-		var auth_password_label = new Gtk.Label(_("Password:"));
-
-		auth_user_label.set_alignment(1.0f, 0.5f);
-		auth_password_label.set_alignment(1.0f, 0.5f);
-
-		auth_user_label.set_hexpand(true);
-		auth_password_label.set_hexpand(true);
-
-		m_authUserEntry = new Gtk.Entry();
-		m_authPasswordEntry = new Gtk.Entry();
-		m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_authPasswordEntry.set_visibility(false);
-
-		m_authUserEntry.activate.connect(() => { tryLogin(); });
-		m_authPasswordEntry.activate.connect(() => { tryLogin(); });
-
-		var authGrid = new Gtk.Grid();
-		authGrid.margin = 10;
-		authGrid.set_column_spacing(10);
-		authGrid.set_row_spacing(10);
-		authGrid.set_valign(Gtk.Align.CENTER);
-		authGrid.set_halign(Gtk.Align.CENTER);
-
-		authGrid.attach(auth_user_label, 0, 0, 1, 1);
-		authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
-		authGrid.attach(auth_password_label, 0, 1, 1, 1);
-		authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
-
-		var frame = new Gtk.Frame(_("HTTP Authorization"));
-		frame.set_halign(Gtk.Align.CENTER);
-		frame.add(authGrid);
-		m_revealer = new Gtk.Revealer();
-		m_revealer.add(frame);
-		//---------------------------------------------------------------------
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-fresh", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to your freshRSS server and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_start(m_revealer, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
-
-		m_urlEntry.set_text(m_utils.getUnmodifiedURL());
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+	return box;
+}
 
-		return box;
-	}
+public void showHtAccess()
+{
+	m_revealer.set_reveal_child(true);
+}
 
-	public void showHtAccess()
+public void writeData()
+{
+	m_utils.setURL(m_urlEntry.get_text());
+	m_utils.setUser(m_userEntry.get_text().strip());
+	m_utils.setPassword(m_passwordEntry.get_text().strip());
+	if(m_need_htaccess)
 	{
-		m_revealer.set_reveal_child(true);
+		m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
+		m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
 	}
+}
 
-	public void writeData()
-	{
-		m_utils.setURL(m_urlEntry.get_text());
-		m_utils.setUser(m_userEntry.get_text().strip());
-		m_utils.setPassword(m_passwordEntry.get_text().strip());
-		if(m_need_htaccess)
-		{
-			m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
-			m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
-		}
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string symbolicIcon()
+{
+	return "feed-service-fresh-symbolic";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-fresh-symbolic";
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public string getServerURL()
+{
+	return m_utils.getUnmodifiedURL();
+}
 
-	public string getServerURL()
-	{
-		return m_utils.getUnmodifiedURL();
-	}
+public string uncategorizedID()
+{
+	return "1";
+}
 
-	public string uncategorizedID()
-	{
-		return "1";
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return false;
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return false;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return true;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public bool serverAvailable()
+{
+	return Utils.ping(m_utils.getUnmodifiedURL());
+}
 
-	public bool serverAvailable()
-	{
-		return Utils.ping(m_utils.getUnmodifiedURL());
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	if(read == ArticleStatus.READ)
+		m_api.editTags(articleIDs, "user/-/state/com.google/read", null);
+	else
+		m_api.editTags(articleIDs, null, "user/-/state/com.google/read");
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		if(read == ArticleStatus.READ)
-			m_api.editTags(articleIDs, "user/-/state/com.google/read", null);
-		else
-			m_api.editTags(articleIDs, null, "user/-/state/com.google/read");
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
+		m_api.editTags(articleID, "user/-/state/com.google/starred", null);
+	else
+		m_api.editTags(articleID, null, "user/-/state/com.google/starred");
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		if(marked == ArticleStatus.MARKED)
-			m_api.editTags(articleID, "user/-/state/com.google/starred", null);
-		else
-			m_api.editTags(articleID, null, "user/-/state/com.google/starred");
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.markAllAsRead(feedID);
+}
 
-	public void setFeedRead(string feedID)
-	{
-		m_api.markAllAsRead(feedID);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markAllAsRead(catID);
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markAllAsRead(catID);
-	}
+public void markAllItemsRead()
+{
+	m_api.markAllAsRead("user/-/state/com.google/reading-list");
+}
 
-	public void markAllItemsRead()
-	{
-		m_api.markAllAsRead("user/-/state/com.google/reading-list");
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	return;
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		return;
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	return;
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		return;
-	}
+public string createTag(string caption)
+{
+	return "";
+}
 
-	public string createTag(string caption)
-	{
-		return "";
-	}
+public void deleteTag(string tagID)
+{
 
-	public void deleteTag(string tagID)
-	{
+}
 
-	}
+public void renameTag(string tagID, string title)
+{
 
-	public void renameTag(string tagID, string title)
-	{
+}
 
-	}
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	string? cat = null;
+	if(catID != null)
+		cat = catID;
+	else if(newCatName != null)
+		cat = newCatName;
+
+	cat = m_api.composeTagID(cat);
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+	var response = m_api.editStream("subscribe", {"feed/" + feedURL}, null, cat, null);
+	if(response.status != 200)
 	{
-		string? cat = null;
-		if(catID != null)
-			cat = catID;
-		else if(newCatName != null)
-			cat = newCatName;
+		feedID = "";
+		errmsg = response.data;
+		return false;
+	}
+
+	errmsg = "";
+	feedID = response.data;
+	return true;
+}
 
-		cat = m_api.composeTagID(cat);
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	string cat = "";
+	string[] urls = {};
 
-		var response = m_api.editStream("subscribe", {"feed/" + feedURL}, null, cat, null);
-		if(response.status != 200)
+	foreach(Feed f in feeds)
+	{
+		if(f.getCatIDs()[0] != cat)
 		{
-			feedID = "";
-			errmsg = response.data;
-			return false;
+			m_api.editStream("subscribe", urls, null, cat, null);
+			urls = {};
+			cat = f.getCatIDs()[0];
 		}
 
-		errmsg = "";
-		feedID = response.data;
-		return true;
+		urls += "feed/" + f.getXmlUrl();
 	}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		string cat = "";
-		string[] urls = {};
+	m_api.editStream("subscribe", urls, null, cat, null);
+}
 
-		foreach(Feed f in feeds)
-		{
-			if(f.getCatIDs()[0] != cat)
-			{
-				m_api.editStream("subscribe", urls, null, cat, null);
-				urls = {};
-				cat = f.getCatIDs()[0];
-			}
+public void removeFeed(string feedID)
+{
+	m_api.editStream("unsubscribe", {feedID}, null, null, null);
+}
 
-			urls += "feed/" + f.getXmlUrl();
-		}
+public void renameFeed(string feedID, string title)
+{
+	m_api.editStream("edit", {feedID}, title, null, null);
+}
 
-		m_api.editStream("subscribe", urls, null, cat, null);
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.editStream("edit", {feedID}, null, newCatID, currentCatID);
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.editStream("unsubscribe", {feedID}, null, null, null);
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.composeTagID(title);
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.editStream("edit", {feedID}, title, null, null);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameTag(catID, title);
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.editStream("edit", {feedID}, null, newCatID, currentCatID);
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.composeTagID(title);
-	}
+public void deleteCategory(string catID)
+{
+	m_api.deleteTag(catID);
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameTag(catID, title);
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public void deleteCategory(string catID)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getSubscriptionList(feeds))
 	{
-		m_api.deleteTag(catID);
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
+
+		if(m_api.getTagList(categories))
+			return true;
 	}
 
-	public void removeCatFromFeed(string feedID, string catID)
+	return false;
+}
+
+public int getUnreadCount()
+{
+	return m_api.getUnreadCounts();
+}
+
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	if(whatToGet == ArticleStatus.READ)
 	{
 		return;
 	}
 
-	public void importOPML(string opml)
+	var articles = new Gee.LinkedList<Article>();
+	string? continuation = null;
+	string? exclude = null;
+	string? labelID = null;
+	int left = count;
+	if(whatToGet == ArticleStatus.ALL)
 	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
+		labelID = "user/-/state/com.google/reading-list";
 	}
-
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+	else if(whatToGet == ArticleStatus.MARKED)
 	{
-		if(m_api.getSubscriptionList(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
-
-			if(m_api.getTagList(categories))
-				return true;
-		}
-
-		return false;
+		labelID = "user/-/state/com.google/starred";
 	}
-
-	public int getUnreadCount()
+	else if(whatToGet == ArticleStatus.UNREAD)
 	{
-		return m_api.getUnreadCounts();
+		labelID = "user/-/state/com.google/reading-list";
+		exclude = "user/-/state/com.google/read";
 	}
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+
+	while(left > 0)
 	{
-		if(whatToGet == ArticleStatus.READ)
-		{
+		if(cancellable != null && cancellable.is_cancelled())
 			return;
-		}
 
-		var articles = new Gee.LinkedList<Article>();
-		string? continuation = null;
-		string? exclude = null;
-		string? labelID = null;
-		int left = count;
-		if(whatToGet == ArticleStatus.ALL)
-		{
-			labelID = "user/-/state/com.google/reading-list";
-		}
-		else if(whatToGet == ArticleStatus.MARKED)
-		{
-			labelID = "user/-/state/com.google/starred";
-		}
-		else if(whatToGet == ArticleStatus.UNREAD)
+		if(left > 1000)
 		{
-			labelID = "user/-/state/com.google/reading-list";
-			exclude = "user/-/state/com.google/read";
+			continuation = m_api.getStreamContents(articles, null, labelID, exclude, 1000, "d");
+			left -= 1000;
 		}
-
-
-		while(left > 0)
+		else
 		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return;
-
-			if(left > 1000)
-			{
-				continuation = m_api.getStreamContents(articles, null, labelID, exclude, 1000, "d");
-				left -= 1000;
-			}
-			else
-			{
-				continuation = m_api.getStreamContents(articles, null, labelID, exclude, left, "d");
-				left = 0;
-			}
+			continuation = m_api.getStreamContents(articles, null, labelID, exclude, left, "d");
+			left = 0;
 		}
-		writeArticles(articles);
 	}
+	writeArticles(articles);
+}
 
 }
 
diff -pruN 2.6.1-1/plugins/backend/fresh/freshUtils.vala 2.7.1-1/plugins/backend/fresh/freshUtils.vala
--- 2.6.1-1/plugins/backend/fresh/freshUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/fresh/freshUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,122 +15,122 @@
 
 public class FeedReader.freshUtils : GLib.Object {
 
-	GLib.Settings m_settings;
-	Password m_password;
-	Password m_htaccess_password;
-
-	public freshUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.fresh", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.fresh");
-
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-										  "URL", Secret.SchemaAttributeType.STRING,
-										  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, pwSchema, "FeedReader: freshRSS login", () => {
+GLib.Settings m_settings;
+Password m_password;
+Password m_htaccess_password;
+
+public freshUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.fresh", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.fresh");
+
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                  "URL", Secret.SchemaAttributeType.STRING,
+	                                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, pwSchema, "FeedReader: freshRSS login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getUser();
 			return attributes;
 		});
 
-		var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-										        "URL", Secret.SchemaAttributeType.STRING,
-									            "Username", Secret.SchemaAttributeType.STRING,
-										        "htaccess", Secret.SchemaAttributeType.BOOLEAN);
-		m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: freshRSS htaccess Authentication", () => {
+	var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                        "URL", Secret.SchemaAttributeType.STRING,
+	                                        "Username", Secret.SchemaAttributeType.STRING,
+	                                        "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+	m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: freshRSS htaccess Authentication", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getHtaccessUser();
 			attributes["htaccess"] = "true";
 			return attributes;
 		});
-	}
+}
 
-	public string getURL()
+public string getURL()
+{
+	string tmp_url = Utils.gsettingReadString(m_settings, "url");
+	if(tmp_url != "")
 	{
-		string tmp_url = Utils.gsettingReadString(m_settings, "url");
-		if(tmp_url != "")
-		{
-			if(!tmp_url.has_suffix("/"))
-				tmp_url = tmp_url + "/";
-
-			if(!tmp_url.has_suffix("/api/greader.php/"))
-				tmp_url = tmp_url + "api/greader.php/";
-
-			if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
-					tmp_url = "https://" + tmp_url;
-		}
+		if(!tmp_url.has_suffix("/"))
+			tmp_url = tmp_url + "/";
 
-		return tmp_url;
-	}
+		if(!tmp_url.has_suffix("/api/greader.php/"))
+			tmp_url = tmp_url + "api/greader.php/";
 
-	public void setURL(string url)
-	{
-		Utils.gsettingWriteString(m_settings, "url", url);
+		if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+			tmp_url = "https://" + tmp_url;
 	}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+	return tmp_url;
+}
 
-	public void setToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "token", token);
-	}
+public void setURL(string url)
+{
+	Utils.gsettingWriteString(m_settings, "url", url);
+}
 
-	public string getToken()
-	{
-		return Utils.gsettingReadString(m_settings, "token");
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public void setToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "token", token);
+}
 
-	public string getHtaccessUser()
-	{
-		return Utils.gsettingReadString(m_settings, "htaccess-username");
-	}
+public string getToken()
+{
+	return Utils.gsettingReadString(m_settings, "token");
+}
 
-	public void setHtaccessUser(string ht_user)
-	{
-		Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getUnmodifiedURL()
-	{
-		return Utils.gsettingReadString(m_settings, "url");
-	}
+public string getHtaccessUser()
+{
+	return Utils.gsettingReadString(m_settings, "htaccess-username");
+}
 
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
+public void setHtaccessUser(string ht_user)
+{
+	Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+}
 
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public string getUnmodifiedURL()
+{
+	return Utils.gsettingReadString(m_settings, "url");
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-		m_htaccess_password.delete_password();
-	}
+public string getPasswd()
+{
+	return m_password.get_password();
+}
 
-	public string getHtaccessPasswd()
-	{
-		return m_htaccess_password.get_password();
-	}
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 
-	public void setHtAccessPassword(string passwd)
-	{
-		m_htaccess_password.set_password(passwd);
-	}
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+	m_htaccess_password.delete_password();
+}
+
+public string getHtaccessPasswd()
+{
+	return m_htaccess_password.get_password();
+}
+
+public void setHtAccessPassword(string passwd)
+{
+	m_htaccess_password.set_password(passwd);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/inoreader/InoReaderAPI.vala 2.7.1-1/plugins/backend/inoreader/InoReaderAPI.vala
--- 2.6.1-1/plugins/backend/inoreader/InoReaderAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/inoreader/InoReaderAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,451 +15,451 @@
 
 public class FeedReader.InoReaderAPI : GLib.Object {
 
-	public enum InoSubscriptionAction {
-		EDIT,
-		SUBSCRIBE,
-		UNSUBSCRIBE
-	}
+public enum InoSubscriptionAction {
+	EDIT,
+	SUBSCRIBE,
+	UNSUBSCRIBE
+}
 
-	private InoReaderConnection m_connection;
-	private InoReaderUtils m_utils;
-	private string m_userID;
-	private DataBaseReadOnly m_db;
+private InoReaderConnection m_connection;
+private InoReaderUtils m_utils;
+private string m_userID;
+
+public InoReaderAPI (InoReaderUtils utils)
+{
+	m_utils = utils;
+	m_connection = new InoReaderConnection(m_utils);
+}
 
-	public InoReaderAPI (InoReaderUtils utils, DataBaseReadOnly db)
+
+public LoginResponse login()
+{
+	if(m_utils.getAccessToken() == "")
 	{
-		m_db = db;
-		m_utils = utils;
-		m_connection = new InoReaderConnection(m_utils);
+		m_connection.getToken();
 	}
 
-
-	public LoginResponse login()
+	if(getUserID())
 	{
-		if(m_utils.getAccessToken() == "")
-		{
-			m_connection.getToken();
-		}
+		return LoginResponse.SUCCESS;
+	}
 
-		if(getUserID())
-		{
-			return LoginResponse.SUCCESS;
-		}
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-		return LoginResponse.UNKNOWN_ERROR;
-	}
+public bool ping() {
+	return Utils.ping("http://www.inoreader.com/");
+}
 
-	public bool ping() {
-		return Utils.ping("http://www.inoreader.com/");
+private bool getUserID()
+{
+	var response = m_connection.send_request("user-info");
+
+	if(response.status != 200)
+		return false;
+
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
+	catch(Error e)
+	{
+		Logger.error("getUserID: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
 
-	private bool getUserID()
+	if(root.has_member("userId"))
 	{
-		var response = m_connection.send_request("user-info");
+		m_userID = root.get_string_member("userId");
+		m_utils.setUserID(m_userID);
+		Logger.info("Inoreader: userID = " + m_userID);
 
-		if(response.status != 200)
-			return false;
+		if(root.has_member("userEmail"))
+			m_utils.setEmail(root.get_string_member("userEmail"));
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getUserID: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
+		if(root.has_member("userName"))
+			m_utils.setUser(root.get_string_member("userName"));
 
-		if(root.has_member("userId"))
-		{
-			m_userID = root.get_string_member("userId");
-			m_utils.setUserID(m_userID);
-			Logger.info("Inoreader: userID = " + m_userID);
+		return true;
+	}
 
-			if(root.has_member("userEmail"))
-				m_utils.setEmail(root.get_string_member("userEmail"));
+	return false;
+}
 
-			if(root.has_member("userName"))
-				m_utils.setUser(root.get_string_member("userName"));
+public bool getFeeds(Gee.List<Feed> feeds)
+{
+	var response = m_connection.send_request("subscription/list");
 
-			return true;
-		}
+	if(response.status != 200)
+		return false;
 
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getFeeds: Could not load message response");
+		Logger.error(e.message);
 		return false;
 	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("subscriptions");
+	uint length = array.get_length();
 
-	public bool getFeeds(Gee.List<Feed> feeds)
+	for (uint i = 0; i < length; i++)
 	{
-		var response = m_connection.send_request("subscription/list");
+		Json.Object object = array.get_object_element(i);
 
-		if(response.status != 200)
-			return false;
+		string feedID = object.get_string_member("id");
+		string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getFeeds: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("subscriptions");
-		uint length = array.get_length();
+		uint catCount = object.get_array_member("categories").get_length();
+		var categories = new Gee.ArrayList<string>();
 
-		for (uint i = 0; i < length; i++)
+		for(uint j = 0; j < catCount; ++j)
 		{
-			Json.Object object = array.get_object_element(i);
-
-			string feedID = object.get_string_member("id");
-			string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
-
-			uint catCount = object.get_array_member("categories").get_length();
-			var categories = new Gee.ArrayList<string>();
-
-			for(uint j = 0; j < catCount; ++j)
-			{
-				categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
-			}
-
-			feeds.add(
-				new Feed(
-						feedID,
-						object.get_string_member("title"),
-						url,
-						0,
-						categories,
-						object.get_string_member("iconUrl")
-					)
-			);
+			categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
 		}
 
-		return true;
+		feeds.add(
+			new Feed(
+				feedID,
+				object.get_string_member("title"),
+				url,
+				0,
+				categories,
+				object.get_string_member("iconUrl")
+				)
+			);
 	}
 
-	public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-	{
-		var response = m_connection.send_request("tag/list");
+	return true;
+}
 
-		if(response.status != 200)
-			return false;
+public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
+{
+	var response = m_connection.send_request("tag/list");
 
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("tags");
-		uint length = array.get_length();
-		int orderID = 0;
+	if(response.status != 200)
+		return false;
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			int start = id.last_index_of_char('/') + 1;
-			string title = id.substring(start);
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e) {
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("tags");
+	uint length = array.get_length();
+	int orderID = 0;
+
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		int start = id.last_index_of_char('/') + 1;
+		string title = id.substring(start);
 
-			if(id.contains("/label/"))
+		if(id.contains("/label/"))
+		{
+			if(m_utils.tagIsCat(id, feeds))
 			{
-				if(m_utils.tagIsCat(id, feeds))
-				{
-					categories.add(
-						new Category(
-							id,
-							title,
-							0,
-							orderID,
-							CategoryID.MASTER.to_string(),
-							1
+				categories.add(
+					new Category(
+						id,
+						title,
+						0,
+						orderID,
+						CategoryID.MASTER.to_string(),
+						1
 						)
 					);
-				}
-				else
-				{
-					tags.add(
-						new Tag(
-							id,
-							title,
-							m_db.getTagColor()
+			}
+			else
+			{
+				tags.add(
+					new Tag(
+						id,
+						title,
+						db.getTagColor()
 						)
 					);
-				}
-
-				++orderID;
 			}
+
+			++orderID;
 		}
-		return true;
 	}
+	return true;
+}
 
 
-	public int getTotalUnread()
-	{
-		var response = m_connection.send_request("unread-count");
+public int getTotalUnread()
+{
+	var response = m_connection.send_request("unread-count");
 
-		if(response.status != 200)
-			return 0;
+	if(response.status != 200)
+		return 0;
 
-		var parser = new Json.Parser();
-		try{
-			parser.load_from_data(response.data, -1);
-		}
-		catch (Error e) {
-			Logger.error("getTotalUnread: Could not load message response");
-			Logger.error(e.message);
-		}
+	var parser = new Json.Parser();
+	try{
+		parser.load_from_data(response.data, -1);
+	}
+	catch (Error e) {
+		Logger.error("getTotalUnread: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("unreadcounts");
-		uint length = array.get_length();
-		int count = 0;
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("unreadcounts");
+	uint length = array.get_length();
+	int count = 0;
 
-		for (uint i = 0; i < length; i++)
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		if(object.get_string_member("id").has_prefix("feed/"))
 		{
-			Json.Object object = array.get_object_element(i);
-			if(object.get_string_member("id").has_prefix("feed/"))
-			{
-				count += (int)object.get_int_member("count");
-			}
-
+			count += (int)object.get_int_member("count");
 		}
 
-		Logger.debug("getTotalUnread %i".printf(count));
-		return count;
 	}
 
+	Logger.debug("getTotalUnread %i".printf(count));
+	return count;
+}
 
-	public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
-	{
-		var message_string = "n=" + count.to_string();
-		message_string += "&xt=user/-/state/com.google/read";
-		if(continuation != null)
-			message_string += "&c=" + continuation;
-		var response = m_connection.send_request("stream/items/ids", message_string);
 
-		if(response.status != 200)
-			return null;
+public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+{
+	var message_string = "n=" + count.to_string();
+	message_string += "&xt=user/-/state/com.google/read";
+	if(continuation != null)
+		message_string += "&c=" + continuation;
+	var response = m_connection.send_request("stream/items/ids", message_string);
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("updateArticles: Could not load message response");
-			Logger.error(e.message);
-		}
-
-		var root = parser.get_root().get_object();
-		if(!root.has_member("itemRefs"))
-			return null;
-		var array = root.get_array_member("itemRefs");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			ids.add(object.get_string_member("id"));
-		}
+	if(response.status != 200)
+		return null;
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("updateArticles: Could not load message response");
+		Logger.error(e.message);
+	}
 
+	var root = parser.get_root().get_object();
+	if(!root.has_member("itemRefs"))
 		return null;
-	}
+	var array = root.get_array_member("itemRefs");
+	uint length = array.get_length();
 
-	public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+	for (uint i = 0; i < length; i++)
 	{
-		var message_string = "n=" + count.to_string();
+		Json.Object object = array.get_object_element(i);
+		ids.add(object.get_string_member("id"));
+	}
 
-		if(whatToGet == ArticleStatus.UNREAD)
-			message_string += "&xt=user/-/state/com.google/read";
-		if(whatToGet == ArticleStatus.READ)
-			message_string += "&it=user/-/state/com.google/read";
-		else if(whatToGet == ArticleStatus.MARKED)
-			message_string += "&it=user/-/state/com.google/starred";
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-		if(continuation != null)
-			message_string += "&c=" + continuation;
+	return null;
+}
 
+public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+{
+	var message_string = "n=" + count.to_string();
 
-		string api_endpoint = "stream/contents";
-		if(feed_id != null)
-			api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
-		else if(tagID != null)
-			api_endpoint += "/" + GLib.Uri.escape_string(tagID);
-		var response = m_connection.send_request(api_endpoint, message_string);
+	if(whatToGet == ArticleStatus.UNREAD)
+		message_string += "&xt=user/-/state/com.google/read";
+	if(whatToGet == ArticleStatus.READ)
+		message_string += "&it=user/-/state/com.google/read";
+	else if(whatToGet == ArticleStatus.MARKED)
+		message_string += "&it=user/-/state/com.google/starred";
+
+	if(continuation != null)
+		message_string += "&c=" + continuation;
+
+
+	string api_endpoint = "stream/contents";
+	if(feed_id != null)
+		api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
+	else if(tagID != null)
+		api_endpoint += "/" + GLib.Uri.escape_string(tagID);
+	var response = m_connection.send_request(api_endpoint, message_string);
 
-		if(response.status != 200)
-			return null;
+	if(response.status != 200)
+		return null;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getArticles: Could not load message response");
+		Logger.error(e.message);
+	}
+
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("items");
+	uint length = array.get_length();
+
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		id = id.substring(id.last_index_of_char('/')+1);
+		var tags = new Gee.ArrayList<string>();
+		bool marked = false;
+		bool read = false;
+		var cats = object.get_array_member("categories");
+		uint cat_length = cats.get_length();
+
+		for (uint j = 0; j < cat_length; j++)
 		{
-			Logger.error("getArticles: Could not load message response");
-			Logger.error(e.message);
+			string cat = cats.get_string_element(j);
+			if(cat.has_suffix("com.google/starred"))
+				marked = true;
+			else if(cat.has_suffix("com.google/read"))
+				read = true;
+			else if(cat.contains("/label/") && db.getTagName(cat) != null)
+				tags.add(cat);
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("items");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			id = id.substring(id.last_index_of_char('/')+1);
-			var tags = new Gee.ArrayList<string>();
-			bool marked = false;
-			bool read = false;
-			var cats = object.get_array_member("categories");
-			uint cat_length = cats.get_length();
+			var attachments = object.get_array_member("enclosure");
 
-			for (uint j = 0; j < cat_length; j++)
-			{
-				string cat = cats.get_string_element(j);
-				if(cat.has_suffix("com.google/starred"))
-					marked = true;
-				else if(cat.has_suffix("com.google/read"))
-					read = true;
-				else if(cat.contains("/label/") && m_db.getTagName(cat) != null)
-					tags.add(cat);
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
-
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(attachment.get_string_member("type")))
+				var attachment = attachments.get_object_element(j);
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(attachment.get_string_member("type")))
 					);
-				}
 			}
-
-			articles.add(new Article(
-									id,
-									object.get_string_member("title"),
-									object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
-									object.get_object_member("origin").get_string_member("streamId"),
-									read ? ArticleStatus.READ : ArticleStatus.UNREAD,
-									marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-									object.get_object_member("summary").get_string_member("content"),
-									null,
-									object.get_string_member("author"),
-									new DateTime.from_unix_local(object.get_int_member("published")),
-									-1,
-									tags,
-									enclosures
-							)
-						);
 		}
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
-
-		return null;
+		articles.add(new Article(
+				     id,
+				     object.get_string_member("title"),
+				     object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+				     object.get_object_member("origin").get_string_member("streamId"),
+				     read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+				     marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				     object.get_object_member("summary").get_string_member("content"),
+				     null,
+				     object.get_string_member("author"),
+				     new DateTime.from_unix_local(object.get_int_member("published")),
+				     -1,
+				     tags,
+				     enclosures
+				     )
+		             );
 	}
 
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-	public void edidTag(string articleIDs, string tagID, bool add = true)
-	{
-		var message_string = "";
-		if(add)
-			message_string += "a=";
-		else
-			message_string += "r=";
+	return null;
+}
 
-		message_string += tagID;
 
-		var id_array = articleIDs.split(",");
-		foreach(string id in id_array)
-		{
-			message_string += "&i=" + id;
-		}
-		m_connection.send_request("edit-tag", message_string);
-	}
+public void edidTag(string articleIDs, string tagID, bool add = true)
+{
+	var message_string = "";
+	if(add)
+		message_string += "a=";
+	else
+		message_string += "r=";
 
-	public void markAsRead(string? streamID = null)
-	{
-		var settingsState = new GLib.Settings("org.gnome.feedreader.saved-state");
-		string message_string = "s=%s&ts=%i".printf(streamID, settingsState.get_int("last-sync"));
-		Logger.debug(message_string);
-		m_connection.send_request("mark-all-as-read", message_string);
-	}
+	message_string += tagID;
 
-	public string composeTagID(string tagName)
+	var id_array = articleIDs.split(",");
+	foreach(string id in id_array)
 	{
-		return "user/%s/label/%s".printf(m_userID, tagName);
+		message_string += "&i=" + id;
 	}
+	m_connection.send_request("edit-tag", message_string);
+}
 
-	public void deleteTag(string tagID)
-	{
-		var message_string = "s=" + tagID;
-		m_connection.send_request("disable-tag", message_string);
-	}
+public void markAsRead(string? streamID = null)
+{
+	var settingsState = new GLib.Settings("org.gnome.feedreader.saved-state");
+	string message_string = "s=%s&ts=%i".printf(streamID, settingsState.get_int("last-sync"));
+	Logger.debug(message_string);
+	m_connection.send_request("mark-all-as-read", message_string);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		var message_string = "s=" + tagID;
-		message_string += "&dest=" + composeTagID(title);
-		m_connection.send_request("rename-tag", message_string);
-	}
+public string composeTagID(string tagName)
+{
+	return "user/%s/label/%s".printf(m_userID, tagName);
+}
 
-	public bool editSubscription(InoSubscriptionAction action, string[] feedID, string? title, string? add, string? remove)
-	{
-		var message_string = "ac=";
+public void deleteTag(string tagID)
+{
+	var message_string = "s=" + tagID;
+	m_connection.send_request("disable-tag", message_string);
+}
 
-		switch(action)
-		{
-			case InoSubscriptionAction.EDIT:
-				message_string += "edit";
-				break;
-			case InoSubscriptionAction.SUBSCRIBE:
-				message_string += "subscribe";
-				break;
-			case InoSubscriptionAction.UNSUBSCRIBE:
-				message_string += "unsubscribe";
-				break;
-		}
+public void renameTag(string tagID, string title)
+{
+	var message_string = "s=" + tagID;
+	message_string += "&dest=" + composeTagID(title);
+	m_connection.send_request("rename-tag", message_string);
+}
+
+public bool editSubscription(InoSubscriptionAction action, string[] feedID, string? title, string? add, string? remove)
+{
+	var message_string = "ac=";
+
+	switch(action)
+	{
+	case InoSubscriptionAction.EDIT:
+		message_string += "edit";
+		break;
+	case InoSubscriptionAction.SUBSCRIBE:
+		message_string += "subscribe";
+		break;
+	case InoSubscriptionAction.UNSUBSCRIBE:
+		message_string += "unsubscribe";
+		break;
+	}
 
-		foreach(string s in feedID)
-			message_string += "&s=" + GLib.Uri.escape_string(s);
+	foreach(string s in feedID)
+		message_string += "&s=" + GLib.Uri.escape_string(s);
 
-		if(title != null)
-			message_string += "&t=" + title;
+	if(title != null)
+		message_string += "&t=" + title;
 
-		if(add != null)
-			message_string += "&a=" + add;
+	if(add != null)
+		message_string += "&a=" + add;
 
-		if(remove != null)
-			message_string += "&r=" + remove;
+	if(remove != null)
+		message_string += "&r=" + remove;
 
 
-		return m_connection.send_request("subscription/edit", message_string).status == 200;
-	}
+	return m_connection.send_request("subscription/edit", message_string).status == 200;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/inoreader/InoReaderConnection.vala 2.7.1-1/plugins/backend/inoreader/InoReaderConnection.vala
--- 2.6.1-1/plugins/backend/inoreader/InoReaderConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/inoreader/InoReaderConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,150 +14,150 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 public class FeedReader.InoReaderConnection {
-	private string m_api_username;
-	private string m_api_code;
-	private InoReaderUtils m_utils;
-	private Soup.Session m_session;
-
-	public InoReaderConnection(InoReaderUtils utils)
-	{
-		m_utils = utils;
-		m_api_username = m_utils.getUser();
-		m_api_code = m_utils.getAccessToken();
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-	}
-
-	public LoginResponse getToken()
-	{
-		Logger.debug("InoReaderConnection: getToken()");
-
-		var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
-		string message_string = "code=" + m_utils.getApiCode()
-								+ "&redirect_uri=" + InoReaderSecret.apiRedirectUri
-								+ "&client_id=" + InoReaderSecret.apiClientId
-								+ "&client_secret=" + InoReaderSecret.apiClientSecret
-								+ "&scope="
-								+ "&grant_type=authorization_code";
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
+private string m_api_username;
+private string m_api_code;
+private InoReaderUtils m_utils;
+private Soup.Session m_session;
+
+public InoReaderConnection(InoReaderUtils utils)
+{
+	m_utils = utils;
+	m_api_username = m_utils.getUser();
+	m_api_code = m_utils.getAccessToken();
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+}
 
-		if(message.status_code != 200)
-			return LoginResponse.NO_CONNECTION;
+public LoginResponse getToken()
+{
+	Logger.debug("InoReaderConnection: getToken()");
+
+	var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
+	string message_string = "code=" + m_utils.getApiCode()
+	                        + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
+	                        + "&client_id=" + InoReaderSecret.apiClientId
+	                        + "&client_secret=" + InoReaderSecret.apiClientSecret
+	                        + "&scope="
+	                        + "&grant_type=authorization_code";
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
 
-		string response = (string)message.response_body.flatten().data;
+	if(message.status_code != 200)
+		return LoginResponse.NO_CONNECTION;
 
-		try
-		{
-			var parser = new Json.Parser();
-			parser.load_from_data(response, -1);
-			var root = parser.get_root().get_object();
-
-			string accessToken = root.get_string_member("access_token");
-			int64 expires = (int)root.get_int_member("expires_in");
-			string refreshToken = root.get_string_member("refresh_token");
-			int64 now = (new DateTime.now_local()).to_unix();
-
-			Logger.debug("access-token: " + accessToken);
-			Logger.debug("expires in: " + expires.to_string());
-			Logger.debug("refresh-token: " + refreshToken);
-			Logger.debug("now: " + now.to_string());
-
-			m_utils.setAccessToken(accessToken);
-			m_utils.setExpiration((int)(now + expires));
-			m_utils.setRefreshToken(refreshToken);
-		}
-		catch(Error e)
-		{
-			Logger.error("InoReaderConnection - getToken: Could not load message response");
-			Logger.error(e.message);
-			return LoginResponse.UNKNOWN_ERROR;
-		}
+	string response = (string)message.response_body.flatten().data;
 
-		return LoginResponse.SUCCESS;
+	try
+	{
+		var parser = new Json.Parser();
+		parser.load_from_data(response, -1);
+		var root = parser.get_root().get_object();
+
+		string accessToken = root.get_string_member("access_token");
+		int64 expires = (int)root.get_int_member("expires_in");
+		string refreshToken = root.get_string_member("refresh_token");
+		int64 now = (new DateTime.now_local()).to_unix();
+
+		Logger.debug("access-token: " + accessToken);
+		Logger.debug("expires in: " + expires.to_string());
+		Logger.debug("refresh-token: " + refreshToken);
+		Logger.debug("now: " + now.to_string());
+
+		m_utils.setAccessToken(accessToken);
+		m_utils.setExpiration((int)(now + expires));
+		m_utils.setRefreshToken(refreshToken);
 	}
-
-	public LoginResponse refreshToken()
+	catch(Error e)
 	{
-		Logger.debug("InoReaderConnection: refreshToken()");
+		Logger.error("InoReaderConnection - getToken: Could not load message response");
+		Logger.error(e.message);
+		return LoginResponse.UNKNOWN_ERROR;
+	}
+
+	return LoginResponse.SUCCESS;
+}
 
-		var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
-		string message_string = "client_id=" + InoReaderSecret.apiClientId
-								+ "&client_secret=" + InoReaderSecret.apiClientSecret
-								+ "&grant_type=refresh_token"
-								+ "&refresh_token=" + m_utils.getRefreshToken();
+public LoginResponse refreshToken()
+{
+	Logger.debug("InoReaderConnection: refreshToken()");
 
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
+	var message = new Soup.Message("POST", "https://www.inoreader.com/oauth2/token");
+	string message_string = "client_id=" + InoReaderSecret.apiClientId
+	                        + "&client_secret=" + InoReaderSecret.apiClientSecret
+	                        + "&grant_type=refresh_token"
+	                        + "&refresh_token=" + m_utils.getRefreshToken();
 
-		if(message.status_code != 200)
-			return LoginResponse.NO_CONNECTION;
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
 
-		string response = (string)message.response_body.flatten().data;
+	if(message.status_code != 200)
+		return LoginResponse.NO_CONNECTION;
 
-		try
-		{
-			var parser = new Json.Parser();
-			parser.load_from_data(response, -1);
-			var root = parser.get_root().get_object();
-
-			if(!root.has_member("access_token"))
-				return getToken();
-
-			string accessToken = root.get_string_member("access_token");
-			int64 expires = (int)root.get_int_member("expires_in");
-			string refreshToken = root.get_string_member("refresh_token");
-			int64 now = (new DateTime.now_local()).to_unix();
-
-			Logger.debug("access-token: " + accessToken);
-			Logger.debug("expires in: " + expires.to_string());
-			Logger.debug("refresh-token: " + refreshToken);
-			Logger.debug("now: " + now.to_string());
-
-			m_utils.setAccessToken(accessToken);
-			m_utils.setExpiration((int)(now + expires));
-			m_utils.setRefreshToken(refreshToken);
-		}
-		catch(Error e)
-		{
-			Logger.error("InoReaderConnection - getToken: Could not load message response");
-			Logger.error(e.message);
-			return LoginResponse.UNKNOWN_ERROR;
-		}
+	string response = (string)message.response_body.flatten().data;
 
-		return LoginResponse.SUCCESS;
+	try
+	{
+		var parser = new Json.Parser();
+		parser.load_from_data(response, -1);
+		var root = parser.get_root().get_object();
+
+		if(!root.has_member("access_token"))
+			return getToken();
+
+		string accessToken = root.get_string_member("access_token");
+		int64 expires = (int)root.get_int_member("expires_in");
+		string refreshToken = root.get_string_member("refresh_token");
+		int64 now = (new DateTime.now_local()).to_unix();
+
+		Logger.debug("access-token: " + accessToken);
+		Logger.debug("expires in: " + expires.to_string());
+		Logger.debug("refresh-token: " + refreshToken);
+		Logger.debug("now: " + now.to_string());
+
+		m_utils.setAccessToken(accessToken);
+		m_utils.setExpiration((int)(now + expires));
+		m_utils.setRefreshToken(refreshToken);
 	}
-
-	public Response send_request(string path, string? message_string = null)
+	catch(Error e)
 	{
-		return send_post_request(path, "POST", message_string);
+		Logger.error("InoReaderConnection - getToken: Could not load message response");
+		Logger.error(e.message);
+		return LoginResponse.UNKNOWN_ERROR;
 	}
 
-	private Response send_post_request(string path, string type, string? message_string = null)
-	{
-		if(!m_utils.accessTokenValid())
-			refreshToken();
+	return LoginResponse.SUCCESS;
+}
 
-		var message = new Soup.Message(type, InoReaderSecret.base_uri + path);
+public Response send_request(string path, string? message_string = null)
+{
+	return send_post_request(path, "POST", message_string);
+}
+
+private Response send_post_request(string path, string type, string? message_string = null)
+{
+	if(!m_utils.accessTokenValid())
+		refreshToken();
 
-		string inoauth = "Bearer " + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", inoauth);
+	var message = new Soup.Message(type, InoReaderSecret.base_uri + path);
 
-		if(message_string != null)
-			message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	string inoauth = "Bearer " + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", inoauth);
 
-		m_session.send_message(message);
+	if(message_string != null)
+		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
 
-		if(message.status_code != 200)
-		{
-			Logger.warning("InoReaderConnection: unexpected response");
-			Logger.debug(message.status_code.to_string());
-		}
+	m_session.send_message(message);
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
+	if(message.status_code != 200)
+	{
+		Logger.warning("InoReaderConnection: unexpected response");
+		Logger.debug(message.status_code.to_string());
 	}
 
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
+
 }
diff -pruN 2.6.1-1/plugins/backend/inoreader/InoReaderInterface.vala 2.7.1-1/plugins/backend/inoreader/InoReaderInterface.vala
--- 2.6.1-1/plugins/backend/inoreader/InoReaderInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/inoreader/InoReaderInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,415 +15,386 @@
 
 public class FeedReader.InoReaderInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private InoReaderAPI m_api;
-	private InoReaderUtils m_utils;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private InoReaderAPI m_api;
+private InoReaderUtils m_utils;
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new InoReaderUtils(settings_backend);
-		m_api = new InoReaderAPI(m_utils, db);
-	}
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new InoReaderUtils(settings_backend);
+	m_api = new InoReaderAPI(m_utils);
+}
 
-	public string getWebsite()
-	{
-		return "http://www.inoreader.com/";
-	}
+public string getWebsite()
+{
+	return "http://www.inoreader.com/";
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
+}
 
-	public string getID()
-	{
-		return "inoreader";
-	}
+public string getID()
+{
+	return "inoreader";
+}
 
-	public string iconName()
-	{
-		return "feed-service-inoreader";
-	}
+public string iconName()
+{
+	return "feed-service-inoreader";
+}
 
-	public string serviceName()
-	{
-		return "InoReader";
-	}
+public string serviceName()
+{
+	return "InoReader";
+}
 
-	public void writeData()
-	{
-		return;
-	}
+public void writeData()
+{
+	return;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public bool extractCode(string redirectURL)
+public bool extractCode(string redirectURL)
+{
+	if(redirectURL.has_prefix(InoReaderSecret.apiRedirectUri))
 	{
-		if(redirectURL.has_prefix(InoReaderSecret.apiRedirectUri))
-		{
-			Logger.debug(redirectURL);
-			int csrf_start = redirectURL.index_of("state=")+6;
-			string csrf_code = redirectURL.substring(csrf_start);
-			Logger.debug("InoReaderLoginWidget: csrf_code: " + csrf_code);
+		Logger.debug(redirectURL);
+		int csrf_start = redirectURL.index_of("state=")+6;
+		string csrf_code = redirectURL.substring(csrf_start);
+		Logger.debug("InoReaderLoginWidget: csrf_code: " + csrf_code);
 
-			if(csrf_code == InoReaderSecret.csrf_protection)
-			{
-				int start = redirectURL.index_of("code=")+5;
-				int end = redirectURL.index_of("&", start);
-				string code = redirectURL.substring(start, end-start);
-				m_utils.setApiCode(code);
-				Logger.debug("InoReaderLoginWidget: set inoreader-api-code: " + code);
-				GLib.Thread.usleep(500000);
-				return true;
-			}
-
-			Logger.error("InoReaderLoginWidget: csrf_code mismatch");
-		}
-		else
+		if(csrf_code == InoReaderSecret.csrf_protection)
 		{
-			Logger.warning("InoReaderLoginWidget: wrong redirect_uri");
+			int start = redirectURL.index_of("code=")+5;
+			int end = redirectURL.index_of("&", start);
+			string code = redirectURL.substring(start, end-start);
+			m_utils.setApiCode(code);
+			Logger.debug("InoReaderLoginWidget: set inoreader-api-code: " + code);
+			GLib.Thread.usleep(500000);
+			return true;
 		}
 
-		return false;
+		Logger.error("InoReaderLoginWidget: csrf_code mismatch");
 	}
-
-	public string buildLoginURL()
+	else
 	{
-		return "https://www.inoreader.com/oauth2/auth"
-			+ "?client_id=" + InoReaderSecret.apiClientId
-			+ "&redirect_uri=" + InoReaderSecret.apiRedirectUri
-			+ "&response_type=code"
-			+ "&scope=read+write"
-			+ "&state=" + InoReaderSecret.csrf_protection;
+		Logger.warning("InoReaderLoginWidget: wrong redirect_uri");
 	}
 
-	public bool needWebLogin()
-	{
-		return true;
-	}
+	return false;
+}
 
-	public Gtk.Box? getWidget()
-	{
-		return null;
-	}
+public string buildLoginURL()
+{
+	return "https://www.inoreader.com/oauth2/auth"
+	       + "?client_id=" + InoReaderSecret.apiClientId
+	       + "&redirect_uri=" + InoReaderSecret.apiRedirectUri
+	       + "&response_type=code"
+	       + "&scope=read+write"
+	       + "&state=" + InoReaderSecret.csrf_protection;
+}
 
-	public void showHtAccess()
-	{
-		return;
-	}
+public bool needWebLogin()
+{
+	return true;
+}
 
-	public bool supportTags()
-	{
-		return true;
-	}
+public Gtk.Box? getWidget()
+{
+	return null;
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public void showHtAccess()
+{
+	return;
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-inoreader-symbolic";
-	}
+public bool supportTags()
+{
+	return true;
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public string getServerURL()
-	{
-		return "http://www.inoreader.com/";
-	}
+public string symbolicIcon()
+{
+	return "feed-service-inoreader-symbolic";
+}
 
-	public string uncategorizedID()
-	{
-		return "";
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public bool hideCategoryWhenEmpty(string cadID)
-	{
-		return false;
-	}
+public string getServerURL()
+{
+	return "http://www.inoreader.com/";
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public string uncategorizedID()
+{
+	return "";
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool hideCategoryWhenEmpty(string cadID)
+{
+	return false;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return true;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return true;
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		if(read == ArticleStatus.READ)
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read");
-		else
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		if(marked == ArticleStatus.MARKED)
-			m_api.edidTag(articleID, "user/-/state/com.google/starred");
-		else
-			m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	if(read == ArticleStatus.READ)
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+	else
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+}
 
-	public void setFeedRead(string feedID)
-	{
-		m_api.markAsRead(feedID);
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
+		m_api.edidTag(articleID, "user/-/state/com.google/starred");
+	else
+		m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markAsRead(catID);
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public void markAllItemsRead()
-	{
-		var categories = m_db.read_categories();
-		foreach(Category cat in categories)
-		{
-			m_api.markAsRead(cat.getCatID());
-		}
+public void setFeedRead(string feedID)
+{
+	m_api.markAsRead(feedID);
+}
 
-		var feeds = m_db.read_feeds_without_cat();
-		foreach(Feed feed in feeds)
-		{
-			m_api.markAsRead(feed.getFeedID());
-		}
-		m_api.markAsRead();
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markAsRead(catID);
+}
 
-	public void tagArticle(string articleID, string tagID)
+public void markAllItemsRead()
+{
+	var db = DataBase.readOnly();
+	var categories = db.read_categories();
+	foreach(Category cat in categories)
 	{
-		m_api.edidTag(articleID, tagID, true);
+		m_api.markAsRead(cat.getCatID());
 	}
 
-	public void removeArticleTag(string articleID, string tagID)
+	var feeds = db.read_feeds_without_cat();
+	foreach(Feed feed in feeds)
 	{
-		m_api.edidTag(articleID, tagID, false);
+		m_api.markAsRead(feed.getFeedID());
 	}
+	m_api.markAsRead();
+}
 
-	public string createTag(string caption)
-	{
-		return m_api.composeTagID(caption);
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, true);
+}
 
-	public void deleteTag(string tagID)
-	{
-		m_api.deleteTag(tagID);
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, false);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		m_api.renameTag(tagID, title);
-	}
+public string createTag(string caption)
+{
+	return m_api.composeTagID(caption);
+}
 
-	public bool serverAvailable()
-	{
-		return m_api.ping();
-	}
+public void deleteTag(string tagID)
+{
+	m_api.deleteTag(tagID);
+}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		bool success = false;
-		feedID = "feed/" + feedURL;
-		errmsg = "";
+public void renameTag(string tagID, string title)
+{
+	m_api.renameTag(tagID, title);
+}
 
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.composeTagID(newCatName);
-			success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID, null);
-		}
-		else
-		{
-			success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID, null);
-		}
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
 
-		if(!success)
-			errmsg = "Inoreader could not add %s";
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	bool success = false;
+	feedID = "feed/" + feedURL;
+	errmsg = "";
 
-		return success;
+	if(catID == null && newCatName != null)
+	{
+		string newCatID = m_api.composeTagID(newCatName);
+		success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID, null);
 	}
-
-	public void addFeeds(Gee.List<Feed> feeds)
+	else
 	{
-		string cat = "";
-		string[] urls = {};
+		success = m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID, null);
+	}
 
-		foreach(Feed f in feeds)
-		{
-			if(f.getCatIDs()[0] != cat)
-			{
-				m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
-				urls = {};
-				cat = f.getCatIDs()[0];
-			}
+	if(!success)
+		errmsg = "Inoreader could not add %s";
 
-			urls += "feed/" + f.getXmlUrl();
-		}
+	return success;
+}
 
-		m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
-	}
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	string cat = "";
+	string[] urls = {};
 
-	public void removeFeed(string feedID)
+	foreach(Feed f in feeds)
 	{
-		m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.UNSUBSCRIBE, {feedID}, null, null, null);
-	}
+		if(f.getCatIDs()[0] != cat)
+		{
+			m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
+			urls = {};
+			cat = f.getCatIDs()[0];
+		}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, title, null, null);
+		urls += "feed/" + f.getXmlUrl();
 	}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-	}
+	m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.SUBSCRIBE, urls, null, cat, null);
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.composeTagID(title);
-	}
+public void removeFeed(string feedID)
+{
+	m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.UNSUBSCRIBE, {feedID}, null, null, null);
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameTag(catID, title);
-	}
+public void renameFeed(string feedID, string title)
+{
+	m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, title, null, null);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.editSubscription(InoReaderAPI.InoSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.deleteTag(catID);
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.composeTagID(title);
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
-	{
-		return;
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameTag(catID, title);
+}
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		if(m_api.getFeeds(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
+public void deleteCategory(string catID)
+{
+	m_api.deleteTag(catID);
+}
 
-			if(m_api.getCategoriesAndTags(feeds, categories, tags))
-				return true;
-		}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-		return false;
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public int getUnreadCount()
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getFeeds(feeds))
 	{
-		return m_api.getTotalUnread();
-	}
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-	{
-		if(whatToGet == ArticleStatus.READ)
-		{
-			return;
-		}
-		else if(whatToGet == ArticleStatus.ALL)
-		{
-			var unreadIDs = new Gee.LinkedList<string>();
-			string? continuation = null;
-			int left = 4*count;
+		if(m_api.getCategoriesAndTags(feeds, categories, tags))
+			return true;
+	}
 
-			while(left > 0)
-			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
+	return false;
+}
 
-				if(left > 1000)
-				{
-					continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
-					left -= 1000;
-				}
-				else
-				{
-					m_api.updateArticles(unreadIDs, left, continuation);
-					left = 0;
-				}
-			}
-			m_db_write.updateArticlesByID(unreadIDs, "unread");
-			updateArticleList();
-		}
+public int getUnreadCount()
+{
+	return m_api.getTotalUnread();
+}
 
-		var articles = new Gee.LinkedList<Article>();
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	if(whatToGet == ArticleStatus.READ)
+	{
+		return;
+	}
+	else if(whatToGet == ArticleStatus.ALL)
+	{
+		var unreadIDs = new Gee.LinkedList<string>();
 		string? continuation = null;
-		int left = count;
-		string? inoreader_feedID = (isTagID) ? null : feedID;
-		string? inoreader_tagID = (isTagID) ? feedID : null;
+		int left = 4*count;
 
 		while(left > 0)
 		{
@@ -432,18 +403,44 @@ public class FeedReader.InoReaderInterfa
 
 			if(left > 1000)
 			{
-				continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+				continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
 				left -= 1000;
 			}
 			else
 			{
-				continuation = m_api.getArticles(articles, left, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+				m_api.updateArticles(unreadIDs, left, continuation);
 				left = 0;
 			}
 		}
-		writeArticles(articles);
+		DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+		updateArticleList();
 	}
 
+	var articles = new Gee.LinkedList<Article>();
+	string? continuation = null;
+	int left = count;
+	string? inoreader_feedID = (isTagID) ? null : feedID;
+	string? inoreader_tagID = (isTagID) ? feedID : null;
+
+	while(left > 0)
+	{
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
+
+		if(left > 1000)
+		{
+			continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+			left -= 1000;
+		}
+		else
+		{
+			continuation = m_api.getArticles(articles, left, whatToGet, continuation, inoreader_tagID, inoreader_feedID);
+			left = 0;
+		}
+	}
+	writeArticles(articles);
+}
+
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/inoreader/InoReaderUtils.vala 2.7.1-1/plugins/backend/inoreader/InoReaderUtils.vala
--- 2.6.1-1/plugins/backend/inoreader/InoReaderUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/inoreader/InoReaderUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,122 +14,122 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.InoReaderSecret {
-	 const string base_uri        = "https://www.inoreader.com/reader/api/0/";
-	 const string apiClientId     = "1000001384";
-	 const string apiClientSecret = "3AA9IyNTFL_Mgu77WPpWbawx9loERRdf";
-	 const string apiRedirectUri  = "http://localhost";
-	 const string csrf_protection = "123456";
+const string base_uri        = "https://www.inoreader.com/reader/api/0/";
+const string apiClientId     = "1000001384";
+const string apiClientSecret = "3AA9IyNTFL_Mgu77WPpWbawx9loERRdf";
+const string apiRedirectUri  = "http://localhost";
+const string csrf_protection = "123456";
 }
 
 public class FeedReader.InoReaderUtils : GLib.Object {
 
-	private GLib.Settings m_settings;
+private GLib.Settings m_settings;
 
-	public InoReaderUtils(GLib.SettingsBackend? settings_backend)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.inoreader", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.inoreader");
-	}
-
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+public InoReaderUtils(GLib.SettingsBackend? settings_backend)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.inoreader", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.inoreader");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public string getRefreshToken()
-	{
-		return Utils.gsettingReadString(m_settings, "refresh-token");
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public void setRefreshToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "refresh-token", token);
-	}
+public string getRefreshToken()
+{
+	return Utils.gsettingReadString(m_settings, "refresh-token");
+}
 
-	public string getAccessToken()
-	{
-		return Utils.gsettingReadString(m_settings, "access-token");
-	}
+public void setRefreshToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "refresh-token", token);
+}
 
-	public void setAccessToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "access-token", token);
-	}
+public string getAccessToken()
+{
+	return Utils.gsettingReadString(m_settings, "access-token");
+}
 
-	public string getApiCode()
-	{
-		return Utils.gsettingReadString(m_settings, "api-code");
-	}
+public void setAccessToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "access-token", token);
+}
 
-	public void setApiCode(string code)
-	{
-		Utils.gsettingWriteString(m_settings, "api-code", code);
-	}
+public string getApiCode()
+{
+	return Utils.gsettingReadString(m_settings, "api-code");
+}
 
-	public int getExpiration()
-	{
-		return m_settings.get_int("access-token-expires");
-	}
+public void setApiCode(string code)
+{
+	Utils.gsettingWriteString(m_settings, "api-code", code);
+}
 
-	public void setExpiration(int seconds)
-	{
-		m_settings.set_int("access-token-expires", seconds);
-	}
+public int getExpiration()
+{
+	return m_settings.get_int("access-token-expires");
+}
 
-	public string getUserID()
-	{
-		return Utils.gsettingReadString(m_settings, "user-id");
-	}
+public void setExpiration(int seconds)
+{
+	m_settings.set_int("access-token-expires", seconds);
+}
 
-	public void setUserID(string id)
-	{
-		Utils.gsettingWriteString(m_settings, "user-id", id);
-	}
+public string getUserID()
+{
+	return Utils.gsettingReadString(m_settings, "user-id");
+}
 
-	public string getEmail()
-	{
-		return Utils.gsettingReadString(m_settings, "user-email");
-	}
+public void setUserID(string id)
+{
+	Utils.gsettingWriteString(m_settings, "user-id", id);
+}
 
-	public void setEmail(string email)
-	{
-		Utils.gsettingWriteString(m_settings, "user-email", email);
-	}
+public string getEmail()
+{
+	return Utils.gsettingReadString(m_settings, "user-email");
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-	}
+public void setEmail(string email)
+{
+	Utils.gsettingWriteString(m_settings, "user-email", email);
+}
 
-	public bool accessTokenValid()
-	{
-		var now = new DateTime.now_local();
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+}
 
-		if((int)now.to_unix() >  getExpiration())
-		{
-			Logger.warning("InoReaderUtils: access token expired");
-			return false;
-		}
+public bool accessTokenValid()
+{
+	var now = new DateTime.now_local();
 
-		return true;
+	if((int)now.to_unix() >  getExpiration())
+	{
+		Logger.warning("InoReaderUtils: access token expired");
+		return false;
 	}
 
-	public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+	return true;
+}
+
+public bool tagIsCat(string tagID, Gee.List<Feed> feeds)
+{
+	foreach(Feed feed in feeds)
 	{
-		foreach(Feed feed in feeds)
+		if(feed.hasCat(tagID))
 		{
-			if(feed.hasCat(tagID))
-			{
-				return true;
-			}
+			return true;
 		}
-		return false;
 	}
+	return false;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/local/localInterface.vala 2.7.1-1/plugins/backend/local/localInterface.vala
--- 2.6.1-1/plugins/backend/local/localInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/local/localInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,522 +15,521 @@
 
 public class FeedReader.localInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private localUtils m_utils;
-	private Soup.Session m_session;
-	private Gtk.ListBox m_feedlist;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
-
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new localUtils();
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_session.timeout = 5;
-	}
+private localUtils m_utils;
+private Soup.Session m_session;
+private Gtk.ListBox m_feedlist;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new localUtils();
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_session.timeout = 5;
+}
 
-	public string getWebsite()
-	{
-		return "http://jangernert.github.io/FeedReader/";
-	}
+public string getWebsite()
+{
+	return "http://jangernert.github.io/FeedReader/";
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.LOCAL | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+}
 
-	public string getID()
-	{
-		return "local";
-	}
+public string getID()
+{
+	return "local";
+}
 
-	public string iconName()
-	{
-		return "feed-service-local";
-	}
+public string iconName()
+{
+	return "feed-service-local";
+}
 
-	public string serviceName()
-	{
-		return "Local RSS";
-	}
+public string serviceName()
+{
+	return "Local RSS";
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public Gtk.Box? getWidget()
-	{
-		var doneLabel = new Gtk.Label(_("Done"));
-		var waitingLabel = new Gtk.Label(_("Adding Feeds"));
-		var waitingSpinner = new Gtk.Spinner();
-		var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
-		waitingBox.pack_start(waitingSpinner, false, false, 0);
-		waitingBox.pack_start(waitingLabel, true, false, 0);
-		var loginStack = new Gtk.Stack();
-		loginStack.add_named(doneLabel, "label");
-		loginStack.add_named(waitingBox, "waiting");
-		var loginButton = new Gtk.Button();
-		loginButton.add(loginStack);
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => {
+public Gtk.Box? getWidget()
+{
+	var doneLabel = new Gtk.Label(_("Done"));
+	var waitingLabel = new Gtk.Label(_("Adding Feeds"));
+	var waitingSpinner = new Gtk.Spinner();
+	var waitingBox = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+	waitingBox.pack_start(waitingSpinner, false, false, 0);
+	waitingBox.pack_start(waitingLabel, true, false, 0);
+	var loginStack = new Gtk.Stack();
+	loginStack.add_named(doneLabel, "label");
+	loginStack.add_named(waitingBox, "waiting");
+	var loginButton = new Gtk.Button();
+	loginButton.add(loginStack);
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => {
 			tryLogin();
 			loginButton.set_sensitive(false);
 			waitingSpinner.start();
 			loginButton.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
 			loginStack.set_visible_child_name("waiting");
 		});
-		loginButton.show_all();
+	loginButton.show_all();
 
-		var headlineLabel = new Gtk.Label("Recommended Feeds:");
-		headlineLabel.get_style_context().add_class("h1");
-		headlineLabel.set_justify(Gtk.Justification.CENTER);
-
-		var loginLabel = new Gtk.Label("Fill your library with feeds. Here are some recommendations.");
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		m_feedlist = new Gtk.ListBox();
-		m_feedlist.set_selection_mode(Gtk.SelectionMode.NONE);
-		m_feedlist.set_sort_func(sortFunc);
-		m_feedlist.set_header_func(headerFunc);
+	var headlineLabel = new Gtk.Label("Recommended Feeds:");
+	headlineLabel.get_style_context().add_class("h1");
+	headlineLabel.set_justify(Gtk.Justification.CENTER);
+
+	var loginLabel = new Gtk.Label("Fill your library with feeds. Here are some recommendations.");
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	m_feedlist = new Gtk.ListBox();
+	m_feedlist.set_selection_mode(Gtk.SelectionMode.NONE);
+	m_feedlist.set_sort_func(sortFunc);
+	m_feedlist.set_header_func(headerFunc);
+
+	try
+	{
+		uint8[] contents;
+		var file = File.new_for_uri("resource:///org/gnome/FeedReader/recommendedFeeds.json");
+		file.load_contents(null, out contents, null);
+
+		var parser = new Json.Parser();
+		parser.load_from_data((string)contents);
+
+		Json.Array array = parser.get_root().get_array();
+
+		for (int i = 0; i < array.get_length (); i++)
+		{
+			Json.Object object = array.get_object_element(i);
+
+			m_feedlist.add(
+				new SuggestedFeedRow(
+					object.get_string_member("url"),
+					object.get_string_member("icon"),
+					object.get_string_member("category"),
+					object.get_string_member("name"),
+					object.get_string_member("description"),
+					object.get_string_member("language")
+					)
+				);
+		}
+	}
+	catch(GLib.Error e)
+	{
+		Logger.error("localLoginWidget: loading json filed");
+		Logger.error(e.message);
+	}
 
-		try
-		{
-			uint8[] contents;
-			var file = File.new_for_uri("resource:///org/gnome/FeedReader/recommendedFeeds.json");
-			file.load_contents(null, out contents, null);
+	var scroll = new Gtk.ScrolledWindow(null, null);
+	scroll.set_size_request(450, 0);
+	scroll.set_halign(Gtk.Align.CENTER);
+	scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+	scroll.add(m_feedlist);
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+	box.margin = 50;
+	box.valign = Gtk.Align.FILL;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(headlineLabel, false, false, 0);
+	box.pack_start(loginLabel, false, false, 2);
+	box.pack_start(scroll, true, true, 20);
+	box.pack_end(loginButton, false, false, 0);
+	return box;
+}
 
-			var parser = new Json.Parser();
-			parser.load_from_data((string)contents);
+public void showHtAccess()
+{
+	return;
+}
 
-			Json.Array array = parser.get_root().get_array();
+public void writeData()
+{
+	return;
+}
 
-			for (int i = 0; i < array.get_length (); i++)
+public async void postLoginAction()
+{
+	SourceFunc callback = postLoginAction.callback;
+	new GLib.Thread<void*>(null, () => {
+		var children = m_feedlist.get_children();
+		foreach(var r in children)
+		{
+			var row = r as SuggestedFeedRow;
+			if(row.checked())
 			{
-				Json.Object object = array.get_object_element(i);
-
-				m_feedlist.add(
-					new SuggestedFeedRow(
-						object.get_string_member("url"),
-						object.get_string_member("icon"),
-						object.get_string_member("category"),
-						object.get_string_member("name"),
-						object.get_string_member("description"),
-						object.get_string_member("language")
-						)
-				);
+				FeedReaderBackend.get_default().addFeed(row.getURL(), row.getCategory(), false);
 			}
 		}
-		catch(GLib.Error e)
-		{
-			Logger.error("localLoginWidget: loading json filed");
-			Logger.error(e.message);
-		}
+		Idle.add((owned) callback);
+		return null;
+	});
+	yield;
+}
 
-		var scroll = new Gtk.ScrolledWindow(null, null);
-		scroll.set_size_request(450, 0);
-		scroll.set_halign(Gtk.Align.CENTER);
-		scroll.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
-		scroll.add(m_feedlist);
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
-		box.margin = 50;
-		box.valign = Gtk.Align.FILL;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(headlineLabel, false, false, 0);
-		box.pack_start(loginLabel, false, false, 2);
-		box.pack_start(scroll, true, true, 20);
-		box.pack_end(loginButton, false, false, 0);
-		return box;
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public void showHtAccess()
-	{
-		return;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public void writeData()
-	{
-		return;
-	}
+private int sortFunc(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
+{
+	var r1 = row1 as SuggestedFeedRow;
+	var r2 = row2 as SuggestedFeedRow;
 
-	public async void postLoginAction()
-	{
-		SourceFunc callback = postLoginAction.callback;
-		new GLib.Thread<void*>(null, () => {
-			var children = m_feedlist.get_children();
-			foreach(var r in children)
-			{
-				var row = r as SuggestedFeedRow;
-				if(row.checked())
-				{
-					FeedReaderBackend.get_default().addFeed(row.getURL(), row.getCategory(), false, false);
-				}
-			}
-			Idle.add((owned) callback);
-			return null;
-		});
-		yield;
-	}
+	string cat1 = r1.getCategory();
+	string cat2 = r2.getCategory();
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+	string name1 = r1.getName();
+	string name2 = r2.getName();
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+	if(cat1 != cat2)
+		return cat1.collate(cat2);
 
-	private int sortFunc(Gtk.ListBoxRow row1, Gtk.ListBoxRow row2)
-	{
-		var r1 = row1 as SuggestedFeedRow;
-		var r2 = row2 as SuggestedFeedRow;
+	return name1.collate(name2);
+}
 
-		string cat1 = r1.getCategory();
-		string cat2 = r2.getCategory();
+private void headerFunc(Gtk.ListBoxRow row, Gtk.ListBoxRow? before)
+{
+	var r1 = row as SuggestedFeedRow;
+	string cat1 = r1.getCategory();
 
-		string name1 = r1.getName();
-		string name2 = r2.getName();
+	var label = new Gtk.Label(cat1);
+	label.get_style_context().add_class("bold");
+	label.margin_top = 20;
+	label.margin_bottom = 5;
 
-		if(cat1 != cat2)
-			return cat1.collate(cat2);
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+	box.pack_start(label, true, true, 0);
+	box.pack_end(new Gtk.Separator(Gtk.Orientation.HORIZONTAL), false, false, 0);
+	box.show_all();
 
-		return name1.collate(name2);
+	if(before == null)
+	{
+		row.set_header(box);
+		return;
 	}
 
-	private void headerFunc(Gtk.ListBoxRow row, Gtk.ListBoxRow? before)
-	{
-		var r1 = row as SuggestedFeedRow;
-		string cat1 = r1.getCategory();
+	var r2 = before as SuggestedFeedRow;
+	string cat2 = r2.getCategory();
 
-		var label = new Gtk.Label(cat1);
-		label.get_style_context().add_class("bold");
-		label.margin_top = 20;
-		label.margin_bottom = 5;
+	if(cat1 != cat2)
+		row.set_header(box);
+}
 
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
-		box.pack_start(label, true, true, 0);
-		box.pack_end(new Gtk.Separator(Gtk.Orientation.HORIZONTAL), false, false, 0);
-		box.show_all();
 
-		if(before == null)
-		{
-			row.set_header(box);
-			return;
-		}
+public bool supportTags()
+{
+	return true;
+}
 
-		var r2 = before as SuggestedFeedRow;
-		string cat2 = r2.getCategory();
+public bool doInitSync()
+{
+	return false;
+}
 
-		if(cat1 != cat2)
-			row.set_header(box);
-	}
+public string symbolicIcon()
+{
+	return "feed-service-local-symbolic";
+}
 
+public string accountName()
+{
+	return "Local RSS";
+}
 
-	public bool supportTags()
-	{
-		return true;
-	}
+public string getServerURL()
+{
+	return "http://localhost/";
+}
 
-	public bool doInitSync()
-	{
-		return false;
-	}
+public string uncategorizedID()
+{
+	return "0";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-local-symbolic";
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return false;
+}
 
-	public string accountName()
-	{
-		return "Local RSS";
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public string getServerURL()
-	{
-		return "http://localhost/";
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public string uncategorizedID()
-	{
-		return "0";
-	}
+public bool supportMultiLevelCategories()
+{
+	return true;
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool syncFeedsAndCategories()
+{
+	return false;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return false;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return true;
-	}
+public void resetAccount()
+{
+	return;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return false;
-	}
+public LoginResponse login()
+{
+	return LoginResponse.SUCCESS;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return false;
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public void resetAccount()
-	{
-		return;
-	}
+public bool serverAvailable()
+{
+	return Utils.ping("https://duckduckgo.com/");
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	return;
+}
 
-	public LoginResponse login()
-	{
-		return LoginResponse.SUCCESS;
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	return;
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public bool serverAvailable()
-	{
-		return Utils.ping("https://duckduckgo.com/");
-	}
+public void setFeedRead(string feedID)
+{
+	return;
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		return;
-	}
+public void setCategoryRead(string catID)
+{
+	return;
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		return;
-	}
+public void markAllItemsRead()
+{
+	return;
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	return;
+}
 
-	public void setFeedRead(string feedID)
-	{
-		return;
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	return;
+}
 
-	public void setCategoryRead(string catID)
-	{
-		return;
-	}
+public string createTag(string caption)
+{
+	string tagID = "1";
+
+	var db = DataBase.readOnly();
+	if(!db.isTableEmpty("tags"))
+		tagID = (int.parse(db.getMaxID("tags", "tagID")) + 1).to_string();
 
-	public void markAllItemsRead()
-	{
-		return;
-	}
+	Logger.info("createTag: ID = " + tagID);
+	return tagID;
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		return;
-	}
+public void deleteTag(string tagID)
+{
+	return;
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		return;
-	}
+public void renameTag(string tagID, string title)
+{
+	return;
+}
 
-	public string createTag(string caption)
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	var catIDs = new Gee.ArrayList<string>();
+	var db = DataBase.writeAccess();
+	if(catID == null && newCatName != null)
 	{
-		string tagID = "1";
-
-		if(!m_db.isTableEmpty("tags"))
-			tagID = (int.parse(m_db.getMaxID("tags", "tagID")) + 1).to_string();
-
-		Logger.info("createTag: ID = " + tagID);
-		return tagID;
+		string cID = createCategory(newCatName, null);
+		var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
+		db.write_categories(ListUtils.single(cat));
+		catIDs.add(cID);
 	}
-
-	public void deleteTag(string tagID)
+	else if(catID != null && newCatName == null)
 	{
-		return;
+		catIDs.add(catID);
 	}
-
-	public void renameTag(string tagID, string title)
+	else
 	{
-		return;
+		catIDs.add("0");
 	}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+	feedID = Uuid.string_random();
+
+	Logger.info(@"addFeed: ID = $feedID");
+	Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
+
+	if(feed != null)
 	{
-	 	var catIDs = new Gee.ArrayList<string>();
-		if(catID == null && newCatName != null)
-		{
-			string cID = createCategory(newCatName, null);
-			var cat = new Category(cID, newCatName, 0, 99, CategoryID.MASTER.to_string(), 1);
-			m_db_write.write_categories(ListUtils.single(cat));
-			catIDs.add(cID);
-		}
-		else if(catID != null && newCatName == null)
-		{
-			catIDs.add(catID);
-		}
-		else
-		{
-			catIDs.add("0");
+		if(!db.feed_exists(feed.getURL())) {
+			db.write_feeds(ListUtils.single(feed));
+			return true;
 		}
+	}
 
-		feedID = Uuid.string_random();
+	return false;
+}
 
-		Logger.info(@"addFeed: ID = $feedID");
-		Feed? feed = m_utils.downloadFeed(m_session, feedURL, feedID, catIDs, out errmsg);
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	var finishedFeeds = new Gee.ArrayList<Feed>();
+
+	foreach(Feed f in feeds)
+	{
+		string feedID = Uuid.string_random();
+
+		string url = f.getXmlUrl();
+		Logger.info(@"addFeed: url = $url, ID = $feedID");
+		string errmsg = "";
+		Feed? feed = m_utils.downloadFeed(m_session, url, feedID, f.getCatIDs(), out errmsg);
 
 		if(feed != null)
 		{
-			if(!m_db.feed_exists(feed.getURL())) {
-				m_db_write.write_feeds(ListUtils.single(feed));
-				return true;
-			}
-		}
+			if(feed.getTitle() != "No Title")
+				feed.setTitle(f.getTitle());
 
-		return false;
+			finishedFeeds.add(feed);
+		}
+		else
+			Logger.error("Couldn't add Feed: " + f.getXmlUrl());
 	}
 
-	public void addFeeds(Gee.List<Feed> feeds)
+	foreach(var feed in finishedFeeds)
 	{
-		var finishedFeeds = new Gee.ArrayList<Feed>();
-
-		foreach(Feed f in feeds)
-		{
-			string feedID = Uuid.string_random();
+		Logger.debug("finishedFeed: " + feed.getTitle());
+	}
 
-			string url = f.getXmlUrl();
-			Logger.info(@"addFeed: url = $url, ID = $feedID");
-			string errmsg = "";
-			Feed? feed = m_utils.downloadFeed(m_session, url, feedID, f.getCatIDs(), out errmsg);
+	DataBase.writeAccess().write_feeds(finishedFeeds);
+}
 
-			if(feed != null)
-			{
-				if(feed.getTitle() != "No Title")
-					feed.setTitle(f.getTitle());
+public void removeFeed(string feedID)
+{
+	return;
+}
 
-				finishedFeeds.add(feed);
-			}
-			else
-				Logger.error("Couldn't add Feed: " + f.getXmlUrl());
-		}
+public void renameFeed(string feedID, string title)
+{
+	return;
+}
 
-		foreach(var feed in finishedFeeds)
-		{
-			Logger.debug("finishedFeed: " + feed.getTitle());
-		}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	return;
+}
 
-		m_db_write.write_feeds(finishedFeeds);
-	}
+public string createCategory(string title, string? parentID)
+{
+	string catID;
 
-	public void removeFeed(string feedID)
+	string? id = DataBase.readOnly().getCategoryID(title);
+	if(id == null)
 	{
-		return;
+		catID = Uuid.string_random();
 	}
-
-	public void renameFeed(string feedID, string title)
+	else
 	{
-		return;
-	}
-
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		return;
+		catID = id;
 	}
 
-	public string createCategory(string title, string? parentID)
-	{
-		string catID;
-
-		string? id = m_db.getCategoryID(title);
-		if(id == null)
-		{
-			catID = Uuid.string_random();
-		}
-		else
-		{
-			catID = id;
-		}
+	Logger.info(@"createCategory: title= $title ID = $catID");
+	return catID;
+}
 
-		Logger.info(@"createCategory: title= $title ID = $catID");
-		return catID;
-	}
+public void renameCategory(string catID, string title)
+{
+	return;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		return;
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void deleteCategory(string catID)
+{
+	return;
+}
 
-	public void deleteCategory(string catID)
-	{
-		return;
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
-	{
-		return;
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
-	}
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	return true;
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		return true;
-	}
+public int getUnreadCount()
+{
+	return 0;
+}
 
-	public int getUnreadCount()
-	{
-		return 0;
-	}
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	var db = DataBase.writeAccess();
+	var feeds = db.read_feeds();
+	var articles = new Gee.ArrayList<Article>();
+	GLib.Mutex mutex = GLib.Mutex();
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+	try
 	{
-		var feeds = m_db.read_feeds();
-		var articles = new Gee.ArrayList<Article>();
-		GLib.Mutex mutex = GLib.Mutex();
-
-		try
-		{
-			var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
+		var threads = new ThreadPool<Feed>.with_owned_data((feed) => {
 				if(cancellable != null && cancellable.is_cancelled())
 					return;
 
@@ -539,8 +538,8 @@ public class FeedReader.localInterface :
 
 				if(url == null || url == "" || GLib.Uri.parse_scheme(url) == null)
 				{
-					Logger.error("no valid URL");
-					return;
+				        Logger.error("no valid URL");
+				        return;
 				}
 
 				var msg = new Soup.Message("GET", url);
@@ -554,127 +553,127 @@ public class FeedReader.localInterface :
 				Rss.Parser parser = new Rss.Parser();
 				try
 				{
-					parser.load_from_data(xml, xml.length);
+				        parser.load_from_data(xml, xml.length);
 				}
 				catch(GLib.Error e)
 				{
-					Logger.error("localInterface.getArticles: %s".printf(e.message));
-					return;
+				        Logger.error("localInterface.getArticles: %s".printf(e.message));
+				        return;
 				}
 				var doc = parser.get_document();
 
 				string? locale = null;
 				if(doc.encoding != null
-				&& doc.encoding != "")
+				   && doc.encoding != "")
 				{
-					locale = doc.encoding;
+				        locale = doc.encoding;
 				}
 
 				Logger.debug("Got %u articles".printf(doc.get_items().length()));
 				var newArticles = new Gee.ArrayList<Article>();
 				foreach(Rss.Item item in doc.get_items())
 				{
-					string? articleID = item.guid;
+				        string? articleID = item.guid;
 
-					if(articleID == null)
-					{
-						if(item.link == null)
-						{
-							Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
-							continue;
+				        if(articleID == null)
+				        {
+				                if(item.link == null)
+				                {
+				                        Logger.warning("no valid id and no valid URL as well? what the hell man? I'm giving up");
+				                        continue;
 						}
 
-						articleID = item.link;
+				                articleID = item.link;
 					}
 
-					var date = Rfc822.parseDate(item.pub_date);
-					if (date != null)
-					{
-						Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
+				        var date = Rfc822.parseDate(item.pub_date);
+				        if (date != null)
+				        {
+				                Logger.info(@"Parsed $(item.pub_date) as $(date.to_string())");
 					}
-					else
-					{
-						if (item.pub_date != null)
+				        else
+				        {
+				                if (item.pub_date != null)
 							Logger.warning(@"RFC 822 date parser failed to parse $(item.pub_date). Falling back to DateTime.now()");
-						date = new DateTime.now_local();
+				                date = new DateTime.now_local();
 					}
 
-					//Logger.info("Got content: " + item.description);
-					string? content = m_utils.convert(item.description, locale);
-					//Logger.info("Converted to: " + item.description);
-					if(content == null)
+				        //Logger.info("Got content: " + item.description);
+				        string? content = m_utils.convert(item.description, locale);
+				        //Logger.info("Converted to: " + item.description);
+				        if(content == null)
 						content = _("Nothing to read here.");
 
-					var enclosures = new Gee.ArrayList<Enclosure>();
+				        var enclosures = new Gee.ArrayList<Enclosure>();
 
-					if(item.enclosure_url != null)
-					{
-						// FIXME: check what type of media we actually got
-						enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
+				        if(item.enclosure_url != null)
+				        {
+				                // FIXME: check what type of media we actually got
+				                enclosures.add(new Enclosure(articleID, item.enclosure_url, EnclosureType.FILE));
 					}
 
-					string articleURL = item.link;
-					if(articleURL.has_prefix("/"))
+				        string articleURL = item.link;
+				        if(articleURL.has_prefix("/"))
 						articleURL = feed.getURL() + articleURL.substring(1);
 
-					var article = new Article(
-										articleID,
-										(item.title != null) ? m_utils.convert(item.title, locale) : null,
-										articleURL,
-										feed.getFeedID(),
-										ArticleStatus.UNREAD,
-										ArticleStatus.UNMARKED,
-										content,
-										content,
-										m_utils.convert(item.author, locale),
-										date,
-										0,
-										null,
-										enclosures
-					);
+				        var article = new Article(
+						articleID,
+						(item.title != null) ? m_utils.convert(item.title, locale) : null,
+						articleURL,
+						feed.getFeedID(),
+						ArticleStatus.UNREAD,
+						ArticleStatus.UNMARKED,
+						content,
+						content,
+						m_utils.convert(item.author, locale),
+						date,
+						0,
+						null,
+						enclosures
+						);
 
-					Logger.debug("Got new article: " + article.getTitle());
+				        Logger.debug("Got new article: " + article.getTitle());
 
-					newArticles.add(article);
+				        newArticles.add(article);
 				}
 				mutex.lock();
 				articles.add_all(newArticles);
 				mutex.unlock();
 			}, (int)GLib.get_num_processors(), true);
 
-			foreach(Feed feed in feeds)
+		foreach(Feed feed in feeds)
+		{
+			try
 			{
-				try
-				{
-					threads.add(feed);
-				}
-				catch(GLib.Error e)
-				{
-					Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
-				}
+				threads.add(feed);
+			}
+			catch(GLib.Error e)
+			{
+				Logger.error("Error creating thread to download Feed %s: %s".printf(feed.getTitle(), e.message));
 			}
-
-			bool immediate = false; // allow to queue up additional tasks
-			bool wait = true; // function will block until all tasks are done
-			ThreadPool.free((owned)threads, immediate, wait);
-		}
-		catch(Error e)
-		{
-			Logger.error("Error creating threads to download Feeds: " + e.message);
 		}
 
-		articles.sort((a, b) => {
+		bool immediate = false;         // allow to queue up additional tasks
+		bool wait = true;         // function will block until all tasks are done
+		ThreadPool.free((owned)threads, immediate, wait);
+	}
+	catch(Error e)
+	{
+		Logger.error("Error creating threads to download Feeds: " + e.message);
+	}
+
+	articles.sort((a, b) => {
 			return strcmp(a.getArticleID(), b.getArticleID());
 		});
 
-		if(articles.size > 0)
-		{
-			m_db_write.write_articles(articles);
-			Logger.debug("localInterface: %i articles written".printf(articles.size));
-			refreshFeedListCounter();
-			updateArticleList();
-		}
+	if(articles.size > 0)
+	{
+		db.write_articles(articles);
+		Logger.debug("localInterface: %i articles written".printf(articles.size));
+		refreshFeedListCounter();
+		updateArticleList();
 	}
+}
 
 }
 
diff -pruN 2.6.1-1/plugins/backend/local/localUtils.vala 2.7.1-1/plugins/backend/local/localUtils.vala
--- 2.6.1-1/plugins/backend/local/localUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/local/localUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,82 +15,82 @@
 
 public class FeedReader.localUtils : GLib.Object {
 
-	public localUtils()
-	{
+public localUtils()
+{
+
+}
 
+public Feed? downloadFeed(Soup.Session session, string xmlURL, string feedID, Gee.List<string> catIDs, out string errmsg)
+{
+	errmsg = "";
+
+	// download
+	//Logger.debug(@"Requesting: $xmlURL");
+	var msg = new Soup.Message("GET", xmlURL);
+	if (msg == null)
+	{
+		errmsg = @"Couldn't parse feed URL: $xmlURL";
+		Logger.warning(errmsg);
+		return null;
+	}
+	uint status = session.send_message(msg);
+	if(status != 200)
+	{
+		errmsg = "Could not download feed";
+		Logger.warning(errmsg);
+		return null;
 	}
+	string xml = (string)msg.response_body.flatten().data;
+	string? url = null;
 
-	public Feed? downloadFeed(Soup.Session session, string xmlURL, string feedID, Gee.List<string> catIDs, out string errmsg)
+	// parse
+	Rss.Parser parser = new Rss.Parser();
+	try
+	{
+		parser.load_from_data(xml, xml.length);
+	}
+	catch(Error e)
 	{
-		errmsg = "";
+		errmsg = "Could not parse feed";
+		Logger.warning(errmsg);
+		return null;
+	}
+
+	var doc = parser.get_document();
 
-		// download
-		//Logger.debug(@"Requesting: $xmlURL");
-		var msg = new Soup.Message("GET", xmlURL);
-		if (msg == null)
-		{
-			errmsg = @"Couldn't parse feed URL: $xmlURL";
-			Logger.warning(errmsg);
-			return null;
-		}
-		uint status = session.send_message(msg);
-		if(status != 200)
-		{
-			errmsg = "Could not download feed";
-			Logger.warning(errmsg);
-			return null;
-		}
-		string xml = (string)msg.response_body.flatten().data;
-		string? url = null;
-
-		// parse
-		Rss.Parser parser = new Rss.Parser();
-		try
-		{
-			parser.load_from_data(xml, xml.length);
-		}
-		catch(Error e)
-		{
-			errmsg = "Could not parse feed";
-			Logger.warning(errmsg);
-			return null;
-		}
-
-		var doc = parser.get_document();
-
-		if(doc.link != null
-		&& doc.link != "")
-			url = doc.link;
-
-		var Feed = new Feed(
-					feedID,
-					doc.title,
-					url,
-					0,
-					catIDs,
-					doc.image_url,
-					xmlURL);
-
-		return Feed;
-	}
-
-	public string? convert(string? text, string? locale)
-	{
-		if(text == null)
-			return null;
-
-		if(locale == null)
-			return text;
-
-		try
-		{
-			return GLib.convert(text, -1, "utf-8", locale);
-		}
-		catch(ConvertError e)
-		{
-			Logger.error(e.message);
-		}
+	if(doc.link != null
+	   && doc.link != "")
+		url = doc.link;
+
+	var Feed = new Feed(
+		feedID,
+		doc.title,
+		url,
+		0,
+		catIDs,
+		doc.image_url,
+		xmlURL);
 
-		return "";
+	return Feed;
+}
+
+public string? convert(string? text, string? locale)
+{
+	if(text == null)
+		return null;
+
+	if(locale == null)
+		return text;
+
+	try
+	{
+		return GLib.convert(text, -1, "utf-8", locale);
 	}
+	catch(ConvertError e)
+	{
+		Logger.error(e.message);
+	}
+
+	return "";
+}
 }
diff -pruN 2.6.1-1/plugins/backend/local/SuggestedFeedRow.vala 2.7.1-1/plugins/backend/local/SuggestedFeedRow.vala
--- 2.6.1-1/plugins/backend/local/SuggestedFeedRow.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/local/SuggestedFeedRow.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,90 +15,90 @@
 
 public class FeedReader.SuggestedFeedRow : Gtk.ListBoxRow {
 
-	private string m_name;
-	private string m_url;
-	private string m_category;
-	private string m_desc;
-	private Gtk.CheckButton m_check;
-
-	public SuggestedFeedRow(string url, string iconURL, string category, string name, string desc, string lang)
-	{
-		m_name = name;
-		m_url = url;
-		m_category = category;
-		m_desc = desc;
-
-		var iconStack = new Gtk.Stack();
-		iconStack.set_size_request(24, 24);
-		iconStack.set_transition_duration(100);
-		iconStack.set_transition_type(Gtk.StackTransitionType.CROSSFADE);
-
-		var spinner = new Gtk.Spinner();
-		iconStack.add_named(spinner, "spinner");
-		spinner.start();
-
-		m_check = new Gtk.CheckButton();
-		var label = new Gtk.Label(name);
-		label.get_style_context().add_class("h3");
-		label.set_alignment(0.0f, 0.5f);
-
-		var langLabel = new Gtk.Label(lang);
-		langLabel.opacity = 0.7;
-		langLabel.set_alignment(1.0f, 0.5f);
-		langLabel.get_style_context().add_class("preview");
-
-		var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-		box.margin_top = 5;
-		box.margin_bottom = 5;
-		box.pack_start(m_check, false, false, 10);
-		box.pack_start(iconStack, false, false, 10);
-		box.pack_start(label, true, true, 10);
-		box.pack_end(langLabel, false, false, 10);
-		var box2 = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
-		box2.pack_start(box);
-		box2.pack_start(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
-		this.add(box2);
-		this.set_tooltip_text(m_desc);
-		show_all();
-
-		var uri = new Soup.URI(url);
-		var fakeFeed = new Feed(uri.get_host(), null, null, 0);
-		load_favicon.begin(iconStack, fakeFeed, iconURL, (obj, res) => {
+private string m_name;
+private string m_url;
+private string m_category;
+private string m_desc;
+private Gtk.CheckButton m_check;
+
+public SuggestedFeedRow(string url, string iconURL, string category, string name, string desc, string lang)
+{
+	m_name = name;
+	m_url = url;
+	m_category = category;
+	m_desc = desc;
+
+	var iconStack = new Gtk.Stack();
+	iconStack.set_size_request(24, 24);
+	iconStack.set_transition_duration(100);
+	iconStack.set_transition_type(Gtk.StackTransitionType.CROSSFADE);
+
+	var spinner = new Gtk.Spinner();
+	iconStack.add_named(spinner, "spinner");
+	spinner.start();
+
+	m_check = new Gtk.CheckButton();
+	var label = new Gtk.Label(name);
+	label.get_style_context().add_class("h3");
+	label.set_alignment(0.0f, 0.5f);
+
+	var langLabel = new Gtk.Label(lang);
+	langLabel.opacity = 0.7;
+	langLabel.set_alignment(1.0f, 0.5f);
+	langLabel.get_style_context().add_class("preview");
+
+	var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+	box.margin_top = 5;
+	box.margin_bottom = 5;
+	box.pack_start(m_check, false, false, 10);
+	box.pack_start(iconStack, false, false, 10);
+	box.pack_start(label, true, true, 10);
+	box.pack_end(langLabel, false, false, 10);
+	var box2 = new Gtk.Box(Gtk.Orientation.VERTICAL, 0);
+	box2.pack_start(box);
+	box2.pack_start(new Gtk.Separator(Gtk.Orientation.HORIZONTAL));
+	this.add(box2);
+	this.set_tooltip_text(m_desc);
+	show_all();
+
+	var uri = new Soup.URI(url);
+	var fakeFeed = new Feed(uri.get_host(), null, null, 0);
+	load_favicon.begin(iconStack, fakeFeed, iconURL, (obj, res) => {
 			load_favicon.end(res);
 		});
-	}
+}
+
+private async void load_favicon(Gtk.Stack iconStack, Feed feed, string iconURL)
+{
+	Gtk.Image? icon = null;
+	var surface = yield FavIcon.for_feed(feed).get_surface();
+	if(surface != null)
+		icon = new Gtk.Image.from_surface(surface);
+	else
+		icon = new Gtk.Image.from_icon_name("feed-rss-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
+
+	iconStack.add_named(icon, "icon");
+	show_all();
+	iconStack.set_visible_child_name("icon");
+}
+
+public bool checked()
+{
+	return m_check.active;
+}
 
-	private async void load_favicon(Gtk.Stack iconStack, Feed feed, string iconURL)
-	{
-		Gtk.Image? icon = null;
-		var surface = yield FavIcon.for_feed(feed).get_surface();
-		if(surface != null)
-			icon = new Gtk.Image.from_surface(surface);
-		else
-			icon = new Gtk.Image.from_icon_name("feed-rss-symbolic", Gtk.IconSize.LARGE_TOOLBAR);
-
-		iconStack.add_named(icon, "icon");
-		show_all();
-		iconStack.set_visible_child_name("icon");
-	}
-
-	public bool checked()
-	{
-		return m_check.active;
-	}
-
-	public string getName()
-	{
-		return m_name;
-	}
-
-	public string getURL()
-	{
-		return m_url;
-	}
-
-	public string getCategory()
-	{
-		return m_category;
-	}
+public string getName()
+{
+	return m_name;
+}
+
+public string getURL()
+{
+	return m_url;
+}
+
+public string getCategory()
+{
+	return m_category;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/local/TestLocalRSS.vala 2.7.1-1/plugins/backend/local/TestLocalRSS.vala
--- 2.6.1-1/plugins/backend/local/TestLocalRSS.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/local/TestLocalRSS.vala	2019-02-01 19:30:50.000000000 +0000
@@ -4,106 +4,106 @@ void main(string[] args)
 {
 	Test.init(ref args);
 
-    Test.add_data_func ("/Rfc822/parseDate/Basic", () => {
+	Test.add_data_func ("/Rfc822/parseDate/Basic", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 2006 23:59:45 +0000");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/LowerCase", () => {
+	Test.add_data_func ("/Rfc822/parseDate/LowerCase", () => {
 		var date = Rfc822.parseDate("thu, 09 feb 2006 16:59:45 mst");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/UpperCase", () => {
+	Test.add_data_func ("/Rfc822/parseDate/UpperCase", () => {
 		var date = Rfc822.parseDate("THU, 09 FEB 2006 16:59:45 MST");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/LotsOfWhiteSpace", () => {
+	Test.add_data_func ("/Rfc822/parseDate/LotsOfWhiteSpace", () => {
 		var date = Rfc822.parseDate("  \t\n Thu, \t\n 09 \t\n Feb \t\n 2006 \t\n 23:59:45 \t\n +0000 \t\n");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2000", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2000", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 00 23:59:45 +0000");
 		assert(new DateTime.utc(2000, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2006", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2006", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 06 23:59:45 +0000");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2049", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear2049", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 49 23:59:45 +0000");
 		assert(new DateTime.utc(2049, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1950", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1950", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 50 23:59:45 +0000");
 		assert(new DateTime.utc(1950, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1956", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1956", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 56 23:59:45 +0000");
 		assert(new DateTime.utc(1956, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1999", () => {
+	Test.add_data_func ("/Rfc822/parseDate/TwoDigitYear1999", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 99 23:59:45 +0000");
 		assert(new DateTime.utc(1999, 2, 9, 23, 59, 45).equal(date));
 	});
 
 	// Just in case we get RSS feeds made by Romans
-    Test.add_data_func ("/Rfc822/parseDate/ThreeDigitYear", () => {
+	Test.add_data_func ("/Rfc822/parseDate/ThreeDigitYear", () => {
 		var date = Rfc822.parseDate("Thu, 09 Feb 156 23:59:45 +0000");
 		assert(new DateTime.utc(156, 2, 9, 23, 59, 45).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/OnlyRequired", () => {
+	Test.add_data_func ("/Rfc822/parseDate/OnlyRequired", () => {
 		var date = Rfc822.parseDate("09 Feb 2006 23:59 +0000");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/OneDigitDay", () => {
+	Test.add_data_func ("/Rfc822/parseDate/OneDigitDay", () => {
 		var date = Rfc822.parseDate("9 Feb 2006 23:59 +0000");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/UnsupportedZone", () => {
+	Test.add_data_func ("/Rfc822/parseDate/UnsupportedZone", () => {
 		var date = Rfc822.parseDate("09 Feb 2006 23:59 X");
 		assert(new DateTime.utc(2006, 2, 9, 23, 59, 0).equal(date));
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingDay", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingDay", () => {
 		var date = Rfc822.parseDate("Feb 2006 23:59 +0000");
 		assert(date == null);
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingMonth", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingMonth", () => {
 		var date = Rfc822.parseDate("09 2006 23:59 +0000");
 		assert(date == null);
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingYear", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingYear", () => {
 		var date = Rfc822.parseDate("09 Feb 23:59 +0000");
 		assert(date == null);
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingHour", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingHour", () => {
 		var date = Rfc822.parseDate("09 Feb 2006 59 +0000");
 		assert(date == null);
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingMinute", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingMinute", () => {
 		var date = Rfc822.parseDate("09 Feb 2006 23 +0000");
 		assert(date == null);
 	});
 
-    Test.add_data_func ("/Rfc822/parseDate/MissingZone", () => {
+	Test.add_data_func ("/Rfc822/parseDate/MissingZone", () => {
 		var date = Rfc822.parseDate("09 Feb 2006 23:59");
 		assert(date == null);
 	});
 
-    Test.run ();
+	Test.run ();
 }
diff -pruN 2.6.1-1/plugins/backend/oldreader/oldreaderAPI.vala 2.7.1-1/plugins/backend/oldreader/oldreaderAPI.vala
--- 2.6.1-1/plugins/backend/oldreader/oldreaderAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/oldreader/oldreaderAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,429 +15,428 @@
 
 public class FeedReader.OldReaderAPI : GLib.Object {
 
-	public enum OldreaderSubscriptionAction {
-		EDIT,
-		SUBSCRIBE,
-		UNSUBSCRIBE
-	}
+public enum OldreaderSubscriptionAction {
+	EDIT,
+	SUBSCRIBE,
+	UNSUBSCRIBE
+}
 
-	private OldReaderConnection m_connection;
-	private OldReaderUtils m_utils;
-	private string m_userID;
-	private DataBaseReadOnly m_db;
+private OldReaderConnection m_connection;
+private OldReaderUtils m_utils;
+private string m_userID;
+
+public OldReaderAPI(OldReaderUtils utils)
+{
+	m_utils = utils;
+	m_connection = new OldReaderConnection(m_utils);
+}
 
-	public OldReaderAPI(OldReaderUtils utils, DataBaseReadOnly db)
+public LoginResponse login()
+{
+	if(m_utils.getAccessToken() == "")
 	{
-		m_db = db;
-		m_utils = utils;
-		m_connection = new OldReaderConnection(m_utils);
+		var response = m_connection.getToken();
+		if(response != LoginResponse.SUCCESS)
+			return response;
 	}
-
-	public LoginResponse login()
+	if(getUserID())
 	{
-		if(m_utils.getAccessToken() == "")
-		{
-			var response = m_connection.getToken();
-			if(response != LoginResponse.SUCCESS)
-				return response;
-		}
-		if(getUserID())
-		{
-			return LoginResponse.SUCCESS;
-		}
+		return LoginResponse.SUCCESS;
+	}
 
-		return LoginResponse.UNKNOWN_ERROR;
+	return LoginResponse.UNKNOWN_ERROR;
+}
+
+public bool ping() {
+	return Utils.ping("https://theoldreader.com/");
+}
+
+private bool getUserID()
+{
+	Logger.debug("getUserID: getting user info");
+	var response = m_connection.send_get_request("user-info?output=json");
+
+	if(response.status != 200)
+		return false;
+
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
+	catch(Error e)
+	{
+		Logger.error("getUserID: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	if(root.has_member("userId"))
+	{
+		m_userID = root.get_string_member("userId");
+		m_utils.setUserID(m_userID);
+		Logger.info("Oldreader: userID = " + m_userID);
 
-	public bool ping() {
-		return Utils.ping("https://theoldreader.com/");
+		return true;
 	}
 
-	private bool getUserID()
-	{
-		Logger.debug("getUserID: getting user info");
-		var response = m_connection.send_get_request("user-info?output=json");
+	return false;
+}
 
-		if(response.status != 200)
-			return false;
+public bool getFeeds(Gee.List<Feed> feeds)
+{
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getUserID: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		if(root.has_member("userId"))
-		{
-			m_userID = root.get_string_member("userId");
-			m_utils.setUserID(m_userID);
-			Logger.info("Oldreader: userID = " + m_userID);
+	var response = m_connection.send_get_request("subscription/list?output=json");
 
-			return true;
-		}
+	if(response.status != 200)
+		return false;
 
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getFeeds: Could not load message response");
+		Logger.error(e.message);
 		return false;
 	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("subscriptions");
+	uint length = array.get_length();
 
-	public bool getFeeds(Gee.List<Feed> feeds)
+	for (uint i = 0; i < length; i++)
 	{
+		Json.Object object = array.get_object_element(i);
 
-		var response = m_connection.send_get_request("subscription/list?output=json");
+		string feedID = object.get_string_member("id");
+		string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
 
-		if(response.status != 200)
-			return false;
-
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+		uint catCount = object.get_array_member("categories").get_length();
+		var categories = new Gee.ArrayList<string>();
+		for(uint j = 0; j < catCount; ++j)
 		{
-			Logger.error("getFeeds: Could not load message response");
-			Logger.error(e.message);
-			return false;
+			categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
 		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("subscriptions");
-		uint length = array.get_length();
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
+		feeds.add(
+			new Feed(
+				feedID,
+				object.get_string_member("title"),
+				url,
+				0,
+				categories,
+				object.get_string_member("iconUrl")
+				)
+			);
+	}
+	return true;
+}
 
-			string feedID = object.get_string_member("id");
-			string url = object.has_member("htmlUrl") ? object.get_string_member("htmlUrl") : object.get_string_member("url");
+public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
+{
+	var response = m_connection.send_get_request("tag/list?output=json");
 
-			uint catCount = object.get_array_member("categories").get_length();
-			var categories = new Gee.ArrayList<string>();
-			for(uint j = 0; j < catCount; ++j)
-			{
-				categories.add(object.get_array_member("categories").get_object_element(j).get_string_member("id"));
-			}
+	if(response.status != 200)
+		return false;
 
-			feeds.add(
-				new Feed(
-						feedID,
-						object.get_string_member("title"),
-						url,
-						0,
-						categories,
-						object.get_string_member("iconUrl")
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+		return false;
+	}
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("tags");
+	uint length = array.get_length();
+	int orderID = 0;
+
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		int start = id.last_index_of_char('/') + 1;
+		string title = id.substring(start);
+
+		if(id.contains("/label/"))
+		{
+			categories.add(
+				new Category(
+					id,
+					title,
+					0,
+					orderID,
+					CategoryID.MASTER.to_string(),
+					1
 					)
-			);
+				);
+			++orderID;
 		}
-		return true;
 	}
+	return true;
+}
 
-	public bool getCategoriesAndTags(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags)
-	{
-		var response = m_connection.send_get_request("tag/list?output=json");
 
-		if(response.status != 200)
-			return false;
+public int getTotalUnread()
+{
+	var response = m_connection.send_get_request("unread-count?output=json");
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
-			return false;
-		}
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("tags");
-		uint length = array.get_length();
-		int orderID = 0;
-
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			int start = id.last_index_of_char('/') + 1;
-			string title = id.substring(start);
+	if(response.status != 200)
+		return 0;
 
-			if(id.contains("/label/"))
-			{
-					categories.add(
-						new Category(
-							id,
-							title,
-							0,
-							orderID,
-							CategoryID.MASTER.to_string(),
-							1
-						)
-					);
-				++orderID;
-			}
-		}
-		return true;
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response.data, -1);
 	}
-
-
-	public int getTotalUnread()
+	catch(Error e)
 	{
-		var response = m_connection.send_get_request("unread-count?output=json");
+		Logger.error("getTotalUnread: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		if(response.status != 200)
-			return 0;
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("unreadcounts");
+	uint length = array.get_length();
+	int count = 0;
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		if(object.get_string_member("id").has_prefix("feed/"))
 		{
-			Logger.error("getTotalUnread: Could not load message response");
-			Logger.error(e.message);
+			count += (int)object.get_int_member("count");
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("unreadcounts");
-		uint length = array.get_length();
-		int count = 0;
+	}
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			if(object.get_string_member("id").has_prefix("feed/"))
-			{
-				count += (int)object.get_int_member("count");
-			}
+	Logger.debug("getTotalUnread %i".printf(count));
+	return count;
+}
 
-		}
 
-		Logger.debug("getTotalUnread %i".printf(count));
-		return count;
-	}
+public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+{
+	var message_string = "n=" + count.to_string();
+	message_string += "&xt=user/-/state/com.google/read";
+	if(continuation != null)
+		message_string += "&c=" + continuation;
+
+	var response = m_connection.send_get_request("stream/items/ids?output=json&"+message_string);
 
+	if(response.status != 200)
+		return null;
 
-	public string? updateArticles(Gee.List<string> ids, int count, string? continuation = null)
+	var parser = new Json.Parser();
+	try
 	{
-		var message_string = "n=" + count.to_string();
-		message_string += "&xt=user/-/state/com.google/read";
-		if(continuation != null)
-			message_string += "&c=" + continuation;
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("updateArticles: Could not load message response");
+		Logger.error(e.message);
+		return null;
+	}
 
-		var response = m_connection.send_get_request("stream/items/ids?output=json&"+message_string);
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("itemRefs");
+	uint length = array.get_length();
 
-		if(response.status != 200)
-			return null;
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		ids.add(object.get_string_member("id"));
+	}
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
-		{
-			Logger.error("updateArticles: Could not load message response");
-			Logger.error(e.message);
-			return null;
-		}
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("itemRefs");
-		uint length = array.get_length();
+	return null;
+}
 
-		for (uint i = 0; i < length; i++)
-		{
-			Json.Object object = array.get_object_element(i);
-			ids.add(object.get_string_member("id"));
-		}
+public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+{
+	var message_string = "n=" + count.to_string();
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
+	if(whatToGet == ArticleStatus.UNREAD)
+		message_string += "&xt=user/-/state/com.google/read";
+	if(whatToGet == ArticleStatus.READ)
+		message_string += "&s=user/-/state/com.google/read";
+	else if(whatToGet == ArticleStatus.MARKED)
+		message_string += "&s=user/-/state/com.google/starred";
+
+	message_string += "&c=" + continuation;
+
+
+	string api_endpoint = "stream/contents";
+	if(feed_id != null)
+		api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
+	else if(tagID != null)
+		api_endpoint += "/" + GLib.Uri.escape_string(tagID);
+	var response = m_connection.send_get_request(api_endpoint+"?output=json&"+message_string);
 
+	if(response.status != 200)
 		return null;
-	}
 
-	public string? getArticles(Gee.List<Article> articles, int count, ArticleStatus whatToGet = ArticleStatus.ALL, string? continuation = null, string? tagID = null, string? feed_id = null)
+	var parser = new Json.Parser();
+	try
 	{
-		var message_string = "n=" + count.to_string();
-
-		if(whatToGet == ArticleStatus.UNREAD)
-			message_string += "&xt=user/-/state/com.google/read";
-		if(whatToGet == ArticleStatus.READ)
-			message_string += "&s=user/-/state/com.google/read";
-		else if(whatToGet == ArticleStatus.MARKED)
-			message_string += "&s=user/-/state/com.google/starred";
-
-			message_string += "&c=" + continuation;
-
+		parser.load_from_data(response.data, -1);
+	}
+	catch(Error e)
+	{
+		Logger.error("getCategoriesAndTags: Could not load message response");
+		Logger.error(e.message);
+	}
 
-		string api_endpoint = "stream/contents";
-		if(feed_id != null)
-			api_endpoint += "/" + GLib.Uri.escape_string(feed_id);
-		else if(tagID != null)
-			api_endpoint += "/" + GLib.Uri.escape_string(tagID);
-		var response = m_connection.send_get_request(api_endpoint+"?output=json&"+message_string);
+	var root = parser.get_root().get_object();
+	var array = root.get_array_member("items");
+	uint length = array.get_length();
 
-		if(response.status != 200)
-			return null;
+	var db = DataBase.readOnly();
+	for (uint i = 0; i < length; i++)
+	{
+		Json.Object object = array.get_object_element(i);
+		string id = object.get_string_member("id");
+		id = id.substring(id.last_index_of_char('/') + 1);
+		bool marked = false;
+		bool read = false;
+		var cats = object.get_array_member("categories");
+		uint cat_length = cats.get_length();
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response.data, -1);
-		}
-		catch(Error e)
+		var tags = new Gee.ArrayList<string>();
+		for (uint j = 0; j < cat_length; j++)
 		{
-			Logger.error("getCategoriesAndTags: Could not load message response");
-			Logger.error(e.message);
+			string cat = cats.get_string_element(j);
+			if(cat.has_suffix("com.google/starred"))
+				marked = true;
+			else if(cat.has_suffix("com.google/read"))
+				read = true;
+			else if(cat.contains("/label/") && db.getTagName(cat) != null)
+				tags.add(cat);
 		}
 
-		var root = parser.get_root().get_object();
-		var array = root.get_array_member("items");
-		uint length = array.get_length();
-
-		for (uint i = 0; i < length; i++)
+		var enclosures = new Gee.ArrayList<Enclosure>();
+		if(object.has_member("enclosure"))
 		{
-			Json.Object object = array.get_object_element(i);
-			string id = object.get_string_member("id");
-			id = id.substring(id.last_index_of_char('/') + 1);
-			bool marked = false;
-			bool read = false;
-			var cats = object.get_array_member("categories");
-			uint cat_length = cats.get_length();
+			var attachments = object.get_array_member("enclosure");
 
-			var tags = new Gee.ArrayList<string>();
-			for (uint j = 0; j < cat_length; j++)
-			{
-				string cat = cats.get_string_element(j);
-				if(cat.has_suffix("com.google/starred"))
-					marked = true;
-				else if(cat.has_suffix("com.google/read"))
-					read = true;
-				else if(cat.contains("/label/") && m_db.getTagName(cat) != null)
-					tags.add(cat);
-			}
+			uint mediaCount = 0;
+			if(attachments != null)
+				mediaCount = attachments.get_length();
 
-			var enclosures = new Gee.ArrayList<Enclosure>();
-			if(object.has_member("enclosure"))
+			for(int j = 0; j < mediaCount; ++j)
 			{
-				var attachments = object.get_array_member("enclosure");
-
-				uint mediaCount = 0;
-				if(attachments != null)
-					mediaCount = attachments.get_length();
-
-				for(int j = 0; j < mediaCount; ++j)
-				{
-					var attachment = attachments.get_object_element(j);
-					enclosures.add(
-						new Enclosure(id, attachment.get_string_member("href"),
-								EnclosureType.from_string(attachment.get_string_member("type")))
+				var attachment = attachments.get_object_element(j);
+				enclosures.add(
+					new Enclosure(id, attachment.get_string_member("href"),
+					              EnclosureType.from_string(attachment.get_string_member("type")))
 					);
-				}
 			}
-
-			articles.add(new Article(
-									id,
-									object.get_string_member("title"),
-									object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
-									object.get_object_member("origin").get_string_member("streamId"),
-									read ? ArticleStatus.READ : ArticleStatus.UNREAD,
-									marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-									object.get_object_member("summary").get_string_member("content"),
-									null,
-									object.get_string_member("author"),
-									new DateTime.from_unix_local(object.get_int_member("published")),
-									-1,
-									tags,
-									enclosures
-							)
-						);
 		}
 
-		if(root.has_member("continuation") && root.get_string_member("continuation") != "")
-			return root.get_string_member("continuation");
-
-		return null;
+		articles.add(new Article(
+				     id,
+				     object.get_string_member("title"),
+				     object.get_array_member("alternate").get_object_element(0).get_string_member("href"),
+				     object.get_object_member("origin").get_string_member("streamId"),
+				     read ? ArticleStatus.READ : ArticleStatus.UNREAD,
+				     marked ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				     object.get_object_member("summary").get_string_member("content"),
+				     null,
+				     object.get_string_member("author"),
+				     new DateTime.from_unix_local(object.get_int_member("published")),
+				     -1,
+				     tags,
+				     enclosures
+				     )
+		             );
 	}
 
+	if(root.has_member("continuation") && root.get_string_member("continuation") != "")
+		return root.get_string_member("continuation");
 
-	public void edidTag(string articleID, string tagID, bool add = true)
-	{
-		var message_string = "";
-		if(add)
-			message_string += "a=";
-		else
-			message_string += "r=";
+	return null;
+}
 
-		message_string += tagID;
-		message_string += "&i=" + articleID;
-		m_connection.send_post_request("edit-tag?output=json", message_string);
-	}
 
-	public void markAsRead(string? streamID = null)
-	{
-		var settingsState = new GLib.Settings("org.gnome.feedreader.saved-state");
-		string message_string = "s=%s&ts=%i000000".printf(streamID, settingsState.get_int("last-sync"));
-		m_connection.send_post_request("mark-all-as-read?output=json", message_string);
-	}
+public void edidTag(string articleID, string tagID, bool add = true)
+{
+	var message_string = "";
+	if(add)
+		message_string += "a=";
+	else
+		message_string += "r=";
+
+	message_string += tagID;
+	message_string += "&i=" + articleID;
+	m_connection.send_post_request("edit-tag?output=json", message_string);
+}
 
-	public string composeTagID(string tagName)
-	{
-		return "user/%s/label/%s".printf(m_userID, tagName);
-	}
+public void markAsRead(string? streamID = null)
+{
+	var settingsState = new GLib.Settings("org.gnome.feedreader.saved-state");
+	string message_string = "s=%s&ts=%i000000".printf(streamID, settingsState.get_int("last-sync"));
+	m_connection.send_post_request("mark-all-as-read?output=json", message_string);
+}
 
-	public void deleteTag(string tagID)
-	{
-		var message_string = "s=" + tagID;
-		m_connection.send_post_request("disable-tag?output=json", message_string);
-	}
+public string composeTagID(string tagName)
+{
+	return "user/%s/label/%s".printf(m_userID, tagName);
+}
 
-	public void renameTag(string tagID, string title)
-	{
-		var message_string = "s=" + tagID;
-		message_string += "&dest=" + composeTagID(title);
-		m_connection.send_post_request("rename-tag?output=json", message_string);
-	}
+public void deleteTag(string tagID)
+{
+	var message_string = "s=" + tagID;
+	m_connection.send_post_request("disable-tag?output=json", message_string);
+}
 
-	public bool editSubscription(OldreaderSubscriptionAction action, string[] feedID, string? title = null, string? add = null, string? remove = null)
-	{
-		var message_string = "ac=";
+public void renameTag(string tagID, string title)
+{
+	var message_string = "s=" + tagID;
+	message_string += "&dest=" + composeTagID(title);
+	m_connection.send_post_request("rename-tag?output=json", message_string);
+}
 
-		switch(action)
-		{
-			case OldreaderSubscriptionAction.EDIT:
-				message_string += "edit";
-				break;
-			case OldreaderSubscriptionAction.SUBSCRIBE:
-				message_string += "subscribe";
-				break;
-			case OldreaderSubscriptionAction.UNSUBSCRIBE:
-				message_string += "unsubscribe";
-				break;
-		}
+public bool editSubscription(OldreaderSubscriptionAction action, string[] feedID, string? title = null, string? add = null, string? remove = null)
+{
+	var message_string = "ac=";
+
+	switch(action)
+	{
+	case OldreaderSubscriptionAction.EDIT:
+		message_string += "edit";
+		break;
+	case OldreaderSubscriptionAction.SUBSCRIBE:
+		message_string += "subscribe";
+		break;
+	case OldreaderSubscriptionAction.UNSUBSCRIBE:
+		message_string += "unsubscribe";
+		break;
+	}
 
-		foreach(string s in feedID)
-			message_string += "&s=" + s;
+	foreach(string s in feedID)
+		message_string += "&s=" + s;
 
-		if(title != null)
-			message_string += "&t=" + title;
+	if(title != null)
+		message_string += "&t=" + title;
 
-		if(add != null)
-			message_string += "&a=" + add;
+	if(add != null)
+		message_string += "&a=" + add;
 
-		if(remove != null)
-			message_string += "&r=" + remove;
+	if(remove != null)
+		message_string += "&r=" + remove;
 
 
-		var response = m_connection.send_post_request("subscription/edit?output=json", message_string);
+	var response = m_connection.send_post_request("subscription/edit?output=json", message_string);
 
-		return response.status == 200;
-	}
+	return response.status == 200;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/oldreader/oldreaderConnection.vala 2.7.1-1/plugins/backend/oldreader/oldreaderConnection.vala
--- 2.6.1-1/plugins/backend/oldreader/oldreaderConnection.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/oldreader/oldreaderConnection.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,96 +14,96 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 public class FeedReader.OldReaderConnection {
-	private string m_api_username;
-	private string m_api_code;
-	private string m_passwd;
-	private OldReaderUtils m_utils;
-	private Soup.Session m_session;
-
-	public OldReaderConnection(OldReaderUtils utils)
-	{
-		m_utils = utils;
-		m_api_username = m_utils.getUser();
-		m_api_code = m_utils.getAccessToken();
-		m_passwd = m_utils.getPasswd();
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-	}
+private string m_api_username;
+private string m_api_code;
+private string m_passwd;
+private OldReaderUtils m_utils;
+private Soup.Session m_session;
+
+public OldReaderConnection(OldReaderUtils utils)
+{
+	m_utils = utils;
+	m_api_username = m_utils.getUser();
+	m_api_code = m_utils.getAccessToken();
+	m_passwd = m_utils.getPasswd();
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+}
 
-	public LoginResponse getToken()
-	{
-		Logger.debug("OldReader Connection: getToken()");
+public LoginResponse getToken()
+{
+	Logger.debug("OldReader Connection: getToken()");
+
+	var message = new Soup.Message("POST", "https://theoldreader.com/accounts/ClientLogin/");
+	string message_string = "Email=" + m_api_username
+	                        + "&Passwd=" + m_passwd
+	                        + "&service=reader"
+	                        + "&accountType=HOSTED_OR_GOOGLE"
+	                        + "&client=FeedReader";
+	message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	m_session.send_message(message);
 
-		var message = new Soup.Message("POST", "https://theoldreader.com/accounts/ClientLogin/");
-		string message_string = "Email=" + m_api_username
-								+ "&Passwd=" + m_passwd
-								+ "&service=reader"
-								+ "&accountType=HOSTED_OR_GOOGLE"
-								+ "&client=FeedReader";
-		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
-		m_session.send_message(message);
+	if(message.status_code != 200)
+		return LoginResponse.NO_CONNECTION;
 
-		if(message.status_code != 200)
-			return LoginResponse.NO_CONNECTION;
-
-		string response = (string)message.response_body.flatten().data;
-		try
+	string response = (string)message.response_body.flatten().data;
+	try
+	{
+		var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
+		if(regex.match(response))
 		{
-			var regex = new Regex(".*\\w\\s.*\\w\\sAuth=");
-			if(regex.match(response))
-			{
-				Logger.debug(@"Regex oldreader - $response");
-				string split = regex.replace( response, -1,0,"");
-				Logger.debug(@"authcode: $split");
-				m_utils.setAccessToken(split.strip());
-				return LoginResponse.SUCCESS;
-			}
-			else
-			{
-				Logger.debug(message_string);
-				Logger.error(response);
-				return LoginResponse.WRONG_LOGIN;
-			}
+			Logger.debug(@"Regex oldreader - $response");
+			string split = regex.replace( response, -1,0,"");
+			Logger.debug(@"authcode: $split");
+			m_utils.setAccessToken(split.strip());
+			return LoginResponse.SUCCESS;
 		}
-		catch(Error e)
+		else
 		{
-			Logger.error("OldReaderConnection - getToken: Could not load message response");
-			Logger.error(e.message);
-			return LoginResponse.UNKNOWN_ERROR;
+			Logger.debug(message_string);
+			Logger.error(response);
+			return LoginResponse.WRONG_LOGIN;
 		}
 	}
-
-	public Response send_get_request(string path, string? message_string = null)
+	catch(Error e)
 	{
-		return send_request(path, "GET", message_string);
+		Logger.error("OldReaderConnection - getToken: Could not load message response");
+		Logger.error(e.message);
+		return LoginResponse.UNKNOWN_ERROR;
 	}
+}
 
-	public Response send_post_request(string path, string? message_string = null)
-	{
-		return send_request(path, "POST", message_string);
-	}
+public Response send_get_request(string path, string? message_string = null)
+{
+	return send_request(path, "GET", message_string);
+}
 
-	private Response send_request(string path, string type, string? message_string = null)
-	{
-		var message = new Soup.Message(type, OldReaderSecret.base_uri + path);
+public Response send_post_request(string path, string? message_string = null)
+{
+	return send_request(path, "POST", message_string);
+}
 
-		string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
-		message.request_headers.append("Authorization", oldauth);
+private Response send_request(string path, string type, string? message_string = null)
+{
+	var message = new Soup.Message(type, OldReaderSecret.base_uri + path);
 
-		if(message_string != null)
-			message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
+	string oldauth = "GoogleLogin auth=" + m_utils.getAccessToken();
+	message.request_headers.append("Authorization", oldauth);
 
-		m_session.send_message(message);
+	if(message_string != null)
+		message.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message_string.data);
 
-		if(message.status_code != 200)
-		{
-			Logger.warning("OldReaderConnection: unexpected response %u".printf(message.status_code));
-		}
+	m_session.send_message(message);
 
-		return Response() {
-			status = message.status_code,
-			data = (string)message.response_body.flatten().data
-		};
+	if(message.status_code != 200)
+	{
+		Logger.warning("OldReaderConnection: unexpected response %u".printf(message.status_code));
 	}
 
+	return Response() {
+		       status = message.status_code,
+		       data = (string)message.response_body.flatten().data
+	};
+}
+
 }
diff -pruN 2.6.1-1/plugins/backend/oldreader/oldreaderInterface.vala 2.7.1-1/plugins/backend/oldreader/oldreaderInterface.vala
--- 2.6.1-1/plugins/backend/oldreader/oldreaderInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/oldreader/oldreaderInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,442 +15,413 @@
 
 public class FeedReader.OldReaderInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private OldReaderAPI m_api;
-	private OldReaderUtils m_utils;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private OldReaderAPI m_api;
+private OldReaderUtils m_utils;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new OldReaderUtils(settings_backend, secrets);
+	m_api = new OldReaderAPI(m_utils);
+}
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new OldReaderUtils(settings_backend, secrets);
-		m_api = new OldReaderAPI(m_utils, db);
-	}
+public string getWebsite()
+{
+	return "https://theoldreader.com/";
+}
 
-	public string getWebsite()
-	{
-		return "https://theoldreader.com/";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.HOSTED | BackendFlags.PROPRIETARY | BackendFlags.PAID_PREMIUM);
-	}
+public string getID()
+{
+	return "oldreader";
+}
 
-	public string getID()
-	{
-		return "oldreader";
-	}
+public string iconName()
+{
+	return "feed-service-oldreader";
+}
 
-	public string iconName()
-	{
-		return "feed-service-oldreader";
-	}
+public string serviceName()
+{
+	return "The Old Reader";
+}
 
-	public string serviceName()
-	{
-		return "The Old Reader";
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public Gtk.Box? getWidget()
+{
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_userEntry.activate.connect(() => { tryLogin(); });
+	m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+	m_passwordEntry.set_invisible_char('*');
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(user_label, 0, 0, 1, 1);
+	grid.attach(m_userEntry, 1, 0, 1, 1);
+	grid.attach(password_label, 0, 1, 1, 1);
+	grid.attach(m_passwordEntry, 1, 1, 1, 1);
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-oldreader", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to the Old Reader and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
 
-	public Gtk.Box? getWidget()
-	{
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
+	return box;
+}
 
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
+public void showHtAccess()
+{
+	return;
+}
 
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_userEntry.activate.connect(() => { tryLogin(); });
-		m_passwordEntry.activate.connect(() => { tryLogin(); });
-
-		m_passwordEntry.set_invisible_char('*');
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(user_label, 0, 0, 1, 1);
-		grid.attach(m_userEntry, 1, 0, 1, 1);
-		grid.attach(password_label, 0, 1, 1, 1);
-		grid.attach(m_passwordEntry, 1, 1, 1, 1);
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-oldreader", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to the Old Reader and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
+public void writeData()
+{
+	m_utils.setUser(m_userEntry.get_text().strip());
+	m_utils.setPassword(m_passwordEntry.get_text().strip());
+}
 
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+public async void postLoginAction()
+{
+	return;
+}
 
-		return box;
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public void showHtAccess()
-	{
-		return;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public void writeData()
-	{
-		m_utils.setUser(m_userEntry.get_text().strip());
-		m_utils.setPassword(m_passwordEntry.get_text().strip());
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public string symbolicIcon()
+{
+	return "feed-service-oldreader-symbolic";
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public string getServerURL()
+{
+	return "https://theoldreader.com/";
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string uncategorizedID()
+{
+	return "";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-oldreader-symbolic";
-	}
+public bool hideCategoryWhenEmpty(string cadID)
+{
+	return false;
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public string getServerURL()
-	{
-		return "https://theoldreader.com/";
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public string uncategorizedID()
-	{
-		return "";
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool hideCategoryWhenEmpty(string cadID)
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return true;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return true;
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	if(read == ArticleStatus.READ)
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read");
+	else
+		m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	if(marked == ArticleStatus.MARKED)
+		m_api.edidTag(articleID, "user/-/state/com.google/starred");
+	else
+		m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.markAsRead(feedID);
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		if(read == ArticleStatus.READ)
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read");
-		else
-			m_api.edidTag(articleIDs, "user/-/state/com.google/read", false);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markAsRead(catID);
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
+public void markAllItemsRead()
+{
+	var db = DataBase.readOnly();
+	var categories = db.read_categories();
+	foreach(Category cat in categories)
 	{
-		if(marked == ArticleStatus.MARKED)
-			m_api.edidTag(articleID, "user/-/state/com.google/starred");
-		else
-			m_api.edidTag(articleID, "user/-/state/com.google/starred", false);
+		m_api.markAsRead(cat.getCatID());
 	}
 
-	public bool alwaysSetReadByID()
+	var feeds = db.read_feeds_without_cat();
+	foreach(Feed feed in feeds)
 	{
-		return false;
+		m_api.markAsRead(feed.getFeedID());
 	}
+	m_api.markAsRead();
+}
 
-	public void setFeedRead(string feedID)
-	{
-		m_api.markAsRead(feedID);
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, true);
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markAsRead(catID);
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	m_api.edidTag(articleID, tagID, false);
+}
 
-	public void markAllItemsRead()
-	{
-		var categories = m_db.read_categories();
-		foreach(Category cat in categories)
-		{
-			m_api.markAsRead(cat.getCatID());
-		}
+public string createTag(string caption)
+{
+	return m_api.composeTagID(caption);
+}
 
-		var feeds = m_db.read_feeds_without_cat();
-		foreach(Feed feed in feeds)
-		{
-			m_api.markAsRead(feed.getFeedID());
-		}
-		m_api.markAsRead();
-	}
+public void deleteTag(string tagID)
+{
+	m_api.deleteTag(tagID);
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		m_api.edidTag(articleID, tagID, true);
-	}
+public void renameTag(string tagID, string title)
+{
+	m_api.renameTag(tagID, title);
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		m_api.edidTag(articleID, tagID, false);
-	}
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
 
-	public string createTag(string caption)
-	{
-		return m_api.composeTagID(caption);
-	}
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	feedID = "feed/" + feedURL;
+	errmsg = "";
+	bool success = false;
 
-	public void deleteTag(string tagID)
+	if(catID == null && newCatName != null)
 	{
-		m_api.deleteTag(tagID);
+		string newCatID = m_api.composeTagID(newCatName);
+		success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
 	}
-
-	public void renameTag(string tagID, string title)
+	else
 	{
-		m_api.renameTag(tagID, title);
+		success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
 	}
 
-	public bool serverAvailable()
-	{
-		return m_api.ping();
-	}
+	if(!success)
+		errmsg = @"The old reader could not add $feedURL";
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		feedID = "feed/" + feedURL;
-		errmsg = "";
-		bool success = false;
+	return success;
+}
 
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.composeTagID(newCatName);
-			success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, newCatID);
-		}
-		else
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	string cat = "";
+	string[] urls = {};
+
+	foreach(Feed f in feeds)
+	{
+		if(f.getCatIDs()[0] != cat)
 		{
-			success = m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, {"feed/"+feedURL}, null, catID);
+			m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
+			urls = {};
+			cat = f.getCatIDs()[0];
 		}
 
-		if(!success)
-			errmsg = @"The old reader could not add $feedURL";
-
-		return success;
+		urls += "feed/" + f.getXmlUrl();
 	}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		string cat = "";
-		string[] urls = {};
-
-		foreach(Feed f in feeds)
-		{
-			if(f.getCatIDs()[0] != cat)
-			{
-				m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
-				urls = {};
-				cat = f.getCatIDs()[0];
-			}
+	m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
+}
 
-			urls += "feed/" + f.getXmlUrl();
-		}
 
-		m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.SUBSCRIBE, urls, null, cat);
-	}
+public void removeFeed(string feedID)
+{
+	m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.UNSUBSCRIBE, {feedID});
+}
 
+public void renameFeed(string feedID, string title)
+{
+	m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, title);
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.UNSUBSCRIBE, {feedID});
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, title);
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.composeTagID(title);
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.editSubscription(OldReaderAPI.OldreaderSubscriptionAction.EDIT, {feedID}, null, newCatID, currentCatID);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameTag(catID, title);
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.composeTagID(title);
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameTag(catID, title);
-	}
+public void deleteCategory(string catID)
+{
+	m_api.deleteTag(catID);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		return;
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.deleteTag(catID);
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getFeeds(feeds))
 	{
-		return;
-	}
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
+		if(m_api.getCategoriesAndTags(feeds, categories, tags))
+			return true;
 	}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
-	{
-		if(m_api.getFeeds(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
-
-			if(m_api.getCategoriesAndTags(feeds, categories, tags))
-				return true;
-		}
+	return false;
+}
 
-		return false;
-	}
+public int getUnreadCount()
+{
+	return m_api.getTotalUnread();
+}
 
-	public int getUnreadCount()
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	if(whatToGet == ArticleStatus.READ)
 	{
-		return m_api.getTotalUnread();
+		return;
 	}
-
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+	else if(whatToGet == ArticleStatus.ALL)
 	{
-		if(whatToGet == ArticleStatus.READ)
-		{
-			return;
-		}
-		else if(whatToGet == ArticleStatus.ALL)
-		{
-			var unreadIDs = new Gee.LinkedList<string>();
-			string? continuation = null;
-			int left = 4*count;
-
-			while(left > 0)
-			{
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
-
-				if(left > 1000)
-				{
-					continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
-					left -= 1000;
-				}
-				else
-				{
-					m_api.updateArticles(unreadIDs, left, continuation);
-					left = 0;
-				}
-			}
-			m_db_write.updateArticlesByID(unreadIDs, "unread");
-			updateArticleList();
-		}
-
-		var articles = new Gee.LinkedList<Article>();
+		var unreadIDs = new Gee.LinkedList<string>();
 		string? continuation = null;
-		int left = count;
-		string? OldReader_feedID = (isTagID) ? null : feedID;
-		string? OldReader_tagID = (isTagID) ? feedID : null;
+		int left = 4*count;
 
 		while(left > 0)
 		{
@@ -459,18 +430,44 @@ public class FeedReader.OldReaderInterfa
 
 			if(left > 1000)
 			{
-				continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+				continuation = m_api.updateArticles(unreadIDs, 1000, continuation);
 				left -= 1000;
 			}
 			else
 			{
-				continuation = m_api.getArticles(articles, left, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+				m_api.updateArticles(unreadIDs, left, continuation);
 				left = 0;
 			}
 		}
-		writeArticles(articles);
+		DataBase.writeAccess().updateArticlesByID(unreadIDs, "unread");
+		updateArticleList();
 	}
 
+	var articles = new Gee.LinkedList<Article>();
+	string? continuation = null;
+	int left = count;
+	string? OldReader_feedID = (isTagID) ? null : feedID;
+	string? OldReader_tagID = (isTagID) ? feedID : null;
+
+	while(left > 0)
+	{
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
+
+		if(left > 1000)
+		{
+			continuation = m_api.getArticles(articles, 1000, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+			left -= 1000;
+		}
+		else
+		{
+			continuation = m_api.getArticles(articles, left, whatToGet, continuation, OldReader_tagID, OldReader_feedID);
+			left = 0;
+		}
+	}
+	writeArticles(articles);
+}
+
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/oldreader/oldreaderUtils.vala 2.7.1-1/plugins/backend/oldreader/oldreaderUtils.vala
--- 2.6.1-1/plugins/backend/oldreader/oldreaderUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/oldreader/oldreaderUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,74 +14,74 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.OldReaderSecret {
-	 const string base_uri        = "https://theoldreader.com/reader/api/0/";
+const string base_uri        = "https://theoldreader.com/reader/api/0/";
 }
 
 public class FeedReader.OldReaderUtils : GLib.Object {
 
-	private GLib.Settings m_settings;
-	private Password m_password;
+private GLib.Settings m_settings;
+private Password m_password;
 
-	public OldReaderUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.oldreader", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.oldreader");
-
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.oldreader", Secret.SchemaFlags.NONE,
-										  "type", "oldreader",
-										  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, pwSchema, "FeedReader: oldreader login", () => {
+public OldReaderUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.oldreader", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.oldreader");
+
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.oldreader", Secret.SchemaFlags.NONE,
+	                                  "type", "oldreader",
+	                                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, pwSchema, "FeedReader: oldreader login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["Username"] = getUser();
 			return attributes;
 		});
-	}
+}
+
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
+
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
+
+public string getAccessToken()
+{
+	return Utils.gsettingReadString(m_settings, "access-token");
+}
+
+public void setAccessToken(string token)
+{
+	Utils.gsettingWriteString(m_settings, "access-token", token);
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
-
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
-
-	public string getAccessToken()
-	{
-		return Utils.gsettingReadString(m_settings, "access-token");
-	}
-
-	public void setAccessToken(string token)
-	{
-		Utils.gsettingWriteString(m_settings, "access-token", token);
-	}
-
-	public string getUserID()
-	{
-		return Utils.gsettingReadString(m_settings, "user-id");
-	}
-
-	public void setUserID(string id)
-	{
-		Utils.gsettingWriteString(m_settings, "user-id", id);
-	}
-
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-	}
-
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
-
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public string getUserID()
+{
+	return Utils.gsettingReadString(m_settings, "user-id");
+}
+
+public void setUserID(string id)
+{
+	Utils.gsettingWriteString(m_settings, "user-id", id);
+}
+
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+}
+
+public string getPasswd()
+{
+	return m_password.get_password();
+}
+
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/owncloud/OwncloudNewsAPI.vala 2.7.1-1/plugins/backend/owncloud/OwncloudNewsAPI.vala
--- 2.6.1-1/plugins/backend/owncloud/OwncloudNewsAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/owncloud/OwncloudNewsAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,550 +15,548 @@
 
 public class FeedReader.OwncloudNewsAPI : GLib.Object {
 
-	public enum OwnCloudType {
-		FEED,
-		FOLDER,
-		STARRED,
-		ALL
-	}
-
-	private string m_OwnCloudURL;
-	private string m_OwnCloudVersion;
-	private Json.Parser m_parser;
-	private string m_username;
-	private string m_password;
-	private OwncloudNewsUtils m_utils;
-	private Soup.Session m_session;
-	private DataBaseReadOnly m_db;
-
-	public OwncloudNewsAPI(OwncloudNewsUtils utils, DataBaseReadOnly db)
-	{
-		m_db = db;
-		m_parser = new Json.Parser ();
-		m_utils = utils;
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_session.ssl_strict = false;
-		m_session.authenticate.connect((msg, auth, retrying) => {
+public enum OwnCloudType {
+	FEED,
+	FOLDER,
+	STARRED,
+	ALL
+}
+
+private string m_OwnCloudURL;
+private string m_OwnCloudVersion;
+private Json.Parser m_parser;
+private string m_username;
+private string m_password;
+private OwncloudNewsUtils m_utils;
+private Soup.Session m_session;
+
+public OwncloudNewsAPI(OwncloudNewsUtils utils)
+{
+	m_parser = new Json.Parser ();
+	m_utils = utils;
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_session.ssl_strict = false;
+	m_session.authenticate.connect((msg, auth, retrying) => {
 			if(m_utils.getHtaccessUser() == "")
 			{
-				Logger.error("Nextcloud Session: need Authentication");
+			        Logger.error("Nextcloud Session: need Authentication");
 			}
 			else if(!retrying)
 			{
-				auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+			        auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
 			}
 		});
-	}
+}
 
-	public LoginResponse login()
-	{
-		Logger.debug("Nextcloud: login");
-		m_username = m_utils.getUser();
-		m_password = m_utils.getPasswd();
-		m_OwnCloudURL = m_utils.getURL();
-
-		if(m_OwnCloudURL == "" && m_username == "" && m_password == ""){
-			m_OwnCloudURL = "example-host/nextcloud";
-			return LoginResponse.ALL_EMPTY;
-		}
-		if(m_OwnCloudURL == "")
-			return LoginResponse.MISSING_URL;
-		if(GLib.Uri.parse_scheme(m_OwnCloudURL) == null)
-			return LoginResponse.INVALID_URL;
-		if(m_username == "")
-			return LoginResponse.MISSING_USER;
-		if(m_password == "")
-			return LoginResponse.MISSING_PASSWD;
+public LoginResponse login()
+{
+	Logger.debug("Nextcloud: login");
+	m_username = m_utils.getUser();
+	m_password = m_utils.getPasswd();
+	m_OwnCloudURL = m_utils.getURL();
 
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "status", m_username, m_password, "GET");
-		int error = message.send();
+	if(m_OwnCloudURL == "" && m_username == "" && m_password == "") {
+		m_OwnCloudURL = "example-host/nextcloud";
+		return LoginResponse.ALL_EMPTY;
+	}
+	if(m_OwnCloudURL == "")
+		return LoginResponse.MISSING_URL;
+	if(GLib.Uri.parse_scheme(m_OwnCloudURL) == null)
+		return LoginResponse.INVALID_URL;
+	if(m_username == "")
+		return LoginResponse.MISSING_USER;
+	if(m_password == "")
+		return LoginResponse.MISSING_PASSWD;
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			m_OwnCloudVersion = response.get_string_member("version");
-			Logger.info("Nextcloud version: %s".printf(m_OwnCloudVersion));
-			return LoginResponse.SUCCESS;
-		}
-		else if(error == ConnectionError.API_ERROR)
-		{
-			return LoginResponse.WRONG_LOGIN;
-		}
-		else if(error == ConnectionError.NO_RESPONSE)
-		{
-			return LoginResponse.NO_CONNECTION;
-		}
-		else if(error == ConnectionError.CA_ERROR)
-		{
-			return LoginResponse.CA_ERROR;
-		}
-		else if(error == ConnectionError.UNAUTHORIZED)
-		{
-			return LoginResponse.UNAUTHORIZED;
-		}
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "status", m_username, m_password, "GET");
+	int error = message.send();
 
-		return LoginResponse.UNKNOWN_ERROR;
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		m_OwnCloudVersion = response.get_string_member("version");
+		Logger.info("Nextcloud version: %s".printf(m_OwnCloudVersion));
+		return LoginResponse.SUCCESS;
+	}
+	else if(error == ConnectionError.API_ERROR)
+	{
+		return LoginResponse.WRONG_LOGIN;
+	}
+	else if(error == ConnectionError.NO_RESPONSE)
+	{
+		return LoginResponse.NO_CONNECTION;
+	}
+	else if(error == ConnectionError.CA_ERROR)
+	{
+		return LoginResponse.CA_ERROR;
+	}
+	else if(error == ConnectionError.UNAUTHORIZED)
+	{
+		return LoginResponse.UNAUTHORIZED;
 	}
 
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-	public bool isloggedin()
-	{
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
 
-		if(message.send() == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool isloggedin()
+{
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
 
-		Logger.error("OwncloudNewsAPI.isloggedin: not logged in");
-		return false;
+	if(message.send() == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool getFeeds(Gee.List<Feed> feeds)
+	Logger.error("OwncloudNewsAPI.isloggedin: not logged in");
+	return false;
+}
+
+public bool getFeeds(Gee.List<Feed> feeds)
+{
+	if(isloggedin())
 	{
-		if(isloggedin())
-		{
-			var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "feeds", m_username, m_password, "GET");
-			int error = message.send();
+		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "feeds", m_username, m_password, "GET");
+		int error = message.send();
 
-			if(error == ConnectionError.SUCCESS)
+		if(error == ConnectionError.SUCCESS)
+		{
+			var response = message.get_response_object();
+			if(response.has_member("feeds"))
 			{
-				var response = message.get_response_object();
-				if(response.has_member("feeds"))
-				{
-					var feed_array = response.get_array_member("feeds");
-					var feed_count = feed_array.get_length();
+				var feed_array = response.get_array_member("feeds");
+				var feed_count = feed_array.get_length();
 
-					for(uint i = 0; i < feed_count; i++)
-					{
-						var feed_node = feed_array.get_object_element(i);
+				for(uint i = 0; i < feed_count; i++)
+				{
+					var feed_node = feed_array.get_object_element(i);
 
-						feeds.add(
-							new Feed(
-									feed_node.get_int_member("id").to_string(),
-									feed_node.get_string_member("title"),
-									feed_node.get_string_member("link"),
-									(int)feed_node.get_int_member("unreadCount"),
-									ListUtils.single(feed_node.get_int_member("folderId").to_string()),
-									feed_node.get_string_member("faviconLink")
-								)
+					feeds.add(
+						new Feed(
+							feed_node.get_int_member("id").to_string(),
+							feed_node.get_string_member("title"),
+							feed_node.get_string_member("link"),
+							(int)feed_node.get_int_member("unreadCount"),
+							ListUtils.single(feed_node.get_int_member("folderId").to_string()),
+							feed_node.get_string_member("faviconLink")
+							)
 						);
-					}
-
-					return true;
-				}
-				else
-				{
-					Logger.error("OwncloudNewsAPI.getFeeds: no member \"feeds\"");
 				}
+
+				return true;
 			}
 			else
 			{
-				Logger.error("OwncloudNewsAPI.getFeeds");
+				Logger.error("OwncloudNewsAPI.getFeeds: no member \"feeds\"");
 			}
 		}
-
-		return false;
+		else
+		{
+			Logger.error("OwncloudNewsAPI.getFeeds");
+		}
 	}
 
+	return false;
+}
+
 
-	public bool getCategories(Gee.List<Category> categories, Gee.List<Feed> feeds)
+public bool getCategories(Gee.List<Category> categories, Gee.List<Feed> feeds)
+{
+	if(isloggedin())
 	{
-		if(isloggedin())
+		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "folders", m_username, m_password, "GET");
+		int error = message.send();
+		int orderID = 0;
+
+		if(error == ConnectionError.SUCCESS)
 		{
-			var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "folders", m_username, m_password, "GET");
-			int error = message.send();
-			int orderID = 0;
+			var response = message.get_response_object();
 
-			if(error == ConnectionError.SUCCESS)
+			if(response.has_member("folders"))
 			{
-				var response = message.get_response_object();
+				var folder_array = response.get_array_member("folders");
+				var folder_count = folder_array.get_length();
 
-				if(response.has_member("folders"))
+				for(uint i = 0; i < folder_count; i++)
 				{
-					var folder_array = response.get_array_member("folders");
-					var folder_count = folder_array.get_length();
-
-					for(uint i = 0; i < folder_count; i++)
-					{
-						++orderID;
-						var folder_node = folder_array.get_object_element(i);
-						string id = folder_node.get_int_member("id").to_string();
-
-						categories.add(
-							new Category (
-								id,
-								folder_node.get_string_member("name"),
-								m_utils.countUnread(feeds, id),
-								orderID,
-								CategoryID.MASTER.to_string(),
-								1
+					++orderID;
+					var folder_node = folder_array.get_object_element(i);
+					string id = folder_node.get_int_member("id").to_string();
+
+					categories.add(
+						new Category (
+							id,
+							folder_node.get_string_member("name"),
+							m_utils.countUnread(feeds, id),
+							orderID,
+							CategoryID.MASTER.to_string(),
+							1
 							)
 						);
-					}
-					return true;
-				}
-				else
-				{
-					Logger.error("OwncloudNewsAPI.getCategories: no member \"folders\"");
 				}
+				return true;
 			}
 			else
 			{
-				Logger.error("OwncloudNewsAPI.getCategories");
+				Logger.error("OwncloudNewsAPI.getCategories: no member \"folders\"");
 			}
 		}
-		return false;
+		else
+		{
+			Logger.error("OwncloudNewsAPI.getCategories");
+		}
 	}
+	return false;
+}
 
 
-	public void getNewArticles(Gee.List<Article> articles, int lastModified, OwnCloudType type, int id)
-	{
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items/updated", m_username, m_password, "GET");
-		message.add_int("lastModified", lastModified);
-		message.add_int("type", type);
-		message.add_int("id", id);
-		int error = message.send();
+public void getNewArticles(Gee.List<Article> articles, int lastModified, OwnCloudType type, int id)
+{
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items/updated", m_username, m_password, "GET");
+	message.add_int("lastModified", lastModified);
+	message.add_int("type", type);
+	message.add_int("id", id);
+	int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("items"))
 		{
-			var response = message.get_response_object();
-			if(response.has_member("items"))
-			{
-				var article_array = response.get_array_member("items");
-				var article_count = article_array.get_length();
-				Logger.debug("getNewArticles: %u articles returned".printf(article_count));
+			var article_array = response.get_array_member("items");
+			var article_count = article_array.get_length();
+			Logger.debug("getNewArticles: %u articles returned".printf(article_count));
 
-				for(uint i = 0; i < article_count; i++)
-				{
-					var article_node = article_array.get_object_element(i);
-					//Logger.debug(article_node.get_int_member("id").to_string());
+			for(uint i = 0; i < article_count; i++)
+			{
+				var article_node = article_array.get_object_element(i);
+				//Logger.debug(article_node.get_int_member("id").to_string());
 
-					ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
-					ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+				ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
+				ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
 
-					var enclosures = new Gee.ArrayList<Enclosure>();
-					if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+				var enclosures = new Gee.ArrayList<Enclosure>();
+				if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+				{
+					if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
 					{
-						if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
-						{
-							enclosures.add(new Enclosure(
-								article_node.get_int_member("id").to_string(),
-								article_node.get_string_member("enclosureLink"),
-								EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
-						}
+						enclosures.add(new Enclosure(
+								       article_node.get_int_member("id").to_string(),
+								       article_node.get_string_member("enclosureLink"),
+								       EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
 					}
+				}
 
-					var Article = new Article(	article_node.get_int_member("id").to_string(),
-												article_node.get_string_member("title"),
-												article_node.get_string_member("url"),
-												article_node.get_int_member("feedId").to_string(),
-												unread,
-												marked,
-												article_node.get_string_member("body"),
-												null,
-												article_node.get_string_member("author"),
-												new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
-												-1,
-												null, 		// tags
-												enclosures,
-												article_node.get_string_member("guidHash"),
-												(int)article_node.get_int_member("lastModified"));
+				var Article = new Article(      article_node.get_int_member("id").to_string(),
+				                                article_node.get_string_member("title"),
+				                                article_node.get_string_member("url"),
+				                                article_node.get_int_member("feedId").to_string(),
+				                                unread,
+				                                marked,
+				                                article_node.get_string_member("body"),
+				                                null,
+				                                article_node.get_string_member("author"),
+				                                new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
+				                                -1,
+				                                null,                                           // tags
+				                                enclosures,
+				                                article_node.get_string_member("guidHash"),
+				                                (int)article_node.get_int_member("lastModified"));
 
-					articles.add(Article);
-				}
-			}
-			else
-			{
-				Logger.error("OwncloudNewsAPI.getNewArticles: no member \"items\"");
+				articles.add(Article);
 			}
 		}
 		else
 		{
-			Logger.error("OwncloudNewsAPI.getNewArticles");
+			Logger.error("OwncloudNewsAPI.getNewArticles: no member \"items\"");
 		}
 	}
+	else
+	{
+		Logger.error("OwncloudNewsAPI.getNewArticles");
+	}
+}
 
 
 
-	public void getArticles(Gee.List<Article> articles, int skip, int count, bool read, OwnCloudType type, int id)
-	{
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items", m_username, m_password, "GET");
-		message.add_bool("oldestFirst", false);
-		message.add_int("type", type);
-		message.add_bool("getRead", read);
-		message.add_int("id", id);
-		message.add_int("offset", skip);
-		message.add_int("batchSize", count);
-		int error = message.send();
-
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.has_member("items"))
+public void getArticles(Gee.List<Article> articles, int skip, int count, bool read, OwnCloudType type, int id)
+{
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "items", m_username, m_password, "GET");
+	message.add_bool("oldestFirst", false);
+	message.add_int("type", type);
+	message.add_bool("getRead", read);
+	message.add_int("id", id);
+	message.add_int("offset", skip);
+	message.add_int("batchSize", count);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("items"))
+		{
+			var article_array = response.get_array_member("items");
+			var article_count = article_array.get_length();
+			Logger.debug("getArticles: %u articles returned".printf(article_count));
+
+			for(uint i = 0; i < article_count; i++)
 			{
-				var article_array = response.get_array_member("items");
-				var article_count = article_array.get_length();
-				Logger.debug("getArticles: %u articles returned".printf(article_count));
+				var article_node = article_array.get_object_element(i);
 
-				for(uint i = 0; i < article_count; i++)
-				{
-					var article_node = article_array.get_object_element(i);
-
-					ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
-					ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
+				ArticleStatus unread = article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ;
+				ArticleStatus marked = article_node.get_boolean_member("starred") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED;
 
-					var enclosures = new Gee.ArrayList<Enclosure>();
-					if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+				var enclosures = new Gee.ArrayList<Enclosure>();
+				if(article_node.has_member("enclosureLink") && article_node.get_string_member("enclosureLink") != null)
+				{
+					if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
 					{
-						if(article_node.has_member("enclosureMime") && article_node.get_string_member("enclosureMime") != null)
-						{
-							enclosures.add(new Enclosure(
-								article_node.get_int_member("id").to_string(),
-								article_node.get_string_member("enclosureLink"),
-								EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
-						}
+						enclosures.add(new Enclosure(
+								       article_node.get_int_member("id").to_string(),
+								       article_node.get_string_member("enclosureLink"),
+								       EnclosureType.from_string(article_node.get_string_member("enclosureMime"))));
 					}
+				}
 
-					var Article = new Article(	article_node.get_int_member("id").to_string(),
-												article_node.get_string_member("title"),
-												article_node.get_string_member("url"),
-												article_node.get_int_member("feedId").to_string(),
-												unread,
-												marked,
-												article_node.get_string_member("body"),
-												null,
-												article_node.get_string_member("author"),
-												new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
-												-1,
-												null, // tags
-												enclosures,
-												article_node.get_string_member("guidHash"),
-												(int)article_node.get_int_member("lastModified"));
+				var Article = new Article(      article_node.get_int_member("id").to_string(),
+				                                article_node.get_string_member("title"),
+				                                article_node.get_string_member("url"),
+				                                article_node.get_int_member("feedId").to_string(),
+				                                unread,
+				                                marked,
+				                                article_node.get_string_member("body"),
+				                                null,
+				                                article_node.get_string_member("author"),
+				                                new DateTime.from_unix_local(article_node.get_int_member("pubDate")),
+				                                -1,
+				                                null,                                 // tags
+				                                enclosures,
+				                                article_node.get_string_member("guidHash"),
+				                                (int)article_node.get_int_member("lastModified"));
 
-					articles.add(Article);
-				}
-			}
-			else
-			{
-				Logger.error("OwncloudNewsAPI.getArticles: no member \"items\"");
+				articles.add(Article);
 			}
 		}
 		else
 		{
-			Logger.error("OwncloudNewsAPI.getArticles");
+			Logger.error("OwncloudNewsAPI.getArticles: no member \"items\"");
 		}
 	}
-
-
-	public bool markFeedRead(string feedID, bool isCatID)
+	else
 	{
-		string url = "%s/%s/read".printf((isCatID) ? "folders" : "feeds", feedID);
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_int("newestItemId", int.parse(m_db.getNewestArticle()));
-		int error = message.send();
+		Logger.error("OwncloudNewsAPI.getArticles");
+	}
+}
 
-		if(error == ConnectionError.SUCCESS)
-			return true;
 
-		Logger.error("OwncloudNewsAPI.markFeedRead");
-		return false;
-	}
+public bool markFeedRead(string feedID, bool isCatID)
+{
+	string url = "%s/%s/read".printf((isCatID) ? "folders" : "feeds", feedID);
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
+	int error = message.send();
 
-	public bool markAllItemsRead()
-	{
-		string url = "items/read";
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_int("newestItemId", int.parse(m_db.getNewestArticle()));
-		int error = message.send();
+	if(error == ConnectionError.SUCCESS)
+		return true;
 
-		if(error == ConnectionError.SUCCESS)
-			return true;
+	Logger.error("OwncloudNewsAPI.markFeedRead");
+	return false;
+}
 
-		Logger.error("OwncloudNewsAPI.markAllItemsRead");
-		return false;
-	}
+public bool markAllItemsRead()
+{
+	string url = "items/read";
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_int("newestItemId", int.parse(DataBase.readOnly().getNewestArticle()));
+	int error = message.send();
 
+	if(error == ConnectionError.SUCCESS)
+		return true;
 
-	public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
-	{
-		string url = "";
+	Logger.error("OwncloudNewsAPI.markAllItemsRead");
+	return false;
+}
 
-		if(unread == ArticleStatus.UNREAD)
-			url = "items/unread/multiple";
-		else if(unread == ArticleStatus.READ)
-			url = "items/read/multiple";
 
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_int_array("items", articleIDs);
-		int error = message.send();
+public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
+{
+	string url = "";
+
+	if(unread == ArticleStatus.UNREAD)
+		url = "items/unread/multiple";
+	else if(unread == ArticleStatus.READ)
+		url = "items/read/multiple";
+
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_int_array("items", articleIDs);
+	int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
-			return true;
+	if(error == ConnectionError.SUCCESS)
+		return true;
 
-		Logger.error("OwncloudNewsAPI.updateArticleUnread");
-		return false;
-	}
+	Logger.error("OwncloudNewsAPI.updateArticleUnread");
+	return false;
+}
 
 
-	public bool updateArticleMarked(string articleID, ArticleStatus marked)
-	{
-		var article = m_db.read_article(articleID);
-		string url = "items/%s/%s/".printf(article.getFeedID(), article.getHash());
+public bool updateArticleMarked(string articleID, ArticleStatus marked)
+{
+	var article = DataBase.readOnly().read_article(articleID);
+	string url = "items/%s/%s/".printf(article.getFeedID(), article.getHash());
+
+	if(marked == ArticleStatus.MARKED)
+		url += "star";
+	else if(marked == ArticleStatus.UNMARKED)
+		url += "unstar";
 
-		if(marked == ArticleStatus.MARKED)
-			url += "star";
-		else if(marked == ArticleStatus.UNMARKED)
-			url += "unstar";
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	int error = message.send();
 
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		int error = message.send();
+	if(error == ConnectionError.SUCCESS)
+		return true;
 
-		if(error == ConnectionError.SUCCESS)
-			return true;
+	Logger.error("OwncloudNewsAPI.updateArticleMarked");
+	return false;
+}
 
-		Logger.error("OwncloudNewsAPI.updateArticleMarked");
-		return false;
-	}
+public bool addFeed(string feedURL, string? catID, out int64 feedID, out string errmsg)
+{
+	string url = "feeds";
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
+	message.add_string("url", feedURL);
+	message.add_int("folderId", (catID != null) ? int.parse(catID) : 0);
+	int error = message.send();
 
-	public bool addFeed(string feedURL, string? catID, out int64 feedID, out string errmsg)
+	if(error == ConnectionError.SUCCESS)
 	{
-		string url = "feeds";
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
-		message.add_string("url", feedURL);
-		message.add_int("folderId", (catID != null) ? int.parse(catID) : 0);
-		int error = message.send();
-
-		if(error == ConnectionError.SUCCESS)
+		var response = message.get_response_object();
+		if(response.has_member("feeds"))
 		{
-			var response = message.get_response_object();
-			if(response.has_member("feeds"))
-			{
-				errmsg = "";
-				feedID = response.get_array_member("feeds").get_object_element(0).get_int_member("id");
-				return true;
-			}
-		}
-		else
-		{
-			Logger.error("OwncloudNewsAPI.addFeed");
+			errmsg = "";
+			feedID = response.get_array_member("feeds").get_object_element(0).get_int_member("id");
+			return true;
 		}
+	}
+	else
+	{
+		Logger.error("OwncloudNewsAPI.addFeed");
+	}
 
 
-		errmsg = "Nextcloud could not add the feed";
-		feedID = 0;
-
-		switch(message.getStatusCode())
-		{
-			case 409:
-				errmsg = "Feed already added (409)";
-				return true;
-			case 422:
-				errmsg = "Nextcloud can't read the feed (422)";
-				break;
-		}
+	errmsg = "Nextcloud could not add the feed";
+	feedID = 0;
 
-		return false;
+	switch(message.getStatusCode())
+	{
+	case 409:
+		errmsg = "Feed already added (409)";
+		return true;
+	case 422:
+		errmsg = "Nextcloud can't read the feed (422)";
+		break;
 	}
 
-	public void removeFeed(string feedID)
-	{
-		string url = "feeds/%s".printf(feedID);
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
-		int error = message.send();
+	return false;
+}
 
-		if(error != ConnectionError.SUCCESS)
-		{
-			Logger.error("OwncloudNewsAPI.removeFeed");
-		}
-	}
+public void removeFeed(string feedID)
+{
+	string url = "feeds/%s".printf(feedID);
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
+	int error = message.send();
 
-	public void renameFeed(string feedID, string title)
+	if(error != ConnectionError.SUCCESS)
 	{
-		string url = "feeds/%s/rename".printf(feedID);
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_string("feedTitle", title);
-		int error = message.send();
-
-		if(error != ConnectionError.SUCCESS)
-		{
-			Logger.error("OwncloudNewsAPI.renameFeed");
-		}
+		Logger.error("OwncloudNewsAPI.removeFeed");
 	}
+}
 
-	public void moveFeed(string feedID, string? newCatID = null)
-	{
-		string url = "feeds/%s/move".printf(feedID);
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_int("folderId", (newCatID != null) ? int.parse(newCatID) : 0);
-		int error = message.send();
+public void renameFeed(string feedID, string title)
+{
+	string url = "feeds/%s/rename".printf(feedID);
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_string("feedTitle", title);
+	int error = message.send();
 
-		if(error != ConnectionError.SUCCESS)
-		{
-			Logger.error("OwncloudNewsAPI.moveFeed");
-		}
+	if(error != ConnectionError.SUCCESS)
+	{
+		Logger.error("OwncloudNewsAPI.renameFeed");
 	}
+}
 
-	public int64 addFolder(string title)
+public void moveFeed(string feedID, string? newCatID = null)
+{
+	string url = "feeds/%s/move".printf(feedID);
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_int("folderId", (newCatID != null) ? int.parse(newCatID) : 0);
+	int error = message.send();
+
+	if(error != ConnectionError.SUCCESS)
 	{
-		string url = "folders";
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
-		message.add_string("name", title);
-		int error = message.send();
+		Logger.error("OwncloudNewsAPI.moveFeed");
+	}
+}
 
-		if(error != ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.has_member("folders"))
-			{
-				return response.get_array_member("folders").get_object_element(0).get_int_member("id");
-			}
-		}
-		else
+public int64 addFolder(string title)
+{
+	string url = "folders";
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "POST");
+	message.add_string("name", title);
+	int error = message.send();
+
+	if(error != ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("folders"))
 		{
-			Logger.error("OwncloudNewsAPI.addFolder");
+			return response.get_array_member("folders").get_object_element(0).get_int_member("id");
 		}
-
-		return 0;
 	}
-
-	public bool removeFolder(string catID)
+	else
 	{
-		string url = "folders/%s".printf(catID);
+		Logger.error("OwncloudNewsAPI.addFolder");
+	}
 
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
-		int error = message.send();
+	return 0;
+}
 
-		if(error == ConnectionError.SUCCESS)
-			return true;
+public bool removeFolder(string catID)
+{
+	string url = "folders/%s".printf(catID);
 
-		Logger.error("OwncloudNewsAPI.removeFolder");
-		return false;
-	}
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "DELETE");
+	int error = message.send();
 
-	public void renameCategory(string catID, string title)
-	{
-		string url = "folders/%s".printf(catID);
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
-		message.add_string("name", title);
-		int error = message.send();
+	if(error == ConnectionError.SUCCESS)
+		return true;
 
-		if(error != ConnectionError.SUCCESS)
-			Logger.error("OwncloudNewsAPI.renameCategory");
-	}
+	Logger.error("OwncloudNewsAPI.removeFolder");
+	return false;
+}
 
-	public bool ping()
-	{
-		var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
-		int error = message.send(true);
+public void renameCategory(string catID, string title)
+{
+	string url = "folders/%s".printf(catID);
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + url, m_username, m_password, "PUT");
+	message.add_string("name", title);
+	int error = message.send();
 
-		if(error == ConnectionError.NO_RESPONSE)
-		{
-			Logger.error("OwncloudNewsAPI.ping: failed");
-			return false;
-		}
+	if(error != ConnectionError.SUCCESS)
+		Logger.error("OwncloudNewsAPI.renameCategory");
+}
 
-		return true;
+public bool ping()
+{
+	var message = new OwnCloudNewsMessage(m_session, m_OwnCloudURL + "version", m_username, m_password, "GET");
+	int error = message.send(true);
+
+	if(error == ConnectionError.NO_RESPONSE)
+	{
+		Logger.error("OwncloudNewsAPI.ping: failed");
+		return false;
 	}
+
+	return true;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/owncloud/OwncloudNewsInterface.vala 2.7.1-1/plugins/backend/owncloud/OwncloudNewsInterface.vala
--- 2.6.1-1/plugins/backend/owncloud/OwncloudNewsInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/owncloud/OwncloudNewsInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,468 +15,464 @@
 
 public class FeedReader.OwncloudNewsInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private OwncloudNewsAPI m_api;
-	private OwncloudNewsUtils m_utils;
-	private Gtk.Entry m_urlEntry;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private Gtk.Entry m_AuthUserEntry;
-	private Gtk.Entry m_AuthPasswordEntry;
-	private Gtk.Revealer m_revealer;
-	private bool m_need_htaccess = false;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private OwncloudNewsAPI m_api;
+private OwncloudNewsUtils m_utils;
+private Gtk.Entry m_urlEntry;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+private Gtk.Entry m_AuthUserEntry;
+private Gtk.Entry m_AuthPasswordEntry;
+private Gtk.Revealer m_revealer;
+private bool m_need_htaccess = false;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new OwncloudNewsUtils(settings_backend, secrets);
+	m_api = new OwncloudNewsAPI(m_utils);
+}
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new OwncloudNewsUtils(settings_backend, secrets);
-		m_api = new OwncloudNewsAPI(m_utils, db);
-	}
+public string getWebsite()
+{
+	return "https://github.com/nextcloud/news";
+}
 
-	public string getWebsite()
-	{
-		return "https://github.com/nextcloud/news";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-	}
+public string getID()
+{
+	return "owncloud";
+}
 
-	public string getID()
-	{
-		return "owncloud";
-	}
+public string iconName()
+{
+	return "feed-service-nextcloud";
+}
 
-	public string iconName()
-	{
-		return "feed-service-nextcloud";
-	}
+public string serviceName()
+{
+	return "Nextcloud News";
+}
 
-	public string serviceName()
+public void writeData()
+{
+	m_utils.setURL(m_urlEntry.get_text());
+	m_utils.setUser(m_userEntry.get_text().strip());
+	m_utils.setPassword(m_passwordEntry.get_text().strip());
+	if(m_need_htaccess)
 	{
-		return "Nextcloud News";
+		m_utils.setHtaccessUser(m_AuthUserEntry.get_text().strip());
+		m_utils.setHtAccessPassword(m_AuthPasswordEntry.get_text().strip());
 	}
+}
 
-	public void writeData()
-	{
-		m_utils.setURL(m_urlEntry.get_text());
-		m_utils.setUser(m_userEntry.get_text().strip());
-		m_utils.setPassword(m_passwordEntry.get_text().strip());
-		if(m_need_htaccess)
-		{
-			m_utils.setHtaccessUser(m_AuthUserEntry.get_text().strip());
-			m_utils.setHtAccessPassword(m_AuthPasswordEntry.get_text().strip());
-		}
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public void showHtAccess()
+{
+	m_revealer.set_reveal_child(true);
+}
 
-	public void showHtAccess()
-	{
-		m_revealer.set_reveal_child(true);
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public Gtk.Box? getWidget()
+{
+	var urlLabel = new Gtk.Label(_("Nextcloud URL:"));
+	var userLabel = new Gtk.Label(_("Username:"));
+	var passwordLabel = new Gtk.Label(_("Password:"));
+
+	urlLabel.set_alignment(1.0f, 0.5f);
+	userLabel.set_alignment(1.0f, 0.5f);
+	passwordLabel.set_alignment(1.0f, 0.5f);
+
+	urlLabel.set_hexpand(true);
+	userLabel.set_hexpand(true);
+	passwordLabel.set_hexpand(true);
+
+	m_urlEntry = new Gtk.Entry();
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_urlEntry.activate.connect(writeData);
+	m_userEntry.activate.connect(writeData);
+	m_passwordEntry.activate.connect(writeData);
+
+	m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-nextcloud", Gtk.IconSize.MENU);
+
+	grid.attach(urlLabel, 0, 0, 1, 1);
+	grid.attach(m_urlEntry, 1, 0, 1, 1);
+	grid.attach(userLabel, 0, 1, 1, 1);
+	grid.attach(m_userEntry, 1, 1, 1, 1);
+	grid.attach(passwordLabel, 0, 2, 1, 1);
+	grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+	// http auth stuff ----------------------------------------------------
+	var authUserLabel = new Gtk.Label(_("Username:"));
+	var authPasswordLabel = new Gtk.Label(_("Password:"));
+
+	authUserLabel.set_alignment(1.0f, 0.5f);
+	authPasswordLabel.set_alignment(1.0f, 0.5f);
+
+	authUserLabel.set_hexpand(true);
+	authPasswordLabel.set_hexpand(true);
+
+	m_AuthUserEntry = new Gtk.Entry();
+	m_AuthPasswordEntry = new Gtk.Entry();
+	m_AuthPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_AuthPasswordEntry.set_visibility(false);
+
+	m_AuthUserEntry.activate.connect(writeData);
+	m_AuthPasswordEntry.activate.connect(writeData);
+
+	var authGrid = new Gtk.Grid();
+	authGrid.margin = 10;
+	authGrid.set_column_spacing(10);
+	authGrid.set_row_spacing(10);
+	authGrid.set_valign(Gtk.Align.CENTER);
+	authGrid.set_halign(Gtk.Align.CENTER);
+
+	authGrid.attach(authUserLabel, 0, 0, 1, 1);
+	authGrid.attach(m_AuthUserEntry, 1, 0, 1, 1);
+	authGrid.attach(authPasswordLabel, 0, 1, 1, 1);
+	authGrid.attach(m_AuthPasswordEntry, 1, 1, 1, 1);
+
+	var frame = new Gtk.Frame(_("HTTP Authorization"));
+	frame.set_halign(Gtk.Align.CENTER);
+	frame.add(authGrid);
+	m_revealer = new Gtk.Revealer();
+	m_revealer.add(frame);
+	//---------------------------------------------------------------------
+
+	var loginLabel = new Gtk.Label(_("Please log in to your Nextcloud News instance and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_start(m_revealer, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
+
+
+	m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-	public Gtk.Box? getWidget()
-	{
-		var urlLabel = new Gtk.Label(_("Nextcloud URL:"));
-		var userLabel = new Gtk.Label(_("Username:"));
-		var passwordLabel = new Gtk.Label(_("Password:"));
-
-		urlLabel.set_alignment(1.0f, 0.5f);
-		userLabel.set_alignment(1.0f, 0.5f);
-		passwordLabel.set_alignment(1.0f, 0.5f);
-
-		urlLabel.set_hexpand(true);
-		userLabel.set_hexpand(true);
-		passwordLabel.set_hexpand(true);
-
-		m_urlEntry = new Gtk.Entry();
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_urlEntry.activate.connect(writeData);
-		m_userEntry.activate.connect(writeData);
-		m_passwordEntry.activate.connect(writeData);
-
-		m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-nextcloud", Gtk.IconSize.MENU);
-
-		grid.attach(urlLabel, 0, 0, 1, 1);
-		grid.attach(m_urlEntry, 1, 0, 1, 1);
-		grid.attach(userLabel, 0, 1, 1, 1);
-		grid.attach(m_userEntry, 1, 1, 1, 1);
-		grid.attach(passwordLabel, 0, 2, 1, 1);
-		grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
-		// http auth stuff ----------------------------------------------------
-		var authUserLabel = new Gtk.Label(_("Username:"));
-		var authPasswordLabel = new Gtk.Label(_("Password:"));
-
-		authUserLabel.set_alignment(1.0f, 0.5f);
-		authPasswordLabel.set_alignment(1.0f, 0.5f);
-
-		authUserLabel.set_hexpand(true);
-		authPasswordLabel.set_hexpand(true);
-
-		m_AuthUserEntry = new Gtk.Entry();
-		m_AuthPasswordEntry = new Gtk.Entry();
-		m_AuthPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_AuthPasswordEntry.set_visibility(false);
-
-		m_AuthUserEntry.activate.connect(writeData);
-		m_AuthPasswordEntry.activate.connect(writeData);
-
-		var authGrid = new Gtk.Grid();
-		authGrid.margin = 10;
-		authGrid.set_column_spacing(10);
-		authGrid.set_row_spacing(10);
-		authGrid.set_valign(Gtk.Align.CENTER);
-		authGrid.set_halign(Gtk.Align.CENTER);
-
-		authGrid.attach(authUserLabel, 0, 0, 1, 1);
-		authGrid.attach(m_AuthUserEntry, 1, 0, 1, 1);
-		authGrid.attach(authPasswordLabel, 0, 1, 1, 1);
-		authGrid.attach(m_AuthPasswordEntry, 1, 1, 1, 1);
-
-		var frame = new Gtk.Frame(_("HTTP Authorization"));
-		frame.set_halign(Gtk.Align.CENTER);
-		frame.add(authGrid);
-		m_revealer = new Gtk.Revealer();
-		m_revealer.add(frame);
-		//---------------------------------------------------------------------
-
-		var loginLabel = new Gtk.Label(_("Please log in to your Nextcloud News instance and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_start(m_revealer, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
-
-
-		m_urlEntry.set_text(m_utils.getUnmodifiedURL());
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+	return box;
+}
 
-		return box;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public bool supportTags()
+{
+	return false;
+}
 
-	public bool supportTags()
-	{
-		return false;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string symbolicIcon()
+{
+	return "feed-service-nextcloud-symbolic";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-nextcloud-symbolic";
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public string getServerURL()
+{
+	return m_utils.getURL();
+}
 
-	public string getServerURL()
-	{
-		return m_utils.getURL();
-	}
+public string uncategorizedID()
+{
+	return "0";
+}
 
-	public string uncategorizedID()
-	{
-		return "0";
-	}
+public bool hideCategoryWhenEmpty(string cadID)
+{
+	return false;
+}
 
-	public bool hideCategoryWhenEmpty(string cadID)
-	{
-		return false;
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool supportMultiLevelCategories()
+{
+	return false;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return false;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return false;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return false;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool useMaxArticles()
+{
+	return false;
+}
 
-	public bool useMaxArticles()
-	{
-		return false;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public bool logout()
+{
+	return true;
+}
 
-	public bool logout()
-	{
-		return true;
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	m_api.updateArticleUnread(articleIDs, read);
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		m_api.updateArticleUnread(articleIDs, read);
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	m_api.updateArticleMarked(articleID, marked);
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		m_api.updateArticleMarked(articleID, marked);
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.markFeedRead(feedID, false);
+}
 
-	public void setFeedRead(string feedID)
-	{
-		m_api.markFeedRead(feedID, false);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.markFeedRead(catID, true);
+}
 
-	public void setCategoryRead(string catID)
-	{
-		m_api.markFeedRead(catID, true);
-	}
+public void markAllItemsRead()
+{
+	m_api.markAllItemsRead();
+}
 
-	public void markAllItemsRead()
-	{
-		m_api.markAllItemsRead();
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	return;
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		return;
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	return;
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		return;
-	}
+public string createTag(string caption)
+{
+	return ":(";
+}
 
-	public string createTag(string caption)
-	{
-		return ":(";
-	}
+public void deleteTag(string tagID)
+{
+	return;
+}
 
-	public void deleteTag(string tagID)
+public void renameTag(string tagID, string title)
+{
+	return;
+}
+
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
+
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	bool success = false;
+	int64 id = 0;
+	if(catID == null && newCatName != null)
 	{
-		return;
+		string newCatID = m_api.addFolder(newCatName).to_string();
+		success = m_api.addFeed(feedURL, newCatID, out id, out errmsg);
 	}
-
-	public void renameTag(string tagID, string title)
+	else
 	{
-		return;
+		success = m_api.addFeed(feedURL, catID, out id, out errmsg);
 	}
 
-	public bool serverAvailable()
+
+	feedID = id.to_string();
+	return success;
+}
+
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	int64 id = 0;
+	string errmsg = "";
+	foreach(Feed f in feeds)
 	{
-		return m_api.ping();
+		m_api.addFeed(f.getXmlUrl(), f.getCatIDs()[0], out id, out errmsg);
 	}
+}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		bool success = false;
-		int64 id = 0;
-		if(catID == null && newCatName != null)
-		{
-			string newCatID = m_api.addFolder(newCatName).to_string();
-			success = m_api.addFeed(feedURL, newCatID, out id, out errmsg);
-		}
-		else
-		{
-			success = m_api.addFeed(feedURL, catID, out id, out errmsg);
-		}
+public void removeFeed(string feedID)
+{
+	m_api.removeFeed(feedID);
+}
 
+public void renameFeed(string feedID, string title)
+{
+	m_api.renameFeed(feedID, title);
+}
 
-		feedID = id.to_string();
-		return success;
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.moveFeed(feedID, newCatID);
+}
 
-	public void addFeeds(Gee.List<Feed> feeds)
-	{
-		int64 id = 0;
-		string errmsg = "";
-		foreach(Feed f in feeds)
-		{
-			m_api.addFeed(f.getXmlUrl(), f.getCatIDs()[0], out id, out errmsg);
-		}
-	}
+public string createCategory(string title, string? parentID)
+{
+	return m_api.addFolder(title).to_string();
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.removeFeed(feedID);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameCategory(catID, title);
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.renameFeed(feedID, title);
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	return;
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.moveFeed(feedID, newCatID);
-	}
+public void deleteCategory(string catID)
+{
+	m_api.removeFolder(catID);
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		return m_api.addFolder(title).to_string();
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameCategory(catID, title);
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public void moveCategory(string catID, string newParentID)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getFeeds(feeds))
 	{
-		return;
-	}
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
 
-	public void deleteCategory(string catID)
-	{
-		m_api.removeFolder(catID);
+		if(m_api.getCategories(categories, feeds))
+			return true;
 	}
 
-	public void removeCatFromFeed(string feedID, string catID)
-	{
-		return;
-	}
+	return false;
+}
+
+public int getUnreadCount()
+{
+	return (int)DataBase.readOnly().get_unread_total();
+}
+
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	var type = OwncloudNewsAPI.OwnCloudType.ALL;
+	bool read = true;
+	int id = 0;
 
-	public void importOPML(string opml)
+	switch(whatToGet)
 	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
+	case ArticleStatus.ALL:
+		break;
+	case ArticleStatus.UNREAD:
+		read = false;
+		break;
+	case ArticleStatus.MARKED:
+		type = OwncloudNewsAPI.OwnCloudType.STARRED;
+		break;
 	}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+	if(feedID != null)
 	{
-		if(m_api.getFeeds(feeds))
-		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return false;
-
-			if(m_api.getCategories(categories, feeds))
-				return true;
-		}
+		if(isTagID == true)
+			return;
 
-		return false;
+		id = int.parse(feedID);
+		type = OwncloudNewsAPI.OwnCloudType.FEED;
 	}
 
-	public int getUnreadCount()
-	{
-		return (int)m_db.get_unread_total();
-	}
+	var articles = new Gee.LinkedList<Article>();
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-	{
-		var type = OwncloudNewsAPI.OwnCloudType.ALL;
-		bool read = true;
-		int id = 0;
-
-		switch(whatToGet)
-		{
-			case ArticleStatus.ALL:
-				break;
-			case ArticleStatus.UNREAD:
-				read = false;
-				break;
-			case ArticleStatus.MARKED:
-				type = OwncloudNewsAPI.OwnCloudType.STARRED;
-				break;
-		}
-
-		if(feedID != null)
-		{
-			if(isTagID == true)
-				return;
-
-			id = int.parse(feedID);
-			type = OwncloudNewsAPI.OwnCloudType.FEED;
-		}
-
-		var articles = new Gee.LinkedList<Article>();
-
-		if(count == -1)
-			m_api.getNewArticles(articles, m_db.getLastModified(), type, id);
-		else
-			m_api.getArticles(articles, 0, -1, read, type, id);
+	if(count == -1)
+		m_api.getNewArticles(articles, DataBase.readOnly().getLastModified(), type, id);
+	else
+		m_api.getArticles(articles, 0, -1, read, type, id);
 
-		writeArticles(articles);
-	}
+	writeArticles(articles);
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/backend/owncloud/OwncloudNewsMessage.vala 2.7.1-1/plugins/backend/owncloud/OwncloudNewsMessage.vala
--- 2.6.1-1/plugins/backend/owncloud/OwncloudNewsMessage.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/owncloud/OwncloudNewsMessage.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,166 +15,166 @@
 
 public class FeedReader.OwnCloudNewsMessage : GLib.Object {
 
-	private Soup.Session m_session;
-	private Soup.Message m_message_soup;
-	private GLib.StringBuilder m_message_string;
-	private string m_contenttype;
-	private Json.Parser m_parser;
-	private Json.Object m_root_object;
-	private string m_method;
-	private string m_destination;
-
-	public OwnCloudNewsMessage(Soup.Session session, string destination, string username, string password, string method)
-	{
-		m_message_string = new GLib.StringBuilder();
-		m_method = method;
-		m_session = session;
-		m_destination = destination;
-
-		if(method == "GET")
-			m_contenttype = "application/x-www-form-urlencoded";
-		else
-			m_contenttype = "application/json";
-
-		m_parser = new Json.Parser();
-		m_message_soup = new Soup.Message(m_method, m_destination);
-
-		string credentials = username + ":" + password;
-		string base64 = GLib.Base64.encode(credentials.data);
-		m_message_soup.request_headers.append("Authorization","Basic %s".printf(base64));
-	}
-
-	public void add_int(string type, int val)
-	{
-		if(m_method == "GET")
-		{
-			if(m_message_string.len > 0)
-				m_message_string.append("&");
-
-			m_message_string.append(type + "=" + val.to_string());
-		}
-		else
-			m_message_string.append(",\"" + type + "\":" + val.to_string());
-	}
-
-	public void add_int_array(string type, string values)
-	{
-		if(m_method == "GET")
-			Logger.warning("OwnCloudNewsMessage.add_int_array: this should not happen");
-		else
-			m_message_string.append(",\"" + type + "\":[" + values + "]");
-	}
-
-	public void add_bool(string type, bool val)
-	{
-		if(m_method == "GET")
-		{
-			if(m_message_string.len > 0)
-				m_message_string.append("&");
-
-			m_message_string.append(type + "=" + (val ? "true" : "false"));
-		}
-		else
-			m_message_string.append(",\"" + type + "\":" + (val ? "true" : "false"));
-	}
-
-	public void add_string(string type, string val)
-	{
-		if(m_method == "GET")
-		{
-			if(m_message_string.len > 0)
-				m_message_string.append("&");
-
-			m_message_string.append(type + "=" + val);
-		}
-		else
-			m_message_string.append(",\"" + type + "\":\"" + val + "\"");
-	}
-
-	public ConnectionError send(bool ping = false)
-	{
-		var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-
-		if(m_method == "GET")
-		{
-			string destination = m_destination;
-			if(m_message_string.len > 0)
-				destination += "?" + m_message_string.str;
-			m_message_soup.set_uri(new Soup.URI(destination));
-			Logger.debug(destination);
-		}
-		else
-		{
-			m_message_string.overwrite(0, "{").append("}");
-			m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
-		}
-
-		if(settingsTweaks.get_boolean("do-not-track"))
-				m_message_soup.request_headers.append("DNT", "1");
-
-		var status = m_session.send_message(m_message_soup);
-
-		if(status == 401) // unauthorized
-		{
-			return ConnectionError.UNAUTHORIZED;
-		}
-
-		if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
-		{
-			Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
-			return ConnectionError.CA_ERROR;
-		}
-
-		if(m_message_soup.status_code != 200)
-		{
-			Logger.error("Nextcloud Message: No response - status code: %u %s".printf(m_message_soup.status_code, Soup.Status.get_phrase(m_message_soup.status_code)));
-			return ConnectionError.NO_RESPONSE;
-		}
-
-		if(ping)
-		{
-			Logger.debug("Nextcloud Message: ping successful");
-			return ConnectionError.SUCCESS;
-		}
-
-		try
-		{
-			m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
-		}
-		catch(Error e)
-		{
-			Logger.error("Could not load response from Message to Nextcloud");
-			printMessage();
-			Logger.error(e.message);
-			return ConnectionError.UNKNOWN;
-		}
+private Soup.Session m_session;
+private Soup.Message m_message_soup;
+private GLib.StringBuilder m_message_string;
+private string m_contenttype;
+private Json.Parser m_parser;
+private Json.Object m_root_object;
+private string m_method;
+private string m_destination;
+
+public OwnCloudNewsMessage(Soup.Session session, string destination, string username, string password, string method)
+{
+	m_message_string = new GLib.StringBuilder();
+	m_method = method;
+	m_session = session;
+	m_destination = destination;
+
+	if(method == "GET")
+		m_contenttype = "application/x-www-form-urlencoded";
+	else
+		m_contenttype = "application/json";
+
+	m_parser = new Json.Parser();
+	m_message_soup = new Soup.Message(m_method, m_destination);
+
+	string credentials = username + ":" + password;
+	string base64 = GLib.Base64.encode(credentials.data);
+	m_message_soup.request_headers.append("Authorization","Basic %s".printf(base64));
+}
 
-		m_root_object = m_parser.get_root().get_object();
-		return ConnectionError.SUCCESS;
+public void add_int(string type, int val)
+{
+	if(m_method == "GET")
+	{
+		if(m_message_string.len > 0)
+			m_message_string.append("&");
+
+		m_message_string.append(type + "=" + val.to_string());
+	}
+	else
+		m_message_string.append(",\"" + type + "\":" + val.to_string());
+}
+
+public void add_int_array(string type, string values)
+{
+	if(m_method == "GET")
+		Logger.warning("OwnCloudNewsMessage.add_int_array: this should not happen");
+	else
+		m_message_string.append(",\"" + type + "\":[" + values + "]");
+}
+
+public void add_bool(string type, bool val)
+{
+	if(m_method == "GET")
+	{
+		if(m_message_string.len > 0)
+			m_message_string.append("&");
+
+		m_message_string.append(type + "=" + (val ? "true" : "false"));
+	}
+	else
+		m_message_string.append(",\"" + type + "\":" + (val ? "true" : "false"));
+}
+
+public void add_string(string type, string val)
+{
+	if(m_method == "GET")
+	{
+		if(m_message_string.len > 0)
+			m_message_string.append("&");
+
+		m_message_string.append(type + "=" + val);
+	}
+	else
+		m_message_string.append(",\"" + type + "\":\"" + val + "\"");
+}
+
+public ConnectionError send(bool ping = false)
+{
+	var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+
+	if(m_method == "GET")
+	{
+		string destination = m_destination;
+		if(m_message_string.len > 0)
+			destination += "?" + m_message_string.str;
+		m_message_soup.set_uri(new Soup.URI(destination));
+		Logger.debug(destination);
+	}
+	else
+	{
+		m_message_string.overwrite(0, "{").append("}");
+		m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
 	}
 
-	public uint getStatusCode()
+	if(settingsTweaks.get_boolean("do-not-track"))
+		m_message_soup.request_headers.append("DNT", "1");
+
+	var status = m_session.send_message(m_message_soup);
+
+	if(status == 401)         // unauthorized
 	{
-		return m_message_soup.status_code;
+		return ConnectionError.UNAUTHORIZED;
 	}
 
-	public Json.Object? get_response_object()
+	if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
 	{
-		return m_root_object;
+		Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
+		return ConnectionError.CA_ERROR;
 	}
 
-	public string getMessage()
+	if(m_message_soup.status_code != 200)
 	{
-		return m_message_string.str;
+		Logger.error("Nextcloud Message: No response - status code: %u %s".printf(m_message_soup.status_code, Soup.Status.get_phrase(m_message_soup.status_code)));
+		return ConnectionError.NO_RESPONSE;
 	}
 
-	public void printMessage()
+	if(ping)
 	{
-		Logger.debug(m_message_string.str);
+		Logger.debug("Nextcloud Message: ping successful");
+		return ConnectionError.SUCCESS;
 	}
 
-	public void printResponse()
+	try
+	{
+		m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+	}
+	catch(Error e)
 	{
-		Logger.debug((string)m_message_soup.response_body.flatten().data);
+		Logger.error("Could not load response from Message to Nextcloud");
+		printMessage();
+		Logger.error(e.message);
+		return ConnectionError.UNKNOWN;
 	}
+
+	m_root_object = m_parser.get_root().get_object();
+	return ConnectionError.SUCCESS;
+}
+
+public uint getStatusCode()
+{
+	return m_message_soup.status_code;
+}
+
+public Json.Object? get_response_object()
+{
+	return m_root_object;
+}
+
+public string getMessage()
+{
+	return m_message_string.str;
+}
+
+public void printMessage()
+{
+	Logger.debug(m_message_string.str);
+}
+
+public void printResponse()
+{
+	Logger.debug((string)m_message_soup.response_body.flatten().data);
+}
 }
diff -pruN 2.6.1-1/plugins/backend/owncloud/OwncloudNewsUtils.vala 2.7.1-1/plugins/backend/owncloud/OwncloudNewsUtils.vala
--- 2.6.1-1/plugins/backend/owncloud/OwncloudNewsUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/owncloud/OwncloudNewsUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,133 +15,133 @@
 
 public class FeedReader.OwncloudNewsUtils : GLib.Object {
 
-	GLib.Settings m_settings;
-	Password m_password;
-	Password m_htaccess_password;
-
-	public OwncloudNewsUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.owncloud", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.owncloud");
-
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-										  "URL", Secret.SchemaAttributeType.STRING,
-										  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, pwSchema, "FeedReader: Nextcloud login", () => {
+GLib.Settings m_settings;
+Password m_password;
+Password m_htaccess_password;
+
+public OwncloudNewsUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.owncloud", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.owncloud");
+
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                  "URL", Secret.SchemaAttributeType.STRING,
+	                                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, pwSchema, "FeedReader: Nextcloud login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getUser();
 			return attributes;
 		});
 
-		var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-											    "URL", Secret.SchemaAttributeType.STRING,
-											    "Username", Secret.SchemaAttributeType.STRING,
-											    "htaccess", Secret.SchemaAttributeType.BOOLEAN);
-		m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: Nextcloud login", () => {
+	var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                        "URL", Secret.SchemaAttributeType.STRING,
+	                                        "Username", Secret.SchemaAttributeType.STRING,
+	                                        "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+	m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: Nextcloud login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getHtaccessUser();
 			attributes["htaccess"] = "true";
 			return attributes;
 		});
-	}
+}
 
-	public string getURL()
-	{
-		string tmp_url = Utils.gsettingReadString(m_settings, "url");
-		if(tmp_url != ""){
-			if(!tmp_url.has_suffix("/"))
-				tmp_url = tmp_url + "/";
+public string getURL()
+{
+	string tmp_url = Utils.gsettingReadString(m_settings, "url");
+	if(tmp_url != "") {
+		if(!tmp_url.has_suffix("/"))
+			tmp_url = tmp_url + "/";
 
-			if(!tmp_url.has_suffix("/index.php/apps/news/api/v1-2/"))
-				tmp_url = tmp_url + "index.php/apps/news/api/v1-2/";
+		if(!tmp_url.has_suffix("/index.php/apps/news/api/v1-2/"))
+			tmp_url = tmp_url + "index.php/apps/news/api/v1-2/";
 
-			if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
-					tmp_url = "https://" + tmp_url;
-		}
+		if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+			tmp_url = "https://" + tmp_url;
+	}
 
-		Logger.debug("Nextcloud URL: " + tmp_url);
+	Logger.debug("Nextcloud URL: " + tmp_url);
 
-		return tmp_url;
-	}
+	return tmp_url;
+}
 
-	public void setURL(string url)
-	{
-		Utils.gsettingWriteString(m_settings, "url", url);
-	}
+public void setURL(string url)
+{
+	Utils.gsettingWriteString(m_settings, "url", url);
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getHtaccessUser()
-	{
-		return Utils.gsettingReadString(m_settings, "htaccess-username");
-	}
+public string getHtaccessUser()
+{
+	return Utils.gsettingReadString(m_settings, "htaccess-username");
+}
 
-	public void setHtaccessUser(string ht_user)
-	{
-		Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-	}
+public void setHtaccessUser(string ht_user)
+{
+	Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+}
 
-	public string getUnmodifiedURL()
-	{
-		return Utils.gsettingReadString(m_settings, "url");
-	}
+public string getUnmodifiedURL()
+{
+	return Utils.gsettingReadString(m_settings, "url");
+}
 
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
+public string getPasswd()
+{
+	return m_password.get_password();
+}
 
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-		m_htaccess_password.delete_password();
-	}
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+	m_htaccess_password.delete_password();
+}
 
-	public string getHtaccessPasswd()
-	{
-		return m_htaccess_password.get_password();
-	}
+public string getHtaccessPasswd()
+{
+	return m_htaccess_password.get_password();
+}
 
-	public void setHtAccessPassword(string passwd)
-	{
-		m_htaccess_password.set_password(passwd);
-	}
+public void setHtAccessPassword(string passwd)
+{
+	m_htaccess_password.set_password(passwd);
+}
 
-	public int countUnread(Gee.List<Feed> feeds, string id)
-	{
-		int unread = 0;
+public int countUnread(Gee.List<Feed> feeds, string id)
+{
+	int unread = 0;
 
-		foreach(Feed feed in feeds)
+	foreach(Feed feed in feeds)
+	{
+		var ids = feed.getCatIDs();
+		foreach(string ID in ids)
 		{
-			var ids = feed.getCatIDs();
-			foreach(string ID in ids)
+			if(ID == id)
 			{
-				if(ID == id)
-				{
-					unread += (int)feed.getUnread();
-					break;
-				}
+				unread += (int)feed.getUnread();
+				break;
 			}
 		}
-
-		return unread;
 	}
+
+	return unread;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/ttrss/ttrssAPI.vala 2.7.1-1/plugins/backend/ttrss/ttrssAPI.vala
--- 2.6.1-1/plugins/backend/ttrss/ttrssAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/ttrss/ttrssAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,966 +15,965 @@
 
 public class FeedReader.ttrssAPI : GLib.Object {
 
-	public string m_ttrss_url { get; private set; }
-	private ttrssUtils m_utils;
-	private string m_ttrss_sessionid;
-	private uint64 m_ttrss_apilevel;
-	private Json.Parser m_parser;
-	private string? m_iconDir = null;
-	private Soup.Session m_session;
-	private DataBaseReadOnly m_db;
-
-	public ttrssAPI (ttrssUtils utils, DataBaseReadOnly db)
-	{
-		m_db = db;
-		m_parser = new Json.Parser();
-		m_utils = utils;
-		m_session = new Soup.Session();
-		m_session.user_agent = Constants.USER_AGENT;
-		m_session.ssl_strict = false;
-		m_session.authenticate.connect((msg, auth, retrying) => {
+public string m_ttrss_url { get; private set; }
+private ttrssUtils m_utils;
+private string m_ttrss_sessionid;
+private uint64 m_ttrss_apilevel;
+private Json.Parser m_parser;
+private string? m_iconDir = null;
+private Soup.Session m_session;
+
+public ttrssAPI (ttrssUtils utils)
+{
+	m_parser = new Json.Parser();
+	m_utils = utils;
+	m_session = new Soup.Session();
+	m_session.user_agent = Constants.USER_AGENT;
+	m_session.ssl_strict = false;
+	m_session.authenticate.connect((msg, auth, retrying) => {
 			if(m_utils.getHtaccessUser() == "")
 			{
-				Logger.error("TTRSS Session: need Authentication");
+			        Logger.error("TTRSS Session: need Authentication");
 			}
 			else if(!retrying)
 			{
-				auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
+			        auth.authenticate(m_utils.getHtaccessUser(), m_utils.getHtaccessPasswd());
 			}
 		});
-	}
-
-
-	public LoginResponse login()
-	{
-		Logger.debug("TTRSS: login");
-		string username = m_utils.getUser();
-		string passwd = m_utils.getPasswd();
-		m_ttrss_url = m_utils.getURL();
-
-		if(m_ttrss_url == "" && username == "" && passwd == "")
-		{
-			m_ttrss_url = "example-host/tt-rss";
-			return LoginResponse.ALL_EMPTY;
-		}
-		if(m_ttrss_url == "")
-			return LoginResponse.MISSING_URL;
-		if(GLib.Uri.parse_scheme(m_ttrss_url) == null)
-			return LoginResponse.INVALID_URL;
-		if(passwd == "")
-			return LoginResponse.MISSING_PASSWD;
-
+}
 
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("op", "login");
-		if(username != "")
-			message.add_string("user", username);
-		message.add_string("password", passwd);
-		int error = message.send();
-		if(error != ConnectionError.NO_RESPONSE)
-			message.printResponse();
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			m_ttrss_sessionid = response.get_string_member("session_id");
-			m_ttrss_apilevel = response.get_int_member("api_level");
-			Logger.info("TTRSS Session ID: %s".printf(m_ttrss_sessionid));
-			Logger.info("TTRSS API Level: %lld".printf(m_ttrss_apilevel));
+public LoginResponse login()
+{
+	Logger.debug("TTRSS: login");
+	string username = m_utils.getUser();
+	string passwd = m_utils.getPasswd();
+	m_ttrss_url = m_utils.getURL();
+
+	if(m_ttrss_url == "" && username == "" && passwd == "")
+	{
+		m_ttrss_url = "example-host/tt-rss";
+		return LoginResponse.ALL_EMPTY;
+	}
+	if(m_ttrss_url == "")
+		return LoginResponse.MISSING_URL;
+	if(GLib.Uri.parse_scheme(m_ttrss_url) == null)
+		return LoginResponse.INVALID_URL;
+	if(passwd == "")
+		return LoginResponse.MISSING_PASSWD;
+
+
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("op", "login");
+	if(username != "")
+		message.add_string("user", username);
+	message.add_string("password", passwd);
+	int error = message.send();
+	if(error != ConnectionError.NO_RESPONSE)
+		message.printResponse();
 
-			m_iconDir = m_ttrss_url.replace("api/", getIconDir());
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		m_ttrss_sessionid = response.get_string_member("session_id");
+		m_ttrss_apilevel = response.get_int_member("api_level");
+		Logger.info("TTRSS Session ID: %s".printf(m_ttrss_sessionid));
+		Logger.info("TTRSS API Level: %lld".printf(m_ttrss_apilevel));
 
-			if(haveAPIplugin())
-				return LoginResponse.SUCCESS;
+		m_iconDir = m_ttrss_url.replace("api/", getIconDir());
 
-			return LoginResponse.PLUGIN_NEEDED;
-		}
-		else
-		{
-			message.printMessage();
-			message.printResponse();
-		}
+		if(haveAPIplugin())
+			return LoginResponse.SUCCESS;
 
-		if(error == ConnectionError.API_ERROR)
-		{
-			return LoginResponse.API_ERROR;
-		}
-		else if(error == ConnectionError.NO_RESPONSE)
-		{
-			return LoginResponse.NO_CONNECTION;
-		}
-		else if(error == ConnectionError.API_DISABLED)
-		{
-			return LoginResponse.NO_API_ACCESS;
-		}
-		else if(error == ConnectionError.CA_ERROR)
-		{
-			return LoginResponse.CA_ERROR;
-		}
-		else if(error == ConnectionError.UNAUTHORIZED)
-		{
-			return LoginResponse.UNAUTHORIZED;
-		}
-
-		return LoginResponse.UNKNOWN_ERROR;
+		return LoginResponse.PLUGIN_NEEDED;
 	}
-
-	public bool logout()
+	else
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "logout");
-		int error = message.send();
-		Logger.warning("TTRSS: logout");
+		message.printMessage();
 		message.printResponse();
-
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			m_ttrss_sessionid = "";
-			return response.get_boolean_member("status");
-		}
-
-		return false;
 	}
 
-
-	public bool isloggedin()
+	if(error == ConnectionError.API_ERROR)
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "isLoggedIn");
-		int error = message.send();
-		Logger.debug("TTRSS: isloggedin?");
-		message.printResponse();
+		return LoginResponse.API_ERROR;
+	}
+	else if(error == ConnectionError.NO_RESPONSE)
+	{
+		return LoginResponse.NO_CONNECTION;
+	}
+	else if(error == ConnectionError.API_DISABLED)
+	{
+		return LoginResponse.NO_API_ACCESS;
+	}
+	else if(error == ConnectionError.CA_ERROR)
+	{
+		return LoginResponse.CA_ERROR;
+	}
+	else if(error == ConnectionError.UNAUTHORIZED)
+	{
+		return LoginResponse.UNAUTHORIZED;
+	}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			return response.get_boolean_member("status");
-		}
+	return LoginResponse.UNKNOWN_ERROR;
+}
 
-		return false;
+public bool logout()
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "logout");
+	int error = message.send();
+	Logger.warning("TTRSS: logout");
+	message.printResponse();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		m_ttrss_sessionid = "";
+		return response.get_boolean_member("status");
 	}
 
-	private bool haveAPIplugin()
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "removeLabel");
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.API_ERROR)
-		{
-			var response = message.get_response_object();
-			if(response.has_member("error"))
-			{
-				if(response.get_string_member("error") == "INCORRECT_USAGE")
-				{
-					return true;
-				}
-			}
-		}
 
-		return false;
+public bool isloggedin()
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "isLoggedIn");
+	int error = message.send();
+	Logger.debug("TTRSS: isloggedin?");
+	message.printResponse();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		return response.get_boolean_member("status");
 	}
 
+	return false;
+}
 
-	public int getUnreadCount()
-	{
-		int unread = 0;
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getUnread");
-		int error = message.send();
+private bool haveAPIplugin()
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "removeLabel");
+	int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
+	if(error == ConnectionError.API_ERROR)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("error"))
 		{
-			var response = message.get_response_object();
-			int64 parsed = 0;
-			bool res = int64.try_parse(response.get_string_member("unread"), out parsed);
-			if(res) {
-				unread = (int) parsed;
-			}
-			else
+			if(response.get_string_member("error") == "INCORRECT_USAGE")
 			{
-				Logger.warning("Could not parse unread articles");
+				return true;
 			}
 		}
-		Logger.info("There are %i unread articles".printf(unread));
-
-		return unread;
 	}
 
+	return false;
+}
 
-	public bool getFeeds(Gee.List<Feed> feeds, Gee.List<Category> categories)
-	{
-		foreach(var item in categories)
-		{
-			if(int.parse(item.getCatID()) > 0)
-			{
-				var message = new ttrssMessage(m_session, m_ttrss_url);
-				message.add_string("sid", m_ttrss_sessionid);
-				message.add_string("op", "getFeeds");
-				message.add_int("cat_id", int.parse(item.getCatID()));
-				int error = message.send();
-
-				if(error == ConnectionError.SUCCESS)
-				{
-					var response = message.get_response_array();
-					var feed_count = response.get_length();
 
-					for(uint i = 0; i < feed_count; i++)
-					{
-						var feed_node = response.get_object_element(i);
-						string feed_id = feed_node.get_int_member("id").to_string();
-						string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
-
-						feeds.add(
-							new Feed(
-									feed_id,
-									feed_node.get_string_member("title"),
-									feed_node.get_string_member("feed_url"),
-									(int)feed_node.get_int_member("unread"),
-									ListUtils.single(feed_node.get_int_member("cat_id").to_string()),
-									icon_url
-								)
-						);
-					}
-				}
-				else
-				{
-					return false;
-				}
-			}
+public int getUnreadCount()
+{
+	int unread = 0;
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getUnread");
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		int64 parsed = 0;
+		bool res = int64.try_parse(response.get_string_member("unread"), out parsed);
+		if(res) {
+			unread = (int) parsed;
+		}
+		else
+		{
+			Logger.warning("Could not parse unread articles");
 		}
-		return true;
 	}
+	Logger.info("There are %i unread articles".printf(unread));
 
+	return unread;
+}
 
-	public bool getUncategorizedFeeds(Gee.List<Feed> feeds)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getFeeds");
-		message.add_int("cat_id", 0);
-		int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
+public bool getFeeds(Gee.List<Feed> feeds, Gee.List<Category> categories)
+{
+	foreach(var item in categories)
+	{
+		if(int.parse(item.getCatID()) > 0)
 		{
-			var response = message.get_response_array();
-			var feed_count = response.get_length();
+			var message = new ttrssMessage(m_session, m_ttrss_url);
+			message.add_string("sid", m_ttrss_sessionid);
+			message.add_string("op", "getFeeds");
+			message.add_int("cat_id", int.parse(item.getCatID()));
+			int error = message.send();
 
-			for(uint i = 0; i < feed_count; i++)
+			if(error == ConnectionError.SUCCESS)
 			{
-				var feed_node = response.get_object_element(i);
-				string feed_id = feed_node.get_int_member("id").to_string();
-				string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
+				var response = message.get_response_array();
+				var feed_count = response.get_length();
+
+				for(uint i = 0; i < feed_count; i++)
+				{
+					var feed_node = response.get_object_element(i);
+					string feed_id = feed_node.get_int_member("id").to_string();
+					string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
 
-				feeds.add(
-					new Feed(
+					feeds.add(
+						new Feed(
 							feed_id,
 							feed_node.get_string_member("title"),
 							feed_node.get_string_member("feed_url"),
 							(int)feed_node.get_int_member("unread"),
 							ListUtils.single(feed_node.get_int_member("cat_id").to_string()),
 							icon_url
-						)
-				);
+							)
+						);
+				}
+			}
+			else
+			{
+				return false;
 			}
-			return true;
 		}
-
-		return false;
 	}
+	return true;
+}
 
-	public bool getTags(Gee.List<Tag> tags)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getLabels");
-		int error = message.send();
-
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_array();
-			var tag_count = response.get_length();
 
-			for(uint i = 0; i < tag_count; ++i)
-			{
-				var tag_node = response.get_object_element(i);
-				tags.add(
-					new Tag(
-						tag_node.get_int_member("id").to_string(),
-						tag_node.get_string_member("caption"),
-						m_db.getTagColor()
+public bool getUncategorizedFeeds(Gee.List<Feed> feeds)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getFeeds");
+	message.add_int("cat_id", 0);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_array();
+		var feed_count = response.get_length();
+
+		for(uint i = 0; i < feed_count; i++)
+		{
+			var feed_node = response.get_object_element(i);
+			string feed_id = feed_node.get_int_member("id").to_string();
+			string? icon_url = feed_node.get_boolean_member("has_icon") ? m_iconDir + feed_id + ".ico" : null;
+
+			feeds.add(
+				new Feed(
+					feed_id,
+					feed_node.get_string_member("title"),
+					feed_node.get_string_member("feed_url"),
+					(int)feed_node.get_int_member("unread"),
+					ListUtils.single(feed_node.get_int_member("cat_id").to_string()),
+					icon_url
 					)
 				);
-			}
+		}
+		return true;
+	}
 
-			return true;
+	return false;
+}
+
+public bool getTags(Gee.List<Tag> tags)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getLabels");
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_array();
+		var tag_count = response.get_length();
+
+		var db = DataBase.readOnly();
+		for(uint i = 0; i < tag_count; ++i)
+		{
+			var tag_node = response.get_object_element(i);
+			tags.add(
+				new Tag(
+					tag_node.get_int_member("id").to_string(),
+					tag_node.get_string_member("caption"),
+					db.getTagColor()
+					)
+				);
 		}
 
-		return false;
+		return true;
 	}
 
+	return false;
+}
 
-	public string? getIconDir()
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getConfig");
-		int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			return response.get_string_member("icons_url") + "/";
-		}
+public string? getIconDir()
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getConfig");
+	int error = message.send();
 
-		return null;
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		return response.get_string_member("icons_url") + "/";
 	}
 
+	return null;
+}
 
-	public bool getCategories(Gee.List<Category> categories)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getFeedTree");
-		message.add_bool("include_empty", true);
-		int error = message.send();
 
-		if(error == ConnectionError.SUCCESS)
+public bool getCategories(Gee.List<Category> categories)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getFeedTree");
+	message.add_bool("include_empty", true);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("categories"))
 		{
-			var response = message.get_response_object();
-			if(response.has_member("categories"))
-			{
-				var category_object = response.get_object_member("categories");
-				getSubCategories(categories, category_object, 0, CategoryID.MASTER.to_string());
-				return true;
-			}
+			var category_object = response.get_object_member("categories");
+			getSubCategories(categories, category_object, 0, CategoryID.MASTER.to_string());
+			return true;
 		}
-
-		return false;
 	}
 
+	return false;
+}
 
-	private void getSubCategories(Gee.List<Category> categories, Json.Object categorie, int level, string parent)
-	{
-		level++;
-		int orderID = 0;
-		var subcategorie = categorie.get_array_member("items");
-		var items_count = subcategorie.get_length();
-		for(uint i = 0; i < items_count; i++)
-		{
-			var categorie_node = subcategorie.get_object_element(i);
-			if(categorie_node.get_string_member("id").has_prefix("CAT:"))
+
+private void getSubCategories(Gee.List<Category> categories, Json.Object categorie, int level, string parent)
+{
+	level++;
+	int orderID = 0;
+	var subcategorie = categorie.get_array_member("items");
+	var items_count = subcategorie.get_length();
+	for(uint i = 0; i < items_count; i++)
+	{
+		var categorie_node = subcategorie.get_object_element(i);
+		if(categorie_node.get_string_member("id").has_prefix("CAT:"))
+		{
+			orderID++;
+			string catID = categorie_node.get_string_member("id");
+			string categorieID = catID.slice(4, catID.length);
+
+			if(int.parse(categorieID) > 0)
 			{
-				orderID++;
-				string catID = categorie_node.get_string_member("id");
-				string categorieID = catID.slice(4, catID.length);
+				string title = categorie_node.get_string_member("name");
+				int unread_count = (int)categorie_node.get_int_member("unread");
 
-				if(int.parse(categorieID) > 0)
+				if(title == "Uncategorized")
 				{
-					string title = categorie_node.get_string_member("name");
-					int unread_count = (int)categorie_node.get_int_member("unread");
-
-					if(title == "Uncategorized")
-					{
-						unread_count = getUncategorizedUnread();
-					}
+					unread_count = getUncategorizedUnread();
+				}
 
-					categories.add(
-						new Category (
-							categorieID,
-							title,
-							unread_count,
-							orderID,
-							parent,
-							level
+				categories.add(
+					new Category (
+						categorieID,
+						title,
+						unread_count,
+						orderID,
+						parent,
+						level
 						)
 					);
-				}
-
-				getSubCategories(categories, categorie_node, level, categorieID);
 			}
+
+			getSubCategories(categories, categorie_node, level, categorieID);
 		}
 	}
+}
 
 
-	private int getUncategorizedUnread()
+private int getUncategorizedUnread()
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getCounters");
+	message.add_string("output_mode", "c");
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getCounters");
-		message.add_string("output_mode", "c");
-		int error = message.send();
+		var response = message.get_response_array();
+		var categorie_count = response.get_length();
 
-		if(error == ConnectionError.SUCCESS)
+		for(int i = 0; i < categorie_count; i++)
 		{
-			var response = message.get_response_array();
-			var categorie_count = response.get_length();
-
-			for(int i = 0; i < categorie_count; i++)
+			var categorie_node = response.get_object_element(i);
+			if(categorie_node.get_int_member("id") == 0)
 			{
-				var categorie_node = response.get_object_element(i);
-				if(categorie_node.get_int_member("id") == 0)
+				if(categorie_node.has_member("kind"))
 				{
-					if(categorie_node.has_member("kind"))
+					if(categorie_node.get_string_member("kind") == "cat")
 					{
-						if(categorie_node.get_string_member("kind") == "cat")
-						{
-							return (int)categorie_node.get_int_member("counter");
-						}
+						return (int)categorie_node.get_int_member("counter");
 					}
 				}
 			}
 		}
-
-		return 0;
 	}
 
+	return 0;
+}
+
 
-	public void getHeadlines(Gee.List<Article> articles, int skip, int limit, ArticleStatus whatToGet, int feedID)
+public void getHeadlines(Gee.List<Article> articles, int skip, int limit, ArticleStatus whatToGet, int feedID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getHeadlines");
+	message.add_int("feed_id", feedID);
+	message.add_int("limit", limit);
+	message.add_int("skip", skip);
+
+	switch(whatToGet)
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getHeadlines");
-		message.add_int("feed_id", feedID);
-		message.add_int("limit", limit);
-		message.add_int("skip", skip);
+	case ArticleStatus.ALL:
+		message.add_string("view_mode", "all_articles");
+		break;
 
-		switch(whatToGet)
-		{
-			case ArticleStatus.ALL:
-				message.add_string("view_mode", "all_articles");
-				break;
+	case ArticleStatus.UNREAD:
+		message.add_string("view_mode", "unread");
+		break;
 
-			case ArticleStatus.UNREAD:
-				message.add_string("view_mode", "unread");
-				break;
+	case ArticleStatus.MARKED:
+		message.add_string("view_mode", "marked");
+		break;
+	}
 
-			case ArticleStatus.MARKED:
-				message.add_string("view_mode", "marked");
-				break;
-		}
+	int error = message.send();
+	message.printMessage();
 
-		int error = message.send();
-		message.printMessage();
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_array();
+		var headline_count = response.get_length();
 
-		if(error == ConnectionError.SUCCESS)
+		for(uint i = 0; i < headline_count; i++)
 		{
-			var response = message.get_response_array();
-			var headline_count = response.get_length();
+			var headline_node = response.get_object_element(i);
 
-			for(uint i = 0; i < headline_count; i++)
+			Gee.List<string>? tags = null;
+			if(headline_node.has_member("labels"))
 			{
-				var headline_node = response.get_object_element(i);
+				var labels = headline_node.get_array_member("labels");
 
-				Gee.List<string>? tags = null;
-				if(headline_node.has_member("labels"))
-				{
-					var labels = headline_node.get_array_member("labels");
+				uint tag_count = 0;
+				if(labels != null)
+					tag_count = labels.get_length();
 
-					uint tag_count = 0;
-					if(labels != null)
-						tag_count = labels.get_length();
-
-					if(tag_count > 0) {
-						tags = new Gee.ArrayList<string>();
-						for(int j = 0; j < tag_count; ++j)
-						{
-							tags.add(labels.get_array_element(j).get_int_element(0).to_string());
-						}
+				if(tag_count > 0) {
+					tags = new Gee.ArrayList<string>();
+					for(int j = 0; j < tag_count; ++j)
+					{
+						tags.add(labels.get_array_element(j).get_int_element(0).to_string());
 					}
 				}
+			}
 
-				var enclosures = new Gee.ArrayList<Enclosure>();
-				if(headline_node.has_member("attachments"))
-				{
-					var attachments = headline_node.get_array_member("attachments");
+			var enclosures = new Gee.ArrayList<Enclosure>();
+			if(headline_node.has_member("attachments"))
+			{
+				var attachments = headline_node.get_array_member("attachments");
 
-					uint mediaCount = 0;
-					if(attachments != null)
-						mediaCount = attachments.get_length();
+				uint mediaCount = 0;
+				if(attachments != null)
+					mediaCount = attachments.get_length();
 
-					for(int j = 0; j < mediaCount; ++j)
-					{
-						var attachment = attachments.get_object_element(j);
-						enclosures.add(new Enclosure(
-							headline_node.get_string_member("id"),
-							attachment.get_string_member("content_url"),
-							EnclosureType.from_string(attachment.get_string_member("content_type"))));
-					}
+				for(int j = 0; j < mediaCount; ++j)
+				{
+					var attachment = attachments.get_object_element(j);
+					enclosures.add(new Enclosure(
+							       headline_node.get_string_member("id"),
+							       attachment.get_string_member("content_url"),
+							       EnclosureType.from_string(attachment.get_string_member("content_type"))));
 				}
-
-				var Article = new Article(
-										headline_node.get_int_member("id").to_string(),
-										headline_node.get_string_member("title"),
-										headline_node.get_string_member("link"),
-										headline_node.get_string_member("feed_id"),
-										headline_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
-										headline_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-										null,
-										null,
-										headline_node.get_string_member("author"),
-										new DateTime.from_unix_local(headline_node.get_int_member("updated")),
-										-1,
-										tags,
-										enclosures
-								);
-
-				articles.add(Article);
 			}
+
+			var Article = new Article(
+				headline_node.get_int_member("id").to_string(),
+				headline_node.get_string_member("title"),
+				headline_node.get_string_member("link"),
+				headline_node.get_string_member("feed_id"),
+				headline_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
+				headline_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				null,
+				null,
+				headline_node.get_string_member("author"),
+				new DateTime.from_unix_local(headline_node.get_int_member("updated")),
+				-1,
+				tags,
+				enclosures
+				);
+
+			articles.add(Article);
 		}
 	}
+}
 
-	// tt-rss server needs newsplusplus extention
-	public Gee.List<string>? NewsPlus(ArticleStatus type, int limit)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getCompactHeadlines");
-		message.add_int("feed_id", ttrssUtils.TTRSSSpecialID.ALL);
-		message.add_int("limit", limit);
-		if(type == ArticleStatus.UNREAD)
-			message.add_string("view_mode", "unread");
-		else if(type == ArticleStatus.MARKED)
-			message.add_string("view_mode", "marked");
-		else
-			return null;
-		int error = message.send();
-		message.printMessage();
+// tt-rss server needs newsplusplus extention
+public Gee.List<string>? NewsPlus(ArticleStatus type, int limit)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getCompactHeadlines");
+	message.add_int("feed_id", ttrssUtils.TTRSSSpecialID.ALL);
+	message.add_int("limit", limit);
+	if(type == ArticleStatus.UNREAD)
+		message.add_string("view_mode", "unread");
+	else if(type == ArticleStatus.MARKED)
+		message.add_string("view_mode", "marked");
+	else
+		return null;
+	int error = message.send();
+	message.printMessage();
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_array();
-			var headline_count = response.get_length();
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_array();
+		var headline_count = response.get_length();
 
-			var ids = new Gee.LinkedList<string>();
+		var ids = new Gee.LinkedList<string>();
 
-			for(uint i = 0; i < headline_count; i++)
-			{
-				var headline_node = response.get_object_element(i);
-				ids.add(headline_node.get_int_member("id").to_string());
-			}
-			return ids;
+		for(uint i = 0; i < headline_count; i++)
+		{
+			var headline_node = response.get_object_element(i);
+			ids.add(headline_node.get_int_member("id").to_string());
 		}
-		return null;
+		return ids;
 	}
+	return null;
+}
 
 
-	public void getArticles(string articleIDs, Gee.List<Article> articles)
+public void getArticles(string articleIDs, Gee.List<Article> articles)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "getArticle");
+	message.add_string("article_id", articleIDs);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "getArticle");
-		message.add_string("article_id", articleIDs);
-		int error = message.send();
+		var response = message.get_response_array();
+		var article_count = response.get_length();
 
-		if(error == ConnectionError.SUCCESS)
+		for(uint i = 0; i < article_count; i++)
 		{
-			var response = message.get_response_array();
-			var article_count = response.get_length();
+			var article_node = response.get_object_element(i);
 
-			for(uint i = 0; i < article_count; i++)
+			Gee.List<string>? tags = null;
+			if(article_node.has_member("labels"))
 			{
-				var article_node = response.get_object_element(i);
-
-				Gee.List<string>? tags = null;
-				if(article_node.has_member("labels"))
-				{
-					var labels = article_node.get_array_member("labels");
+				var labels = article_node.get_array_member("labels");
 
-					uint tag_count = 0;
-					if(labels != null)
-						tag_count = labels.get_length();
+				uint tag_count = 0;
+				if(labels != null)
+					tag_count = labels.get_length();
 
-					if(tag_count > 0)
-						tags = new Gee.ArrayList<string>();
+				if(tag_count > 0)
+					tags = new Gee.ArrayList<string>();
 
-					for(int j = 0; j < tag_count; ++j)
-					{
-						tags.add(labels.get_array_element(j).get_int_element(0).to_string());
-					}
+				for(int j = 0; j < tag_count; ++j)
+				{
+					tags.add(labels.get_array_element(j).get_int_element(0).to_string());
 				}
+			}
 
-				var enclosures = new Gee.ArrayList<Enclosure>();
-				if(article_node.has_member("attachments"))
-				{
-					var attachments = article_node.get_array_member("attachments");
+			var enclosures = new Gee.ArrayList<Enclosure>();
+			if(article_node.has_member("attachments"))
+			{
+				var attachments = article_node.get_array_member("attachments");
 
-					uint mediaCount = 0;
-					if(attachments != null)
-						mediaCount = attachments.get_length();
+				uint mediaCount = 0;
+				if(attachments != null)
+					mediaCount = attachments.get_length();
 
-					for(int j = 0; j < mediaCount; ++j)
-					{
-						var attachment = attachments.get_object_element(j);
-						enclosures.add(new Enclosure(
-							article_node.get_string_member("id"),
-							attachment.get_string_member("content_url"),
-							EnclosureType.from_string(attachment.get_string_member("content_type"))));
-					}
+				for(int j = 0; j < mediaCount; ++j)
+				{
+					var attachment = attachments.get_object_element(j);
+					enclosures.add(new Enclosure(
+							       article_node.get_string_member("id"),
+							       attachment.get_string_member("content_url"),
+							       EnclosureType.from_string(attachment.get_string_member("content_type"))));
 				}
+			}
 
-				var Article = new Article(
-										article_node.get_string_member("id"),
-										article_node.get_string_member("title"),
-										article_node.get_string_member("link"),
-										article_node.get_string_member("feed_id"),
-										article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
-										article_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
-										article_node.get_string_member("content"),
-										null,
-										article_node.get_string_member("author"),
-										new DateTime.from_unix_local(article_node.get_int_member("updated")),
-										-1,
-										tags,
-										enclosures
-								);
+			var Article = new Article(
+				article_node.get_string_member("id"),
+				article_node.get_string_member("title"),
+				article_node.get_string_member("link"),
+				article_node.get_string_member("feed_id"),
+				article_node.get_boolean_member("unread") ? ArticleStatus.UNREAD : ArticleStatus.READ,
+				article_node.get_boolean_member("marked") ? ArticleStatus.MARKED : ArticleStatus.UNMARKED,
+				article_node.get_string_member("content"),
+				null,
+				article_node.get_string_member("author"),
+				new DateTime.from_unix_local(article_node.get_int_member("updated")),
+				-1,
+				tags,
+				enclosures
+				);
 
-				articles.add(Article);
-			}
+			articles.add(Article);
 		}
 	}
+}
+
+public bool catchupFeed(string feedID, bool isCatID)
+{
+	bool return_value = false;
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "catchupFeed");
+	message.add_int_array("feed_id", feedID);
+	message.add_bool("is_cat", isCatID);
+	int error = message.send();
 
-	public bool catchupFeed(string feedID, bool isCatID)
+	if(error == ConnectionError.SUCCESS)
 	{
-		bool return_value = false;
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "catchupFeed");
-		message.add_int_array("feed_id", feedID);
-		message.add_bool("is_cat", isCatID);
-		int error = message.send();
+		var response = message.get_response_object();
+		if(response.get_string_member("status") == "OK")
+			return_value = true;
+	}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.get_string_member("status") == "OK")
-				return_value = true;
-		}
 
+	return return_value;
+}
 
-		return return_value;
+public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
+{
+	bool return_value = false;
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "updateArticle");
+	message.add_int_array("article_ids", articleIDs);
+	if(unread == ArticleStatus.UNREAD)
+		message.add_int("mode", 1);
+	else if(unread == ArticleStatus.READ)
+		message.add_int("mode", 0);
+	message.add_int("field", 2);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.get_string_member("status") == "OK")
+			return_value = true;
 	}
 
-	public bool updateArticleUnread(string articleIDs, ArticleStatus unread)
-	{
-		bool return_value = false;
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "updateArticle");
-		message.add_int_array("article_ids", articleIDs);
-		if(unread == ArticleStatus.UNREAD)
-			message.add_int("mode", 1);
-		else if(unread == ArticleStatus.READ)
-			message.add_int("mode", 0);
-		message.add_int("field", 2);
-		int error = message.send();
+	return return_value;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.get_string_member("status") == "OK")
-				return_value = true;
-		}
 
-		return return_value;
+public bool updateArticleMarked(int articleID, ArticleStatus marked)
+{
+	bool return_value = false;
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "updateArticle");
+	message.add_int("article_ids", articleID);
+	if(marked == ArticleStatus.MARKED)
+		message.add_int("mode", 1);
+	else if(marked == ArticleStatus.UNMARKED)
+		message.add_int("mode", 0);
+	message.add_int("field", 0);
+	int error = message.send();
+
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.get_string_member("status") == "OK")
+			return_value = true;
 	}
 
+	return return_value;
+}
 
-	public bool updateArticleMarked(int articleID, ArticleStatus marked)
-	{
-		bool return_value = false;
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "updateArticle");
-		message.add_int("article_ids", articleID);
-		if(marked == ArticleStatus.MARKED)
-			message.add_int("mode", 1);
-		else if(marked == ArticleStatus.UNMARKED)
-			message.add_int("mode", 0);
-		message.add_int("field", 0);
-		int error = message.send();
-
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.get_string_member("status") == "OK")
-				return_value = true;
-		}
-
-		return return_value;
-	}
+public bool setArticleLabel(int articleID, int tagID, bool add)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "setArticleLabel");
+	message.add_int("article_ids", articleID);
+	message.add_int("label_id", tagID);
+	message.add_bool("assign", add);
+	int error = message.send();
 
-	public bool setArticleLabel(int articleID, int tagID, bool add)
+	if(error == ConnectionError.SUCCESS)
 	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "setArticleLabel");
-		message.add_int("article_ids", articleID);
-		message.add_int("label_id", tagID);
-		message.add_bool("assign", add);
-		int error = message.send();
-
-		if(error == ConnectionError.SUCCESS)
-		{
-			var response = message.get_response_object();
-			if(response.get_string_member("status") == "OK")
+		var response = message.get_response_object();
+		if(response.get_string_member("status") == "OK")
 			return true;
-		}
-
-		return false;
 	}
 
-	public int64 addLabel(string caption)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "addLabel");
-		message.add_string("caption", caption);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return message.get_response_int();
-		}
+public int64 addLabel(string caption)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "addLabel");
+	message.add_string("caption", caption);
+	int error = message.send();
 
-		return 0;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return message.get_response_int();
 	}
 
-	public bool removeLabel(int tagID)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "removeLabel");
-		message.add_int("label_id", tagID);
-		int error = message.send();
+	return 0;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool removeLabel(int tagID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "removeLabel");
+	message.add_int("label_id", tagID);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool renameLabel(int tagID, string newName)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "renameLabel");
-		message.add_int("label_id", tagID);
-		message.add_string("caption", newName);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool renameLabel(int tagID, string newName)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "renameLabel");
+	message.add_int("label_id", tagID);
+	message.add_string("caption", newName);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
+	return false;
+}
 
-	public bool subscribeToFeed(string feedURL, string? catID, string? username, string? password, out string errmsg)
-	{
-		errmsg = "";
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "subscribeToFeed");
-		message.add_string("feed_url", feedURL);
 
-		if(catID != null)
-			message.add_int("category_id", int.parse(catID));
-		if(username != null && password != null)
-		{
-			message.add_string("login", username);
-			message.add_string("password", password);
-		}
+public bool subscribeToFeed(string feedURL, string? catID, string? username, string? password, out string errmsg)
+{
+	errmsg = "";
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "subscribeToFeed");
+	message.add_string("feed_url", feedURL);
 
-		int error = message.send();
-		message.printMessage();
-		message.printResponse();
-		Logger.debug(message.getStatusCode().to_string());
+	if(catID != null)
+		message.add_int("category_id", int.parse(catID));
+	if(username != null && password != null)
+	{
+		message.add_string("login", username);
+		message.add_string("password", password);
+	}
+
+	int error = message.send();
+	message.printMessage();
+	message.printResponse();
+	Logger.debug(message.getStatusCode().to_string());
 
-		if(error == ConnectionError.SUCCESS)
+	if(error == ConnectionError.SUCCESS)
+	{
+		var response = message.get_response_object();
+		if(response.has_member("status"))
 		{
-			var response = message.get_response_object();
-			if(response.has_member("status"))
+			var status = response.get_object_member("status");
+			if(status.has_member("code"))
 			{
-				var status = response.get_object_member("status");
-				if(status.has_member("code"))
+				switch(status.get_int_member("code"))
 				{
-					switch(status.get_int_member("code"))
-					{
-						case 0:
-						case 1:
-							return true;
-						case 2:
-							errmsg = _("Invalid URL");
-							return false;
-						case 3:
-							errmsg = _("URL content is HTML, no feeds available");
-							return false;
-						case 4:
-							errmsg = _("URL content is HTML which contains multiple feeds.");
-							return false;
-						case 5:
-							errmsg = _("Couldn't download the URL content.");
-							return false;
-						case 6:
-							errmsg = _("The content is invalid XML.");
-							return false;
-						default:
-							if(status.has_member("message"))
-								errmsg = status.get_string_member("message");
-							else
-								errmsg = "ttrss error";
-							return false;
-					}
+				case 0:
+				case 1:
+					return true;
+				case 2:
+					errmsg = _("Invalid URL");
+					return false;
+				case 3:
+					errmsg = _("URL content is HTML, no feeds available");
+					return false;
+				case 4:
+					errmsg = _("URL content is HTML which contains multiple feeds.");
+					return false;
+				case 5:
+					errmsg = _("Couldn't download the URL content.");
+					return false;
+				case 6:
+					errmsg = _("The content is invalid XML.");
+					return false;
+				default:
+					if(status.has_member("message"))
+						errmsg = status.get_string_member("message");
+					else
+						errmsg = "ttrss error";
+					return false;
 				}
 			}
 		}
-
-		errmsg = _("Error reaching tt-rss");
-		return false;
 	}
 
-	public bool unsubscribeFeed(int feedID)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "unsubscribeFeed");
-		message.add_int("feed_id", feedID);
-		int error = message.send();
+	errmsg = _("Error reaching tt-rss");
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool unsubscribeFeed(int feedID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "unsubscribeFeed");
+	message.add_int("feed_id", feedID);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public string? createCategory(string title, int? parentID = null)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "addCategory");
-		message.add_string("caption", title);
-		if(parentID != null)
-			message.add_int("parent_id", parentID);
-		int error = message.send();
-		message.printMessage();
+	return false;
+}
 
+public string? createCategory(string title, int? parentID = null)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "addCategory");
+	message.add_string("caption", title);
+	if(parentID != null)
+		message.add_int("parent_id", parentID);
+	int error = message.send();
+	message.printMessage();
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return message.get_response_string();
-		}
 
-		return null;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return message.get_response_string();
 	}
 
-	public bool removeCategory(int catID)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "removeCategory");
-		message.add_int("category_id", catID);
-		int error = message.send();
+	return null;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool removeCategory(int catID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "removeCategory");
+	message.add_int("category_id", catID);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool moveCategory(int catID, int parentID)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "moveCategory");
-		message.add_int("category_id", catID);
-		if(parentID != int.parse(CategoryID.MASTER.to_string()))
-			message.add_int("parent_id", parentID);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool moveCategory(int catID, int parentID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "moveCategory");
+	message.add_int("category_id", catID);
+	if(parentID != int.parse(CategoryID.MASTER.to_string()))
+		message.add_int("parent_id", parentID);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool renameCategory(int catID, string title)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "renameCategory");
-		message.add_int("category_id", catID);
-		message.add_string("caption", title);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool renameCategory(int catID, string title)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "renameCategory");
+	message.add_int("category_id", catID);
+	message.add_string("caption", title);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool renameFeed(int feedID, string title)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "renameFeed");
-		message.add_int("feed_id", feedID);
-		message.add_string("caption", title);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool renameFeed(int feedID, string title)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "renameFeed");
+	message.add_int("feed_id", feedID);
+	message.add_string("caption", title);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool moveFeed(int feedID, int catID)
-	{
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		message.add_string("sid", m_ttrss_sessionid);
-		message.add_string("op", "moveFeed");
-		message.add_int("feed_id", feedID);
-		message.add_int("category_id", catID);
-		int error = message.send();
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool moveFeed(int feedID, int catID)
+{
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	message.add_string("sid", m_ttrss_sessionid);
+	message.add_string("op", "moveFeed");
+	message.add_int("feed_id", feedID);
+	message.add_int("category_id", catID);
+	int error = message.send();
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
 
-	public bool ping()
-	{
-		Logger.debug("TTRSS: ping");
-		var message = new ttrssMessage(m_session, m_ttrss_url);
-		int error = message.send(true);
+	return false;
+}
 
-		if(error == ConnectionError.SUCCESS)
-		{
-			return true;
-		}
+public bool ping()
+{
+	Logger.debug("TTRSS: ping");
+	var message = new ttrssMessage(m_session, m_ttrss_url);
+	int error = message.send(true);
 
-		return false;
+	if(error == ConnectionError.SUCCESS)
+	{
+		return true;
 	}
+
+	return false;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/ttrss/ttrssInterface.vala 2.7.1-1/plugins/backend/ttrss/ttrssInterface.vala
--- 2.6.1-1/plugins/backend/ttrss/ttrssInterface.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/ttrss/ttrssInterface.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,536 +15,533 @@
 
 public class FeedReader.ttrssInterface : Peas.ExtensionBase, FeedServerInterface {
 
-	private ttrssAPI m_api;
-	private ttrssUtils m_utils;
-	private Gtk.Entry m_urlEntry;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passwordEntry;
-	private Gtk.Entry m_authPasswordEntry;
-	private Gtk.Entry m_authUserEntry;
-	private Gtk.Revealer m_revealer;
-	private bool m_need_htaccess = false;
-	private DataBaseReadOnly m_db;
-	private DataBase m_db_write;
+private ttrssAPI m_api;
+private ttrssUtils m_utils;
+private Gtk.Entry m_urlEntry;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passwordEntry;
+private Gtk.Entry m_authPasswordEntry;
+private Gtk.Entry m_authUserEntry;
+private Gtk.Revealer m_revealer;
+private bool m_need_htaccess = false;
+
+public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	m_utils = new ttrssUtils(settings_backend, secrets);
+	m_api = new ttrssAPI(m_utils);
+}
 
-	public void init(GLib.SettingsBackend? settings_backend, Secret.Collection secrets, DataBaseReadOnly db, DataBase db_write)
-	{
-		m_db = db;
-		m_db_write = db_write;
-		m_utils = new ttrssUtils(settings_backend, secrets);
-		m_api = new ttrssAPI(m_utils, db);
-	}
+public string getWebsite()
+{
+	return "https://tt-rss.org/";
+}
 
-	public string getWebsite()
-	{
-		return "https://tt-rss.org/";
-	}
+public BackendFlags getFlags()
+{
+	return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
+}
 
-	public BackendFlags getFlags()
-	{
-		return (BackendFlags.SELF_HOSTED | BackendFlags.FREE_SOFTWARE | BackendFlags.FREE);
-	}
+public string getID()
+{
+	return "ttrss";
+}
 
-	public string getID()
-	{
-		return "ttrss";
-	}
+public string iconName()
+{
+	return "feed-service-ttrss";
+}
 
-	public string iconName()
-	{
-		return "feed-service-ttrss";
-	}
+public string serviceName()
+{
+	return "Tiny Tiny RSS";
+}
 
-	public string serviceName()
-	{
-		return "Tiny Tiny RSS";
-	}
+public bool needWebLogin()
+{
+	return false;
+}
 
-	public bool needWebLogin()
-	{
-		return false;
-	}
+public Gtk.Box? getWidget()
+{
+	var url_label = new Gtk.Label(_("Tiny Tiny RSS URL:"));
+	var user_label = new Gtk.Label(_("Username:"));
+	var password_label = new Gtk.Label(_("Password:"));
+
+	url_label.set_alignment(1.0f, 0.5f);
+	user_label.set_alignment(1.0f, 0.5f);
+	password_label.set_alignment(1.0f, 0.5f);
+
+	url_label.set_hexpand(true);
+	user_label.set_hexpand(true);
+	password_label.set_hexpand(true);
+
+	m_urlEntry = new Gtk.Entry();
+	m_userEntry = new Gtk.Entry();
+	m_passwordEntry = new Gtk.Entry();
+
+	m_urlEntry.activate.connect(() => { tryLogin(); });
+	m_userEntry.activate.connect(() => { tryLogin(); });
+	m_passwordEntry.activate.connect(() => { tryLogin(); });
+
+	m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passwordEntry.set_visibility(false);
+
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+
+	grid.attach(url_label, 0, 0, 1, 1);
+	grid.attach(m_urlEntry, 1, 0, 1, 1);
+	grid.attach(user_label, 0, 1, 1, 1);
+	grid.attach(m_userEntry, 1, 1, 1, 1);
+	grid.attach(password_label, 0, 2, 1, 1);
+	grid.attach(m_passwordEntry, 1, 2, 1, 1);
+
+
+	// http auth stuff ----------------------------------------------------
+	var auth_user_label = new Gtk.Label(_("Username:"));
+	var auth_password_label = new Gtk.Label(_("Password:"));
+
+	auth_user_label.set_alignment(1.0f, 0.5f);
+	auth_password_label.set_alignment(1.0f, 0.5f);
+
+	auth_user_label.set_hexpand(true);
+	auth_password_label.set_hexpand(true);
+
+	m_authUserEntry = new Gtk.Entry();
+	m_authPasswordEntry = new Gtk.Entry();
+	m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_authPasswordEntry.set_visibility(false);
+
+	m_authUserEntry.activate.connect(() => { tryLogin(); });
+	m_authPasswordEntry.activate.connect(() => { tryLogin(); });
+
+	var authGrid = new Gtk.Grid();
+	authGrid.margin = 10;
+	authGrid.set_column_spacing(10);
+	authGrid.set_row_spacing(10);
+	authGrid.set_valign(Gtk.Align.CENTER);
+	authGrid.set_halign(Gtk.Align.CENTER);
+
+	authGrid.attach(auth_user_label, 0, 0, 1, 1);
+	authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
+	authGrid.attach(auth_password_label, 0, 1, 1, 1);
+	authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
+
+	var frame = new Gtk.Frame(_("HTTP Authorization"));
+	frame.set_halign(Gtk.Align.CENTER);
+	frame.add(authGrid);
+	m_revealer = new Gtk.Revealer();
+	m_revealer.add(frame);
+	//---------------------------------------------------------------------
+
+	var logo = new Gtk.Image.from_icon_name("feed-service-ttrss", Gtk.IconSize.MENU);
+
+	var loginLabel = new Gtk.Label(_("Please log in to your Tiny Tiny RSS server and enjoy using FeedReader"));
+	loginLabel.get_style_context().add_class("h2");
+	loginLabel.set_justify(Gtk.Justification.CENTER);
+	loginLabel.set_lines(3);
+
+	var loginButton = new Gtk.Button.with_label(_("Login"));
+	loginButton.halign = Gtk.Align.END;
+	loginButton.set_size_request(80, 30);
+	loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	loginButton.clicked.connect(() => { tryLogin(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
+	box.valign = Gtk.Align.CENTER;
+	box.halign = Gtk.Align.CENTER;
+	box.pack_start(loginLabel, false, false, 10);
+	box.pack_start(logo, false, false, 10);
+	box.pack_start(grid, true, true, 10);
+	box.pack_start(m_revealer, true, true, 10);
+	box.pack_end(loginButton, false, false, 20);
+
+	m_urlEntry.set_text(m_utils.getUnmodifiedURL());
+	m_userEntry.set_text(m_utils.getUser());
+	m_passwordEntry.set_text(m_utils.getPasswd());
 
-	public Gtk.Box? getWidget()
-	{
-		var url_label = new Gtk.Label(_("Tiny Tiny RSS URL:"));
-		var user_label = new Gtk.Label(_("Username:"));
-		var password_label = new Gtk.Label(_("Password:"));
-
-		url_label.set_alignment(1.0f, 0.5f);
-		user_label.set_alignment(1.0f, 0.5f);
-		password_label.set_alignment(1.0f, 0.5f);
-
-		url_label.set_hexpand(true);
-		user_label.set_hexpand(true);
-		password_label.set_hexpand(true);
-
-		m_urlEntry = new Gtk.Entry();
-		m_userEntry = new Gtk.Entry();
-		m_passwordEntry = new Gtk.Entry();
-
-		m_urlEntry.activate.connect(() => { tryLogin(); });
-		m_userEntry.activate.connect(() => { tryLogin(); });
-		m_passwordEntry.activate.connect(() => { tryLogin(); });
-
-		m_passwordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passwordEntry.set_visibility(false);
-
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-
-		grid.attach(url_label, 0, 0, 1, 1);
-		grid.attach(m_urlEntry, 1, 0, 1, 1);
-		grid.attach(user_label, 0, 1, 1, 1);
-		grid.attach(m_userEntry, 1, 1, 1, 1);
-		grid.attach(password_label, 0, 2, 1, 1);
-		grid.attach(m_passwordEntry, 1, 2, 1, 1);
-
-
-		// http auth stuff ----------------------------------------------------
-		var auth_user_label = new Gtk.Label(_("Username:"));
-		var auth_password_label = new Gtk.Label(_("Password:"));
-
-		auth_user_label.set_alignment(1.0f, 0.5f);
-		auth_password_label.set_alignment(1.0f, 0.5f);
-
-		auth_user_label.set_hexpand(true);
-		auth_password_label.set_hexpand(true);
-
-		m_authUserEntry = new Gtk.Entry();
-		m_authPasswordEntry = new Gtk.Entry();
-		m_authPasswordEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_authPasswordEntry.set_visibility(false);
-
-		m_authUserEntry.activate.connect(() => { tryLogin(); });
-		m_authPasswordEntry.activate.connect(() => { tryLogin(); });
-
-		var authGrid = new Gtk.Grid();
-		authGrid.margin = 10;
-		authGrid.set_column_spacing(10);
-		authGrid.set_row_spacing(10);
-		authGrid.set_valign(Gtk.Align.CENTER);
-		authGrid.set_halign(Gtk.Align.CENTER);
-
-		authGrid.attach(auth_user_label, 0, 0, 1, 1);
-		authGrid.attach(m_authUserEntry, 1, 0, 1, 1);
-		authGrid.attach(auth_password_label, 0, 1, 1, 1);
-		authGrid.attach(m_authPasswordEntry, 1, 1, 1, 1);
-
-		var frame = new Gtk.Frame(_("HTTP Authorization"));
-		frame.set_halign(Gtk.Align.CENTER);
-		frame.add(authGrid);
-		m_revealer = new Gtk.Revealer();
-		m_revealer.add(frame);
-		//---------------------------------------------------------------------
-
-		var logo = new Gtk.Image.from_icon_name("feed-service-ttrss", Gtk.IconSize.MENU);
-
-		var loginLabel = new Gtk.Label(_("Please log in to your Tiny Tiny RSS server and enjoy using FeedReader"));
-		loginLabel.get_style_context().add_class("h2");
-		loginLabel.set_justify(Gtk.Justification.CENTER);
-		loginLabel.set_lines(3);
-
-		var loginButton = new Gtk.Button.with_label(_("Login"));
-		loginButton.halign = Gtk.Align.END;
-		loginButton.set_size_request(80, 30);
-		loginButton.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		loginButton.clicked.connect(() => { tryLogin(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.VERTICAL, 10);
-		box.valign = Gtk.Align.CENTER;
-		box.halign = Gtk.Align.CENTER;
-		box.pack_start(loginLabel, false, false, 10);
-		box.pack_start(logo, false, false, 10);
-		box.pack_start(grid, true, true, 10);
-		box.pack_start(m_revealer, true, true, 10);
-		box.pack_end(loginButton, false, false, 20);
-
-		m_urlEntry.set_text(m_utils.getUnmodifiedURL());
-		m_userEntry.set_text(m_utils.getUser());
-		m_passwordEntry.set_text(m_utils.getPasswd());
+	return box;
+}
 
-		return box;
-	}
+public void showHtAccess()
+{
+	m_revealer.set_reveal_child(true);
+}
 
-	public void showHtAccess()
+public void writeData()
+{
+	m_utils.setURL(m_urlEntry.get_text());
+	m_utils.setUser(m_userEntry.get_text().strip());
+	m_utils.setPassword(m_passwordEntry.get_text().strip());
+	if(m_need_htaccess)
 	{
-		m_revealer.set_reveal_child(true);
+		m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
+		m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
 	}
+}
 
-	public void writeData()
-	{
-		m_utils.setURL(m_urlEntry.get_text());
-		m_utils.setUser(m_userEntry.get_text().strip());
-		m_utils.setPassword(m_passwordEntry.get_text().strip());
-		if(m_need_htaccess)
-		{
-			m_utils.setHtaccessUser(m_authUserEntry.get_text().strip());
-			m_utils.setHtAccessPassword(m_authPasswordEntry.get_text().strip());
-		}
-	}
+public async void postLoginAction()
+{
+	return;
+}
 
-	public async void postLoginAction()
-	{
-		return;
-	}
+public bool extractCode(string redirectURL)
+{
+	return false;
+}
 
-	public bool extractCode(string redirectURL)
-	{
-		return false;
-	}
+public string buildLoginURL()
+{
+	return "";
+}
 
-	public string buildLoginURL()
-	{
-		return "";
-	}
+public bool supportTags()
+{
+	return true;
+}
 
-	public bool supportTags()
-	{
-		return true;
-	}
+public bool doInitSync()
+{
+	return true;
+}
 
-	public bool doInitSync()
-	{
-		return true;
-	}
+public string symbolicIcon()
+{
+	return "feed-service-ttrss-symbolic";
+}
 
-	public string symbolicIcon()
-	{
-		return "feed-service-ttrss-symbolic";
-	}
+public string accountName()
+{
+	return m_utils.getUser();
+}
 
-	public string accountName()
-	{
-		return m_utils.getUser();
-	}
+public string getServerURL()
+{
+	return m_utils.getURL();
+}
 
-	public string getServerURL()
-	{
-		return m_utils.getURL();
-	}
+public string uncategorizedID()
+{
+	return "0";
+}
 
-	public string uncategorizedID()
-	{
-		return "0";
-	}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return catID == "0";
+}
 
-	public bool hideCategoryWhenEmpty(string catID)
-	{
-		return catID == "0";
-	}
+public bool supportCategories()
+{
+	return true;
+}
 
-	public bool supportCategories()
-	{
-		return true;
-	}
+public bool supportFeedManipulation()
+{
+	return true;
+}
 
-	public bool supportFeedManipulation()
-	{
-		return true;
-	}
+public bool supportMultiLevelCategories()
+{
+	return true;
+}
 
-	public bool supportMultiLevelCategories()
-	{
-		return true;
-	}
+public bool supportMultiCategoriesPerFeed()
+{
+	return false;
+}
 
-	public bool supportMultiCategoriesPerFeed()
-	{
-		return false;
-	}
+public bool syncFeedsAndCategories()
+{
+	return true;
+}
 
-	public bool syncFeedsAndCategories()
-	{
-		return true;
-	}
+public bool tagIDaffectedByNameChange()
+{
+	return false;
+}
 
-	public bool tagIDaffectedByNameChange()
-	{
-		return false;
-	}
+public void resetAccount()
+{
+	m_utils.resetAccount();
+}
 
-	public void resetAccount()
-	{
-		m_utils.resetAccount();
-	}
+public bool useMaxArticles()
+{
+	return true;
+}
 
-	public bool useMaxArticles()
-	{
-		return true;
-	}
+public LoginResponse login()
+{
+	return m_api.login();
+}
 
-	public LoginResponse login()
-	{
-		return m_api.login();
-	}
+public bool logout()
+{
+	return m_api.logout();
+}
 
-	public bool logout()
-	{
-		return m_api.logout();
-	}
+public bool serverAvailable()
+{
+	return m_api.ping();
+}
 
-	public bool serverAvailable()
-	{
-		return m_api.ping();
-	}
+public void setArticleIsRead(string articleIDs, ArticleStatus read)
+{
+	m_api.updateArticleUnread(articleIDs, read);
+}
 
-	public void setArticleIsRead(string articleIDs, ArticleStatus read)
-	{
-		m_api.updateArticleUnread(articleIDs, read);
-	}
+public void setArticleIsMarked(string articleID, ArticleStatus marked)
+{
+	m_api.updateArticleMarked(int.parse(articleID), marked);
+}
 
-	public void setArticleIsMarked(string articleID, ArticleStatus marked)
-	{
-		m_api.updateArticleMarked(int.parse(articleID), marked);
-	}
+public bool alwaysSetReadByID()
+{
+	return false;
+}
 
-	public bool alwaysSetReadByID()
-	{
-		return false;
-	}
+public void setFeedRead(string feedID)
+{
+	m_api.catchupFeed(feedID, false);
+}
 
-	public void setFeedRead(string feedID)
-	{
-		m_api.catchupFeed(feedID, false);
-	}
+public void setCategoryRead(string catID)
+{
+	m_api.catchupFeed(catID, true);
+}
 
-	public void setCategoryRead(string catID)
+public void markAllItemsRead()
+{
+	var categories = DataBase.readOnly().read_categories();
+	foreach(Category cat in categories)
 	{
-		m_api.catchupFeed(catID, true);
+		m_api.catchupFeed(cat.getCatID(), true);
 	}
+}
 
-	public void markAllItemsRead()
-	{
-		var categories = m_db.read_categories();
-		foreach(Category cat in categories)
-		{
-			m_api.catchupFeed(cat.getCatID(), true);
-		}
-	}
+public void tagArticle(string articleID, string tagID)
+{
+	m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), true);
+}
 
-	public void tagArticle(string articleID, string tagID)
-	{
-		m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), true);
-	}
+public void removeArticleTag(string articleID, string tagID)
+{
+	m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), false);
+}
 
-	public void removeArticleTag(string articleID, string tagID)
-	{
-		m_api.setArticleLabel(int.parse(articleID), int.parse(tagID), false);
-	}
+public string createTag(string caption)
+{
+	return m_api.addLabel(caption).to_string();
+}
 
-	public string createTag(string caption)
-	{
-		return m_api.addLabel(caption).to_string();
-	}
+public void deleteTag(string tagID)
+{
+	m_api.removeLabel(int.parse(tagID));
+}
 
-	public void deleteTag(string tagID)
+public void renameTag(string tagID, string title)
+{
+	m_api.renameLabel(int.parse(tagID), title);
+}
+
+public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
+{
+	bool success = false;
+	if(catID == null && newCatName != null)
 	{
-		m_api.removeLabel(int.parse(tagID));
+		var newCatID = m_api.createCategory(newCatName);
+		success = m_api.subscribeToFeed(feedURL, newCatID, null, null, out errmsg);
 	}
-
-	public void renameTag(string tagID, string title)
+	else
 	{
-		m_api.renameLabel(int.parse(tagID), title);
+		success = m_api.subscribeToFeed(feedURL, catID, null, null, out errmsg);
 	}
 
-	public bool addFeed(string feedURL, string? catID, string? newCatName, out string feedID, out string errmsg)
-	{
-		bool success = false;
-		if(catID == null && newCatName != null)
-		{
-			var newCatID = m_api.createCategory(newCatName);
-			success = m_api.subscribeToFeed(feedURL, newCatID, null, null, out errmsg);
-		}
-		else
-		{
-			success = m_api.subscribeToFeed(feedURL, catID, null, null, out errmsg);
-		}
+	if(success)
+		feedID = (int.parse(DataBase.readOnly().getMaxID("feeds", "feed_id")) + 1).to_string();
+	else
+		feedID = "-98";
 
-		if(success)
-			feedID = (int.parse(m_db.getMaxID("feeds", "feed_id")) + 1).to_string();
-		else
-			feedID = "-98";
 
+	return success;
+}
 
-		return success;
-	}
-
-	public void addFeeds(Gee.List<Feed> feeds)
+public void addFeeds(Gee.List<Feed> feeds)
+{
+	string? errmsg = null;
+	foreach(Feed f in feeds)
 	{
-		string? errmsg = null;
-		foreach(Feed f in feeds)
-		{
-			m_api.subscribeToFeed(f.getXmlUrl(), f.getCatIDs()[0], null, null, out errmsg);
-		}
+		m_api.subscribeToFeed(f.getXmlUrl(), f.getCatIDs()[0], null, null, out errmsg);
 	}
+}
 
-	public void removeFeed(string feedID)
-	{
-		m_api.unsubscribeFeed(int.parse(feedID));
-	}
+public void removeFeed(string feedID)
+{
+	m_api.unsubscribeFeed(int.parse(feedID));
+}
 
-	public void renameFeed(string feedID, string title)
-	{
-		m_api.renameFeed(int.parse(feedID), title);
-	}
+public void renameFeed(string feedID, string title)
+{
+	m_api.renameFeed(int.parse(feedID), title);
+}
 
-	public void moveFeed(string feedID, string newCatID, string? currentCatID)
-	{
-		m_api.moveFeed(int.parse(feedID), int.parse(newCatID));
-	}
+public void moveFeed(string feedID, string newCatID, string? currentCatID)
+{
+	m_api.moveFeed(int.parse(feedID), int.parse(newCatID));
+}
 
-	public string createCategory(string title, string? parentID)
-	{
-		if(parentID != null)
-			return m_api.createCategory(title, int.parse(parentID));
+public string createCategory(string title, string? parentID)
+{
+	if(parentID != null)
+		return m_api.createCategory(title, int.parse(parentID));
 
-		return m_api.createCategory(title);
-	}
+	return m_api.createCategory(title);
+}
 
-	public void renameCategory(string catID, string title)
-	{
-		m_api.renameCategory(int.parse(catID), title);
-	}
+public void renameCategory(string catID, string title)
+{
+	m_api.renameCategory(int.parse(catID), title);
+}
 
-	public void moveCategory(string catID, string newParentID)
-	{
-		m_api.moveCategory(int.parse(catID), int.parse(newParentID));
-	}
+public void moveCategory(string catID, string newParentID)
+{
+	m_api.moveCategory(int.parse(catID), int.parse(newParentID));
+}
 
-	public void deleteCategory(string catID)
-	{
-		m_api.removeCategory(int.parse(catID));
-	}
+public void deleteCategory(string catID)
+{
+	m_api.removeCategory(int.parse(catID));
+}
 
-	public void removeCatFromFeed(string feedID, string catID)
-	{
-		return;
-	}
+public void removeCatFromFeed(string feedID, string catID)
+{
+	return;
+}
 
-	public void importOPML(string opml)
-	{
-		var parser = new OPMLparser(opml);
-		parser.parse();
-	}
+public void importOPML(string opml)
+{
+	var parser = new OPMLparser(opml);
+	parser.parse();
+}
 
-	public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+public bool getFeedsAndCats(Gee.List<Feed> feeds, Gee.List<Category> categories, Gee.List<Tag> tags, GLib.Cancellable? cancellable = null)
+{
+	if(m_api.getCategories(categories))
 	{
-		if(m_api.getCategories(categories))
+		if(cancellable != null && cancellable.is_cancelled())
+			return false;
+
+		if(m_api.getFeeds(feeds, categories))
 		{
 			if(cancellable != null && cancellable.is_cancelled())
 				return false;
 
-			if(m_api.getFeeds(feeds, categories))
+			if(m_api.getUncategorizedFeeds(feeds))
 			{
 				if(cancellable != null && cancellable.is_cancelled())
 					return false;
 
-				if(m_api.getUncategorizedFeeds(feeds))
-				{
-					if(cancellable != null && cancellable.is_cancelled())
-						return false;
-
-					if(m_api.getTags(tags))
-						return true;
-				}
+				if(m_api.getTags(tags))
+					return true;
 			}
 		}
-
-		return false;
 	}
 
-	public int getUnreadCount()
+	return false;
+}
+
+public int getUnreadCount()
+{
+	return m_api.getUnreadCount();
+}
+
+public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
+{
+	var settings_general = new GLib.Settings("org.gnome.feedreader");
+
+	// first use newsPlus plugin to update states of 10x as much articles as we would normaly do
+	var unreadIDs = m_api.NewsPlus(ArticleStatus.UNREAD, 10*settings_general.get_int("max-articles"));
+
+	if(cancellable != null && cancellable.is_cancelled())
+		return;
+
+	var db = DataBase.writeAccess();
+	if(unreadIDs != null && whatToGet == ArticleStatus.ALL)
 	{
-		return m_api.getUnreadCount();
+		Logger.debug("getArticles: newsplus plugin active");
+		var markedIDs = m_api.NewsPlus(ArticleStatus.MARKED, settings_general.get_int("max-articles"));
+		db.updateArticlesByID(unreadIDs, "unread");
+		db.updateArticlesByID(markedIDs, "marked");
+		//updateArticleList();
 	}
 
-	public void getArticles(int count, ArticleStatus whatToGet, DateTime? since, string? feedID, bool isTagID, GLib.Cancellable? cancellable = null)
-	{
-		var settings_general = new GLib.Settings("org.gnome.feedreader");
+	if(cancellable != null && cancellable.is_cancelled())
+		return;
 
-		// first use newsPlus plugin to update states of 10x as much articles as we would normaly do
-		var unreadIDs = m_api.NewsPlus(ArticleStatus.UNREAD, 10*settings_general.get_int("max-articles"));
+	string articleIDs = "";
+	int skip = count;
+	int amount = 200;
 
+	while(skip > 0)
+	{
 		if(cancellable != null && cancellable.is_cancelled())
 			return;
 
-		if(unreadIDs != null && whatToGet == ArticleStatus.ALL)
+		if(skip >= amount)
 		{
-			Logger.debug("getArticles: newsplus plugin active");
-			var markedIDs = m_api.NewsPlus(ArticleStatus.MARKED, settings_general.get_int("max-articles"));
-			m_db_write.updateArticlesByID(unreadIDs, "unread");
-			m_db_write.updateArticlesByID(markedIDs, "marked");
-			//updateArticleList();
+			skip -= amount;
 		}
-
-		if(cancellable != null && cancellable.is_cancelled())
-			return;
-
-		string articleIDs = "";
-		int skip = count;
-		int amount = 200;
-
-		while(skip > 0)
+		else
 		{
-			if(cancellable != null && cancellable.is_cancelled())
-				return;
-
-			if(skip >= amount)
-			{
-				skip -= amount;
-			}
-			else
-			{
-				amount = skip;
-				skip = 0;
-			}
+			amount = skip;
+			skip = 0;
+		}
 
-			var articles = new Gee.LinkedList<Article>();
-			m_api.getHeadlines(articles, skip, amount, whatToGet, (feedID == null) ? ttrssUtils.TTRSSSpecialID.ALL : int.parse(feedID));
+		var articles = new Gee.LinkedList<Article>();
+		m_api.getHeadlines(articles, skip, amount, whatToGet, (feedID == null) ? ttrssUtils.TTRSSSpecialID.ALL : int.parse(feedID));
 
-			// only update article states if they haven't been updated by the newsPlus-plugin
-			if(unreadIDs == null || whatToGet != ArticleStatus.ALL)
-			{
-				m_db_write.update_articles(articles);
-				updateArticleList();
-			}
+		// only update article states if they haven't been updated by the newsPlus-plugin
+		if(unreadIDs == null || whatToGet != ArticleStatus.ALL)
+		{
+			db.update_articles(articles);
+			updateArticleList();
+		}
 
-			foreach(Article article in articles)
+		foreach(Article article in articles)
+		{
+			var id = article.getArticleID();
+			if(!db.article_exists(id))
 			{
-				var id = article.getArticleID();
-				if(!m_db.article_exists(id))
-				{
-					articleIDs += id + ",";
-				}
+				articleIDs += id + ",";
 			}
 		}
+	}
 
-		if(articleIDs.length > 0)
-			articleIDs = articleIDs.substring(0, articleIDs.length -1);
+	if(articleIDs.length > 0)
+		articleIDs = articleIDs.substring(0, articleIDs.length -1);
 
-		var articles = new Gee.LinkedList<Article>();
+	var articles = new Gee.LinkedList<Article>();
 
-		if(articleIDs != "")
-			m_api.getArticles(articleIDs, articles);
+	if(articleIDs != "")
+		m_api.getArticles(articleIDs, articles);
 
-		articles.sort((a, b) => {
-				return strcmp(a.getArticleID(), b.getArticleID());
+	articles.sort((a, b) => {
+			return strcmp(a.getArticleID(), b.getArticleID());
 		});
 
-		if(cancellable != null && cancellable.is_cancelled())
-			return;
+	if(cancellable != null && cancellable.is_cancelled())
+		return;
 
-		if(articles.size > 0)
-		{
-			m_db_write.write_articles(articles);
-			refreshFeedListCounter();
-			updateArticleList();
-		}
+	if(articles.size > 0)
+	{
+		db.write_articles(articles);
+		refreshFeedListCounter();
+		updateArticleList();
 	}
+}
 
 }
 
diff -pruN 2.6.1-1/plugins/backend/ttrss/ttrssMessage.vala 2.7.1-1/plugins/backend/ttrss/ttrssMessage.vala
--- 2.6.1-1/plugins/backend/ttrss/ttrssMessage.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/ttrss/ttrssMessage.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,219 +15,219 @@
 
 public class FeedReader.ttrssMessage : GLib.Object {
 
-	private Soup.Session m_session;
-	private Soup.Message m_message_soup;
-	private GLib.StringBuilder m_message_string;
-	private string m_contenttype;
-	private Json.Parser m_parser;
-	private Json.Object m_root_object;
+private Soup.Session m_session;
+private Soup.Message m_message_soup;
+private GLib.StringBuilder m_message_string;
+private string m_contenttype;
+private Json.Parser m_parser;
+private Json.Object m_root_object;
+
+public ttrssMessage(Soup.Session session, string destination)
+{
+	m_message_string = new GLib.StringBuilder();
+	m_session = session;
+	m_contenttype = "application/x-www-form-urlencoded";
+	m_parser = new Json.Parser();
 
-	public ttrssMessage(Soup.Session session, string destination)
-	{
-		m_message_string = new GLib.StringBuilder();
-		m_session = session;
-		m_contenttype = "application/x-www-form-urlencoded";
-		m_parser = new Json.Parser();
+	m_message_soup = new Soup.Message("POST", destination);
 
-		m_message_soup = new Soup.Message("POST", destination);
+	if(m_message_soup == null)
+		Logger.error(@"ttrssMessage: can't send message to $destination");
+}
 
-		if(m_message_soup == null)
-			Logger.error(@"ttrssMessage: can't send message to $destination");
-	}
 
+public void add_int(string type, int val)
+{
+	m_message_string.append(",\"" + type + "\":" + val.to_string());
+}
+
+public void add_int_array(string type, string values)
+{
+	m_message_string.append(",\"" + type + "\":\"" + values + "\"");
+}
+
+public void add_bool(string type, bool val)
+{
+	m_message_string.append(",\"" + type + "\":");
+	if(val)
+		m_message_string.append("true");
+	else
+		m_message_string.append("false");
+}
+
+public void add_string(string type, string val)
+{
+	m_message_string.append(",\"" + type + "\":\"" + val.replace("\"", "\\\"").replace("\\", "\\\\") + "\"");
+}
 
-	public void add_int(string type, int val)
+public ConnectionError send(bool ping = false)
+{
+	var error = send_impl(ping);
+	if(error != ConnectionError.SUCCESS)
 	{
-		m_message_string.append(",\"" + type + "\":" + val.to_string());
+		printMessage();
+		printResponse();
 	}
 
-	public void add_int_array(string type, string values)
+	return error;
+}
+
+public ConnectionError send_impl(bool ping)
+{
+	if(m_message_soup == null)
 	{
-		m_message_string.append(",\"" + type + "\":\"" + values + "\"");
+		Logger.error(@"ttrssMessage: can't send message");
+		return ConnectionError.UNKNOWN;
 	}
 
-	public void add_bool(string type, bool val)
+	var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
+	m_message_string.overwrite(0, "{").append("}");
+	m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
+
+	if(settingsTweaks.get_boolean("do-not-track"))
+		m_message_soup.request_headers.append("DNT", "1");
+
+	var status = m_session.send_message(m_message_soup);
+
+	if(status == 401)         // unauthorized
 	{
-		m_message_string.append(",\"" + type + "\":");
-		if(val)
-			m_message_string.append("true");
-		else
-			m_message_string.append("false");
+		return ConnectionError.UNAUTHORIZED;
 	}
 
-	public void add_string(string type, string val)
+	if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
 	{
-		m_message_string.append(",\"" + type + "\":\"" + val.replace("\"", "\\\"").replace("\\", "\\\\") + "\"");
+		Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
+		return ConnectionError.CA_ERROR;
 	}
 
-	public ConnectionError send(bool ping = false)
+
+	if(m_message_soup.status_code != 200)
 	{
-		var error = send_impl(ping);
-		if(error != ConnectionError.SUCCESS)
-		{
-			printMessage();
-			printResponse();
-		}
+		Logger.error("TTRSS Message: No response - status code: %s".printf(Soup.Status.get_phrase(m_message_soup.status_code)));
+		return ConnectionError.NO_RESPONSE;
+	}
 
-		return error;
+	if(ping)
+	{
+		Logger.debug("TTRSS Message: ping successful");
+		return ConnectionError.SUCCESS;
 	}
 
-	public ConnectionError send_impl(bool ping)
+	try
 	{
-		if(m_message_soup == null)
-		{
-			Logger.error(@"ttrssMessage: can't send message");
-			return ConnectionError.UNKNOWN;
-		}
+		m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
+	}
+	catch(Error e)
+	{
+		Logger.error("Could not load response from Message to ttrss");
+		Logger.error(e.message);
+		return ConnectionError.NO_RESPONSE;
+	}
 
-		var settingsTweaks = new GLib.Settings("org.gnome.feedreader.tweaks");
-		m_message_string.overwrite(0, "{").append("}");
-		m_message_soup.set_request(m_contenttype, Soup.MemoryUse.COPY, m_message_string.str.data);
+	m_root_object = m_parser.get_root().get_object();
 
-		if(settingsTweaks.get_boolean("do-not-track"))
-				m_message_soup.request_headers.append("DNT", "1");
 
-		var status = m_session.send_message(m_message_soup);
+	if(m_root_object.has_member("error"))
+		parseError(m_root_object);
 
-		if(status == 401) // unauthorized
-		{
-			return ConnectionError.UNAUTHORIZED;
-		}
 
-		if(m_message_soup.tls_errors != 0 && !settingsTweaks.get_boolean("ignore-tls-errors"))
+	if(m_root_object.has_member("status"))
+	{
+		if(m_root_object.get_int_member("status") == 1)
 		{
-			Logger.info("TLS errors: " + Utils.printTlsCertificateFlags(m_message_soup.tls_errors));
-			return ConnectionError.CA_ERROR;
-		}
-
+			if(m_root_object.has_member("content"))
+			{
+				var content = m_root_object.get_object_member("content");
+				if(content.has_member("error"))
+					parseError(content);
+			}
 
-		if(m_message_soup.status_code != 200)
-		{
-			Logger.error("TTRSS Message: No response - status code: %s".printf(Soup.Status.get_phrase(m_message_soup.status_code)));
-			return ConnectionError.NO_RESPONSE;
+			return ApiError();
 		}
-
-		if(ping)
+		else if(m_root_object.get_int_member("status") == 0)
 		{
-			Logger.debug("TTRSS Message: ping successful");
 			return ConnectionError.SUCCESS;
 		}
-
-		try
-		{
-			m_parser.load_from_data((string)m_message_soup.response_body.flatten().data);
-		}
-		catch(Error e)
-		{
-			Logger.error("Could not load response from Message to ttrss");
-			Logger.error(e.message);
-			return ConnectionError.NO_RESPONSE;
-		}
-
-		m_root_object = m_parser.get_root().get_object();
-
-
-		if(m_root_object.has_member("error"))
-			parseError(m_root_object);
-
-
-		if(m_root_object.has_member("status"))
-		{
-			if(m_root_object.get_int_member("status") == 1)
-			{
-				if(m_root_object.has_member("content"))
-				{
-					var content = m_root_object.get_object_member("content");
-					if(content.has_member("error"))
-						parseError(content);
-				}
-
-				return ApiError();
-			}
-			else if(m_root_object.get_int_member("status") == 0)
-			{
-				return ConnectionError.SUCCESS;
-			}
-		}
-
-		Logger.error("unknown error while sending ttrss message");
-		return ConnectionError.UNKNOWN;
 	}
 
-	public Json.Object? get_response_object()
+	Logger.error("unknown error while sending ttrss message");
+	return ConnectionError.UNKNOWN;
+}
+
+public Json.Object? get_response_object()
+{
+	if(m_root_object.has_member("content"))
 	{
-		if(m_root_object.has_member("content"))
-		{
-			return m_root_object.get_object_member("content");
-		}
-		return null;
+		return m_root_object.get_object_member("content");
 	}
+	return null;
+}
 
-	public int64? get_response_int()
+public int64? get_response_int()
+{
+	if(m_root_object.has_member("content"))
 	{
-		if(m_root_object.has_member("content"))
-		{
-			return m_root_object.get_int_member("content");
-		}
-		return null;
+		return m_root_object.get_int_member("content");
 	}
+	return null;
+}
 
-	public string? get_response_string()
+public string? get_response_string()
+{
+	if(m_root_object.has_member("content"))
 	{
-		if(m_root_object.has_member("content"))
-		{
-			return m_root_object.get_string_member("content");
-		}
-		return null;
+		return m_root_object.get_string_member("content");
 	}
+	return null;
+}
 
 
-	public Json.Array? get_response_array()
+public Json.Array? get_response_array()
+{
+	if(m_root_object.has_member("content"))
 	{
-		if(m_root_object.has_member("content"))
-		{
-			return m_root_object.get_array_member("content");
-		}
-		return null;
+		return m_root_object.get_array_member("content");
 	}
+	return null;
+}
 
-	public uint getStatusCode()
-	{
-		return m_message_soup.status_code;
-	}
+public uint getStatusCode()
+{
+	return m_message_soup.status_code;
+}
 
-	public void printMessage()
-	{
-		Logger.debug(m_message_string.str);
-	}
+public void printMessage()
+{
+	Logger.debug(m_message_string.str);
+}
 
-	public void printResponse()
-	{
-		Logger.debug((string)m_message_soup.response_body.flatten().data);
-	}
+public void printResponse()
+{
+	Logger.debug((string)m_message_soup.response_body.flatten().data);
+}
 
-	private ConnectionError parseError(Json.Object err)
+private ConnectionError parseError(Json.Object err)
+{
+	string error = err.get_string_member("error");
+	if(error == "NOT_LOGGED_IN")
 	{
-		string error = err.get_string_member("error");
-		if(error == "NOT_LOGGED_IN")
-		{
-			Logger.error("invalid ttrss session id");
-			return ConnectionError.INVALID_SESSIONID;
-		}
-		else if(error == "API_DISABLED")
-		{
-			Logger.error("ttrss api is disabled: please enable it first");
-			return ConnectionError.API_DISABLED;
-		}
-
-		return ApiError();
+		Logger.error("invalid ttrss session id");
+		return ConnectionError.INVALID_SESSIONID;
 	}
-
-	private ConnectionError ApiError()
+	else if(error == "API_DISABLED")
 	{
-		Logger.error("ttrss api error");
-		printMessage();
-		printResponse();
-		return ConnectionError.API_ERROR;
+		Logger.error("ttrss api is disabled: please enable it first");
+		return ConnectionError.API_DISABLED;
 	}
+
+	return ApiError();
+}
+
+private ConnectionError ApiError()
+{
+	Logger.error("ttrss api error");
+	printMessage();
+	printResponse();
+	return ConnectionError.API_ERROR;
+}
 }
diff -pruN 2.6.1-1/plugins/backend/ttrss/ttrssUtils.vala 2.7.1-1/plugins/backend/ttrss/ttrssUtils.vala
--- 2.6.1-1/plugins/backend/ttrss/ttrssUtils.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/backend/ttrss/ttrssUtils.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,124 +15,124 @@
 
 public class FeedReader.ttrssUtils : GLib.Object {
 
-	public enum TTRSSSpecialID {
-		ARCHIVED      = 0,
-		STARRED       = -1,
-		PUBLISHED     = -2,
-		FRESH         = -3,
-		ALL           = -4,
-		RECENTLY_READ = -6
-	}
+public enum TTRSSSpecialID {
+	ARCHIVED      = 0,
+	STARRED       = -1,
+	PUBLISHED     = -2,
+	FRESH         = -3,
+	ALL           = -4,
+	RECENTLY_READ = -6
+}
 
-	private GLib.Settings m_settings;
-	private Password m_password;
-	private Password m_htaccess_password;
-
-	public ttrssUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
-	{
-		if(settings_backend != null)
-			m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.ttrss", settings_backend);
-		else
-			m_settings = new GLib.Settings("org.gnome.feedreader.ttrss");
-
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-										  "URL", Secret.SchemaAttributeType.STRING,
-										  "Username", Secret.SchemaAttributeType.STRING);
-		m_password = new Password(secrets, pwSchema, "FeedReader: ttrss login", () => {
+private GLib.Settings m_settings;
+private Password m_password;
+private Password m_htaccess_password;
+
+public ttrssUtils(GLib.SettingsBackend? settings_backend, Secret.Collection secrets)
+{
+	if(settings_backend != null)
+		m_settings = new GLib.Settings.with_backend("org.gnome.feedreader.ttrss", settings_backend);
+	else
+		m_settings = new GLib.Settings("org.gnome.feedreader.ttrss");
+
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                  "URL", Secret.SchemaAttributeType.STRING,
+	                                  "Username", Secret.SchemaAttributeType.STRING);
+	m_password = new Password(secrets, pwSchema, "FeedReader: ttrss login", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getUser();
 			return attributes;
 		});
 
-		var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
-										        "URL", Secret.SchemaAttributeType.STRING,
-										        "Username", Secret.SchemaAttributeType.STRING,
-										        "htaccess", Secret.SchemaAttributeType.BOOLEAN);
-		m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: ttrss htaccess Authentication", () => {
+	var htAccessSchema = new Secret.Schema ("org.gnome.feedreader.password", Secret.SchemaFlags.NONE,
+	                                        "URL", Secret.SchemaAttributeType.STRING,
+	                                        "Username", Secret.SchemaAttributeType.STRING,
+	                                        "htaccess", Secret.SchemaAttributeType.BOOLEAN);
+	m_htaccess_password = new Password(secrets, htAccessSchema, "FeedReader: ttrss htaccess Authentication", () => {
 			var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
 			attributes["URL"] = getURL();
 			attributes["Username"] = getHtaccessUser();
 			attributes["htaccess"] = "true";
 			return attributes;
 		});
-	}
+}
 
-	public string getURL()
-	{
+public string getURL()
+{
 
-		string tmp_url = Utils.gsettingReadString(m_settings, "url");
+	string tmp_url = Utils.gsettingReadString(m_settings, "url");
 
-		if(tmp_url != ""){
-			if(!tmp_url.has_suffix("/"))
-				tmp_url = tmp_url + "/";
+	if(tmp_url != "") {
+		if(!tmp_url.has_suffix("/"))
+			tmp_url = tmp_url + "/";
 
-			if(!tmp_url.has_suffix("/api/"))
-				tmp_url = tmp_url + "api/";
+		if(!tmp_url.has_suffix("/api/"))
+			tmp_url = tmp_url + "api/";
 
-			if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
-					tmp_url = "https://" + tmp_url;
-		}
+		if(!tmp_url.has_prefix("http://") && !tmp_url.has_prefix("https://"))
+			tmp_url = "https://" + tmp_url;
+	}
 
-		Logger.debug("ttrss URL: " + tmp_url);
+	Logger.debug("ttrss URL: " + tmp_url);
 
-		return tmp_url;
-	}
+	return tmp_url;
+}
 
-	public void setURL(string url)
-	{
-		Utils.gsettingWriteString(m_settings, "url", url);
-	}
+public void setURL(string url)
+{
+	Utils.gsettingWriteString(m_settings, "url", url);
+}
 
-	public string getUser()
-	{
-		return Utils.gsettingReadString(m_settings, "username");
-	}
+public string getUser()
+{
+	return Utils.gsettingReadString(m_settings, "username");
+}
 
-	public void setUser(string user)
-	{
-		Utils.gsettingWriteString(m_settings, "username", user);
-	}
+public void setUser(string user)
+{
+	Utils.gsettingWriteString(m_settings, "username", user);
+}
 
-	public string getHtaccessUser()
-	{
-		return Utils.gsettingReadString(m_settings, "htaccess-username");
-	}
+public string getHtaccessUser()
+{
+	return Utils.gsettingReadString(m_settings, "htaccess-username");
+}
 
-	public void setHtaccessUser(string ht_user)
-	{
-		Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
-	}
+public void setHtaccessUser(string ht_user)
+{
+	Utils.gsettingWriteString(m_settings, "htaccess-username", ht_user);
+}
 
-	public string getUnmodifiedURL()
-	{
-		return Utils.gsettingReadString(m_settings, "url");
-	}
+public string getUnmodifiedURL()
+{
+	return Utils.gsettingReadString(m_settings, "url");
+}
 
-	public string getPasswd()
-	{
-		return m_password.get_password();
-	}
+public string getPasswd()
+{
+	return m_password.get_password();
+}
 
-	public void setPassword(string passwd)
-	{
-		m_password.set_password(passwd);
-	}
+public void setPassword(string passwd)
+{
+	m_password.set_password(passwd);
+}
 
-	public void resetAccount()
-	{
-		Utils.resetSettings(m_settings);
-		m_password.delete_password();
-		m_htaccess_password.delete_password();
-	}
+public void resetAccount()
+{
+	Utils.resetSettings(m_settings);
+	m_password.delete_password();
+	m_htaccess_password.delete_password();
+}
 
-	public string getHtaccessPasswd()
-	{
-		return m_htaccess_password.get_password();
-	}
+public string getHtaccessPasswd()
+{
+	return m_htaccess_password.get_password();
+}
 
-	public void setHtAccessPassword(string passwd)
-	{
-		m_htaccess_password.set_password(passwd);
-	}
+public void setHtAccessPassword(string passwd)
+{
+	m_htaccess_password.set_password(passwd);
+}
 }
diff -pruN 2.6.1-1/plugins/share/Browser/Browser.vala 2.7.1-1/plugins/share/Browser/Browser.vala
--- 2.6.1-1/plugins/share/Browser/Browser.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Browser/Browser.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,88 +16,88 @@
 
 public class FeedReader.Browser : ShareAccountInterface, Peas.ExtensionBase {
 
-	public bool addBookmark(string id, string url, bool system)
+public bool addBookmark(string id, string url, bool system)
+{
+	try
 	{
-		try
-		{
-			Gtk.show_uri_on_window(MainWindow.get_default(), url, Gdk.CURRENT_TIME);
-			return true;
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("BrowserPlugin: Error opening url: " + e.message);
-		}
-
-		return false;
+		Gtk.show_uri_on_window(MainWindow.get_default(), url, Gdk.CURRENT_TIME);
+		return true;
 	}
-
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+	catch(GLib.Error e)
 	{
-
+		Logger.error("BrowserPlugin: Error opening url: " + e.message);
 	}
 
-	public bool logout(string id)
-	{
-		return false;
-	}
+	return false;
+}
 
-	public string getIconName()
-	{
-		if(Gtk.IconTheme.get_default().lookup_icon("applications-internet", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
-			return "applications-internet";
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-		return "feed-share-browser";
-	}
+}
 
-	public string getUsername(string id)
-	{
-		return "Browser";
-	}
+public bool logout(string id)
+{
+	return false;
+}
 
-	public bool needSetup()
-	{
-		return false;
-	}
+public string getIconName()
+{
+	if(Gtk.IconTheme.get_default().lookup_icon("applications-internet", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+		return "applications-internet";
 
-	public bool singleInstance()
-	{
-		return true;
-	}
+	return "feed-share-browser";
+}
 
-	public bool useSystemAccounts()
-	{
-		return false;
-	}
+public string getUsername(string id)
+{
+	return "Browser";
+}
 
-	public string pluginID()
-	{
-		return "browser";
-	}
+public bool needSetup()
+{
+	return false;
+}
 
-	public string pluginName()
-	{
-		return _("Open in Browser");
-	}
+public bool singleInstance()
+{
+	return true;
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return null;
-	}
+public bool useSystemAccounts()
+{
+	return false;
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return null;
-	}
+public string pluginID()
+{
+	return "browser";
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return null;
-	}
+public string pluginName()
+{
+	return _("Open in Browser");
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		return null;
-	}
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return null;
+}
+
+public ServiceSetup? newSetup()
+{
+	return null;
+}
+
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
+
+public ShareForm? shareWidget(string url)
+{
+	return null;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Email/EmailForm.vala 2.7.1-1/plugins/share/Email/EmailForm.vala
--- 2.6.1-1/plugins/share/Email/EmailForm.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Email/EmailForm.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,77 +16,77 @@
 
 public class FeedReader.EmailForm : ShareForm {
 
-	private Gtk.Entry m_entry;
-	private Gtk.TextView m_textView;
+private Gtk.Entry m_entry;
+private Gtk.TextView m_textView;
 
-	public EmailForm(string url)
-	{
-		string body = _("Hey,\n\nCheck out this interesting article I used FeedReader to read: $URL");
-		string to = "john.doe@domain.com";
-
-		var labelTo = new Gtk.Label(_("To:"));
-		labelTo.set_alignment(0.0f, 0.5f);
-		labelTo.get_style_context().add_class("h3");
-		m_entry = new Gtk.Entry();
-		m_entry.set_text(to);
-		var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
-		box.pack_start(labelTo, false, false);
-		box.pack_start(m_entry, true, true);
-
-		m_textView = new Gtk.TextView();
-		m_textView.get_style_context().add_class("h3");
-		m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
-		m_textView.buffer.text = body;
-		m_textView.border_width = 2;
-
-		var scrolled = new Gtk.ScrolledWindow(null, null);
-		scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
-		scrolled.add(m_textView);
-
-		int margin = 5;
-		m_textView.left_margin = margin;
-		m_textView.right_margin = margin;
-		m_textView.top_margin = margin;
-		m_textView.bottom_margin = margin;
-
-		var button = new Gtk.Button.with_label(_("Send"));
-		button.halign = Gtk.Align.END;
-		button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		button.clicked.connect(() => { share(); });
-
-		var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
-		backButton.set_focus_on_click(false);
-		backButton.set_relief(Gtk.ReliefStyle.NONE);
-		backButton.halign = Gtk.Align.START;
-		backButton.clicked.connect(() => {
+public EmailForm(string url)
+{
+	string body = _("Hey,\n\nCheck out this interesting article I used FeedReader to read: $URL");
+	string to = "john.doe@domain.com";
+
+	var labelTo = new Gtk.Label(_("To:"));
+	labelTo.set_alignment(0.0f, 0.5f);
+	labelTo.get_style_context().add_class("h3");
+	m_entry = new Gtk.Entry();
+	m_entry.set_text(to);
+	var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+	box.pack_start(labelTo, false, false);
+	box.pack_start(m_entry, true, true);
+
+	m_textView = new Gtk.TextView();
+	m_textView.get_style_context().add_class("h3");
+	m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+	m_textView.buffer.text = body;
+	m_textView.border_width = 2;
+
+	var scrolled = new Gtk.ScrolledWindow(null, null);
+	scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+	scrolled.add(m_textView);
+
+	int margin = 5;
+	m_textView.left_margin = margin;
+	m_textView.right_margin = margin;
+	m_textView.top_margin = margin;
+	m_textView.bottom_margin = margin;
+
+	var button = new Gtk.Button.with_label(_("Send"));
+	button.halign = Gtk.Align.END;
+	button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	button.clicked.connect(() => { share(); });
+
+	var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+	backButton.set_focus_on_click(false);
+	backButton.set_relief(Gtk.ReliefStyle.NONE);
+	backButton.halign = Gtk.Align.START;
+	backButton.clicked.connect(() => {
 			goBack();
 		});
 
-		var headline = new Gtk.Label(_("Write Email"));
-		headline.get_style_context().add_class("h2");
-		headline.set_alignment(0.4f, 0.5f);
-		var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-		box2.pack_start(backButton, false, false, 0);
-		box2.pack_start(headline, true, true, 0);
-
-		this.pack_start(box2, false, false, 0);
-		this.pack_start(box, false, false);
-		this.pack_start(scrolled);
-		this.pack_end(button, false, false);
-		this.orientation = Gtk.Orientation.VERTICAL;
-		this.spacing = 5;
-		this.margin = 10;
-		this.show_all();
-	}
-
-	public string getTo()
-	{
-		return m_entry.get_text();
-	}
-
-	public string getBody()
-	{
-		return m_textView.buffer.text;
-	}
+	var headline = new Gtk.Label(_("Write Email"));
+	headline.get_style_context().add_class("h2");
+	headline.set_alignment(0.4f, 0.5f);
+	var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+	box2.pack_start(backButton, false, false, 0);
+	box2.pack_start(headline, true, true, 0);
+
+	this.pack_start(box2, false, false, 0);
+	this.pack_start(box, false, false);
+	this.pack_start(scrolled);
+	this.pack_end(button, false, false);
+	this.orientation = Gtk.Orientation.VERTICAL;
+	this.spacing = 5;
+	this.margin = 10;
+	this.show_all();
+}
+
+public string getTo()
+{
+	return m_entry.get_text();
+}
+
+public string getBody()
+{
+	return m_textView.buffer.text;
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Email/Email.vala 2.7.1-1/plugins/share/Email/Email.vala
--- 2.6.1-1/plugins/share/Email/Email.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Email/Email.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,101 +16,101 @@
 
 public class FeedReader.ShareMail : ShareAccountInterface, Peas.ExtensionBase {
 
-	private string m_body;
-	private string m_to;
+private string m_body;
+private string m_to;
 
-	public bool addBookmark(string id, string url, bool system)
-	{
-		string subject = GLib.Uri.escape_string("Amazing article");
-		string body = GLib.Uri.escape_string(m_body.replace("$URL", url));
-		string mailto = @"mailto:$m_to?subject=$subject&body=$body";
-		Logger.debug(mailto);
-
-		try
-		{
-			Gtk.show_uri_on_window(MainWindow.get_default(), mailto, Gdk.CURRENT_TIME);
-			return true;
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("share via mail failed: %s".printf(e.message));
-		}
-
-		return false;
-	}
+public bool addBookmark(string id, string url, bool system)
+{
+	string subject = GLib.Uri.escape_string("Amazing article");
+	string body = GLib.Uri.escape_string(m_body.replace("$URL", url));
+	string mailto = @"mailto:$m_to?subject=$subject&body=$body";
+	Logger.debug(mailto);
 
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+	try
 	{
-
+		Gtk.show_uri_on_window(MainWindow.get_default(), mailto, Gdk.CURRENT_TIME);
+		return true;
 	}
-
-	public bool logout(string id)
+	catch(GLib.Error e)
 	{
-		return false;
+		Logger.error("share via mail failed: %s".printf(e.message));
 	}
 
-	public string getIconName()
-	{
-		if(Gtk.IconTheme.get_default().lookup_icon("mail-send", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
-			return "mail-send";
+	return false;
+}
 
-		return "feed-share-mail";
-	}
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-	public string getUsername(string id)
-	{
-		return "Email";
-	}
+}
 
-	public bool needSetup()
-	{
-		return false;
-	}
+public bool logout(string id)
+{
+	return false;
+}
 
-	public bool singleInstance()
-	{
-		return true;
-	}
+public string getIconName()
+{
+	if(Gtk.IconTheme.get_default().lookup_icon("mail-send", 0, Gtk.IconLookupFlags.FORCE_SVG) != null)
+		return "mail-send";
 
-	public bool useSystemAccounts()
-	{
-		return false;
-	}
+	return "feed-share-mail";
+}
 
-	public string pluginID()
-	{
-		return "mail";
-	}
+public string getUsername(string id)
+{
+	return "Email";
+}
 
-	public string pluginName()
-	{
-		return "Email";
-	}
+public bool needSetup()
+{
+	return false;
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return null;
-	}
+public bool singleInstance()
+{
+	return true;
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return null;
-	}
+public bool useSystemAccounts()
+{
+	return false;
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return null;
-	}
+public string pluginID()
+{
+	return "mail";
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		var widget = new EmailForm(url);
-		widget.share.connect(() => {
+public string pluginName()
+{
+	return "Email";
+}
+
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return null;
+}
+
+public ServiceSetup? newSetup()
+{
+	return null;
+}
+
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
+
+public ShareForm? shareWidget(string url)
+{
+	var widget = new EmailForm(url);
+	widget.share.connect(() => {
 			m_to = widget.getTo();
 			m_body = widget.getBody();
 		});
-		return widget;
-	}
+	return widget;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Instapaper/InstapaperAPI.vala 2.7.1-1/plugins/share/Instapaper/InstapaperAPI.vala
--- 2.6.1-1/plugins/share/Instapaper/InstapaperAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Instapaper/InstapaperAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,289 +14,289 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.InstapaperSecrets {
-	const string base_uri			= "https://www.instapaper.com/api/";
-	const string oauth_consumer_key		= "b7681e07bf554b15813511217054e1b2";
-	const string oauth_consumer_secret	= "c5307cb359d54685904f6d38aaeede6f";
-	const string oauth_callback			= "feedreader://instapaper";
+const string base_uri                   = "https://www.instapaper.com/api/";
+const string oauth_consumer_key         = "b7681e07bf554b15813511217054e1b2";
+const string oauth_consumer_secret      = "c5307cb359d54685904f6d38aaeede6f";
+const string oauth_callback                     = "feedreader://instapaper";
 }
 
 public class FeedReader.InstaAPI : ShareAccountInterface, Peas.ExtensionBase {
 
-	public InstaAPI()
-	{
-
-	}
+public InstaAPI()
+{
 
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-	{
+}
 
-	}
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-	public string getRequestToken()
-	{
-		return "";
-	}
+}
 
-	public bool getAccessToken(string id, string username, string password)
-	{
-		string userID = "";
+public string getRequestToken()
+{
+	return "";
+}
 
-		var oauthObject = new Rest.OAuthProxy (
-			InstapaperSecrets.oauth_consumer_key,
-			InstapaperSecrets.oauth_consumer_secret,
-			"https://www.instapaper.com/api/1/",
-			false);
+public bool getAccessToken(string id, string username, string password)
+{
+	string userID = "";
 
-		var call = oauthObject.new_call();
-		oauthObject.url_format = "https://www.instapaper.com/api/1/";
-		call.set_function ("oauth/access_token");
-		call.set_method("POST");
-		call.add_param("x_auth_mode", "client_auth");
-		call.add_param("x_auth_username", username);
-		call.add_param("x_auth_password", password);
-		try
-		{
-			call.run();
-		}
-		catch(Error e)
-		{
-			Logger.error("instapaper getAccessToken: " + e.message);
-		}
+	var oauthObject = new Rest.OAuthProxy (
+		InstapaperSecrets.oauth_consumer_key,
+		InstapaperSecrets.oauth_consumer_secret,
+		"https://www.instapaper.com/api/1/",
+		false);
 
-		string response = call.get_payload();
-		int64 status = call.get_status_code();
+	var call = oauthObject.new_call();
+	oauthObject.url_format = "https://www.instapaper.com/api/1/";
+	call.set_function ("oauth/access_token");
+	call.set_method("POST");
+	call.add_param("x_auth_mode", "client_auth");
+	call.add_param("x_auth_username", username);
+	call.add_param("x_auth_password", password);
+	try
+	{
+		call.run();
+	}
+	catch(Error e)
+	{
+		Logger.error("instapaper getAccessToken: " + e.message);
+	}
 
-		if(status != 200)
-		{
-			return false;
-		}
+	string response = call.get_payload();
+	int64 status = call.get_status_code();
 
+	if(status != 200)
+	{
+		return false;
+	}
 
-		int secretStart = response.index_of_char('=')+1;
-		int secretEnd = response.index_of_char('&', secretStart);
-		int tokenStart = response.index_of_char('=', secretEnd)+1;
 
-		string accessToken_secret = response.substring(secretStart, secretEnd-secretStart);
-		string accessToken = response.substring(tokenStart);
+	int secretStart = response.index_of_char('=')+1;
+	int secretEnd = response.index_of_char('&', secretStart);
+	int tokenStart = response.index_of_char('=', secretEnd)+1;
 
-		oauthObject.set_token(accessToken);
-		oauthObject.set_token_secret(accessToken_secret);
+	string accessToken_secret = response.substring(secretStart, secretEnd-secretStart);
+	string accessToken = response.substring(tokenStart);
 
-		// get userID -------------------------------------------------------------------------------------------------
-		var call2 = oauthObject.new_call();
-		oauthObject.url_format = "https://www.instapaper.com/api/1/";
-		call2.set_function("account/verify_credentials");
-		call2.set_method("POST");
-		try
-		{
-			call2.run();
-		}
-		catch(Error e)
-		{
-			Logger.debug("getUserID: " + e.message);
-		}
+	oauthObject.set_token(accessToken);
+	oauthObject.set_token_secret(accessToken_secret);
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(call2.get_payload());
-		}
-		catch (Error e)
-		{
-			Logger.error("Could not load response to Message from instapaper");
-			Logger.error(e.message);
-		}
+	// get userID -------------------------------------------------------------------------------------------------
+	var call2 = oauthObject.new_call();
+	oauthObject.url_format = "https://www.instapaper.com/api/1/";
+	call2.set_function("account/verify_credentials");
+	call2.set_method("POST");
+	try
+	{
+		call2.run();
+	}
+	catch(Error e)
+	{
+		Logger.debug("getUserID: " + e.message);
+	}
 
-		var root_node = parser.get_root();
-		var userArray = root_node.get_array();
-		var root_object = userArray.get_object_element(0);
-		if(root_object.has_member("user_id"))
-		{
-			userID = root_object.get_int_member("user_id").to_string();
-		}
-		else if(root_object.has_member("error"))
-		{
-			Logger.error(root_object.get_int_member("error_code").to_string());
-			Logger.error(root_object.get_string_member("message"));
-		}
-		//-------------------------------------------------------------------------------------------------------------
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(call2.get_payload());
+	}
+	catch (Error e)
+	{
+		Logger.error("Could not load response to Message from instapaper");
+		Logger.error(e.message);
+	}
 
+	var root_node = parser.get_root();
+	var userArray = root_node.get_array();
+	var root_object = userArray.get_object_element(0);
+	if(root_object.has_member("user_id"))
+	{
+		userID = root_object.get_int_member("user_id").to_string();
+	}
+	else if(root_object.has_member("error"))
+	{
+		Logger.error(root_object.get_int_member("error_code").to_string());
+		Logger.error(root_object.get_string_member("message"));
+	}
+	//-------------------------------------------------------------------------------------------------------------
 
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
-		settings.set_string("oauth-access-token", accessToken);
-		settings.set_string("oauth-access-token-secret", accessToken_secret);
-		settings.set_string("username", username);
-		settings.set_string("user-id", userID);
 
-		var array = Settings.share("instapaper").get_strv("account-ids");
-		array += id;
-		Settings.share("instapaper").set_strv("account-ids", array);
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+	settings.set_string("oauth-access-token", accessToken);
+	settings.set_string("oauth-access-token-secret", accessToken_secret);
+	settings.set_string("username", username);
+	settings.set_string("user-id", userID);
 
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE,
-										"userID", Secret.SchemaAttributeType.STRING);
+	var array = Settings.share("instapaper").get_strv("account-ids");
+	array += id;
+	Settings.share("instapaper").set_strv("account-ids", array);
 
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["userID"] = userID;
-		try
-		{
-			Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Instapaper login", password, null);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("InstaAPI - getAccessToken: " + e.message);
-		}
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE,
+	                                  "userID", Secret.SchemaAttributeType.STRING);
 
-		return true;
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["userID"] = userID;
+	try
+	{
+		Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Instapaper login", password, null);
 	}
-
-	public bool addBookmark(string id, string url, bool system)
+	catch(GLib.Error e)
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+		Logger.error("InstaAPI - getAccessToken: " + e.message);
+	}
 
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["userID"] = settings.get_string("user-id");
+	return true;
+}
 
-		string password = "";
-		try
-		{
-			password = Secret.password_lookupv_sync(pwSchema, attributes, null);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("InstaAPI addBookmark: " + e.message);
-		}
+public bool addBookmark(string id, string url, bool system)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
 
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message  = "user_id=" + settings.get_string("user-id")
-						+ "&username=" + settings.get_string("username")
-						+ "&password=" + password
-						+ "&url=" + GLib.Uri.escape_string(url);
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.instapaper.password", Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["userID"] = settings.get_string("user-id");
 
-		Logger.debug("InstaAPI: " + message);
+	string password = "";
+	try
+	{
+		password = Secret.password_lookupv_sync(pwSchema, attributes, null);
+	}
+	catch(GLib.Error e)
+	{
+		Logger.error("InstaAPI addBookmark: " + e.message);
+	}
 
-		var message_soup = new Soup.Message("POST", "https://www.instapaper.com/api/add");
-		message_soup.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message.data);
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message  = "user_id=" + settings.get_string("user-id")
+	                  + "&username=" + settings.get_string("username")
+	                  + "&password=" + password
+	                  + "&url=" + GLib.Uri.escape_string(url);
 
-		if(Settings.tweaks().get_boolean("do-not-track"))
-				message_soup.request_headers.append("DNT", "1");
+	Logger.debug("InstaAPI: " + message);
 
-		session.send_message(message_soup);
-		string response = (string)message_soup.response_body.flatten().data;
+	var message_soup = new Soup.Message("POST", "https://www.instapaper.com/api/add");
+	message_soup.set_request("application/x-www-form-urlencoded", Soup.MemoryUse.COPY, message.data);
 
-		if(response == null || response == "")
-			return false;
+	if(Settings.tweaks().get_boolean("do-not-track"))
+		message_soup.request_headers.append("DNT", "1");
 
-		Logger.debug("InstaAPI: " + response);
+	session.send_message(message_soup);
+	string response = (string)message_soup.response_body.flatten().data;
 
-		return true;
-	}
+	if(response == null || response == "")
+		return false;
 
-	public bool logout(string id)
-	{
-		Logger.debug(@"InstaAPI.logout($id)");
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", @"/org/gnome/feedreader/share/instapaper/$id/");
-		var pwSchema = new Secret.Schema("org.gnome.feedreader.instapaper.password",
-										Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
+	Logger.debug("InstaAPI: " + response);
 
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["userID"] = settings.get_string("user-id");
-		bool removed = false;
+	return true;
+}
 
-		Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
+public bool logout(string id)
+{
+	Logger.debug(@"InstaAPI.logout($id)");
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", @"/org/gnome/feedreader/share/instapaper/$id/");
+	var pwSchema = new Secret.Schema("org.gnome.feedreader.instapaper.password",
+	                                 Secret.SchemaFlags.NONE, "userID", Secret.SchemaAttributeType.STRING);
+
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["userID"] = settings.get_string("user-id");
+	bool removed = false;
+
+	Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
 			try
 			{
-				removed = Secret.password_clearv.end(async_res);
-				if(!removed)
+			        removed = Secret.password_clearv.end(async_res);
+			        if(!removed)
 					Logger.error(@"Could not delete password of InstaAPI account $id");
 			}
 			catch(GLib.Error e)
 			{
-				Logger.error("InstaAPI.logout: %s".printf(e.message));
+			        Logger.error("InstaAPI.logout: %s".printf(e.message));
 			}
 		});
 
-		var keys = settings.list_keys();
-		foreach(string key in keys)
-		{
-			settings.reset(key);
-		}
-
-		var array = Settings.share("instapaper").get_strv("account-ids");
-
-		string[] array2 = {};
-		foreach(string i in array)
-		{
-			if(i != id)
-				array2 += i;
-		}
-		Settings.share("instapaper").set_strv("account-ids", array2);
-		deleteAccount(id);
-
-		return true;
-	}
-
-	public string getIconName()
+	var keys = settings.list_keys();
+	foreach(string key in keys)
 	{
-		return "feed-share-instapaper";
+		settings.reset(key);
 	}
 
-	public string getUsername(string id)
-	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
-		return settings.get_string("username");
-	}
+	var array = Settings.share("instapaper").get_strv("account-ids");
 
-	public bool needSetup()
+	string[] array2 = {};
+	foreach(string i in array)
 	{
-		return true;
+		if(i != id)
+			array2 += i;
 	}
+	Settings.share("instapaper").set_strv("account-ids", array2);
+	deleteAccount(id);
 
-	public bool singleInstance()
-	{
-		return false;
-	}
+	return true;
+}
 
-	public bool useSystemAccounts()
-	{
-		return false;
-	}
+public string getIconName()
+{
+	return "feed-share-instapaper";
+}
 
-	public string pluginID()
-	{
-		return "instapaper";
-	}
+public string getUsername(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/instapaper/%s/".printf(id));
+	return settings.get_string("username");
+}
 
-	public string pluginName()
-	{
-		return "Instapaper";
-	}
+public bool needSetup()
+{
+	return true;
+}
 
-	public string getURL(string token)
-	{
-		return "";
-	}
+public bool singleInstance()
+{
+	return false;
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return new InstapaperSetup(id, this, username);
-	}
+public bool useSystemAccounts()
+{
+	return false;
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return new InstapaperSetup(null, this);
-	}
+public string pluginID()
+{
+	return "instapaper";
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return null;
-	}
+public string pluginName()
+{
+	return "Instapaper";
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		return null;
-	}
+public string getURL(string token)
+{
+	return "";
+}
+
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return new InstapaperSetup(id, this, username);
+}
+
+public ServiceSetup? newSetup()
+{
+	return new InstapaperSetup(null, this);
+}
+
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
+
+public ShareForm? shareWidget(string url)
+{
+	return null;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Instapaper/InstapaperSetup.vala 2.7.1-1/plugins/share/Instapaper/InstapaperSetup.vala
--- 2.6.1-1/plugins/share/Instapaper/InstapaperSetup.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Instapaper/InstapaperSetup.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,108 +15,108 @@
 
 public class FeedReader.InstapaperSetup : ServiceSetup {
 
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passEntry;
-	private Gtk.Revealer m_login_revealer;
-	private InstaAPI m_api;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passEntry;
+private Gtk.Revealer m_login_revealer;
+private InstaAPI m_api;
+
+public InstapaperSetup(string? id, InstaAPI api, string username = "")
+{
+	bool loggedIN = false;
+	if(username != "")
+		loggedIN = true;
+
+	base("Instapaper", "feed-share-instapaper", loggedIN, username);
+
+	//------------------------------------------------
+	// XAuth revealer
+	//------------------------------------------------
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+	grid.margin_bottom = 10;
+	grid.margin_top = 5;
+
+	m_userEntry = new Gtk.Entry();
+	m_passEntry = new Gtk.Entry();
+	m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passEntry.set_visibility(false);
 
-	public InstapaperSetup(string? id, InstaAPI api, string username = "")
-	{
-		bool loggedIN = false;
-		if(username != "")
-			loggedIN = true;
-
-		base("Instapaper", "feed-share-instapaper", loggedIN, username);
-
-		//------------------------------------------------
-		// XAuth revealer
-		//------------------------------------------------
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-		grid.margin_bottom = 10;
-		grid.margin_top = 5;
-
-		m_userEntry = new Gtk.Entry();
-		m_passEntry = new Gtk.Entry();
-		m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passEntry.set_visibility(false);
-
-		m_userEntry.activate.connect(() => {
+	m_userEntry.activate.connect(() => {
 			m_passEntry.grab_focus();
 		});
 
-		m_passEntry.activate.connect(() => {
+	m_passEntry.activate.connect(() => {
 			login();
 		});
 
-		grid.attach(new Gtk.Label(_("Username:")), 0, 0, 1, 1);
-		grid.attach(new Gtk.Label(_("Password:")), 0, 1, 1, 1);
-		grid.attach(m_userEntry, 1, 0, 1, 1);
-		grid.attach(m_passEntry, 1, 1, 1, 1);
+	grid.attach(new Gtk.Label(_("Username:")), 0, 0, 1, 1);
+	grid.attach(new Gtk.Label(_("Password:")), 0, 1, 1, 1);
+	grid.attach(m_userEntry, 1, 0, 1, 1);
+	grid.attach(m_passEntry, 1, 1, 1, 1);
+
+	m_login_revealer = new Gtk.Revealer();
+	m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
+	m_login_revealer.add(grid);
+	//------------------------------------------------
 
-		m_login_revealer = new Gtk.Revealer();
-		m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
-		m_login_revealer.add(grid);
-		//------------------------------------------------
+	m_seperator_box.pack_start(m_login_revealer, false, false, 0);
 
-		m_seperator_box.pack_start(m_login_revealer, false, false, 0);
+	m_api = api;
 
-		m_api = api;
-
-		if(id != null)
-			m_id = id;
-	}
+	if(id != null)
+		m_id = id;
+}
 
 
-	public override void login()
+public override void login()
+{
+	if(m_login_revealer.get_child_revealed())
 	{
-		if(m_login_revealer.get_child_revealed())
-		{
-			m_spinner.start();
-			m_iconStack.set_visible_child_name("spinner");
-			string id = Share.get_default().generateNewID();
-			string username = m_userEntry.get_text();
-			string password = m_passEntry.get_text();
-
-			if(m_api.getAccessToken(id, username, password))
-			{
-				m_id = id;
-				m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
-				m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-				m_login_revealer.set_reveal_child(false);
-				m_isLoggedIN = true;
-				m_iconStack.set_visible_child_name("loggedIN");
-				m_spinner.stop();
-				m_label.set_label(username);
-				m_labelStack.set_visible_child_name("loggedIN");
-				m_login_button.clicked.disconnect(login);
-				m_login_button.clicked.connect(logout);
-			}
-			else
-			{
-				showInfoBar(_("Username or Password incorrect"));
-				m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-			}
+		m_spinner.start();
+		m_iconStack.set_visible_child_name("spinner");
+		string id = Share.get_default().generateNewID();
+		string username = m_userEntry.get_text();
+		string password = m_passEntry.get_text();
 
+		if(m_api.getAccessToken(id, username, password))
+		{
+			m_id = id;
+			m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
+			m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+			m_login_revealer.set_reveal_child(false);
+			m_isLoggedIN = true;
+			m_iconStack.set_visible_child_name("loggedIN");
+			m_spinner.stop();
+			m_label.set_label(username);
+			m_labelStack.set_visible_child_name("loggedIN");
+			m_login_button.clicked.disconnect(login);
+			m_login_button.clicked.connect(logout);
 		}
 		else
 		{
-			m_login_revealer.set_reveal_child(true);
-			m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-			m_userEntry.grab_focus();
+			showInfoBar(_("Username or Password incorrect"));
+			m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
 		}
-	}
 
-	public override void logout()
+	}
+	else
 	{
-		Logger.debug("InstapaperSetup.logout()");
-		m_isLoggedIN = false;
-		m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-		m_labelStack.set_visible_child_name("loggedOUT");
-		m_api.logout(m_id);
-		removeRow();
+		m_login_revealer.set_reveal_child(true);
+		m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+		m_userEntry.grab_focus();
 	}
 }
+
+public override void logout()
+{
+	Logger.debug("InstapaperSetup.logout()");
+	m_isLoggedIN = false;
+	m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+	m_labelStack.set_visible_child_name("loggedOUT");
+	m_api.logout(m_id);
+	removeRow();
+}
+}
diff -pruN 2.6.1-1/plugins/share/Pocket/PocketAPI.vala 2.7.1-1/plugins/share/Pocket/PocketAPI.vala
--- 2.6.1-1/plugins/share/Pocket/PocketAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Pocket/PocketAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,274 +14,274 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.PocketSecrets {
-	const string base_uri			= "https://getpocket.com/v3/";
-	const string oauth_consumer_key		= "43273-30a11c29b5eeabfa905df168";
-	const string oauth_callback			= "feedreader://pocket";
+const string base_uri                   = "https://getpocket.com/v3/";
+const string oauth_consumer_key         = "43273-30a11c29b5eeabfa905df168";
+const string oauth_callback                     = "feedreader://pocket";
 }
 
 public class FeedReader.PocketAPI : ShareAccountInterface, Peas.ExtensionBase {
 
-	public PocketAPI()
-	{
+public PocketAPI()
+{
 
-	}
+}
 
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
+	try
 	{
-		try
+		Goa.Client? client = new Goa.Client.sync();
+		if(client != null)
 		{
-			Goa.Client? client = new Goa.Client.sync();
-			if(client != null)
+			var goaAccounts = client.get_accounts();
+			foreach(var object in goaAccounts)
 			{
-				var goaAccounts = client.get_accounts();
-				foreach(var object in goaAccounts)
+				if(object.account.provider_type == "pocket"
+				   && !object.account.read_later_disabled)
 				{
-					if(object.account.provider_type == "pocket"
-					&& !object.account.read_later_disabled)
-					{
-						accounts.add(
-							new ShareAccount(
-								object.account.id,
-								pluginID(),
-								object.account.identity,
-								getIconName(),
-								pluginName(),
-								true
+					accounts.add(
+						new ShareAccount(
+							object.account.id,
+							pluginID(),
+							object.account.identity,
+							getIconName(),
+							pluginName(),
+							true
 							)
 						);
-					}
 				}
 			}
-			else
-			{
-				Logger.error("PocketAPI: goa not available");
-			}
 		}
-		catch(GLib.Error e)
+		else
 		{
-			Logger.error("PocketAPI.setupSystemAccounts: %s".printf(e.message));
+			Logger.error("PocketAPI: goa not available");
 		}
 	}
-
-	public string getRequestToken()
+	catch(GLib.Error e)
 	{
-		Logger.debug("PocketAPI: get request token");
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&redirect_uri=" + PocketSecrets.oauth_callback;
+		Logger.error("PocketAPI.setupSystemAccounts: %s".printf(e.message));
+	}
+}
 
-		var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/request");
-		message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+public string getRequestToken()
+{
+	Logger.debug("PocketAPI: get request token");
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&redirect_uri=" + PocketSecrets.oauth_callback;
+
+	var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/request");
+	message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
 
-		if(Settings.tweaks().get_boolean("do-not-track"))
-				message_soup.request_headers.append("DNT", "1");
+	if(Settings.tweaks().get_boolean("do-not-track"))
+		message_soup.request_headers.append("DNT", "1");
 
-		session.send_message(message_soup);
+	session.send_message(message_soup);
 
-		string response = (string)message_soup.response_body.flatten().data;
-		return response.substring(response.index_of_char('=')+1);
-	}
+	string response = (string)message_soup.response_body.flatten().data;
+	return response.substring(response.index_of_char('=')+1);
+}
 
-	public bool getAccessToken(string id, string requestToken)
-	{
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&code=" + requestToken;
-
-		var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/authorize");
-		message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-
-		if(Settings.tweaks().get_boolean("do-not-track"))
-				message_soup.request_headers.append("DNT", "1");
-
-		session.send_message(message_soup);
-
-		if((string)message_soup.response_body.flatten().data == null
-		|| (string)message_soup.response_body.flatten().data == "")
-			return false;
-
-		string response = (string)message_soup.response_body.flatten().data;
-		Logger.debug(response);
-		int tokenStart = response.index_of_char('=')+1;
-		int tokenEnd = response.index_of_char('&', tokenStart);
-		int userStart = response.index_of_char('=', tokenEnd)+1;
+public bool getAccessToken(string id, string requestToken)
+{
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message = "consumer_key=" + PocketSecrets.oauth_consumer_key + "&code=" + requestToken;
+
+	var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/oauth/authorize");
+	message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
 
-		string accessToken = response.substring(tokenStart, tokenEnd-tokenStart);
-		string user = GLib.Uri.unescape_string(response.substring(userStart));
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
-		settings.set_string("oauth-access-token", accessToken);
-		settings.set_string("username", user);
+	if(Settings.tweaks().get_boolean("do-not-track"))
+		message_soup.request_headers.append("DNT", "1");
 
-		var array = Settings.share("pocket").get_strv("account-ids");
-		array += id;
-		Settings.share("pocket").set_strv("account-ids", array);
+	session.send_message(message_soup);
 
-		return true;
-	}
+	if((string)message_soup.response_body.flatten().data == null
+	   || (string)message_soup.response_body.flatten().data == "")
+		return false;
 
+	string response = (string)message_soup.response_body.flatten().data;
+	Logger.debug(response);
+	int tokenStart = response.index_of_char('=')+1;
+	int tokenEnd = response.index_of_char('&', tokenStart);
+	int userStart = response.index_of_char('=', tokenEnd)+1;
+
+	string accessToken = response.substring(tokenStart, tokenEnd-tokenStart);
+	string user = GLib.Uri.unescape_string(response.substring(userStart));
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+	settings.set_string("oauth-access-token", accessToken);
+	settings.set_string("username", user);
+
+	var array = Settings.share("pocket").get_strv("account-ids");
+	array += id;
+	Settings.share("pocket").set_strv("account-ids", array);
 
-	public bool addBookmark(string id, string url, bool system)
-	{
-		string oauthToken = "";
+	return true;
+}
 
-		if(system)
+
+public bool addBookmark(string id, string url, bool system)
+{
+	string oauthToken = "";
+
+	if(system)
+	{
+		Logger.debug(@"PocketAPI.addBookmark: $id is system account");
+		try
 		{
-			Logger.debug(@"PocketAPI.addBookmark: $id is system account");
-			try
+			Goa.Client? client = new Goa.Client.sync();
+			if(client != null)
 			{
-				Goa.Client? client = new Goa.Client.sync();
-				if(client != null)
+				var accounts = client.get_accounts();
+				foreach(var object in accounts)
 				{
-					var accounts = client.get_accounts();
-					foreach(var object in accounts)
+					if(object.account.provider_type == "pocket"
+					   && object.account.id == id)
 					{
-						if(object.account.provider_type == "pocket"
-						&& object.account.id == id)
-						{
-							int expires = -1;
-							object.oauth2_based.call_get_access_token_sync(out oauthToken, out expires);
-							break;
-						}
+						int expires = -1;
+						object.oauth2_based.call_get_access_token_sync(out oauthToken, out expires);
+						break;
 					}
 				}
-				else
-				{
-					Logger.error("PocketAPI: goa not available");
-				}
 			}
-			catch(GLib.Error e)
+			else
 			{
-				Logger.error("PocketAPI GOA: %s".printf(e.message));
+				Logger.error("PocketAPI: goa not available");
 			}
 		}
-		else
+		catch(GLib.Error e)
 		{
-			var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
-			oauthToken = settings.get_string("oauth-access-token");
+			Logger.error("PocketAPI GOA: %s".printf(e.message));
 		}
+	}
+	else
+	{
+		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+		oauthToken = settings.get_string("oauth-access-token");
+	}
+
 
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message = "url=" + GLib.Uri.escape_string(url)
+	                 + "&consumer_key=" + PocketSecrets.oauth_consumer_key
+	                 + "&access_token=" + oauthToken;
 
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message = "url=" + GLib.Uri.escape_string(url)
-						+ "&consumer_key=" + PocketSecrets.oauth_consumer_key
-						+ "&access_token=" + oauthToken;
+	Logger.debug("PocketAPI: " + message);
 
-		Logger.debug("PocketAPI: " + message);
+	var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/add");
+	message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
 
-		var message_soup = new Soup.Message("POST", "https://getpocket.com/v3/add");
-		message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+	if(Settings.tweaks().get_boolean("do-not-track"))
+		message_soup.request_headers.append("DNT", "1");
 
-		if(Settings.tweaks().get_boolean("do-not-track"))
-				message_soup.request_headers.append("DNT", "1");
+	session.send_message(message_soup);
 
-		session.send_message(message_soup);
+	if((string)message_soup.response_body.flatten().data == null
+	   || (string)message_soup.response_body.flatten().data == "")
+		return false;
 
-		if((string)message_soup.response_body.flatten().data == null
-		|| (string)message_soup.response_body.flatten().data == "")
-			return false;
+	return true;
+}
 
-		return true;
+public bool logout(string id)
+{
+	Logger.debug(@"PocketAPI: logout($id)");
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+	var keys = settings.list_keys();
+	foreach(string key in keys)
+	{
+		settings.reset(key);
 	}
 
-	public bool logout(string id)
+	var array = Settings.share("pocket").get_strv("account-ids");
+	string[] array2 = {};
+
+	foreach(string i in array)
 	{
-		Logger.debug(@"PocketAPI: logout($id)");
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
-		var keys = settings.list_keys();
-		foreach(string key in keys)
-		{
-			settings.reset(key);
-		}
+		if(i != id)
+			array2 += i;
+	}
+	Settings.share("pocket").set_strv("account-ids", array2);
+	deleteAccount(id);
 
-		var array = Settings.share("pocket").get_strv("account-ids");
-		string[] array2 = {};
+	return true;
+}
 
-		foreach(string i in array)
-		{
-			if(i != id)
-				array2 += i;
-		}
-		Settings.share("pocket").set_strv("account-ids", array2);
-		deleteAccount(id);
+public string getURL(string token)
+{
+	return "https://getpocket.com/auth/authorize?request_token="
+	       + token + "&redirect_uri="
+	       + GLib.Uri.escape_string(PocketSecrets.oauth_callback);
+}
 
-		return true;
-	}
+public string getIconName()
+{
+	return "feed-share-pocket";
+}
 
-	public string getURL(string token)
-	{
-		return	"https://getpocket.com/auth/authorize?request_token="
-				+ token + "&redirect_uri="
-				+ GLib.Uri.escape_string(PocketSecrets.oauth_callback);
-	}
+public string getUsername(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
+	return settings.get_string("username");
+}
 
-	public string getIconName()
-	{
-		return "feed-share-pocket";
-	}
+public bool needSetup()
+{
+	return true;
+}
 
-	public string getUsername(string id)
-	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/pocket/%s/".printf(id));
-		return settings.get_string("username");
-	}
+public bool singleInstance()
+{
+	return false;
+}
 
-	public bool needSetup()
-	{
-		return true;
-	}
+public bool useSystemAccounts()
+{
+	try
+	{
+		Goa.Client? client = new Goa.Client.sync();
+		if(client != null)
+			return true;
 
-	public bool singleInstance()
-	{
 		return false;
 	}
-
-	public bool useSystemAccounts()
+	catch(GLib.Error e)
 	{
-		try
-		{
-			Goa.Client? client = new Goa.Client.sync();
-			if(client != null)
-				return true;
-
-			return false;
-		}
-		catch(GLib.Error e)
-		{
-			Logger.debug("PocketAPI.useSystemAccounts(): %s".printf(e.message));
-			return false;
-		}
+		Logger.debug("PocketAPI.useSystemAccounts(): %s".printf(e.message));
+		return false;
 	}
+}
 
-	public string pluginID()
-	{
-		return "pocket";
-	}
+public string pluginID()
+{
+	return "pocket";
+}
 
-	public string pluginName()
-	{
-		return "Pocket";
-	}
+public string pluginName()
+{
+	return "Pocket";
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return new PocketSetup(id, this, username);
-	}
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return new PocketSetup(id, this, username);
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return new PocketSetup(null, this);
-	}
+public ServiceSetup? newSetup()
+{
+	return new PocketSetup(null, this);
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return new PocketSetup(id, this, username, true);
-	}
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return new PocketSetup(id, this, username, true);
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		return null;
-	}
+public ShareForm? shareWidget(string url)
+{
+	return null;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Pocket/PocketSetup.vala 2.7.1-1/plugins/share/Pocket/PocketSetup.vala
--- 2.6.1-1/plugins/share/Pocket/PocketSetup.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Pocket/PocketSetup.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,72 +15,72 @@
 
 public class FeedReader.PocketSetup : ServiceSetup {
 
-	private PocketAPI m_api;
+private PocketAPI m_api;
 
-	public PocketSetup(string? id, PocketAPI api, string username = "", bool system = false)
-	{
-		bool loggedIN = false;
-		if(username != "")
-			loggedIN = true;
+public PocketSetup(string? id, PocketAPI api, string username = "", bool system = false)
+{
+	bool loggedIN = false;
+	if(username != "")
+		loggedIN = true;
 
-		base("Pocket", "feed-share-pocket", loggedIN, username, system);
+	base("Pocket", "feed-share-pocket", loggedIN, username, system);
 
-		m_api = api;
+	m_api = api;
 
-		if(id != null)
-			m_id = id;
-	}
+	if(id != null)
+		m_id = id;
+}
 
 
-	public override void login()
+public override void login()
+{
+	string id = Share.get_default().generateNewID();
+	string requestToken = m_api.getRequestToken();
+	string url = m_api.getURL(requestToken);
+	m_spinner.start();
+	m_iconStack.set_visible_child_name("spinner");
+	try
 	{
-		string id = Share.get_default().generateNewID();
-		string requestToken = m_api.getRequestToken();
-		string url = m_api.getURL(requestToken);
-		m_spinner.start();
-		m_iconStack.set_visible_child_name("spinner");
-		try
-		{
-			Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
-		}
-		catch(GLib.Error e)
-		{
-
-		}
-
-
-		m_login_button.set_label(_("waiting"));
-		m_login_button.set_sensitive(false);
-		FeedReaderApp.get_default().callback.connect((content) => {
+		Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
+	}
+	catch(GLib.Error e)
+	{
+
+	}
+
+
+	m_login_button.set_label(_("waiting"));
+	m_login_button.set_sensitive(false);
+	FeedReaderApp.get_default().callback.connect((content) => {
 			if(content == PocketSecrets.oauth_callback)
 			{
-				if(m_api.getAccessToken(id, requestToken))
-				{
-					m_id = id;
-					m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
-					m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
-					m_spinner.stop();
-					m_isLoggedIN = true;
-					m_label.set_label(m_api.getUsername(id));
-					m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
-					m_login_button.clicked.disconnect(login);
-					m_login_button.clicked.connect(logout);
+			        if(m_api.getAccessToken(id, requestToken))
+			        {
+			                m_id = id;
+			                m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
+			                m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+			                m_spinner.stop();
+			                m_isLoggedIN = true;
+			                m_label.set_label(m_api.getUsername(id));
+			                m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+			                m_login_button.clicked.disconnect(login);
+			                m_login_button.clicked.connect(logout);
 				}
-				else
-				{
-					m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+			        else
+			        {
+			                m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
 				}
 			}
 		});
-	}
+}
 
-	public override void logout()
-	{
-		m_isLoggedIN = false;
-		m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-		m_labelStack.set_visible_child_name("loggedOUT");
-		m_api.logout(m_id);
-		removeRow();
-	}
+public override void logout()
+{
+	m_isLoggedIN = false;
+	m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+	m_labelStack.set_visible_child_name("loggedOUT");
+	m_api.logout(m_id);
+	removeRow();
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Telegram/TelegramForm.vala 2.7.1-1/plugins/share/Telegram/TelegramForm.vala
--- 2.6.1-1/plugins/share/Telegram/TelegramForm.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Telegram/TelegramForm.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,62 +16,62 @@
 
 public class FeedReader.TelegramForm : ShareForm {
 
-	private Gtk.TextView m_textView;
+private Gtk.TextView m_textView;
 
-	public TelegramForm()
-	{
-		string tg_msg_text = _("Hey, check out this interesting article I used FeedReader to read");
-		var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
-
-		m_textView = new Gtk.TextView();
-		m_textView.get_style_context().add_class("h3");
-		m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
-		m_textView.buffer.text = tg_msg_text;
-		m_textView.border_width = 2;
-
-		var scrolled = new Gtk.ScrolledWindow(null, null);
-		scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
-		scrolled.add(m_textView);
-
-		int margin = 5;
-		m_textView.left_margin = margin;
-		m_textView.right_margin = margin;
-		m_textView.top_margin = margin;
-		m_textView.bottom_margin = margin;
-
-		var button = new Gtk.Button.with_label(_("Send"));
-		button.halign = Gtk.Align.END;
-		button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		button.clicked.connect(() => { share(); });
-
-		var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
-		backButton.set_focus_on_click(false);
-		backButton.set_relief(Gtk.ReliefStyle.NONE);
-		backButton.halign = Gtk.Align.START;
-		backButton.clicked.connect(() => {
+public TelegramForm()
+{
+	string tg_msg_text = _("Hey, check out this interesting article I used FeedReader to read");
+	var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 5);
+
+	m_textView = new Gtk.TextView();
+	m_textView.get_style_context().add_class("h3");
+	m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+	m_textView.buffer.text = tg_msg_text;
+	m_textView.border_width = 2;
+
+	var scrolled = new Gtk.ScrolledWindow(null, null);
+	scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+	scrolled.add(m_textView);
+
+	int margin = 5;
+	m_textView.left_margin = margin;
+	m_textView.right_margin = margin;
+	m_textView.top_margin = margin;
+	m_textView.bottom_margin = margin;
+
+	var button = new Gtk.Button.with_label(_("Send"));
+	button.halign = Gtk.Align.END;
+	button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	button.clicked.connect(() => { share(); });
+
+	var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+	backButton.set_focus_on_click(false);
+	backButton.set_relief(Gtk.ReliefStyle.NONE);
+	backButton.halign = Gtk.Align.START;
+	backButton.clicked.connect(() => {
 			goBack();
 		});
 
-		var headline = new Gtk.Label(_("Send Telegram"));
-		headline.get_style_context().add_class("h2");
-		headline.set_alignment(0.4f, 0.5f);
-		var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-		box2.pack_start(backButton, false, false, 0);
-		box2.pack_start(headline, true, true, 0);
-
-		this.pack_start(box2, false, false, 0);
-		this.pack_start(box, false, false);
-		this.pack_start(scrolled);
-		this.pack_end(button, false, false);
-		this.orientation = Gtk.Orientation.VERTICAL;
-		this.spacing = 5;
-		this.margin = 10;
-		this.show_all();
-	}
-
-	public string getMessage()
-	{
-		return m_textView.buffer.text;
-	}
+	var headline = new Gtk.Label(_("Send Telegram"));
+	headline.get_style_context().add_class("h2");
+	headline.set_alignment(0.4f, 0.5f);
+	var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+	box2.pack_start(backButton, false, false, 0);
+	box2.pack_start(headline, true, true, 0);
+
+	this.pack_start(box2, false, false, 0);
+	this.pack_start(box, false, false);
+	this.pack_start(scrolled);
+	this.pack_end(button, false, false);
+	this.orientation = Gtk.Orientation.VERTICAL;
+	this.spacing = 5;
+	this.margin = 10;
+	this.show_all();
+}
+
+public string getMessage()
+{
+	return m_textView.buffer.text;
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Telegram/TelegramSetup.vala 2.7.1-1/plugins/share/Telegram/TelegramSetup.vala
--- 2.6.1-1/plugins/share/Telegram/TelegramSetup.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Telegram/TelegramSetup.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,45 +15,45 @@
 
 public class FeedReader.TelegramSetup : ServiceSetup {
 
-	private Telegram m_tg;
+private Telegram m_tg;
 
-	public TelegramSetup(string? id, Telegram tg, string username = "")
-	{
-		bool loggedIN = false;
-		if(username != "")
-			loggedIN = true;
-
-		base("Telegram", "feed-share-telegram", loggedIN, username);
-
-		m_tg = tg;
-		//no login, so change the labels
-		m_login_button.set_label(_("Add"));
-		m_logout_button.set_label(_("Remove"));
-		m_id = m_tg.pluginID();
-	}
-
-
-	public override void login()
-	{
-		showInfoBar(_("Info: Telegram would need to be installed for this plugin to work."));
-		m_login_button.set_sensitive(false);
-		Settings.share("telegram").set_boolean("enabled", true);
-		m_tg.addAccount(m_id, m_tg.pluginID(), m_tg.getUsername(m_id), m_tg.getIconName(), m_tg.pluginName());
-		m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
-		m_isLoggedIN = true;
-		m_label.set_label(m_tg.getUsername(m_id));
-		m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
-		m_login_button.clicked.disconnect(login);
-		m_login_button.clicked.connect(logout);
-	}
-
-	public override void logout()
-	{
-		m_isLoggedIN = false;
-		m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-		m_labelStack.set_visible_child_name("loggedOUT");
-		m_tg.logout(m_id);
-		removeRow();
-	}
+public TelegramSetup(string? id, Telegram tg, string username = "")
+{
+	bool loggedIN = false;
+	if(username != "")
+		loggedIN = true;
+
+	base("Telegram", "feed-share-telegram", loggedIN, username);
+
+	m_tg = tg;
+	//no login, so change the labels
+	m_login_button.set_label(_("Add"));
+	m_logout_button.set_label(_("Remove"));
+	m_id = m_tg.pluginID();
+}
+
+
+public override void login()
+{
+	showInfoBar(_("Info: Telegram would need to be installed for this plugin to work."));
+	m_login_button.set_sensitive(false);
+	Settings.share("telegram").set_boolean("enabled", true);
+	m_tg.addAccount(m_id, m_tg.pluginID(), m_tg.getUsername(m_id), m_tg.getIconName(), m_tg.pluginName());
+	m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+	m_isLoggedIN = true;
+	m_label.set_label(m_tg.getUsername(m_id));
+	m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+	m_login_button.clicked.disconnect(login);
+	m_login_button.clicked.connect(logout);
+}
+
+public override void logout()
+{
+	m_isLoggedIN = false;
+	m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+	m_labelStack.set_visible_child_name("loggedOUT");
+	m_tg.logout(m_id);
+	removeRow();
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Telegram/Telegram.vala 2.7.1-1/plugins/share/Telegram/Telegram.vala
--- 2.6.1-1/plugins/share/Telegram/Telegram.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Telegram/Telegram.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,94 +16,94 @@
 
 public class FeedReader.Telegram : ShareAccountInterface, Peas.ExtensionBase {
 
-	string tg_text;
+string tg_text;
 
-	public bool addBookmark(string id, string url, bool system)
-	{
-		string tg_msg = @"tg://msg_url?url=$url&text=$tg_text";
-
-		try
-		{
-			Gtk.show_uri_on_window(MainWindow.get_default(), tg_msg, Gdk.CURRENT_TIME);
-			return true;
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("TelegramPlugin: Error opening url: " + e.message);
-		}
-		return false;
-	}
-
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-	{
-
-	}
+public bool addBookmark(string id, string url, bool system)
+{
+	string tg_msg = @"tg://msg_url?url=$url&text=$tg_text";
 
-	public bool logout(string id)
+	try
 	{
-		Settings.share("telegram").set_boolean("enabled", false);
-		deleteAccount(id);
+		Gtk.show_uri_on_window(MainWindow.get_default(), tg_msg, Gdk.CURRENT_TIME);
 		return true;
 	}
-
-	public string getIconName()
+	catch(GLib.Error e)
 	{
-		return "feed-share-telegram";
+		Logger.error("TelegramPlugin: Error opening url: " + e.message);
 	}
+	return false;
+}
 
-	public string getUsername(string id)
-	{
-		return "Telegram";
-	}
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-	public bool needSetup()
-	{
-		return true;
-	}
+}
 
-	public bool singleInstance()
-	{
-		return true;
-	}
+public bool logout(string id)
+{
+	Settings.share("telegram").set_boolean("enabled", false);
+	deleteAccount(id);
+	return true;
+}
 
-	public bool useSystemAccounts()
-	{
-		return false;
-	}
+public string getIconName()
+{
+	return "feed-share-telegram";
+}
 
-	public string pluginID()
-	{
-		return "telegram";
-	}
+public string getUsername(string id)
+{
+	return "Telegram";
+}
 
-	public string pluginName()
-	{
-		return _("Telegram");
-	}
+public bool needSetup()
+{
+	return true;
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return new TelegramSetup(id, this, username);
-	}
+public bool singleInstance()
+{
+	return true;
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return new TelegramSetup(null, this);
-	}
+public bool useSystemAccounts()
+{
+	return false;
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return null;
-	}
+public string pluginID()
+{
+	return "telegram";
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		var widget = new TelegramForm();
-		widget.share.connect(() => {
+public string pluginName()
+{
+	return _("Telegram");
+}
+
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return new TelegramSetup(id, this, username);
+}
+
+public ServiceSetup? newSetup()
+{
+	return new TelegramSetup(null, this);
+}
+
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
+
+public ShareForm? shareWidget(string url)
+{
+	var widget = new TelegramForm();
+	widget.share.connect(() => {
 			tg_text = widget.getMessage();
 		});
-		return widget;
-	}
+	return widget;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Twitter/TwitterAPI.vala 2.7.1-1/plugins/share/Twitter/TwitterAPI.vala
--- 2.6.1-1/plugins/share/Twitter/TwitterAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Twitter/TwitterAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -14,283 +14,283 @@
 //	along with FeedReader.  If not, see <http://www.gnu.org/licenses/>.
 
 namespace FeedReader.TwitterSecrets {
-	const string base_uri			= "https://api.twitter.com/";
-	const string key				= "hqScCfRLj5ImAtwypRKhbVpXo";
-	const string secret				= "wydD2zd6mgBUnlrdbqNqS0U0dJCWBJ9X0cqtdErk8Hn7aeperP";
-	const string callback			= "feedreader://twitter";
+const string base_uri                   = "https://api.twitter.com/";
+const string key                                = "hqScCfRLj5ImAtwypRKhbVpXo";
+const string secret                             = "wydD2zd6mgBUnlrdbqNqS0U0dJCWBJ9X0cqtdErk8Hn7aeperP";
+const string callback                   = "feedreader://twitter";
 }
 
 public class FeedReader.TwitterAPI : ShareAccountInterface, Peas.ExtensionBase {
 
-	private Rest.OAuthProxy m_oauthObject;
-	private string m_tweet;
-	private int m_urlLength = 0;
+private Rest.OAuthProxy m_oauthObject;
+private string m_tweet;
+private int m_urlLength = 0;
 
-	public TwitterAPI()
-	{
-
-	}
+public TwitterAPI()
+{
 
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-	{
+}
 
-	}
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-	public string getRequestToken()
-	{
-		Logger.debug("TwitterAPI: get request token");
+}
 
-		m_oauthObject = new Rest.OAuthProxy (
-			TwitterSecrets.key,
-			TwitterSecrets.secret,
-			"https://api.twitter.com/",
-			false);
+public string getRequestToken()
+{
+	Logger.debug("TwitterAPI: get request token");
 
-		try
-		{
-			m_oauthObject.request_token("oauth/request_token", TwitterSecrets.callback);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("TwitterAPI.getRequestToken: %s".printf(e.message));
-		}
+	m_oauthObject = new Rest.OAuthProxy (
+		TwitterSecrets.key,
+		TwitterSecrets.secret,
+		"https://api.twitter.com/",
+		false);
 
-		return m_oauthObject.get_token();
+	try
+	{
+		m_oauthObject.request_token("oauth/request_token", TwitterSecrets.callback);
 	}
-
-	public bool getAccessToken(string id, string verifier)
+	catch(GLib.Error e)
 	{
-		try
-		{
-			m_oauthObject.access_token("oauth/access_token", verifier);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("TwitterAPI.getAccessToken: %s".printf(e.message));
-		}
-
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
-		string token = m_oauthObject.get_token();
-		string secret = m_oauthObject.get_token_secret();
-		settings.set_string("oauth-access-token", token);
-		settings.set_string("oauth-access-token-secret", secret);
-
-		var call = m_oauthObject.new_call();
-		call.set_function("1.1/account/verify_credentials.json");
-		call.set_method("GET");
-		call.add_param ("include_entities", "false");
-		call.add_param ("skip_status", "true");
-		call.add_param ("include_email", "true");
-
-		try
-		{
-			call.run();
-		}
-		catch(Error e)
-		{
-			Logger.error(e.message);
-		}
-
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(call.get_payload());
-		}
-		catch(Error e)
-		{
-			Logger.error("Could not load response to Message from twitter");
-			Logger.error(e.message);
-		}
-
-		var root_object = parser.get_root().get_object();
-
-		if(root_object.has_member("screen_name"))
-		{
-			string screenName = "@" + root_object.get_string_member("screen_name");
-			settings.set_string("username", screenName);
-		}
-		else
-		{
-			settings.set_string("username", root_object.get_string_member("name"));
-		}
-
-
-
-		var array = Settings.share("twitter").get_strv("account-ids");
-		array += id;
-		Settings.share("twitter").set_strv("account-ids", array);
-
-		return true;
+		Logger.error("TwitterAPI.getRequestToken: %s".printf(e.message));
 	}
 
+	return m_oauthObject.get_token();
+}
 
-	public bool addBookmark(string id, string url, bool system)
+public bool getAccessToken(string id, string verifier)
+{
+	try
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
-		string token = settings.get_string("oauth-access-token");
-		string secret = settings.get_string("oauth-access-token-secret");
-
-		var oauthObject = new Rest.OAuthProxy.with_token (
-			TwitterSecrets.key,
-			TwitterSecrets.secret,
-			token,
-			secret,
-			"https://api.twitter.com/",
-			false);
-
-		var call = oauthObject.new_call();
-		call.set_function("1.1/statuses/update.json");
-		call.set_method("POST");
-		call.add_param ("status", m_tweet.replace("$URL", url));
-
-		try
-		{
-			call.run();
-		}
-		catch(Error e)
-		{
-			Logger.error(e.message);
-			return false;
-		}
-
-		return true;
+		m_oauthObject.access_token("oauth/access_token", verifier);
 	}
-
-	public bool logout(string id)
+	catch(GLib.Error e)
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
-		var keys = settings.list_keys();
-		foreach(string key in keys)
-		{
-			settings.reset(key);
-		}
+		Logger.error("TwitterAPI.getAccessToken: %s".printf(e.message));
+	}
 
-		var array = Settings.share("twitter").get_strv("account-ids");
-		string[] array2 = {};
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+	string token = m_oauthObject.get_token();
+	string secret = m_oauthObject.get_token_secret();
+	settings.set_string("oauth-access-token", token);
+	settings.set_string("oauth-access-token-secret", secret);
 
-		foreach(string i in array)
-		{
-			if(i != id)
-				array2 += i;
-		}
-		Settings.share("twitter").set_strv("account-ids", array2);
-		deleteAccount(id);
+	var call = m_oauthObject.new_call();
+	call.set_function("1.1/account/verify_credentials.json");
+	call.set_method("GET");
+	call.add_param ("include_entities", "false");
+	call.add_param ("skip_status", "true");
+	call.add_param ("include_email", "true");
 
-		return true;
-	}
-
-	public string getURL(string token)
+	try
 	{
-		return	TwitterSecrets.base_uri
-				+ "oauth/authenticate"
-				+ "?oauth_token=" + token;
+		call.run();
 	}
-
-	public string getIconName()
+	catch(Error e)
 	{
-		return "feed-share-twitter";
+		Logger.error(e.message);
 	}
 
-	public string getUsername(string id)
+	var parser = new Json.Parser();
+	try
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
-		return settings.get_string("username");
+		parser.load_from_data(call.get_payload());
 	}
-
-	public bool needSetup()
+	catch(Error e)
 	{
-		return true;
+		Logger.error("Could not load response to Message from twitter");
+		Logger.error(e.message);
 	}
 
-	public bool singleInstance()
-	{
-		return false;
-	}
+	var root_object = parser.get_root().get_object();
 
-	public bool useSystemAccounts()
+	if(root_object.has_member("screen_name"))
 	{
-		return false;
+		string screenName = "@" + root_object.get_string_member("screen_name");
+		settings.set_string("username", screenName);
 	}
-
-	public string pluginID()
+	else
 	{
-		return "twitter";
+		settings.set_string("username", root_object.get_string_member("name"));
 	}
 
-	public string pluginName()
+
+
+	var array = Settings.share("twitter").get_strv("account-ids");
+	array += id;
+	Settings.share("twitter").set_strv("account-ids", array);
+
+	return true;
+}
+
+
+public bool addBookmark(string id, string url, bool system)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+	string token = settings.get_string("oauth-access-token");
+	string secret = settings.get_string("oauth-access-token-secret");
+
+	var oauthObject = new Rest.OAuthProxy.with_token (
+		TwitterSecrets.key,
+		TwitterSecrets.secret,
+		token,
+		secret,
+		"https://api.twitter.com/",
+		false);
+
+	var call = oauthObject.new_call();
+	call.set_function("1.1/statuses/update.json");
+	call.set_method("POST");
+	call.add_param ("status", m_tweet.replace("$URL", url));
+
+	try
 	{
-		return "Twitter";
+		call.run();
 	}
-
-	public ServiceSetup? newSetup_withID(string id, string username)
+	catch(Error e)
 	{
-		return new TwitterSetup(id, this, username);
+		Logger.error(e.message);
+		return false;
 	}
 
-	public ServiceSetup? newSetup()
+	return true;
+}
+
+public bool logout(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+	var keys = settings.list_keys();
+	foreach(string key in keys)
 	{
-		return new TwitterSetup(null, this);
+		settings.reset(key);
 	}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
+	var array = Settings.share("twitter").get_strv("account-ids");
+	string[] array2 = {};
+
+	foreach(string i in array)
 	{
-		return null;
+		if(i != id)
+			array2 += i;
 	}
+	Settings.share("twitter").set_strv("account-ids", array2);
+	deleteAccount(id);
 
-	public ShareForm? shareWidget(string url)
-	{
-		var widget = new TwitterForm(url);
+	return true;
+}
+
+public string getURL(string token)
+{
+	return TwitterSecrets.base_uri
+	       + "oauth/authenticate"
+	       + "?oauth_token=" + token;
+}
+
+public string getIconName()
+{
+	return "feed-share-twitter";
+}
+
+public string getUsername(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+	return settings.get_string("username");
+}
+
+public bool needSetup()
+{
+	return true;
+}
+
+public bool singleInstance()
+{
+	return false;
+}
+
+public bool useSystemAccounts()
+{
+	return false;
+}
+
+public string pluginID()
+{
+	return "twitter";
+}
+
+public string pluginName()
+{
+	return "Twitter";
+}
 
-		widget.setAPI.begin(this, (obj, res) => {
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return new TwitterSetup(id, this, username);
+}
+
+public ServiceSetup? newSetup()
+{
+	return new TwitterSetup(null, this);
+}
+
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
+
+public ShareForm? shareWidget(string url)
+{
+	var widget = new TwitterForm(url);
+
+	widget.setAPI.begin(this, (obj, res) => {
 			widget.setAPI.end(res);
 		});
-		widget.share.connect(() => {
+	widget.share.connect(() => {
 			m_tweet = widget.getTweet();
 		});
-		return widget;
-	}
+	return widget;
+}
 
-	public int getUrlLength()
-	{
-		if(m_urlLength > 0)
-			return m_urlLength;
+public int getUrlLength()
+{
+	if(m_urlLength > 0)
+		return m_urlLength;
 
-		var array = Settings.share("twitter").get_strv("account-ids");
-		string id = array[0];
-
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
-		string token = settings.get_string("oauth-access-token");
-		string secret = settings.get_string("oauth-access-token-secret");
-
-		var oauthObject = new Rest.OAuthProxy.with_token (
-			TwitterSecrets.key,
-			TwitterSecrets.secret,
-			token,
-			secret,
-			"https://api.twitter.com/",
-			false);
-
-		var call = oauthObject.new_call();
-		call.set_function("1.1/help/configuration.json");
-		call.set_method("GET");
-
-		try
-		{
-			call.run();
-		}
-		catch(Error e){}
-
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(call.get_payload());
-		}
-		catch(Error e){}
+	var array = Settings.share("twitter").get_strv("account-ids");
+	string id = array[0];
 
-		var root_object = parser.get_root().get_object();
-		m_urlLength = (int)root_object.get_int_member("short_url_length");
-		return m_urlLength;
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/twitter/%s/".printf(id));
+	string token = settings.get_string("oauth-access-token");
+	string secret = settings.get_string("oauth-access-token-secret");
+
+	var oauthObject = new Rest.OAuthProxy.with_token (
+		TwitterSecrets.key,
+		TwitterSecrets.secret,
+		token,
+		secret,
+		"https://api.twitter.com/",
+		false);
+
+	var call = oauthObject.new_call();
+	call.set_function("1.1/help/configuration.json");
+	call.set_method("GET");
+
+	try
+	{
+		call.run();
 	}
+	catch(Error e) {}
+
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(call.get_payload());
+	}
+	catch(Error e) {}
+
+	var root_object = parser.get_root().get_object();
+	m_urlLength = (int)root_object.get_int_member("short_url_length");
+	return m_urlLength;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Twitter/TwitterForm.vala 2.7.1-1/plugins/share/Twitter/TwitterForm.vala
--- 2.6.1-1/plugins/share/Twitter/TwitterForm.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Twitter/TwitterForm.vala	2019-02-01 19:30:50.000000000 +0000
@@ -16,122 +16,122 @@
 
 public class FeedReader.TwitterForm : ShareForm {
 
-	private Gtk.TextView m_textView;
-	private int m_urlLength = 0;
-	private string m_url;
-	private Gtk.Stack m_stack;
-	private Gtk.Label m_countLabel;
+private Gtk.TextView m_textView;
+private int m_urlLength = 0;
+private string m_url;
+private Gtk.Stack m_stack;
+private Gtk.Label m_countLabel;
+
+public TwitterForm(string url)
+{
+	m_url = url;
+	m_stack = new Gtk.Stack();
+	string body = _("Hey,\n\nCheck out this interesting article I just read: $URL");
+
+	m_textView = new Gtk.TextView();
+	m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
+	m_textView.buffer.text = body;
+	m_textView.border_width = 2;
+	m_textView.get_style_context().add_class("h3");
+
+	var scrolled = new Gtk.ScrolledWindow(null, null);
+	scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
+	scrolled.add(m_textView);
+
+	int margin = 5;
+	m_textView.left_margin = margin;
+	m_textView.right_margin = margin;
+	m_textView.top_margin = margin;
+	m_textView.bottom_margin = margin;
+
+	var limitLabel = new Gtk.Label(_("Limit: "));
+	limitLabel.set_alignment(0.0f, 0.5f);
+	limitLabel.get_style_context().add_class("h3");
+
+	m_countLabel = new Gtk.Label("");
+	m_countLabel.set_alignment(0.0f, 0.5f);
+	m_countLabel.get_style_context().add_class("h3");
+	var spinner = new Gtk.Spinner();
 
-	public TwitterForm(string url)
-	{
-		m_url = url;
-		m_stack = new Gtk.Stack();
-		string body = _("Hey,\n\nCheck out this interesting article I just read: $URL");
-
-		m_textView = new Gtk.TextView();
-		m_textView.set_wrap_mode(Gtk.WrapMode.WORD);
-		m_textView.buffer.text = body;
-		m_textView.border_width = 2;
-		m_textView.get_style_context().add_class("h3");
-
-		var scrolled = new Gtk.ScrolledWindow(null, null);
-		scrolled.get_style_context().add_class(Gtk.STYLE_CLASS_FRAME);
-		scrolled.add(m_textView);
-
-		int margin = 5;
-		m_textView.left_margin = margin;
-		m_textView.right_margin = margin;
-		m_textView.top_margin = margin;
-		m_textView.bottom_margin = margin;
-
-		var limitLabel = new Gtk.Label(_("Limit: "));
-		limitLabel.set_alignment(0.0f, 0.5f);
-		limitLabel.get_style_context().add_class("h3");
-
-		m_countLabel = new Gtk.Label("");
-		m_countLabel.set_alignment(0.0f, 0.5f);
-		m_countLabel.get_style_context().add_class("h3");
-		var spinner = new Gtk.Spinner();
-
-		m_stack.add_named(m_countLabel, "label");
-		m_stack.add_named(spinner, "spinner");
+	m_stack.add_named(m_countLabel, "label");
+	m_stack.add_named(spinner, "spinner");
 
-		m_textView.buffer.changed.connect(() => {
+	m_textView.buffer.changed.connect(() => {
 			updateCount();
 		});
 
-		var button = new Gtk.Button.with_label(_("Tweet"));
-		button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-		button.clicked.connect(() => { share(); });
-
-		var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-		box.pack_start(limitLabel, false, false, 0);
-		box.pack_start(m_stack, false, false, 0);
-		box.pack_end(button, false, false, 0);
-
-		var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
-		backButton.set_focus_on_click(false);
-		backButton.set_relief(Gtk.ReliefStyle.NONE);
-		backButton.halign = Gtk.Align.START;
-		backButton.clicked.connect(() => {
+	var button = new Gtk.Button.with_label(_("Tweet"));
+	button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+	button.clicked.connect(() => { share(); });
+
+	var box = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+	box.pack_start(limitLabel, false, false, 0);
+	box.pack_start(m_stack, false, false, 0);
+	box.pack_end(button, false, false, 0);
+
+	var backButton = new Gtk.Button.from_icon_name("go-previous-symbolic");
+	backButton.set_focus_on_click(false);
+	backButton.set_relief(Gtk.ReliefStyle.NONE);
+	backButton.halign = Gtk.Align.START;
+	backButton.clicked.connect(() => {
 			goBack();
 		});
 
-		var headline = new Gtk.Label(_("Tweet to Followers"));
-		headline.get_style_context().add_class("h2");
-		headline.set_alignment(0.4f, 0.5f);
-		var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
-		box2.pack_start(backButton, false, false, 0);
-		box2.pack_start(headline, true, true, 0);
-
-		this.pack_start(box2, false, false, 0);
-		this.pack_start(scrolled);
-		this.pack_end(box, false, false);
-		this.orientation = Gtk.Orientation.VERTICAL;
-		this.spacing = 5;
-		this.margin = 10;
-		this.show_all();
+	var headline = new Gtk.Label(_("Tweet to Followers"));
+	headline.get_style_context().add_class("h2");
+	headline.set_alignment(0.4f, 0.5f);
+	var box2 = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0);
+	box2.pack_start(backButton, false, false, 0);
+	box2.pack_start(headline, true, true, 0);
+
+	this.pack_start(box2, false, false, 0);
+	this.pack_start(scrolled);
+	this.pack_end(box, false, false);
+	this.orientation = Gtk.Orientation.VERTICAL;
+	this.spacing = 5;
+	this.margin = 10;
+	this.show_all();
 
-		m_stack.set_visible_child_name("spinner");
-		spinner.start();
-	}
+	m_stack.set_visible_child_name("spinner");
+	spinner.start();
+}
 
-	public string getTweet()
-	{
-		return m_textView.buffer.text;
-	}
+public string getTweet()
+{
+	return m_textView.buffer.text;
+}
 
-	public async void setAPI(TwitterAPI api)
-	{
-		SourceFunc callback = setAPI.callback;
+public async void setAPI(TwitterAPI api)
+{
+	SourceFunc callback = setAPI.callback;
 
-		new GLib.Thread<void*>(null, () => {
+	new Thread<void*>(null, () => {
 			m_urlLength = api.getUrlLength();
 			Idle.add((owned) callback, GLib.Priority.HIGH_IDLE);
 			return null;
 		});
 
-		yield;
-		updateCount();
-		m_stack.set_visible_child_name("label");
-	}
+	yield;
+	updateCount();
+	m_stack.set_visible_child_name("label");
+}
 
-	private int calcLenght(string text)
+private int calcLenght(string text)
+{
+	if(text.contains("$URL"))
 	{
-		if(text.contains("$URL"))
-		{
-			if(m_url.length >= m_urlLength)
-				return (text.length-3) + m_urlLength;
-			else
-				return (text.length-3) + m_url.length;
-		}
-
-		return text.length;
+		if(m_url.length >= m_urlLength)
+			return (text.length-3) + m_urlLength;
+		else
+			return (text.length-3) + m_url.length;
 	}
 
-	private void updateCount()
-	{
-		m_countLabel.set_text(calcLenght(m_textView.buffer.text).to_string() + "/140");
-	}
+	return text.length;
+}
+
+private void updateCount()
+{
+	m_countLabel.set_text(calcLenght(m_textView.buffer.text).to_string() + "/140");
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Twitter/TwitterSetup.vala 2.7.1-1/plugins/share/Twitter/TwitterSetup.vala
--- 2.6.1-1/plugins/share/Twitter/TwitterSetup.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Twitter/TwitterSetup.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,83 +15,83 @@
 
 public class FeedReader.TwitterSetup : ServiceSetup {
 
-	private TwitterAPI m_api;
+private TwitterAPI m_api;
 
-	public TwitterSetup(string? id, TwitterAPI api, string username = "")
-	{
-		bool loggedIN = false;
-		if(username != "")
-			loggedIN = true;
+public TwitterSetup(string? id, TwitterAPI api, string username = "")
+{
+	bool loggedIN = false;
+	if(username != "")
+		loggedIN = true;
 
-		base("Twitter", "feed-share-twitter", loggedIN, username);
+	base("Twitter", "feed-share-twitter", loggedIN, username);
 
-		m_api = api;
+	m_api = api;
 
-		if(id != null)
-			m_id = id;
-	}
+	if(id != null)
+		m_id = id;
+}
 
 
-	public override void login()
+public override void login()
+{
+	string id = Share.get_default().generateNewID();
+	string requestToken = m_api.getRequestToken();
+	string url = m_api.getURL(requestToken);
+	m_spinner.start();
+	m_iconStack.set_visible_child_name("spinner");
+	try
 	{
-		string id = Share.get_default().generateNewID();
-		string requestToken = m_api.getRequestToken();
-		string url = m_api.getURL(requestToken);
-		m_spinner.start();
-		m_iconStack.set_visible_child_name("spinner");
-		try
-		{
-			Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
-		}
-		catch(GLib.Error e)
-		{
-
-		}
-
-		m_login_button.set_label(_("waiting"));
-		m_login_button.set_sensitive(false);
-		FeedReaderApp.get_default().callback.connect((content) => {
+		Gtk.show_uri_on_window(SettingsDialog.get_default(), url, Gdk.CURRENT_TIME);
+	}
+	catch(GLib.Error e)
+	{
+
+	}
+
+	m_login_button.set_label(_("waiting"));
+	m_login_button.set_sensitive(false);
+	FeedReaderApp.get_default().callback.connect((content) => {
 
 			if(content.has_prefix(TwitterSecrets.callback))
 			{
-				int token_start = content.index_of("token=")+6;
-				int token_end = content.index_of("&", token_start);
-				string token = content.substring(token_start, token_end-token_start);
-
-				int verifier_start = content.index_of("verifier=")+9;
-				string verifier = content.substring(verifier_start);
-
-				if(token == requestToken)
-				{
-					if(m_api.getAccessToken(id, verifier))
-					{
-						m_id = id;
-						m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
-						m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
-						m_isLoggedIN = true;
-						m_spinner.stop();
-						m_label.set_label(m_api.getUsername(id));
-						m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
-						m_login_button.clicked.disconnect(login);
-						m_login_button.clicked.connect(logout);
+			        int token_start = content.index_of("token=")+6;
+			        int token_end = content.index_of("&", token_start);
+			        string token = content.substring(token_start, token_end-token_start);
+
+			        int verifier_start = content.index_of("verifier=")+9;
+			        string verifier = content.substring(verifier_start);
+
+			        if(token == requestToken)
+			        {
+			                if(m_api.getAccessToken(id, verifier))
+			                {
+			                        m_id = id;
+			                        m_api.addAccount(id, m_api.pluginID(), m_api.getUsername(id), m_api.getIconName(), m_api.pluginName());
+			                        m_iconStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.SLIDE_LEFT);
+			                        m_isLoggedIN = true;
+			                        m_spinner.stop();
+			                        m_label.set_label(m_api.getUsername(id));
+			                        m_labelStack.set_visible_child_full("loggedIN", Gtk.StackTransitionType.CROSSFADE);
+			                        m_login_button.clicked.disconnect(login);
+			                        m_login_button.clicked.connect(logout);
 					}
-					else
-					{
-						m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+			                else
+			                {
+			                        m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
 					}
 				}
 
 			}
 		});
-	}
+}
 
-	public override void logout()
-	{
-		m_isLoggedIN = false;
-		m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-		m_labelStack.set_visible_child_name("loggedOUT");
-		m_api.logout(m_id);
-		removeRow();
-	}
+public override void logout()
+{
+	m_isLoggedIN = false;
+	m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+	m_labelStack.set_visible_child_name("loggedOUT");
+	m_api.logout(m_id);
+	removeRow();
+}
 
 }
diff -pruN 2.6.1-1/plugins/share/Wallabag/WallabagAPI.vala 2.7.1-1/plugins/share/Wallabag/WallabagAPI.vala
--- 2.6.1-1/plugins/share/Wallabag/WallabagAPI.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Wallabag/WallabagAPI.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,313 +15,313 @@
 
 public class FeedReader.WallabagAPI : ShareAccountInterface, Peas.ExtensionBase {
 
-	public WallabagAPI()
-	{
-
-	}
-
-	public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
-	{
-
-	}
+public WallabagAPI()
+{
 
-	public bool getAccessToken(string id, string username, string password, string clientID, string clientSecret, string baseURL)
-	{
-		Logger.debug("WallabagAPI getAccessToken");
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message = "grant_type=password"
-		 				+ "&client_id=" + clientID
-						+ "&client_secret=" + clientSecret
-						+ "&username=" + GLib.Uri.escape_string(username)
-						+ "&password=" + GLib.Uri.escape_string(password);
+}
 
+public void setupSystemAccounts(Gee.List<ShareAccount> accounts)
+{
 
-		string url = baseURL + "oauth/v2/token";
-		var message_soup = new Soup.Message("POST", url);
-		message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-		session.send_message(message_soup);
+}
 
-		if((string)message_soup.response_body.flatten().data == null
-		|| (string)message_soup.response_body.flatten().data == "")
-		{
-			Logger.error("WallabagAPI - getAccessToken: no response");
-			Logger.error(url);
-			Logger.error(message);
-			return false;
-		}
+public bool getAccessToken(string id, string username, string password, string clientID, string clientSecret, string baseURL)
+{
+	Logger.debug("WallabagAPI getAccessToken");
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message = "grant_type=password"
+	                 + "&client_id=" + clientID
+	                 + "&client_secret=" + clientSecret
+	                 + "&username=" + GLib.Uri.escape_string(username)
+	                 + "&password=" + GLib.Uri.escape_string(password);
+
+
+	string url = baseURL + "oauth/v2/token";
+	var message_soup = new Soup.Message("POST", url);
+	message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+	session.send_message(message_soup);
+
+	if((string)message_soup.response_body.flatten().data == null
+	   || (string)message_soup.response_body.flatten().data == "")
+	{
+		Logger.error("WallabagAPI - getAccessToken: no response");
+		Logger.error(url);
+		Logger.error(message);
+		return false;
+	}
 
-		string response = (string)message_soup.response_body.flatten().data;
-		Logger.debug(response);
+	string response = (string)message_soup.response_body.flatten().data;
+	Logger.debug(response);
 
-		var parser = new Json.Parser();
-		try
-		{
-			parser.load_from_data(response);
-		}
-		catch (Error e)
-		{
-			Logger.error("Could not load response to Message from Wallabag");
-			Logger.error(e.message);
-			return false;
-		}
+	var parser = new Json.Parser();
+	try
+	{
+		parser.load_from_data(response);
+	}
+	catch (Error e)
+	{
+		Logger.error("Could not load response to Message from Wallabag");
+		Logger.error(e.message);
+		return false;
+	}
 
-		var root_node = parser.get_root();
-		var root_object = root_node.get_object();
+	var root_node = parser.get_root();
+	var root_object = root_node.get_object();
 
-		if(!root_object.has_member("access_token"))
-		{
-			Logger.error("WallabagAPI.getAccessToken: no member access_token in response");
-			return false;
-		}
-		string accessToken = root_object.get_string_member("access_token");
+	if(!root_object.has_member("access_token"))
+	{
+		Logger.error("WallabagAPI.getAccessToken: no member access_token in response");
+		return false;
+	}
+	string accessToken = root_object.get_string_member("access_token");
 
 
-		int64 now = (new DateTime.now_local()).to_unix();
-		if(!root_object.has_member("expires_in"))
-		{
-			Logger.error("WallabagAPI.getAccessToken: no member expires_in in response");
-			return false;
-		}
-		int64 expires = root_object.get_int_member("expires_in");
-		//string refreshToken = root_object.get_string_member("refresh_token");
+	int64 now = (new DateTime.now_local()).to_unix();
+	if(!root_object.has_member("expires_in"))
+	{
+		Logger.error("WallabagAPI.getAccessToken: no member expires_in in response");
+		return false;
+	}
+	int64 expires = root_object.get_int_member("expires_in");
+	//string refreshToken = root_object.get_string_member("refresh_token");
 
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-		settings.set_string("oauth-access-token", accessToken);
-		settings.set_string("username", username);
-		settings.set_int("access-token-expires", (int)(now + expires));
-		settings.set_string("url", baseURL);
-		settings.set_string("client-id", clientID);
-		settings.set_string("client-secret", clientSecret);
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+	settings.set_string("oauth-access-token", accessToken);
+	settings.set_string("username", username);
+	settings.set_int("access-token-expires", (int)(now + expires));
+	settings.set_string("url", baseURL);
+	settings.set_string("client-id", clientID);
+	settings.set_string("client-secret", clientSecret);
 
 
-		var array = Settings.share("wallabag").get_strv("account-ids");
-		foreach(string i in array)
+	var array = Settings.share("wallabag").get_strv("account-ids");
+	foreach(string i in array)
+	{
+		if(i == id)
 		{
-			if(i == id)
-			{
-				Logger.warning("WallabagAPI - getAccessToken: id already part of array. Returning");
-				return true;
-			}
+			Logger.warning("WallabagAPI - getAccessToken: id already part of array. Returning");
+			return true;
 		}
-		array += id;
-		Settings.share("wallabag").set_strv("account-ids", array);
+	}
+	array += id;
+	Settings.share("wallabag").set_strv("account-ids", array);
 
 
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
-										"username", Secret.SchemaAttributeType.STRING,
-										"id", Secret.SchemaAttributeType.STRING);
-
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["username"] = username;
-		attributes["id"] = id;
-		try
-		{
-			Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Wallabag login", password, null);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error("WallabagAPI - getAccessToken: " + e.message);
-		}
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+	                                  "username", Secret.SchemaAttributeType.STRING,
+	                                  "id", Secret.SchemaAttributeType.STRING);
 
-		return true;
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["username"] = username;
+	attributes["id"] = id;
+	try
+	{
+		Secret.password_storev_sync(pwSchema, attributes, Secret.COLLECTION_DEFAULT, "Feedreader: Wallabag login", password, null);
 	}
-
-
-	public bool addBookmark(string id, string url, bool system)
+	catch(GLib.Error e)
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-
-		Logger.debug("WallabagAPI - addBookmark: " + url);
-		if(!accessTokenValid(id))
-		{
-			string username = getUsername(id);
-			string password = getPasswd(id);
-			string clientID = settings.get_string("client-id");
-			string clientSecret = settings.get_string("client-secret");
-			string baseURL = settings.get_string("url");
+		Logger.error("WallabagAPI - getAccessToken: " + e.message);
+	}
 
-			getAccessToken(id, username, password, clientID, clientSecret, baseURL);
-		}
+	return true;
+}
 
-		Logger.debug("WallabagAPI - addBookmark: token still valid");
 
-		var session = new Soup.Session();
-		session.user_agent = Constants.USER_AGENT;
-		string message = "url=" + GLib.Uri.escape_string(url);
+public bool addBookmark(string id, string url, bool system)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+
+	Logger.debug("WallabagAPI - addBookmark: " + url);
+	if(!accessTokenValid(id))
+	{
+		string username = getUsername(id);
+		string password = getPasswd(id);
+		string clientID = settings.get_string("client-id");
+		string clientSecret = settings.get_string("client-secret");
 		string baseURL = settings.get_string("url");
 
-		var message_soup = new Soup.Message("POST", baseURL + "api/entries.json");
-		message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
-		message_soup.request_headers.append("Authorization", "Bearer " + settings.get_string("oauth-access-token"));
-		session.send_message(message_soup);
-
-		if((string)message_soup.response_body.flatten().data == null
-		|| (string)message_soup.response_body.flatten().data == "")
-		{
-			Logger.error("WallabagAPI - addBookmark: no response");
-			Logger.error(url);
-			Logger.error(message);
-			return false;
-		}
-
-		return true;
+		getAccessToken(id, username, password, clientID, clientSecret, baseURL);
 	}
 
-	public bool logout(string id)
-	{
-		Logger.debug("WallabagAPI - logout");
-		deletePassword(id);
+	Logger.debug("WallabagAPI - addBookmark: token still valid");
 
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-		var keys = settings.list_keys();
-		foreach(string key in keys)
-		{
-			settings.reset(key);
-		}
+	var session = new Soup.Session();
+	session.user_agent = Constants.USER_AGENT;
+	string message = "url=" + GLib.Uri.escape_string(url);
+	string baseURL = settings.get_string("url");
 
-		var array = Settings.share("wallabag").get_strv("account-ids");
-		string[] array2 = {};
+	var message_soup = new Soup.Message("POST", baseURL + "api/entries.json");
+	message_soup.set_request("application/x-www-form-urlencoded; charset=UTF8", Soup.MemoryUse.COPY, message.data);
+	message_soup.request_headers.append("Authorization", "Bearer " + settings.get_string("oauth-access-token"));
+	session.send_message(message_soup);
 
-		foreach(string i in array)
-		{
-			if(i != id)
-				array2 += i;
-		}
-		Settings.share("wallabag").set_strv("account-ids", array2);
-		deleteAccount(id);
-
-		return true;
+	if((string)message_soup.response_body.flatten().data == null
+	   || (string)message_soup.response_body.flatten().data == "")
+	{
+		Logger.error("WallabagAPI - addBookmark: no response");
+		Logger.error(url);
+		Logger.error(message);
+		return false;
 	}
 
-	private bool accessTokenValid(string id)
-	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-		var now = new DateTime.now_local();
-		int expires = settings.get_int("access-token-expires");
+	return true;
+}
 
-		if((int)now.to_unix() >  expires)
-		{
-			Logger.warning("WallabagAPI: access token expired");
-			return false;
-		}
+public bool logout(string id)
+{
+	Logger.debug("WallabagAPI - logout");
+	deletePassword(id);
 
-		return true;
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+	var keys = settings.list_keys();
+	foreach(string key in keys)
+	{
+		settings.reset(key);
 	}
 
-	public string getIconName()
+	var array = Settings.share("wallabag").get_strv("account-ids");
+	string[] array2 = {};
+
+	foreach(string i in array)
 	{
-		return "feed-share-wallabag";
+		if(i != id)
+			array2 += i;
 	}
+	Settings.share("wallabag").set_strv("account-ids", array2);
+	deleteAccount(id);
 
-	public string getUsername(string id)
+	return true;
+}
+
+private bool accessTokenValid(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+	var now = new DateTime.now_local();
+	int expires = settings.get_int("access-token-expires");
+
+	if((int)now.to_unix() >  expires)
 	{
-		var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
-		return settings.get_string("username");
+		Logger.warning("WallabagAPI: access token expired");
+		return false;
 	}
 
-	public string getPasswd(string id)
-	{
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
-										"username", Secret.SchemaAttributeType.STRING,
-										"id", Secret.SchemaAttributeType.STRING);
+	return true;
+}
+
+public string getIconName()
+{
+	return "feed-share-wallabag";
+}
 
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["username"] = getUsername(id);
-		attributes["id"] = id;
+public string getUsername(string id)
+{
+	var settings = new GLib.Settings.with_path("org.gnome.feedreader.share.account", "/org/gnome/feedreader/share/wallabag/%s/".printf(id));
+	return settings.get_string("username");
+}
 
-		string passwd = "";
+public string getPasswd(string id)
+{
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+	                                  "username", Secret.SchemaAttributeType.STRING,
+	                                  "id", Secret.SchemaAttributeType.STRING);
 
-		try
-		{
-			passwd = Secret.password_lookupv_sync(pwSchema, attributes, null);
-		}
-		catch(GLib.Error e)
-		{
-			Logger.error(e.message);
-		}
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["username"] = getUsername(id);
+	attributes["id"] = id;
 
-		if(passwd == null)
-		{
-			return "";
-		}
+	string passwd = "";
 
-		return passwd;
+	try
+	{
+		passwd = Secret.password_lookupv_sync(pwSchema, attributes, null);
+	}
+	catch(GLib.Error e)
+	{
+		Logger.error(e.message);
 	}
 
-	private void deletePassword(string id)
+	if(passwd == null)
 	{
-		bool removed = false;
-		var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
-										"username", Secret.SchemaAttributeType.STRING,
-										"id", Secret.SchemaAttributeType.STRING);
+		return "";
+	}
 
-		var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
-		attributes["username"] = getUsername(id);
-		attributes["id"] = id;
+	return passwd;
+}
 
-		Logger.debug(getUsername(id));
-		Logger.debug(id);
+private void deletePassword(string id)
+{
+	bool removed = false;
+	var pwSchema = new Secret.Schema ("org.gnome.feedreader.wallabag.password", Secret.SchemaFlags.NONE,
+	                                  "username", Secret.SchemaAttributeType.STRING,
+	                                  "id", Secret.SchemaAttributeType.STRING);
+
+	var attributes = new GLib.HashTable<string,string>(str_hash, str_equal);
+	attributes["username"] = getUsername(id);
+	attributes["id"] = id;
 
-		Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
+	Logger.debug(getUsername(id));
+	Logger.debug(id);
+
+	Secret.password_clearv.begin(pwSchema, attributes, null, (obj, async_res) => {
 			try
 			{
-				removed = Secret.password_clearv.end(async_res);
+			        removed = Secret.password_clearv.end(async_res);
 
-				if(!removed)
+			        if(!removed)
 					Logger.error(@"WallabagAPI: could not delete password of account $id");
 			}
 			catch(GLib.Error e)
 			{
-				Logger.error("WallabagAPI.deletePassword: %s".printf(e.message));
+			        Logger.error("WallabagAPI.deletePassword: %s".printf(e.message));
 			}
 		});
-	}
+}
 
-	public bool needSetup()
-	{
-		return true;
-	}
+public bool needSetup()
+{
+	return true;
+}
 
-	public bool singleInstance()
-	{
-		return false;
-	}
+public bool singleInstance()
+{
+	return false;
+}
 
-	public bool useSystemAccounts()
-	{
-		return false;
-	}
+public bool useSystemAccounts()
+{
+	return false;
+}
 
-	public string pluginID()
-	{
-		return "wallabag";
-	}
+public string pluginID()
+{
+	return "wallabag";
+}
 
-	public string pluginName()
-	{
-		return "wallabag";
-	}
+public string pluginName()
+{
+	return "wallabag";
+}
 
-	public ServiceSetup? newSetup_withID(string id, string username)
-	{
-		return new WallabagSetup(id, this, username);
-	}
+public ServiceSetup? newSetup_withID(string id, string username)
+{
+	return new WallabagSetup(id, this, username);
+}
 
-	public ServiceSetup? newSetup()
-	{
-		return new WallabagSetup(null, this);
-	}
+public ServiceSetup? newSetup()
+{
+	return new WallabagSetup(null, this);
+}
 
-	public ServiceSetup? newSystemAccount(string id, string username)
-	{
-		return null;
-	}
+public ServiceSetup? newSystemAccount(string id, string username)
+{
+	return null;
+}
 
-	public ShareForm? shareWidget(string url)
-	{
-		return null;
-	}
+public ShareForm? shareWidget(string url)
+{
+	return null;
+}
 }
 
 [ModuleInit]
diff -pruN 2.6.1-1/plugins/share/Wallabag/WallabagSetup.vala 2.7.1-1/plugins/share/Wallabag/WallabagSetup.vala
--- 2.6.1-1/plugins/share/Wallabag/WallabagSetup.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/plugins/share/Wallabag/WallabagSetup.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,194 +15,194 @@
 
 public class FeedReader.WallabagSetup : ServiceSetup {
 
-	private Gtk.Entry m_urlEntry;
-	private Gtk.Entry m_idEntry;
-	private Gtk.Entry m_secretEntry;
-	private Gtk.Entry m_userEntry;
-	private Gtk.Entry m_passEntry;
-	private Gtk.Revealer m_login_revealer;
-	private WallabagAPI m_api;
+private Gtk.Entry m_urlEntry;
+private Gtk.Entry m_idEntry;
+private Gtk.Entry m_secretEntry;
+private Gtk.Entry m_userEntry;
+private Gtk.Entry m_passEntry;
+private Gtk.Revealer m_login_revealer;
+private WallabagAPI m_api;
+
+public WallabagSetup(string? id, WallabagAPI api, string username = "")
+{
+	bool loggedIN = false;
+	if(username != "")
+		loggedIN = true;
+
+	base("wallabag", "feed-share-wallabag", loggedIN, username);
+
+	//------------------------------------------------
+	// XAuth revealer
+	//------------------------------------------------
+	var grid = new Gtk.Grid();
+	grid.set_column_spacing(10);
+	grid.set_row_spacing(10);
+	grid.set_valign(Gtk.Align.CENTER);
+	grid.set_halign(Gtk.Align.CENTER);
+	grid.margin_bottom = 10;
+	grid.margin_top = 5;
+
+	m_urlEntry = new Gtk.Entry();
+	m_idEntry = new Gtk.Entry();
+	m_secretEntry = new Gtk.Entry();
+	m_userEntry = new Gtk.Entry();
+	m_passEntry = new Gtk.Entry();
+	m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
+	m_passEntry.set_visibility(false);
 
-	public WallabagSetup(string? id, WallabagAPI api, string username = "")
-	{
-		bool loggedIN = false;
-		if(username != "")
-			loggedIN = true;
-
-		base("wallabag", "feed-share-wallabag", loggedIN, username);
-
-		//------------------------------------------------
-		// XAuth revealer
-		//------------------------------------------------
-		var grid = new Gtk.Grid();
-		grid.set_column_spacing(10);
-		grid.set_row_spacing(10);
-		grid.set_valign(Gtk.Align.CENTER);
-		grid.set_halign(Gtk.Align.CENTER);
-		grid.margin_bottom = 10;
-		grid.margin_top = 5;
-
-		m_urlEntry = new Gtk.Entry();
-		m_idEntry = new Gtk.Entry();
-		m_secretEntry = new Gtk.Entry();
-		m_userEntry = new Gtk.Entry();
-		m_passEntry = new Gtk.Entry();
-		m_passEntry.set_input_purpose(Gtk.InputPurpose.PASSWORD);
-		m_passEntry.set_visibility(false);
-
-		m_urlEntry.activate.connect(() => {
+	m_urlEntry.activate.connect(() => {
 			m_idEntry.grab_focus();
 		});
 
-		m_idEntry.activate.connect(() => {
+	m_idEntry.activate.connect(() => {
 			m_secretEntry.grab_focus();
 		});
 
-		m_secretEntry.activate.connect(() => {
+	m_secretEntry.activate.connect(() => {
 			m_userEntry.grab_focus();
 		});
 
-		m_userEntry.activate.connect(() => {
+	m_userEntry.activate.connect(() => {
 			m_passEntry.grab_focus();
 		});
 
-		m_passEntry.activate.connect(() => {
+	m_passEntry.activate.connect(() => {
 			login();
 		});
 
-		var urlLabel = new Gtk.Label(_("URL:"));
-		var idLabel = new Gtk.Label(_("Client ID:"));
-		var secretLabel = new Gtk.Label(_("Client Secret:"));
-		var userLabel = new Gtk.Label(_("Username:"));
-		var pwLabel = new Gtk.Label(_("Password:"));
-
-		urlLabel.set_alignment(1.0f, 0.5f);
-		idLabel.set_alignment(1.0f, 0.5f);
-		secretLabel.set_alignment(1.0f, 0.5f);
-		userLabel.set_alignment(1.0f, 0.5f);
-		pwLabel.set_alignment(1.0f, 0.5f);
-
-		grid.attach(urlLabel, 0, 0, 1, 1);
-		grid.attach(idLabel, 0, 1, 1, 1);
-		grid.attach(secretLabel, 0, 2, 1, 1);
-		grid.attach(userLabel, 0, 3, 1, 1);
-		grid.attach(pwLabel, 0, 4, 1, 1);
-		grid.attach(m_urlEntry, 1, 0, 1, 1);
-		grid.attach(m_idEntry, 1, 1, 1, 1);
-		grid.attach(m_secretEntry, 1, 2, 1, 1);
-		grid.attach(m_userEntry, 1, 3, 1, 1);
-		grid.attach(m_passEntry, 1, 4, 1, 1);
-
-		m_login_revealer = new Gtk.Revealer();
-		m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
-		m_login_revealer.add(grid);
-		//------------------------------------------------
+	var urlLabel = new Gtk.Label(_("URL:"));
+	var idLabel = new Gtk.Label(_("Client ID:"));
+	var secretLabel = new Gtk.Label(_("Client Secret:"));
+	var userLabel = new Gtk.Label(_("Username:"));
+	var pwLabel = new Gtk.Label(_("Password:"));
+
+	urlLabel.set_alignment(1.0f, 0.5f);
+	idLabel.set_alignment(1.0f, 0.5f);
+	secretLabel.set_alignment(1.0f, 0.5f);
+	userLabel.set_alignment(1.0f, 0.5f);
+	pwLabel.set_alignment(1.0f, 0.5f);
+
+	grid.attach(urlLabel, 0, 0, 1, 1);
+	grid.attach(idLabel, 0, 1, 1, 1);
+	grid.attach(secretLabel, 0, 2, 1, 1);
+	grid.attach(userLabel, 0, 3, 1, 1);
+	grid.attach(pwLabel, 0, 4, 1, 1);
+	grid.attach(m_urlEntry, 1, 0, 1, 1);
+	grid.attach(m_idEntry, 1, 1, 1, 1);
+	grid.attach(m_secretEntry, 1, 2, 1, 1);
+	grid.attach(m_userEntry, 1, 3, 1, 1);
+	grid.attach(m_passEntry, 1, 4, 1, 1);
+
+	m_login_revealer = new Gtk.Revealer();
+	m_login_revealer.set_transition_type(Gtk.RevealerTransitionType.SLIDE_DOWN);
+	m_login_revealer.add(grid);
+	//------------------------------------------------
 
-		m_seperator_box.pack_start(m_login_revealer, false, false, 0);
+	m_seperator_box.pack_start(m_login_revealer, false, false, 0);
 
-		m_api = api;
+	m_api = api;
 
-		if(id != null)
-			m_id = id;
-	}
+	if(id != null)
+		m_id = id;
+}
 
 
-	public override void login()
+public override void login()
+{
+	if(m_login_revealer.get_child_revealed())
 	{
-		if(m_login_revealer.get_child_revealed())
+		string id = Share.get_default().generateNewID();
+		string username = m_userEntry.get_text();
+		string password = m_passEntry.get_text();
+		string clientID = m_idEntry.get_text();
+		string clientSecret = m_secretEntry.get_text();
+		string baseURL = m_urlEntry.get_text();
+
+		// check each and every value
+		if(baseURL == null || baseURL == "")
 		{
-			string id = Share.get_default().generateNewID();
-			string username = m_userEntry.get_text();
-			string password = m_passEntry.get_text();
-			string clientID = m_idEntry.get_text();
-			string clientSecret = m_secretEntry.get_text();
-			string baseURL = m_urlEntry.get_text();
-
-			// check each and every value
-			if(baseURL == null || baseURL == "")
-			{
-				showInfoBar(_("Please fill in the URL."));
-				m_urlEntry.grab_focus();
-				return;
-			}
-			else if(GLib.Uri.parse_scheme(baseURL) == null)
-			{
-				showInfoBar(_("URL seems to not be valid."));
-				m_urlEntry.grab_focus();
-				return;
-			}
-
-			if(!baseURL.has_suffix("/"))
-				baseURL += "/";
-
-			if(clientID == null || clientID == "")
-			{
-				showInfoBar(_("Please fill in the clientID."));
-				m_idEntry.grab_focus();
-				return;
-			}
-
-			if(clientSecret == null || clientSecret == "")
-			{
-				showInfoBar(_("Please fill in the clientSecret."));
-				m_secretEntry.grab_focus();
-				return;
-			}
-
-			if(password == null || password == "")
-			{
-				showInfoBar(_("Please fill in the password."));
-				m_passEntry.grab_focus();
-				return;
-			}
-
-			if(username == null || username == "")
-			{
-				showInfoBar(_("Please fill in the username."));
-				m_userEntry.grab_focus();
-				return;
-			}
-
-			m_spinner.start();
-			m_iconStack.set_visible_child_name("spinner");
-
-			if(m_api.getAccessToken(id, username, password, clientID, clientSecret, baseURL))
-			{
-				m_id = id;
-				m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
-				m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-				m_login_revealer.set_reveal_child(false);
-				m_isLoggedIN = true;
-				m_iconStack.set_visible_child_name("loggedIN");
-				m_spinner.stop();
-				m_label.set_label(username);
-				m_labelStack.set_visible_child_name("loggedIN");
-				m_login_button.clicked.disconnect(login);
-				m_login_button.clicked.connect(logout);
-			}
-			else
-			{
-				m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-				showInfoBar(_("Something went wrong."));
-			}
+			showInfoBar(_("Please fill in the URL."));
+			m_urlEntry.grab_focus();
+			return;
+		}
+		else if(GLib.Uri.parse_scheme(baseURL) == null)
+		{
+			showInfoBar(_("URL seems to not be valid."));
+			m_urlEntry.grab_focus();
+			return;
+		}
+
+		if(!baseURL.has_suffix("/"))
+			baseURL += "/";
 
+		if(clientID == null || clientID == "")
+		{
+			showInfoBar(_("Please fill in the clientID."));
+			m_idEntry.grab_focus();
+			return;
+		}
+
+		if(clientSecret == null || clientSecret == "")
+		{
+			showInfoBar(_("Please fill in the clientSecret."));
+			m_secretEntry.grab_focus();
+			return;
+		}
+
+		if(password == null || password == "")
+		{
+			showInfoBar(_("Please fill in the password."));
+			m_passEntry.grab_focus();
+			return;
+		}
+
+		if(username == null || username == "")
+		{
+			showInfoBar(_("Please fill in the username."));
+			m_userEntry.grab_focus();
+			return;
+		}
+
+		m_spinner.start();
+		m_iconStack.set_visible_child_name("spinner");
+
+		if(m_api.getAccessToken(id, username, password, clientID, clientSecret, baseURL))
+		{
+			m_id = id;
+			m_api.addAccount(id, m_api.pluginID(), username, m_api.getIconName(), m_api.pluginName());
+			m_login_button.get_style_context().remove_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+			m_login_revealer.set_reveal_child(false);
+			m_isLoggedIN = true;
+			m_iconStack.set_visible_child_name("loggedIN");
+			m_spinner.stop();
+			m_label.set_label(username);
+			m_labelStack.set_visible_child_name("loggedIN");
+			m_login_button.clicked.disconnect(login);
+			m_login_button.clicked.connect(logout);
 		}
 		else
 		{
-			m_login_revealer.set_reveal_child(true);
-			m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-			m_urlEntry.grab_focus();
+			m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+			showInfoBar(_("Something went wrong."));
 		}
-	}
 
-	public override void logout()
+	}
+	else
 	{
-		Logger.debug("WallabagSetup: logout");
-		m_isLoggedIN = false;
-		m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
-		m_labelStack.set_visible_child_name("loggedOUT");
-		m_api.logout(m_id);
-		removeRow();
+		m_login_revealer.set_reveal_child(true);
+		m_login_button.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+		m_urlEntry.grab_focus();
 	}
+}
+
+public override void logout()
+{
+	Logger.debug("WallabagSetup: logout");
+	m_isLoggedIN = false;
+	m_iconStack.set_visible_child_full("button", Gtk.StackTransitionType.SLIDE_RIGHT);
+	m_labelStack.set_visible_child_name("loggedOUT");
+	m_api.logout(m_id);
+	removeRow();
+}
 
 }
diff -pruN 2.6.1-1/po/be.po 2.7.1-1/po/be.po
--- 2.6.1-1/po/be.po	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/po/be.po	2019-02-01 19:30:50.000000000 +0000
@@ -2,71 +2,80 @@ msgid ""
 msgstr ""
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-06 21:59+0200\n"
+"PO-Revision-Date: 2019-01-24 07:04+0000\n"
+"Last-Translator: Viktar Vauchkevich <victorenator@gmail.com>\n"
+"Language-Team: Belarusian <https://hosted.weblate.org/projects/feedreader/"
+"translations/be/>\n"
+"Language: be\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<="
+"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 3.4\n"
 
 #: Constants.vala.in:26
 msgid "Desktop Client for various RSS Services"
-msgstr ""
+msgstr "Кліент для розных RSS-сэрвісаў"
 
 #: Constants.vala.in:31
 msgid "translator-credits"
-msgstr ""
+msgstr "падзякі перакладчыкам"
 
 #: Constants.vala.in:36
 msgid "About"
-msgstr ""
+msgstr "Аб праграме"
 
 #: Constants.vala.in:37 src/Widgets/ColumnViewHeader.vala:101
 msgid "Settings"
-msgstr ""
+msgstr "Налады"
 
 #: Constants.vala.in:38
 msgid "Change Account"
-msgstr ""
+msgstr "Змяніць конт"
 
 #: Constants.vala.in:39 src/Widgets/ShortcutsWindow.vala:29
 msgid "Quit"
-msgstr ""
+msgstr "Выйсці"
 
 #: Constants.vala.in:40
 msgid "Report a Bug"
-msgstr ""
+msgstr "Паведаміць пра памылку"
 
 #: Constants.vala.in:41
 msgid "Bounties"
-msgstr ""
+msgstr "Шчадроты"
 
 #: Constants.vala.in:42
 msgid "Shortcuts"
-msgstr ""
+msgstr "Скароты"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:3
 msgid "FeedReader Autostart"
-msgstr ""
+msgstr "Аўтазапуск FeedReader"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:4
 #: data/org.gnome.FeedReader.desktop.in:4
 msgid "RSS Client"
-msgstr ""
+msgstr "RSS-кліент"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:6
 msgid "Categories=Network;Feed;"
-msgstr ""
+msgstr "Categories=Network;Feed;"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:8
 #: data/org.gnome.FeedReader.desktop.in:8
 msgid "org.gnome.FeedReader"
-msgstr ""
+msgstr "org.gnome.FeedReader"
 
 #: data/org.gnome.FeedReader.appdata.xml.in:6
 #: data/org.gnome.FeedReader.desktop.in:3 src/Widgets/MainWindow.vala:44
 msgid "FeedReader"
-msgstr ""
+msgstr "FeedReader"
 
 #: data/org.gnome.FeedReader.appdata.xml.in:7
 msgid "RSS client for various webservices"
-msgstr ""
+msgstr "RSS-кліент для розных вэб-сэрвісаў"
 
 #: data/org.gnome.FeedReader.appdata.xml.in:10
 msgid ""
diff -pruN 2.6.1-1/po/fi.po 2.7.1-1/po/fi.po
--- 2.6.1-1/po/fi.po	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/po/fi.po	2019-02-01 19:30:50.000000000 +0000
@@ -8,7 +8,7 @@ msgstr ""
 "Project-Id-Version: feedreader\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-06 21:59+0200\n"
-"PO-Revision-Date: 2018-08-27 19:37+0000\n"
+"PO-Revision-Date: 2018-12-07 16:08+0000\n"
 "Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>\n"
 "Language-Team: Finnish <https://hosted.weblate.org/projects/feedreader/"
 "translations/fi/>\n"
@@ -17,7 +17,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n != 1;\n"
-"X-Generator: Weblate 3.2-dev\n"
+"X-Generator: Weblate 3.4-dev\n"
 "X-Launchpad-Export-Date: 2016-01-13 05:53+0000\n"
 
 #: Constants.vala.in:26
@@ -57,9 +57,8 @@ msgid "Shortcuts"
 msgstr "Pikanäppäimet"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:3
-#, fuzzy
 msgid "FeedReader Autostart"
-msgstr "Syötteenlukija"
+msgstr "Syötteenlukijan automaatikäynnistys"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:4
 #: data/org.gnome.FeedReader.desktop.in:4
@@ -68,7 +67,7 @@ msgstr "RSS-sovellus"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:6
 msgid "Categories=Network;Feed;"
-msgstr ""
+msgstr "Categories=Network;Feed;"
 
 #: data/org.gnome.FeedReader-autostart.desktop.in:8
 #: data/org.gnome.FeedReader.desktop.in:8
@@ -89,6 +88,8 @@ msgid ""
 "FeedReader is a program designed to complement an already existing web-based "
 "RSS reader account."
 msgstr ""
+"Syötteenlukija on ohjelma, jonka tarkoitus on täydentää olemassa olevan, "
+"selainpohjaisen RSS-lukutilin käyttöä."
 
 #: data/org.gnome.FeedReader.appdata.xml.in:14
 msgid "Currently supported services:"
@@ -413,14 +414,14 @@ msgid "New articles"
 msgstr "Uudet artikkelit"
 
 #: src/Notification.vala:27
-#, fuzzy, c-format
+#, c-format
 msgid "There is 1 new article (%u unread)"
-msgstr "1 uusi artikkeli (%u lukematon)"
+msgstr "Yksi uusi artikkeli (lukemattomia %u)"
 
 #: src/Notification.vala:29
-#, fuzzy, c-format
+#, c-format
 msgid "There are %u new articles (%u unread)"
-msgstr "%u uutta artikkelia (%u lukematonta)"
+msgstr "%u uutta artikkelia (lukemattomia %u)"
 
 #: src/Share/ServiceSetup.vala:61
 msgid "Logout"
diff -pruN 2.6.1-1/po/fr.po 2.7.1-1/po/fr.po
--- 2.6.1-1/po/fr.po	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/po/fr.po	2019-02-01 19:30:50.000000000 +0000
@@ -13,8 +13,8 @@ msgstr ""
 "Project-Id-Version: FeedReader\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2018-05-06 21:59+0200\n"
-"PO-Revision-Date: 2018-11-16 21:07+0000\n"
-"Last-Translator: wellinkstein <guilbaud.jeremie@tutanota.com>\n"
+"PO-Revision-Date: 2019-01-21 21:20+0000\n"
+"Last-Translator: Nathan <bonnemainsnathan@gmail.com>\n"
 "Language-Team: French <https://hosted.weblate.org/projects/feedreader/"
 "translations/fr/>\n"
 "Language: fr\n"
@@ -22,7 +22,7 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n > 1;\n"
-"X-Generator: Weblate 3.3-dev\n"
+"X-Generator: Weblate 3.4-dev\n"
 
 #: Constants.vala.in:26
 msgid "Desktop Client for various RSS Services"
@@ -983,7 +983,6 @@ msgid "Toggle reading status of selected
 msgstr "Changer le statut de lecture de l’article sélectionné"
 
 #: src/Widgets/ShortcutsWindow.vala:65
-#, fuzzy
 msgid "Toggle marking of selected article"
 msgstr "Marquer l’article sélectionné comme non lu"
 
diff -pruN 2.6.1-1/src/ActionCache.vala 2.7.1-1/src/ActionCache.vala
--- 2.6.1-1/src/ActionCache.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/src/ActionCache.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,219 +15,225 @@
 
 public class FeedReader.ActionCache : GLib.Object {
 
-	// Similar to CachedActionManager this class collects all the actions done during a period of time
-	// to use that information at a later point of time
-	// however this class does not write the actions to the database
-	// this class is used cache the actions during a sync so the synced data can be updated accordingly afterwards
-	// this prevents articles that were marked as read after the sync began but before the data was written to the database
-	// to suddenly become unread again after the sync (and similar issues)
+// Similar to CachedActionManager this class collects all the actions done during a period of time
+// to use that information at a later point of time
+// however this class does not write the actions to the database
+// this class is used cache the actions during a sync so the synced data can be updated accordingly afterwards
+// this prevents articles that were marked as read after the sync began but before the data was written to the database
+// to suddenly become unread again after the sync (and similar issues)
+
+private Gee.List<CachedAction> m_list;
+
+private static ActionCache? m_cache = null;
+
+public static ActionCache get_default()
+{
+	if(m_cache == null)
+		m_cache = new ActionCache();
 
-	private Gee.List<CachedAction> m_list;
-
-	private static ActionCache? m_cache = null;
+	return m_cache;
+}
 
-	public static ActionCache get_default()
-	{
-		if(m_cache == null)
-			m_cache = new ActionCache();
+private ActionCache()
+{
+	m_list = new Gee.ArrayList<CachedAction>();
+}
 
-		return m_cache;
-	}
+public void markArticleRead(string id, ArticleStatus read)
+{
+	var cachedAction = CachedActions.MARK_READ;
+	if(read == ArticleStatus.UNREAD)
+		cachedAction = CachedActions.MARK_UNREAD;
 
-	private ActionCache()
-	{
-		m_list = new Gee.ArrayList<CachedAction>();
-	}
+	var action = new CachedAction(cachedAction, id, "");
+	addAction(action);
+}
 
-	public void markArticleRead(string id, ArticleStatus read)
-	{
-		var cachedAction = CachedActions.MARK_READ;
-		if(read == ArticleStatus.UNREAD)
-			cachedAction = CachedActions.MARK_UNREAD;
+public void markArticleStarred(string id, ArticleStatus marked)
+{
+	var cachedAction = CachedActions.MARK_STARRED;
+	if(marked == ArticleStatus.UNMARKED)
+		cachedAction = CachedActions.MARK_UNSTARRED;
 
-		var action = new CachedAction(cachedAction, id, "");
-		addAction(action);
-	}
+	var action = new CachedAction(cachedAction, id, "");
+	addAction(action);
+}
 
-	public void markArticleStarred(string id, ArticleStatus marked)
-	{
-		var cachedAction = CachedActions.MARK_STARRED;
-		if(marked == ArticleStatus.UNMARKED)
-			cachedAction = CachedActions.MARK_UNSTARRED;
+public void markFeedRead(string id)
+{
+	var action = new CachedAction(CachedActions.MARK_READ_FEED, id, "");
+	addAction(action);
+}
 
-		var action = new CachedAction(cachedAction, id, "");
-		addAction(action);
-	}
+public void markCategoryRead(string id)
+{
+	var action = new CachedAction(CachedActions.MARK_READ_CATEGORY, id, "");
+	addAction(action);
+}
 
-	public void markFeedRead(string id)
-	{
-		var action = new CachedAction(CachedActions.MARK_READ_FEED, id, "");
-		addAction(action);
-	}
+public void markAllRead()
+{
+	var action = new CachedAction(CachedActions.MARK_READ_ALL, "", "");
+	addAction(action);
+}
 
-	public void markCategoryRead(string id)
-	{
-		var action = new CachedAction(CachedActions.MARK_READ_CATEGORY, id, "");
-		addAction(action);
+private void addAction(CachedAction action)
+{
+	switch(action.getType())
+	{
+	case CachedActions.MARK_READ:
+	case CachedActions.MARK_UNREAD:
+	case CachedActions.MARK_STARRED:
+	case CachedActions.MARK_UNSTARRED:
+		removeOpposite(action);
+		break;
+
+	case CachedActions.MARK_READ_FEED:
+		removeForFeed(action.getID());
+		break;
+
+	case CachedActions.MARK_READ_CATEGORY:
+		removeForCategory(action.getID());
+		break;
+
+	case CachedActions.MARK_READ_ALL:
+		removeForALL();
+		break;
 	}
 
-	public void markAllRead()
-	{
-		var action = new CachedAction(CachedActions.MARK_READ_ALL, "", "");
-		addAction(action);
-	}
+	m_list.add(action);
+}
 
-	private void addAction(CachedAction action)
+private void removeOpposite(CachedAction action)
+{
+	foreach(CachedAction a in m_list)
 	{
-		switch(action.getType())
+		if(a.getID() == action.getID()
+		   && a.getType() == action.opposite())
 		{
-			case CachedActions.MARK_READ:
-			case CachedActions.MARK_UNREAD:
-			case CachedActions.MARK_STARRED:
-			case CachedActions.MARK_UNSTARRED:
-				removeOpposite(action);
-				break;
-
-			case CachedActions.MARK_READ_FEED:
-				removeForFeed(action.getID());
-				break;
-
-			case CachedActions.MARK_READ_CATEGORY:
-				removeForCategory(action.getID());
-				break;
-
-			case CachedActions.MARK_READ_ALL:
-				removeForALL();
-				break;
+			m_list.remove(a);
+			break;
 		}
-
-		m_list.add(action);
 	}
+}
 
-	private void removeOpposite(CachedAction action)
-	{
-		foreach(CachedAction a in m_list)
-		{
-			if(a.getID() == action.getID()
-			&& a.getType() == action.opposite())
+private void removeForFeed(string feedID)
+{
+	DataBaseReadOnly db = null;
+	foreach(CachedAction a in m_list)
+	{
+		if(a.getType() == CachedActions.MARK_READ
+		   || a.getType() == CachedActions.MARK_UNREAD)
+		{
+			if (db == null)
+				db = DataBase.readOnly();
+			if(feedID == db.getFeedIDofArticle(a.getID()))
 			{
 				m_list.remove(a);
-				break;
 			}
 		}
 	}
+}
 
-	private void removeForFeed(string feedID)
+private void removeForCategory(string catID)
+{
+	var feedIDs = DataBase.readOnly().getFeedIDofCategorie(catID);
+	foreach(string feedID in feedIDs)
 	{
 		foreach(CachedAction a in m_list)
 		{
-			if(a.getType() == CachedActions.MARK_READ
-			|| a.getType() == CachedActions.MARK_UNREAD)
+			if(a.getType() == CachedActions.MARK_READ_FEED
+			   && a.getID() == feedID)
 			{
-				if(feedID == DataBase.readOnly().getFeedIDofArticle(a.getID()))
-				{
-					m_list.remove(a);
-				}
+				m_list.remove(a);
 			}
 		}
-	}
-
-	private void removeForCategory(string catID)
-	{
-		var feedIDs = DataBase.readOnly().getFeedIDofCategorie(catID);
-		foreach(string feedID in feedIDs)
-		{
-			foreach(CachedAction a in m_list)
-			{
-				if(a.getType() == CachedActions.MARK_READ_FEED
-				&& a.getID() == feedID)
-				{
-					m_list.remove(a);
-				}
-			}
 
-			removeForFeed(feedID);
-		}
+		removeForFeed(feedID);
 	}
+}
 
-	private void removeForALL()
-	{
-		foreach(CachedAction a in m_list)
-		{
-			switch(a.getType())
-			{
-				case CachedActions.MARK_READ:
-				case CachedActions.MARK_UNREAD:
-				case CachedActions.MARK_READ_FEED:
-				case CachedActions.MARK_READ_CATEGORY:
-				case CachedActions.MARK_READ_ALL:
-					m_list.remove(a);
-					break;
-			}
+private void removeForALL()
+{
+	foreach(CachedAction a in m_list)
+	{
+		switch(a.getType())
+		{
+		case CachedActions.MARK_READ:
+		case CachedActions.MARK_UNREAD:
+		case CachedActions.MARK_READ_FEED:
+		case CachedActions.MARK_READ_CATEGORY:
+		case CachedActions.MARK_READ_ALL:
+			m_list.remove(a);
+			break;
 		}
 	}
+}
 
-	public ArticleStatus checkStarred(string articleID, ArticleStatus marked)
-	{
-		var type = CachedActions.NONE;
-		if(marked == ArticleStatus.UNMARKED)
-			type = CachedActions.MARK_STARRED;
-		else if(marked == ArticleStatus.MARKED)
-			type = CachedActions.MARK_UNSTARRED;
+public ArticleStatus checkStarred(string articleID, ArticleStatus marked)
+{
+	var type = CachedActions.NONE;
+	if(marked == ArticleStatus.UNMARKED)
+		type = CachedActions.MARK_STARRED;
+	else if(marked == ArticleStatus.MARKED)
+		type = CachedActions.MARK_UNSTARRED;
 
-		foreach(CachedAction a in m_list)
+	foreach(CachedAction a in m_list)
+	{
+		if(a.getType() == type
+		   && a.getID() == articleID)
 		{
-			if(a.getType() == type
-			&& a.getID() == articleID)
-			{
-				if(type == CachedActions.MARK_STARRED)
-					return ArticleStatus.MARKED;
+			if(type == CachedActions.MARK_STARRED)
+				return ArticleStatus.MARKED;
 
-				if(type == CachedActions.MARK_UNSTARRED)
-					return ArticleStatus.UNMARKED;
-			}
+			if(type == CachedActions.MARK_UNSTARRED)
+				return ArticleStatus.UNMARKED;
 		}
-
-		return marked;
 	}
 
-	public ArticleStatus checkRead(Article a)
+	return marked;
+}
+
+public ArticleStatus checkRead(Article a)
+{
+	if(a.getUnread() == ArticleStatus.READ)
 	{
-		if(a.getUnread() == ArticleStatus.READ)
+		foreach(CachedAction action in m_list)
 		{
-			foreach(CachedAction action in m_list)
-			{
-				if(action.getType() == CachedActions.MARK_UNREAD
-				&& action.getID() == a.getArticleID())
-					return ArticleStatus.UNREAD;
-			}
+			if(action.getType() == CachedActions.MARK_UNREAD
+			   && action.getID() == a.getArticleID())
+				return ArticleStatus.UNREAD;
 		}
-		else if(a.getUnread() == ArticleStatus.UNREAD)
+	}
+	else if(a.getUnread() == ArticleStatus.UNREAD)
+	{
+		DataBaseReadOnly db = null;
+		foreach(CachedAction action in m_list)
 		{
-			foreach(CachedAction action in m_list)
+			switch(action.getType())
 			{
-				switch(action.getType())
+			case CachedActions.MARK_READ_ALL:
+				return ArticleStatus.READ;
+
+			case CachedActions.MARK_READ_FEED:
+				if(action.getID() == a.getFeedID())
+					return ArticleStatus.READ;
+				break;
+
+			case CachedActions.MARK_READ_CATEGORY:
+				if (db == null)
+					db = DataBase.readOnly();
+				var feedIDs = db.getFeedIDofCategorie(a.getArticleID());
+				foreach(string feedID in feedIDs)
 				{
-					case CachedActions.MARK_READ_ALL:
+					if(feedID == a.getFeedID())
 						return ArticleStatus.READ;
-
-					case CachedActions.MARK_READ_FEED:
-						if(action.getID() == a.getFeedID())
-							return ArticleStatus.READ;
-						break;
-
-					case CachedActions.MARK_READ_CATEGORY:
-						var feedIDs = DataBase.readOnly().getFeedIDofCategorie(a.getArticleID());
-						foreach(string feedID in feedIDs)
-						{
-							if(feedID == a.getFeedID())
-								return ArticleStatus.READ;
-						}
-						break;
 				}
+				break;
 			}
 		}
-
-		return a.getUnread();
 	}
+
+	return a.getUnread();
+}
 }
diff -pruN 2.6.1-1/src/Backend/Backend.vala 2.7.1-1/src/Backend/Backend.vala
--- 2.6.1-1/src/Backend/Backend.vala	2018-12-07 01:04:46.000000000 +0000
+++ 2.7.1-1/src/Backend/Backend.vala	2019-02-01 19:30:50.000000000 +0000
@@ -15,867 +15,857 @@
 
 namespace FeedReader {
 
-	public class FeedReaderBackend : GLib.Object {
+public class FeedReaderBackend : GLib.Object {
 
 #if LIBUNITY
-		private Unity.LauncherEntry m_launcher;
+private Unity.LauncherEntry m_launcher;
 #endif
-		private LoginResponse m_loggedin;
-		private GLib.Cancellable m_cancellable;
-		private bool m_offline = true;
-		private bool m_cacheSync = false;
-		private uint m_timeout_source_id = 0;
-		private Mutex m_sync_lock;
-		private delegate void asyncPayload();
-
-		public signal void syncStarted();
-		public signal void syncFinished();
-		public signal void springCleanStarted();
-		public signal void springCleanFinished();
-		public signal void newFeedList();
-		public signal void refreshFeedListCounter();
-		public signal void updateArticleList();
-		public signal void showArticleListOverlay();
-		public signal void setOffline();
-		public signal void setOnline();
-		public signal void feedAdded(bool error, string errmsg);
-		public signal void opmlImported();
-		public signal void updateSyncProgress(string progress);
-		public signal void tryLogin();
-
-		private static FeedReaderBackend? m_backend;
-
-		public static FeedReaderBackend get_default()
-		{
-			if(m_backend == null)
-				m_backend = new FeedReaderBackend();
-
-			return m_backend;
-		}
+private LoginResponse m_loggedin;
+private GLib.Cancellable m_cancellable;
+private bool m_offline = true;
+private bool m_cacheSync = false;
+private uint m_timeout_source_id = 0;
+private Mutex m_sync_lock;
+private delegate void asyncPayload();
+
+public signal void syncStarted();
+public signal void syncFinished();
+public signal void springCleanStarted();
+public signal void springCleanFinished();
+public signal void newFeedList();
+public signal void refreshFeedListCounter();
+public signal void updateArticleList();
+public signal void showArticleListOverlay();
+public signal void setOffline();
+public signal void setOnline();
+public signal void feedAdded(bool error, string errmsg);
+public signal void opmlImported();
+public signal void updateSyncProgress(string progress);
+public signal void tryLogin();
+
+private static FeedReaderBackend? m_backend;
+
+public static FeedReaderBackend get_default()
+{
+	if(m_backend == null)
+		m_backend = new FeedReaderBackend();
 
-		private FeedReaderBackend()
-		{
-			Logger.debug("backend: constructor");
-			var plugID = Settings.general().get_string("plugin");
+	return m_backend;
+}
 
-			if(plugID == "none")
-				m_loggedin = LoginResponse.NO_BACKEND;
-			else
-				login(plugID);
+private FeedReaderBackend()
+{
+	Logger.debug("backend: constructor");
+	var plugID = Settings.general().get_string("plugin");
+
+	if(plugID == "none")
+		m_loggedin = LoginResponse.NO_BACKEND;
+	else
+		login(plugID);
 
 #if LIBUNITY
-			m_launcher = Unity.LauncherEntry.get_for_desktop_id("org.gnome.FeedReader.desktop");
-			updateBadge();
+	m_launcher = Unity.LauncherEntry.get_for_desktop_id("org.gnome.FeedReader.desktop");
+	updateBadge();
 #endif
-			m_cancellable = new GLib.Cancellable();
-			scheduleSync(Settings.general().get_int("sync"));
+	m_cancellable = new GLib.Cancellable();
+	scheduleSync(Settings.general().get_int("sync"));
 
-			GLib.NetworkMonitor.get_default().network_changed.connect((available) => {
+	GLib.NetworkMonitor.get_default().network_changed.connect((available) => {
 				if(available)
 				{
-					checkOnline();
+				        checkOnline();
 				}
 				else
 				{
-					setOffline();
+				        setOffline();
 				}
 			});
 
-			this.setOffline.connect(() => {
+	this.setOffline.connect(() => {
 				m_offline = true;
 			});
-			this.setOnline.connect(() => {
+	this.setOnline.connect(() => {
 				m_offline = false;
 				CachedActionManager.get_default().executeActions();
 			});
-		}
+}
 
-		public void startSync(bool initSync = false)
-		{
-			m_cancellable.reset();
-			asyncPayload pl = () => { sync(initSync, m_cancellable); };
-			callAsync.begin((owned)pl, (obj, res) => {
+public void startSync(bool initSync = false)
+{
+	m_cancellable.reset();
+	asyncPayload pl = () => { sync(initSync, m_cancellable); };
+	callAsync.begin((owned)pl, (obj, res) => {
 				callAsync.end(res);
 			});
-		}
+}
 
-		public void cancelSync()
-		{
-			Logger.warning("backend: Cancel current sync");
-			m_cancellable.cancel();
-		}
+public void cancelSync()
+{
+	Logger.warning("backend: Cancel current sync");
+	m_cancellable.cancel();
+}
 
-		public string getVersion()
-		{
-			return AboutInfo.version;
-		}
+public string getVersion()
+{
+	return AboutInfo.version;
+}
 
 
-		public bool supportTags()
-		{
-			return FeedServer.get_default().supportTags();
-		}
+public bool supportTags()
+{
+	return FeedServer.get_default().supportTags();
+}
 
-		public bool supportCategories()
-		{
-			return FeedServer.get_default().supportCategories();
-		}
+public bool supportCategories()
+{
+	return FeedServer.get_default().supportCategories();
+}
 
-		public bool supportFeedManipulation()
-		{
-			return FeedServer.get_default().supportFeedManipulation();
-		}
+public bool supportFeedManipulation()
+{
+	return FeedServer.get_default().supportFeedManipulation();
+}
 
-		public bool supportMultiLevelCategories()
-		{
-			return FeedServer.get_default().supportMultiLevelCategories();
-		}
+public bool supportMultiLevelCategories()
+{
+	return FeedServer.get_default().supportMultiLevelCategories();
+}
 
-		public string symbolicIcon()
-		{
-			Logger.debug("backend: symbolicIcon");
-			return FeedServer.get_default().symbolicIcon();
-		}
+public string symbolicIcon()
+{
+	Logger.debug("backend: symbolicIcon");
+	return FeedServer.get_default().symbolicIcon();
+}
 
-		public string accountName()
-		{
-			return FeedServer.get_default().accountName();
-		}
+public string accountName()
+{
+	return FeedServer.get_default().accountName();
+}
 
-		public string getServerURL()
-		{
-			return FeedServer.get_default().getServerURL();
-		}
+public string getServerURL()
+{
+	return FeedServer.get_default().getServerURL();
+}
 
-		public string uncategorizedID()
-		{
-			return FeedServer.get_default().uncategorizedID();
-		}
+public string uncategorizedID()
+{
+	return FeedServer.get_default().uncategorizedID();
+}
 
-		public bool hideCategoryWhenEmpty(string catID)
-		{
-			return FeedServer.get_default().hideCategoryWhenEmpty(catID);
-		}
+public bool hideCategoryWhenEmpty(string catID)
+{
+	return FeedServer.get_default().hideCategoryWhenEmpty(catID);
+}
 
-		public bool useMaxArticles()
-		{
-			return FeedServer.get_default().useMaxArticles();
-		}
+public bool useMaxArticles()
+{
+	return FeedServer.get_default().useMaxArticles();
+}
 
-		public void scheduleSync(int time)
-		{
-			if (m_timeout_source_id > 0)
-			{
-				GLib.Source.remove(m_timeout_source_id);
-				m_timeout_source_id = 0;
-			}
+public void scheduleSync(int time)
+{
+	if (m_timeout_source_id > 0)
+	{
+		GLib.Source.remove(m_timeout_source_id);
+		m_timeout_source_id = 0;
+	}
 
-			if(time == 0)
-				return;
+	if(time == 0)
+		return;
 
-			m_timeout_source_id = GLib.Timeout.add_seconds_full(GLib.Priority.DEFAULT, time*60, () => {
+	m_timeout_source_id = GLib.Timeout.add_seconds_full(GLib.Priority.DEFAULT, time*60, () => {
 				if(!Settings.state().get_boolean("currently-updating")
-				&& FeedServer.get_default().pluginLoaded())
+				   && FeedServer.get_default().pluginLoaded())
 				{
-					Logger.debug("backend: Timeout!");
-					startSync(false);
+				        Logger.debug("backend: Timeout!");
+				        startSync(false);
 				}
 				return true;
 			});
-		}
+}
 
-		private void sync(bool initSync = false, GLib.Cancellable? cancellable = null)
+private void sync(bool initSync = false, GLib.Cancellable? cancellable = null)
+{
+	// Prevent multiple concurrent syncs or spring cleanings
+	// We would prefer to use MutexLocker but it doesn't seem to work
+	m_sync_lock.lock();
+	try
+	{
+		if(Settings.state().get_boolean("currently-updating"))
 		{
-			// Prevent multiple concurrent syncs or spring cleanings
-			// We would prefer to use MutexLocker but it doesn't seem to work
-			m_sync_lock.lock();
-			try
-			{
-				if(Settings.state().get_boolean("currently-updating"))
-				{
-					Logger.debug("Cant sync because login failed or sync/clean already ongoing");
-					return;
-				}
+			Logger.debug("Cant sync because login failed or sync/clean already ongoing");
+			return;
+		}
 
-				if(Utils.springCleaningNecessary())
-				{
-					Logger.info("backend: spring cleaning");
-					springCleanStarted();
-					DataBase.writeAccess().springCleaning();
-					springCleanFinished();
-				}
+		if(Utils.springCleaningNecessary())
+		{
+			Logger.info("backend: spring cleaning");
+			springCleanStarted();
+			DataBase.writeAccess().springCleaning();
+			springCleanFinished();
+		}
 
-				if(cancellable != null && cancellable.is_cancelled())
-					return;
+		if(cancellable != null && cancellable.is_cancelled())
+			return;
 
-				Logger.info("backend: sync started");
-				syncStarted();
-				Settings.state().set_boolean("currently-updating", true);
+		Logger.info("backend: sync started");
+		syncStarted();
+		Settings.state().set_boolean("currently-updating", true);
 
-				if(!checkOnline())
-				{
-					Logger.info("Cancelling sync because we're not online");
-					finishSync();
-					return;
-				}
+		if(!checkOnline())
+		{
+			Logger.info("Cancelling sync because we're not online");
+			finishSync();
+			return;
+		}
 
-				if(cancellable != null && cancellable.is_cancelled())
-				{
-					finishSync();
-					return;
-				}
+		if(cancellable != null && cancellable.is_cancelled())
+		{
+			finishSync();
+			return;
+		}
 
-				m_cacheSync = true;
+		m_cacheSync = true;
 
-				if(initSync && FeedServer.get_default().doInitSync())
-					FeedServer.get_default().InitSyncContent(cancellable);
-				else
-					FeedServer.get_default().syncContent(cancellable);
+		if(initSync && FeedServer.get_default().doInitSync())
+			FeedServer.get_default().InitSyncContent(cancellable);
+		else
+			FeedServer.get_default().syncContent(cancellable);
 
-				if(cancellable != null && cancellable.is_cancelled())
-				{
-					finishSync();
-					return;
-				}
+		if(cancellable != null && cancellable.is_cancelled())
+		{
+			finishSync();
+			return;
+		}
 
-				updateBadge();
-				m_cacheSync = false;
-				FeedServer.get_default().grabContent.begin(cancellable, (obj, res) => {
+		updateBadge();
+		m_cacheSync = false;
+		FeedServer.get_default().grabContent.begin(cancellable, (obj, res) => {
 					FeedServer.get_default().grabContent.end(res);
 					finishSync();
 				});
-			}
-			finally
-			{
-				m_sync_lock.unlock();
-			}
-		}
-
-		private void finishSync()
-		{
-			Settings.state().set_boolean("currently-updating", false);
-			Settings.state().set_string("sync-status", "");
-			Logger.info("backend: sync finished/cancelled");
-			syncFinished();
-		}
-
-		public bool checkOnline()
-		{
-			Logger.debug("backend: checkOnline");
-
-			if(GLib.NetworkMonitor.get_default().get_connectivity() != GLib.NetworkConnectivity.FULL)
-			{
-				Logger.error("backend: no network available");
-			}
-
-			if(!FeedServer.get_default().serverAvailable())
-			{
-				m_loggedin = LoginResponse.UNKNOWN_ERROR;
-				setOffline();
-				return false;
-			}
+	}
+	finally
+	{
+		m_sync_lock.unlock();
+	}
+}
 
-			if(m_loggedin != LoginResponse.SUCCESS)
-			{
-				FeedServer.get_default().logout();
-				login(Settings.general().get_string("plugin"));
-				if(m_loggedin != LoginResponse.SUCCESS)
-				{
-					setOffline();
-					return false;
-				}
-			}
+private void finishSync()
+{
+	Settings.state().set_boolean("currently-updating", false);
+	Settings.state().set_string("sync-status", "");
+	Logger.info("backend: sync finished/cancelled");
+	syncFinished();
+}
 
-			setOnline();
-			return true;
-		}
+public bool checkOnline()
+{
+	Logger.debug("backend: checkOnline");
+
+	if(GLib.NetworkMonitor.get_default().get_connectivity() != GLib.NetworkConnectivity.FULL)
+	{
+		Logger.error("backend: no network available");
+	}
 
+	if(!FeedServer.get_default().serverAvailable())
+	{
+		m_loggedin = LoginResponse.UNKNOWN_ERROR;
+		setOffline();
+		return false;
+	}
 
-		public async bool checkOnlineAsync()
+	if(m_loggedin != LoginResponse.SUCCESS)
+	{
+		FeedServer.get_default().logout();
+		login(Settings.general().get_string("plugin"));
+		if(m_loggedin != LoginResponse.SUCCESS)
 		{
-			if(!FeedServer.get_default().pluginLoaded())
-				return false;
-
-			Logger.debug("backend: checkOnlineAsync");
-			bool online = false;
-			SourceFunc callback = checkOnlineAsync.callback;
-			ThreadFunc<void*> run = () => {
-				Idle.add((owned) callback);
-				online = checkOnline();
-				return null;
-			};
-
-			new GLib.Thread<void*>("checkOnlineAsync", run);
-			yield;
-			return online;
+			setOffline();
+			return false;
 		}
+	}
 
-		public LoginResponse login(string plugName)
-		{
-			Logger.debug("backend: new FeedServer and login");
+	setOnline();
+	return true;
+}
 
-			FeedServer.get_default().setActivePlugin(plugName);
 
-			if(!FeedServer.get_default().pluginLoaded())
-			{
-				Logger.error(@"backend: no active plugin");
-				m_loggedin = LoginResponse.NO_BACKEND;
-				return m_loggedin;
-			}
+public async bool checkOnlineAsync()
+{
+	if(!FeedServer.get_default().pluginLoaded())
+		return false;
+
+	Logger.debug("backend: checkOnlineAsync");
+	bool online = false;
+	SourceFunc callback = checkOnlineAsync.callback;
+	ThreadFunc<void*> run = () => {
+		Idle.add((owned) callback);
+		online = checkOnline();
+		return null;
+	};
+
+	new Thread<void*>("checkOnlineAsync", run);
+	yield;
+	return online;
+}
 
-			m_loggedin = FeedServer.get_default().login();
+public LoginResponse login(string plugName)
+{
+	Logger.debug("backend: new FeedServer and login");
+
+	FeedServer.get_default().setActivePlugin(plugName);
+
+	if(!FeedServer.get_default().pluginLoaded())
+	{
+		Logger.error(@"backend: no active plugin");
+		m_loggedin = LoginResponse.NO_BACKEND;
+		return m_loggedin;
+	}
 
-			if(m_loggedin == LoginResponse.SUCCESS)
-			{
-				Settings.general().set_string("plugin", plugName);
-				setOnline();
-			}
-			else if(m_loggedin == LoginResponse.NO_BACKEND)
-			{
-				// do nothing
-			}
-			else
-			{
-				setOffline();
-			}
+	m_loggedin = FeedServer.get_default().login();
 
+	if(m_loggedin == LoginResponse.SUCCESS)
+	{
+		Settings.general().set_string("plugin", plugName);
+		setOnline();
+	}
+	else if(m_loggedin == LoginResponse.NO_BACKEND)
+	{
+		// do nothing
+	}
+	else
+	{
+		setOffline();
+	}
 
-			Logger.debug("backend: login status = " + m_loggedin.to_string());
-			return m_loggedin;
-		}
 
-		public LoginResponse isLoggedIn()
-		{
-			return m_loggedin;
-		}
+	Logger.debug("backend: login status = " + m_loggedin.to_string());
+	return m_loggedin;
+}
 
-		public bool isOnline()
-		{
-			if(m_loggedin != LoginResponse.SUCCESS)
-			{
-				return false;
-			}
+public LoginResponse isLoggedIn()
+{
+	return m_loggedin;
+}
 
-			return true;
-		}
+public bool isOnline()
+{
+	if(m_loggedin != LoginResponse.SUCCESS)
+	{
+		return false;
+	}
 
-		public void updateArticleRead(Article article)
-		{
-			if(m_offline)
-				CachedActionManager.get_default().markArticleRead(article.getArticleID(), article.getUnread());
-			else
-			{
-				if(m_cacheSync)
-					ActionCache.get_default().markArticleRead(article.getArticleID(), article.getUnread());
+	return true;
+}
 
-				asyncPayload pl = () => { FeedServer.get_default().setArticleIsRead(article.getArticleID(), article.getUnread()); };
-				callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
-			}
+public void updateArticleRead(Article article)
+{
+	if(m_offline)
+		CachedActionManager.get_default().markArticleRead(article.getArticleID(), article.getUnread());
+	else
+	{
+		if(m_cacheSync)
+			ActionCache.get_default().markArticleRead(article.getArticleID(), article.getUnread());
 
-			asyncPayload pl = () => { DataBase.writeAccess().update_article(article); };
-			callAsync.begin((owned)pl, (obj, res) => {
+		asyncPayload pl = () => { FeedServer.get_default().setArticleIsRead(article.getArticleID(), article.getUnread()); };
+		callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	}
+
+	asyncPayload pl = () => { DataBase.writeAccess().update_article(article); };
+	callAsync.begin((owned)pl, (obj, res) => {
 				callAsync.end(res);
 				refreshFeedListCounter();
 				updateBadge();
 			});
-		}
+}
 
-		public void updateArticleMarked(Article article)
-		{
-			if(m_offline)
-				CachedActionManager.get_default().markArticleStarred(article.getArticleID(), article.getMarked());
-			else
-			{
-				if(m_cacheSync)
-					ActionCache.get_default().markArticleStarred(article.getArticleID(), article.getMarked());
-				asyncPayload pl = () => { FeedServer.get_default().setArticleIsMarked(article.getArticleID(), article.getMarked()); };
-				callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
-			}
+public void updateArticleMarked(Article article)
+{
+	if(m_offline)
+		CachedActionManager.get_default().markArticleStarred(article.getArticleID(), article.getMarked());
+	else
+	{
+		if(m_cacheSync)
+			ActionCache.get_default().markArticleStarred(article.getArticleID(), article.getMarked());
+		asyncPayload pl = () => { FeedServer.get_default().setArticleIsMarked(article.getArticleID(), article.getMarked()); };
+		callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	}
 
 
-			asyncPayload pl = () => { DataBase.writeAccess().update_article(article); };
-			callAsync.begin((owned)pl, (obj, res) => {
+	asyncPayload pl = () => { DataBase.writeAccess().update_article(article); };
+	callAsync.begin((owned)pl, (obj, res) => {
 				callAsync.end(res);
 				refreshFeedListCounter();
 			});
-		}
-
-
-		public Tag? createTag(string caption)
-		{
-			if(m_offline)
-				return null;
+}
 
-			string tagID = FeedServer.get_default().createTag(caption);
-			var tag = new Tag(tagID, caption, 0);
-			DataBase.writeAccess().write_tag(tag);
-			newFeedList();
 
-			return tag;
-		}
+public Tag? createTag(string caption)
+{
+	if(m_offline)
+		return null;
+
+	string tagID = FeedServer.get_default().createTag(caption);
+	var tag = new Tag(tagID, caption, 0);
+	DataBase.writeAccess().write_tag(tag);
+	newFeedList();
 
-		public void tagArticle(Article article, Tag tag, bool add)
-		{
-			if(m_offline)
-				return;
+	return tag;
+}
 
-			if(add)
-			{
-				asyncPayload pl = () => { FeedServer.get_default().tagArticle(article, tag); };
-				callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void tagArticle(Article article, Tag tag, bool add)
+{
+	if(m_offline)
+		return;
+
+	if(add)
+	{
+		asyncPayload pl = () => { FeedServer.get_default().tagArticle(article, tag); };
+		callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-				article.addTag(tag.getTagID());
+		article.addTag(tag.getTagID());
 
-			}
-			else
-			{
-				Logger.debug("backend: remove tag: " + tag.getTagID() + " from article: " + article.getArticleID());
+	}
+	else
+	{
+		Logger.debug("backend: remove tag: " + tag.getTagID() + " from article: " + article.getArticleID());
 
-				asyncPayload pl = () => { FeedServer.get_default().removeArticleTag(article, tag); };
-				callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+		asyncPayload pl = () => { FeedServer.get_default().removeArticleTag(article, tag); };
+		callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-				article.removeTag(tag.getTagID());
-			}
+		article.removeTag(tag.getTagID());
+	}
 
-			DataBase.writeAccess().update_article(article);
+	var db = DataBase.writeAccess();
+	db.update_article(article);
 
-			if(!add && !DataBase.readOnly().tag_still_used(tag))
-			{
-				Logger.debug("backend: remove tag completely");
-				asyncPayload pl2 = () => { FeedServer.get_default().deleteTag(tag.getTagID()); };
-				callAsync.begin((owned)pl2, (obj, res) => { callAsync.end(res); });
+	if(!add && !db.tag_still_used(tag))
+	{
+		Logger.debug("backend: remove tag completely");
+		asyncPayload pl2 = () => { FeedServer.get_default().deleteTag(tag.getTagID()); };
+		callAsync.begin((owned)pl2, (obj, res) => { callAsync.end(res); });
 
-				asyncPayload pl3 = () => { DataBase.writeAccess().dropTag(tag); };
-				callAsync.begin((owned)pl3, (obj, res) => {
+		asyncPayload pl3 = () => { db.dropTag(tag); };
+		callAsync.begin((owned)pl3, (obj, res) => {
 					callAsync.end(res);
 					newFeedList();
 				});
-			}
-		}
+	}
+}
 
-		public Tag renameTag(Tag tag, string newName)
-		{
-			if(m_offline)
-				return tag;
+public Tag renameTag(Tag tag, string newName)
+{
+	if(m_offline)
+		return tag;
 
-			tag.setTitle(newName);
+	tag.setTitle(newName);
 
-			asyncPayload pl = () => { FeedServer.get_default().renameTag(tag.getTagID(), newName); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	asyncPayload pl = () => { FeedServer.get_default().renameTag(tag.getTagID(), newName); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().update_tag(tag); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().update_tag(tag); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
 
-			return tag;
-		}
+	return tag;
+}
 
-		public void deleteTag(Tag tag)
-		{
-			if(m_offline)
-				return;
+public void deleteTag(Tag tag)
+{
+	if(m_offline)
+		return;
 
-			asyncPayload pl = () => { FeedServer.get_default().deleteTag(tag.getTagID()); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	asyncPayload pl = () => { FeedServer.get_default().deleteTag(tag.getTagID()); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().dropTag(tag); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().dropTag(tag); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
+}
 
-		public void updateTagColor(Tag tag)
-		{
-			DataBase.writeAccess().update_tag(tag);
-		}
+public void updateTagColor(Tag tag)
+{
+	DataBase.writeAccess().update_tag(tag);
+}
 
-		public void resetDB()
-		{
-			DataBase.writeAccess().resetDB();
-			DataBase.writeAccess().init();
-		}
+public void resetDB()
+{
+	var db = DataBase.writeAccess();
+	db.resetDB();
+	db.init();
+}
+
+public void resetAccount()
+{
+	FeedServer.get_default().resetAccount();
+}
 
-		public void resetAccount()
+public void markFeedAsRead(string feedID, bool isCat)
+{
+	var useID = FeedServer.get_default().alwaysSetReadByID();
+	var articleIDs = "";
+	if(useID)
+	{
+		var listType = isCat ? FeedListType.CATEGORY : FeedListType.FEED;
+		var articles = DataBase.readOnly().read_articles(feedID, listType, ArticleListState.UNREAD, "", -1);
+		var articleIDsList = new Gee.ArrayList<string>();
+		foreach (var article in articles)
 		{
-			FeedServer.get_default().resetAccount();
+			articleIDsList.add(article.getArticleID());
 		}
+		articleIDs = StringUtils.join(articleIDsList, ",");
+	}
 
-		public void markFeedAsRead(string feedID, bool isCat)
+	if(isCat)
+	{
+		if(m_offline)
 		{
-			var useID = FeedServer.get_default().alwaysSetReadByID();
-			var articleIDs = "";
 			if(useID)
+				CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
+			else
+				CachedActionManager.get_default().markCategoryRead(feedID);
+		}
+		else
+		{
+			if(m_cacheSync)
 			{
-				var listType = isCat ? FeedListType.CATEGORY : FeedListType.FEED;
-				var articles = DataBase.readOnly().read_articles(feedID, listType, ArticleListState.UNREAD, "", -1);
-				var articleIDsList = new Gee.ArrayList<string>();
-				foreach (var article in articles)
-				{
-					articleIDsList.add(article.getArticleID());
-				}
-				articleIDs = StringUtils.join(articleIDsList, ",");
+				if(useID)
+					ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
+				else
+					ActionCache.get_default().markCategoryRead(feedID);
 			}
-
-			if(isCat)
-			{
-				if(m_offline)
-				{
-					if(useID)
-						CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-					else
-						CachedActionManager.get_default().markCategoryRead(feedID);
-				}
+			asyncPayload pl = () => {
+				if(useID)
+					FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
 				else
-				{
-					if(m_cacheSync)
-					{
-						if(useID)
-							ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-						else
-							ActionCache.get_default().markCategoryRead(feedID);
-					}
-					asyncPayload pl = () => {
-						if(useID)
-							FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
-						else
-							FeedServer.get_default().setCategoryRead(feedID);
-					};
-					callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
-				}
+					FeedServer.get_default().setCategoryRead(feedID);
+			};
+			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+		}
 
-				asyncPayload pl = () => { DataBase.writeAccess().markCategorieRead(feedID); };
-				callAsync.begin((owned)pl, (obj, res) => {
+		asyncPayload pl = () => { DataBase.writeAccess().markCategorieRead(feedID); };
+		callAsync.begin((owned)pl, (obj, res) => {
 					callAsync.end(res);
 					updateBadge();
 					newFeedList();
 					updateArticleList();
 				});
-			}
+	}
+	else
+	{
+		if(m_offline)
+		{
+			if(useID)
+				CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
 			else
+				CachedActionManager.get_default().markFeedRead(feedID);
+		}
+		else
+		{
+			if(m_cacheSync)
 			{
-				if(m_offline)
-				{
-					if(useID)
-						CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-					else
-						CachedActionManager.get_default().markFeedRead(feedID);
-				}
+				if(useID)
+					ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
 				else
-				{
-					if(m_cacheSync)
-					{
-						if(useID)
-							ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-						else
-							ActionCache.get_default().markFeedRead(feedID);
-					}
-					asyncPayload pl = () => {
-						if(useID)
-							FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
-						else
-							FeedServer.get_default().setFeedRead(feedID);
-					};
-					callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
-				}
+					ActionCache.get_default().markFeedRead(feedID);
+			}
+			asyncPayload pl = () => {
+				if(useID)
+					FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
+				else
+					FeedServer.get_default().setFeedRead(feedID);
+			};
+			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+		}
 
-				asyncPayload pl = () => { DataBase.writeAccess().markFeedRead(feedID); };
-				callAsync.begin((owned)pl, (obj, res) => {
+		asyncPayload pl = () => { DataBase.writeAccess().markFeedRead(feedID); };
+		callAsync.begin((owned)pl, (obj, res) => {
 					callAsync.end(res);
 					updateBadge();
 					newFeedList();
 					updateArticleList();
 				});
-			}
+	}
+}
+
+public void markAllItemsRead()
+{
+	var useID = FeedServer.get_default().alwaysSetReadByID();
+	var articleIDs = "";
+	if(useID)
+	{
+		var articles = DataBase.readOnly().read_articles(FeedID.ALL.to_string(), FeedListType.FEED, ArticleListState.UNREAD, "", -1);
+		var articleIDsList = new Gee.ArrayList<string>();
+		foreach (var article in articles)
+		{
+			articleIDsList.add(article.getArticleID());
 		}
+		articleIDs = StringUtils.join(articleIDsList, ",");
+	}
 
-		public void markAllItemsRead()
+	if(m_offline)
+	{
+		if(useID)
+			CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
+		else
+			CachedActionManager.get_default().markAllRead();
+	}
+	else
+	{
+		if(m_cacheSync)
 		{
-			var useID = FeedServer.get_default().alwaysSetReadByID();
-			var articleIDs = "";
 			if(useID)
-			{
-				var articles = DataBase.readOnly().read_articles(FeedID.ALL.to_string(), FeedListType.FEED, ArticleListState.UNREAD, "", -1);
-				var articleIDsList = new Gee.ArrayList<string>();
-				foreach (var article in articles)
-				{
-					articleIDsList.add(article.getArticleID());
-				}
-				articleIDs = StringUtils.join(articleIDsList, ",");
-			}
-
-			if(m_offline)
-			{
-				if(useID)
-					CachedActionManager.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-				else
-					CachedActionManager.get_default().markAllRead();
-			}
+				ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
 			else
-			{
-				if(m_cacheSync)
-				{
-					if(useID)
-						ActionCache.get_default().markArticleRead(articleIDs, ArticleStatus.READ);
-					else
-						ActionCache.get_default().markAllRead();
-				}
-				asyncPayload pl = () => {
-					if(useID)
-						FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
-					else
-						FeedServer.get_default().markAllItemsRead();
-				};
-				callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
-			}
+				ActionCache.get_default().markAllRead();
+		}
+		asyncPayload pl = () => {
+			if(useID)
+				FeedServer.get_default().setArticleIsRead(articleIDs, ArticleStatus.READ);
+			else
+				FeedServer.get_default().markAllItemsRead();
+		};
+		callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	}
 
-			asyncPayload pl = () => { DataBase.writeAccess().markAllRead(); };
-			callAsync.begin((owned)pl, (obj, res) => {
+	asyncPayload pl = () => { DataBase.writeAccess().markAllRead(); };
+	callAsync.begin((owned)pl, (obj, res) => {
 				callAsync.end(res);
 				updateBadge();
 				newFeedList();
 				updateArticleList();
 			});
-		}
+}
 
-		public void removeCategory(string catID)
+public void removeCategory(string catID)
+{
+	var db = DataBase.writeAccess();
+	var feeds = db.read_feeds();
+	foreach(Feed feed in feeds)
+	{
+		if(feed.hasCat(catID))
 		{
-			var feeds = DataBase.readOnly().read_feeds();
-			foreach(Feed feed in feeds)
-			{
-				if(feed.hasCat(catID))
-				{
-					moveFeed(feed.getFeedID(), catID);
-				}
-			}
+			moveFeed(feed.getFeedID(), catID);
+		}
+	}
 
-			var cats = DataBase.readOnly().read_categories(feeds);
-			foreach(var cat in cats)
-			{
-				if(cat.getParent() == catID)
-				{
-					moveCategory(cat.getCatID(), uncategorizedID());
-				}
-			}
+	var cats = db.read_categories(feeds);
+	foreach(var cat in cats)
+	{
+		if(cat.getParent() == catID)
+		{
+			moveCategory(cat.getCatID(), uncategorizedID());
+		}
+	}
 
-			asyncPayload pl = () => { FeedServer.get_default().deleteCategory(catID); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	asyncPayload pl = () => { FeedServer.get_default().deleteCategory(catID); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().delete_category(catID); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { db.delete_category(catID); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
+}
 
-		public void moveCategory(string catID, string newParentID)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().moveCategory(catID, newParentID); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void moveCategory(string catID, string newParentID)
+{
+	asyncPayload pl = () => { FeedServer.get_default().moveCategory(catID, newParentID); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().move_category(catID, newParentID); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().move_category(catID, newParentID); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
-
-		public string addCategory(string title, string? parentID = null, bool createLocally = false)
-		{
-			Logger.debug("backend: addCategory " + title);
-			string catID = FeedServer.get_default().createCategory(title, parentID);
-
-			if(createLocally)
-			{
-				string? parent = parentID;
-				int level = 1;
-				if(parentID == null || parentID == "")
-				{
-					parent = CategoryID.MASTER.to_string();
-				}
-				else
-				{
-					var parentCat = DataBase.readOnly().read_category(parentID);
-					level = parentCat.getLevel()+1;
-				}
+}
 
-				var cat = new Category(catID, title, 0, 99, parent, level);
-				var list = new Gee.LinkedList<Category>();
-				list.add(cat);
-				DataBase.writeAccess().write_categories(list);
-			}
+public string addCategory(string title, string? parentID = null, bool createLocally = false)
+{
+	Logger.debug("backend: addCategory " + title);
+	string catID = FeedServer.get_default().createCategory(title, parentID);
+
+	if(createLocally)
+	{
+		string? parent = parentID;
+		int level = 1;
+		var db = DataBase.writeAccess();
+		if(parentID == null || parentID == "")
+		{
+			parent = CategoryID.MASTER.to_string();
+		}
+		else
+		{
+			var parentCat = db.read_category(parentID);
+			level = parentCat.getLevel()+1;
+		}
+
+		var cat = new Category(catID, title, 0, 99, parent, level);
+		var list = new Gee.LinkedList<Category>();
+		list.add(cat);
+		db.write_categories(list);
+	}
 
-			return catID;
-		}
+	return catID;
+}
 
-		public void removeCategoryWithChildren(string catID)
+public void removeCategoryWithChildren(string catID)
+{
+	var db = DataBase.readOnly();
+	var feeds = db.read_feeds();
+	deleteFeedsInCategory(catID, feeds);
+
+	var cats = db.read_categories(feeds);
+	foreach(var cat in cats)
+	{
+		if(cat.getParent() == catID)
 		{
-			var feeds = DataBase.readOnly().read_feeds();
-			deleteFeedsInCategory(catID, feeds);
-
-			var cats = DataBase.readOnly().read_categories(feeds);
-			foreach(var cat in cats)
-			{
-				if(cat.getParent() == catID)
-				{
-					removeCategoryWithChildren(catID);
-				}
-			}
-
-			removeCategory(catID);
+			removeCategoryWithChildren(catID);
 		}
+	}
 
-		private void deleteFeedsInCategory(string catID, Gee.List<Feed> feeds)
+	removeCategory(catID);
+}
+
+private void deleteFeedsInCategory(string catID, Gee.List<Feed> feeds)
+{
+	foreach(Feed feed in feeds)
+	{
+		if(feed.hasCat(catID))
 		{
-			foreach(Feed feed in feeds)
-			{
-				if(feed.hasCat(catID))
-				{
-					removeFeed(feed.getFeedID());
-				}
-			}
+			removeFeed(feed.getFeedID());
 		}
+	}
+}
 
-		public void renameCategory(string catID, string newName)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().renameCategory(catID, newName); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void renameCategory(string catID, string newName)
+{
+	asyncPayload pl = () => { FeedServer.get_default().renameCategory(catID, newName); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().rename_category(catID, newName); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().rename_category(catID, newName); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
+}
 
-		public void renameFeed(string feedID, string newName)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().renameFeed(feedID, newName); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void renameFeed(string feedID, string newName)
+{
+	asyncPayload pl = () => { FeedServer.get_default().renameFeed(feedID, newName); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().rename_feed(feedID, newName); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().rename_feed(feedID, newName); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
+}
 
-		public void moveFeed(string feedID, string currentCatID, string? newCatID = null)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().moveFeed(feedID, newCatID, currentCatID); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void moveFeed(string feedID, string currentCatID, string? newCatID = null)
+{
+	asyncPayload pl = () => { FeedServer.get_default().moveFeed(feedID, newCatID, currentCatID); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().move_feed(feedID, currentCatID, newCatID); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().move_feed(feedID, currentCatID, newCatID); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
-
-		public void addFeed(string feedURL, string cat, bool isID, bool asynchron)
-		{
-			string? catID = null;
-			string? newCatName = null;
-			string? feedID = null;
-			bool success = false;
-			string errmsg = "";
-
-			if(cat != "")
-			{
-				if(isID)
-					catID = cat;
-				else
-					newCatName = cat;
-			}
-
-			if(asynchron)
-			{
-				new GLib.Thread<void*>(null, () => {
-					success = FeedServer.get_default().addFeed(feedURL, catID, newCatName, out feedID, out errmsg);
-					errmsg = (success) ? "" : errmsg; // just to be sure :P
-					feedAdded(!success, errmsg);
-
-					if(success)
-					{
-						startSync();
-					}
+}
 
-					return null;
-				});
-			}
-			else
-			{
-				success = FeedServer.get_default().addFeed(feedURL, catID, newCatName, out feedID, out errmsg);
-				errmsg = (success) ? "" : errmsg;
-				feedAdded(!success, errmsg);
-			}
-		}
+public void addFeed(string feedURL, string cat, bool isID)
+{
+	string? catID = null;
+	string? newCatName = null;
+	string? feedID = null;
+
+	if(cat != "")
+	{
+		if(isID)
+			catID = cat;
+		else
+			newCatName = cat;
+	}
 
-		public void removeFeed(string feedID)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().removeFeed(feedID); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+	string errmsg;
+	bool success = FeedServer.get_default().addFeed(feedURL, catID, newCatName, out feedID, out errmsg);
+	errmsg = success ? "" : errmsg;
+	feedAdded(!success, errmsg);
+	if(success)
+	{
+		startSync();
+	}
+}
 
-			asyncPayload pl2 = () => {
-				FeedReader.FavIcon.delete_feed(feedID);
-				DataBase.writeAccess().delete_feed(feedID);
-			};
-			callAsync.begin((owned)pl2, (obj, res) => {
+public void removeFeed(string feedID)
+{
+	asyncPayload pl = () => { FeedServer.get_default().removeFeed(feedID); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+
+	asyncPayload pl2 = () => {
+		FeedReader.FavIcon.delete_feed(feedID);
+		DataBase.writeAccess().delete_feed(feedID);
+	};
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 				updateArticleList();
 			});
-		}
+}
 
-		public void removeFeedOnlyFromCat(string feedID, string catID)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().removeCatFromFeed(feedID, catID); };
-			callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
+public void removeFeedOnlyFromCat(string feedID, string catID)
+{
+	asyncPayload pl = () => { FeedServer.get_default().removeCatFromFeed(feedID, catID); };
+	callAsync.begin((owned)pl, (obj, res) => { callAsync.end(res); });
 
-			asyncPayload pl2 = () => { DataBase.writeAccess().removeCatFromFeed(feedID, catID); };
-			callAsync.begin((owned)pl2, (obj, res) => {
+	asyncPayload pl2 = () => { DataBase.writeAccess().removeCatFromFeed(feedID, catID); };
+	callAsync.begin((owned)pl2, (obj, res) => {
 				callAsync.end(res);
 				newFeedList();
 			});
-		}
+}
 
-		public void importOPML(string opml)
-		{
-			asyncPayload pl = () => { FeedServer.get_default().importOPML(opml); };
-			callAsync.begin((owned)pl, (obj, res) => {
+public void importOPML(string opml)
+{
+	asyncPayload pl = () => { FeedServer.get_default().importOPML(opml); };
+	callAsync.begin((owned)pl, (obj, res) => {
 				callAsync.end(res);
 				opmlImported();
 			});
-		}
+}
 
-		public void updateBadge()
-		{
+public void updateBadge()
+{
 #if LIBUNITY
-			if(Settings.tweaks().get_boolean("show-badge"))
-			{
-				var count = DataBase.readOnly().get_unread_total();
-				Logger.debug("backend: update badge count %u".printf(count));
-				m_launc