[gnome-todo/wip/gbsneto/plugins: 10/10] eds: implement eds plugin



commit e5b5a33c9972c4559715988262bf8829a4b9a76d
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date:   Thu Dec 24 00:20:20 2015 -0200

    eds: implement eds plugin
    
    This plugin is the default handler of
    Evolution-Data-Server backend, which serves
    both for local and Online Account providers.
    
    This commit adapts GtdTaskList to remove all
    EDS-specific code, and adds a GtdTaskListEds
    subclass which handles ESources internally.

 Makefile.am                                        |    6 +-
 common.am                                          |    8 +
 configure.ac                                       |    9 +
 data/Makefile.am                                   |    8 +-
 data/todo.gresource.xml                            |    8 +-
 data/ui/{storage-dialog.ui => provider-dialog.ui}  |   10 +-
 .../ui/{storage-popover.ui => provider-popover.ui} |   20 +-
 data/ui/{storage-row.ui => provider-row.ui}        |    4 +-
 .../{storage-selector.ui => provider-selector.ui}  |    6 +-
 data/ui/window.ui                                  |    4 +-
 plugins/Makefile.am                                |    3 +
 plugins/eds/Makefile.am                            |   46 +
 plugins/eds/edit-pane.ui                           |  274 ++++
 plugins/eds/eds.gresource.xml                      |    6 +
 plugins/eds/eds.plugin.in                          |   13 +
 plugins/eds/gtd-plugin-eds.c                       |  378 ++++++
 .../eds/gtd-plugin-eds.h                           |   19 +-
 plugins/eds/gtd-provider-eds.c                     |  972 ++++++++++++++
 plugins/eds/gtd-provider-eds.h                     |   67 +
 plugins/eds/gtd-provider-goa.c                     |  379 ++++++
 .../eds/gtd-provider-goa.h                         |   26 +-
 plugins/eds/gtd-provider-local.c                   |  247 ++++
 .../eds/gtd-provider-local.h                       |   22 +-
 plugins/eds/gtd-task-list-eds.c                    |  248 ++++
 .../eds/gtd-task-list-eds.h                        |   29 +-
 src/Makefile.am                                    |   24 +-
 src/gtd-initial-setup-window.c                     |   12 +-
 src/gtd-manager.c                                  | 1346 ++------------------
 src/gtd-manager.h                                  |   14 +-
 src/gtd-task-list.c                                |   69 +-
 src/gtd-task-list.h                                |    3 +-
 src/gtd-types.h                                    |    1 +
 src/gtd-window.c                                   |   22 +-
 .../gtd-provider-dialog.c}                         |  108 +-
 .../gtd-provider-dialog.h}                         |   18 +-
 .../gtd-provider-popover.c}                        |  166 ++--
 .../gtd-provider-popover.h}                        |   14 +-
 .../gtd-provider-row.c}                            |  146 ++--
 .../gtd-provider-row.h}                            |   14 +-
 .../gtd-provider-selector.c}                       |  424 +++----
 .../gtd-provider-selector.h}                       |   30 +-
 src/storage/gtd-storage-goa.c                      |  375 ------
 src/storage/gtd-storage-goa.h                      |   50 -
 src/storage/gtd-storage-local.c                    |  136 --
 src/storage/gtd-storage.c                          |  528 --------
 src/storage/gtd-storage.h                          |   85 --
 46 files changed, 3366 insertions(+), 3031 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 6bd056d..9851c4b 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,9 @@
+include $(top_srcdir)/common.am
+
 ACLOCAL_AMFLAGS = --install -I m4 ${ACLOCAL_FLAGS}
 
-SUBDIRS = src data po
-DIST_SUBDIRS = src data po
+SUBDIRS = src data plugins po
+DIST_SUBDIRS = src data plugins po
 
 INTLTOOL_FILES = \
        intltool-extract.in \
diff --git a/common.am b/common.am
new file mode 100644
index 0000000..ce557d1
--- /dev/null
+++ b/common.am
@@ -0,0 +1,8 @@
+plugindir = @GNOME_TODO_PLUGIN_DIR@
+
+GNOME_TODO_PLUGIN_CFLAGS = \
+       $(GNOME_TODO_CFLAGS)
+
+
+GNOME_TODO_PLUGIN_WARN_CFLAGS = \
+       $(GNOME_TODO_WARN_CFLAGS)
diff --git a/configure.ac b/configure.ac
index ce570cb..c9a5e7f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -74,12 +74,21 @@ PKG_CHECK_MODULES(GNOME_TODO,
 
 APPSTREAM_XML
 
+
+dnl ================================================================
+dnl Plugins
+dnl ================================================================
+GNOME_TODO_ADD_PLUGIN([eds], [Evolution-Data-Server], [yes])
+
+AC_SUBST([GNOME_TODO_PLUGIN_DIR], [${libdir}])
+
 AC_CONFIG_FILES([
       Makefile
       src/Makefile
       data/Makefile
       data/icons/Makefile
       data/org.gnome.Todo.desktop.in
+      plugins/Makefile
       po/Makefile.in
 ])
 
diff --git a/data/Makefile.am b/data/Makefile.am
index 3b70c21..3e8b513 100644
--- a/data/Makefile.am
+++ b/data/Makefile.am
@@ -34,10 +34,10 @@ EXTRA_DIST=                     \
   ui/initial-setup.ui \
   ui/list-view.ui \
   ui/notification.ui \
-  ui/storage-dialog.ui \
-  ui/storage-popover.ui \
-  ui/storage-row.ui \
-  ui/storage-selector.ui \
+  ui/provider-dialog.ui \
+  ui/provider-popover.ui \
+  ui/provider-row.ui \
+  ui/provider-selector.ui \
   ui/task-list-item.ui \
   ui/task-row.ui \
   ui/window.ui \
diff --git a/data/todo.gresource.xml b/data/todo.gresource.xml
index c81567a..46e12c4 100644
--- a/data/todo.gresource.xml
+++ b/data/todo.gresource.xml
@@ -6,10 +6,10 @@
     <file compressed="true" preprocess="xml-stripblanks">ui/initial-setup.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/list-view.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/notification.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">ui/storage-dialog.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">ui/storage-popover.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">ui/storage-row.ui</file>
-    <file compressed="true" preprocess="xml-stripblanks">ui/storage-selector.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">ui/provider-dialog.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">ui/provider-popover.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">ui/provider-row.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks">ui/provider-selector.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/task-list-item.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/task-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks">ui/window.ui</file>
diff --git a/data/ui/storage-dialog.ui b/data/ui/provider-dialog.ui
similarity index 81%
rename from data/ui/storage-dialog.ui
rename to data/ui/provider-dialog.ui
index 159661e..1bfceb9 100644
--- a/data/ui/storage-dialog.ui
+++ b/data/ui/provider-dialog.ui
@@ -1,13 +1,13 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="3.16"/>
-  <template class="GtdStorageDialog" parent="GtkDialog">
+  <template class="GtdProviderDialog" parent="GtkDialog">
     <property name="can_focus">False</property>
     <property name="type_hint">dialog</property>
     <property name="width_request">450</property>
     <property name="height_request">450</property>
-    <signal name="close" handler="gtk_widget_hide" object="GtdStorageDialog" swapped="no" />
-    <signal name="response" handler="gtk_widget_hide" object="GtdStorageDialog" swapped="no" />
+    <signal name="close" handler="gtk_widget_hide" object="GtdProviderDialog" swapped="no" />
+    <signal name="response" handler="gtk_widget_hide" object="GtdProviderDialog" swapped="no" />
     <child internal-child="vbox">
       <object class="GtkBox" id="main_box">
         <property name="can_focus">False</property>
@@ -24,11 +24,11 @@
           </object>
         </child>
         <child>
-          <object class="GtdStorageSelector" id="storage_selector">
+          <object class="GtdProviderSelector" id="provider_selector">
             <property name="visible">True</property>
             <property name="select_default">True</property>
             <property name="show_local">True</property>
-            <signal name="storage-selected" handler="gtd_storage_dialog__storage_selected" 
object="GtdStorageDialog" swapped="yes" />
+            <signal name="provider-selected" handler="gtd_provider_dialog__provider_selected" 
object="GtdProviderDialog" swapped="yes" />
           </object>
         </child>
       </object>
diff --git a/data/ui/storage-popover.ui b/data/ui/provider-popover.ui
similarity index 86%
rename from data/ui/storage-popover.ui
rename to data/ui/provider-popover.ui
index 998d202..56a4521 100644
--- a/data/ui/storage-popover.ui
+++ b/data/ui/provider-popover.ui
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="3.16"/>
-  <template class="GtdStoragePopover" parent="GtkPopover">
+  <template class="GtdProviderPopover" parent="GtkPopover">
     <property name="can_focus">False</property>
     <property name="border_width">18</property>
-    <signal name="closed" handler="gtd_storage_popover__closed" swapped="no" />
+    <signal name="closed" handler="gtd_provider_popover__closed" swapped="no" />
     <child>
       <object class="GtkStack" id="stack">
         <property name="visible">True</property>
@@ -26,7 +26,7 @@
                 <property name="sensitive">False</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <signal name="clicked" handler="gtd_storage_popover__action_button_clicked" 
object="GtdStoragePopover" swapped="yes" />
+                <signal name="clicked" handler="gtd_provider_popover__action_button_clicked" 
object="GtdProviderPopover" swapped="yes" />
                 <style>
                   <class name="suggested-action"/>
                 </style>
@@ -42,7 +42,7 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">True</property>
-                <signal name="clicked" handler="gtd_storage_popover__action_button_clicked" 
object="GtdStoragePopover" swapped="yes" />
+                <signal name="clicked" handler="gtd_provider_popover__action_button_clicked" 
object="GtdProviderPopover" swapped="yes" />
               </object>
               <packing>
                 <property name="left_attach">0</property>
@@ -75,8 +75,8 @@
                     <property name="can_focus">True</property>
                     <property name="hexpand">True</property>
                     <property name="width_chars">35</property>
-                    <signal name="notify::text" handler="gtd_storage_popover__text_changed_cb" 
object="GtdStoragePopover" swapped="yes" />
-                    <signal name="activate" handler="gtd_storage_popover__entry_activate" 
object="GtdStoragePopover" swapped="yes" />
+                    <signal name="notify::text" handler="gtd_provider_popover__text_changed_cb" 
object="GtdProviderPopover" swapped="yes" />
+                    <signal name="activate" handler="gtd_provider_popover__entry_activate" 
object="GtdProviderPopover" swapped="yes" />
                   </object>
                   <packing>
                     <property name="expand">False</property>
@@ -90,7 +90,7 @@
                     <property name="can_focus">True</property>
                     <property name="receives_default">True</property>
                     <property name="sensitive">False</property>
-                    <signal name="clicked" handler="gtd_storage_popover__change_location_clicked" 
object="GtdStoragePopover" swapped="yes" />
+                    <signal name="clicked" handler="gtd_provider_popover__change_location_clicked" 
object="GtdProviderPopover" swapped="yes" />
                     <child>
                       <object class="GtkImage" id="location_provider_image">
                         <property name="visible">True</property>
@@ -130,7 +130,7 @@
               <object class="GtkButton" id="back_button">
                 <property name="visible">True</property>
                 <property name="halign">start</property>
-                <signal name="clicked" handler="gtd_storage_popover__change_location_clicked" 
object="GtdStoragePopover" swapped="yes" />
+                <signal name="clicked" handler="gtd_provider_popover__change_location_clicked" 
object="GtdProviderPopover" swapped="yes" />
                 <child>
                   <object class="GtkImage" id="back_image">
                     <property name="visible">True</property>
@@ -158,13 +158,13 @@
               </packing>
             </child>
             <child>
-              <object class="GtdStorageSelector" id="storage_selector">
+              <object class="GtdProviderSelector" id="provider_selector">
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="show_local">True</property>
                 <property name="select_default">True</property>
                 <property name="show_stub_rows">False</property>
-                <signal name="storage-selected" handler="gtd_storage_popover__storage_selected" 
object="GtdStoragePopover" swapped="yes" />
+                <signal name="provider-selected" handler="gtd_provider_popover__provider_selected" 
object="GtdProviderPopover" swapped="yes" />
               </object>
               <packing>
                 <property name="left_attach">0</property>
diff --git a/data/ui/storage-row.ui b/data/ui/provider-row.ui
similarity index 96%
rename from data/ui/storage-row.ui
rename to data/ui/provider-row.ui
index de31889..299641e 100644
--- a/data/ui/storage-row.ui
+++ b/data/ui/provider-row.ui
@@ -2,7 +2,7 @@
 <!-- Generated with glade 3.18.1 -->
 <interface>
   <requires lib="gtk+" version="3.16"/>
-  <template class="GtdStorageRow" parent="GtkListBoxRow">
+  <template class="GtdProviderRow" parent="GtkListBoxRow">
     <property name="visible">True</property>
     <property name="can_focus">True</property>
     <property name="selectable">False</property>
@@ -53,7 +53,7 @@
           </packing>
         </child>
         <child>
-          <object class="GtkLabel" id="provider">
+          <object class="GtkLabel" id="description">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
             <property name="xalign">0</property>
diff --git a/data/ui/storage-selector.ui b/data/ui/provider-selector.ui
similarity index 96%
rename from data/ui/storage-selector.ui
rename to data/ui/provider-selector.ui
index e9254f7..19b04ab 100644
--- a/data/ui/storage-selector.ui
+++ b/data/ui/provider-selector.ui
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
   <requires lib="gtk+" version="3.16"/>
-  <template class="GtdStorageSelector" parent="GtkBox">
+  <template class="GtdProviderSelector" parent="GtkBox">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="orientation">vertical</property>
@@ -19,7 +19,7 @@
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
             <property name="selection_mode">none</property>
-            <signal name="row-activated" handler="gtd_storage_selector__listbox_row_activated" 
object="GtdStorageSelector" swapped="yes" />
+            <signal name="row-activated" handler="gtd_provider_selector__listbox_row_activated" 
object="GtdProviderSelector" swapped="yes" />
             <child>
               <object class="GtkListBoxRow" id="google_stub_row">
                 <property name="visible">True</property>
@@ -156,7 +156,7 @@
         <property name="can_focus">True</property>
         <property name="receives_default">False</property>
         <property name="draw_indicator">True</property>
-        <signal name="toggled" handler="gtd_storage_selector__check_toggled" object="GtdStorageSelector" 
swapped="yes" />
+        <signal name="toggled" handler="gtd_provider_selector__check_toggled" object="GtdProviderSelector" 
swapped="yes" />
       </object>
       <packing>
         <property name="expand">False</property>
diff --git a/data/ui/window.ui b/data/ui/window.ui
index 0e63ad4..8d6f1c8 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -2,11 +2,11 @@
 <!-- Generated with glade 3.18.1 -->
 <interface>
   <requires lib="gtk+" version="3.16"/>
-  <object class="GtdStoragePopover" id="new_list_popover">
+  <object class="GtdProviderPopover" id="new_list_popover">
     <property name="can_focus">False</property>
     <property name="position">bottom</property>
   </object>
-  <object class="GtdStorageDialog" id="storage_dialog">
+  <object class="GtdProviderDialog" id="provider_dialog">
     <property name="visible">False</property>
     <property name="modal">True</property>
     <property name="transient_for">GtdWindow</property>
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
new file mode 100644
index 0000000..da699ff
--- /dev/null
+++ b/plugins/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS = eds
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/plugins/eds/Makefile.am b/plugins/eds/Makefile.am
new file mode 100644
index 0000000..5310323
--- /dev/null
+++ b/plugins/eds/Makefile.am
@@ -0,0 +1,46 @@
+include $(top_srcdir)/common.am
+
+plugindir = $(datadir)/gnome-todo/plugins
+
+plugin_LTLIBRARIES = libeds.la
+plugin_DATA = eds.plugin
+
+BUILT_SOURCES = \
+       gtd-plugin-eds-resources.c
+
+libeds_la_SOURCES = \
+       gtd-plugin-eds.c \
+       gtd-plugin-eds.h \
+       gtd-provider-eds.c \
+       gtd-provider-eds.h \
+       gtd-provider-goa.c \
+       gtd-provider-goa.h \
+       gtd-provider-local.c \
+       gtd-provider-local.h \
+       gtd-task-list-eds.c \
+       gtd-task-list-eds.h \
+       $(BUILT_SOURCES)
+
+libeds_la_CFLAGS = \
+       $(GNOME_TODO_PLUGIN_CFLAGS) \
+       $(GNOME_TODO_PLUGIN_WARN_CFLAGS) \
+       -DGOA_API_IS_SUBJECT_TO_CHANGE \
+       -DG_LOG_DOMAIN='"EDS"'
+
+libeds_la_LIBADD = \
+       $(GNOME_TODO_LIBS)
+
+libeds_la_LDFLAGS = \
+       -Wl -module \
+       $(GNOME_TODO_WARN_LDFLAGS)
+
+# generate binary-bundle resources
+resource_files = $(shell $(GLIB_COMPILE_RESOURCES) --generate-dependencies \
+                --sourcedir=$(top_srcdir)/plugins/eds $(top_srcdir)/plugins/eds/eds.gresource.xml)
+
+gtd-plugin-eds-resources.c: eds.gresource.xml $(resource_files)
+       $(AM_V_GEN) $(GLIB_COMPILE_RESOURCES) --target=$@ --sourcedir=$(top_srcdir)/plugins/eds 
--generate-source $<
+
+
+
+EXTRA_DIST = eds.plugin.in
diff --git a/plugins/eds/edit-pane.ui b/plugins/eds/edit-pane.ui
new file mode 100644
index 0000000..50f039b
--- /dev/null
+++ b/plugins/eds/edit-pane.ui
@@ -0,0 +1,274 @@
+<interface>
+  <object class="GtkGrid" id="eds_edit_grid">
+    <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_top">6</property>
+    <property name="margin_bottom">12</property>
+    <property name="vexpand">True</property>
+    <property name="row_spacing">6</property>
+    <property name="column_spacing">12</property>
+    <child>
+      <object class="GtkButton" id="close_button">
+        <property name="visible">True</property>
+        <property name="can_focus">True</property>
+        <property name="receives_default">False</property>
+        <property name="margin_start">12</property>
+        <property name="margin_end">12</property>
+        <property name="relief">none</property>
+        <signal name="clicked" handler="gtd_edit_pane__close_button_clicked" object="GtdEditPane" 
swapped="no"/>
+        <child>
+          <object class="GtkImage" id="close_button_image">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="icon_name">window-close-symbolic</property>
+          </object>
+        </child>
+        <style>
+          <class name="image-button"/>
+          <class name="flat"/>
+        </style>
+      </object>
+      <packing>
+        <property name="left_attach">1</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkLabel" id="details_label">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="margin_start">12</property>
+        <property name="margin_end">12</property>
+        <property name="hexpand">True</property>
+        <property name="label" translatable="yes">Details</property>
+        <property name="xalign">0</property>
+        <attributes>
+          <attribute name="weight" value="bold"/>
+        </attributes>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">0</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkSeparator" id="separator">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">1</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+    <child>
+      <object class="GtkGrid" id="grid">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="vexpand">True</property>
+        <property name="border_width">12</property>
+        <property name="row_spacing">12</property>
+        <child>
+          <object class="GtkLabel" id="notes_dim_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Notes</property>
+            <property name="xalign">0</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">0</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow" id="notes_scrolled_window">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="shadow_type">in</property>
+            <property name="min_content_width">325</property>
+            <property name="min_content_height">225</property>
+            <child>
+              <object class="GtkTextView" id="notes_textview">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="accepts_tab">False</property>
+                <property name="left-margin">6</property>
+                <property name="right-margin">6</property>
+                <property name="pixels-above-lines">6</property>
+                <property name="wrap-mode">word-char</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">1</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="due_date_dim_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Due Date</property>
+            <property name="xalign">0</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">2</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkMenuButton" id="date_button">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="popover">date_popover</property>
+            <child>
+              <object class="GtkBox" id="date_button_box">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="spacing">6</property>
+                <child>
+                  <object class="GtkLabel" id="date_label">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="hexpand">True</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkImage" id="date_button_image">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">pan-down-symbolic</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">3</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkLabel" id="priority_dim_label">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="label" translatable="yes">Priority</property>
+            <property name="xalign">0</property>
+            <style>
+              <class name="dim-label"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">4</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkComboBoxText" id="priority_combo">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="active">0</property>
+            <items>
+              <item translatable="yes" context="taskpriority">None</item>
+              <item translatable="yes">Low</item>
+              <item translatable="yes">Medium</item>
+              <item translatable="yes">High</item>
+            </items>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">5</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="remove_button">
+            <property name="label" translatable="yes">Delete</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">True</property>
+            <property name="valign">end</property>
+            <property name="vexpand">True</property>
+            <signal name="clicked" handler="gtd_edit_pane__delete_button_clicked" object="GtdEditPane" 
swapped="no" />
+            <style>
+              <class name="destructive-action"/>
+            </style>
+          </object>
+          <packing>
+            <property name="left_attach">0</property>
+            <property name="top_attach">6</property>
+            <property name="width">2</property>
+          </packing>
+        </child>
+      </object>
+      <packing>
+        <property name="left_attach">0</property>
+        <property name="top_attach">2</property>
+        <property name="width">2</property>
+      </packing>
+    </child>
+  </object>
+  <object class="GtkPopover" id="date_popover">
+    <property name="can_focus">False</property>
+    <property name="border_width">12</property>
+    <property name="position">bottom</property>
+    <child>
+      <object class="GtkBox" id="date_popover_box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkCalendar" id="calendar">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="show_week_numbers">True</property>
+            <signal name="day-selected" handler="gtd_edit_pane__date_selected" object="GtdEditPane" 
swapped="no"/>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="no_date_button">
+            <property name="label" translatable="yes" context="taskdate">None</property>
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="receives_default">False</property>
+            <signal name="clicked" handler="gtd_edit_pane__no_date_button_clicked" object="GtdEditPane" 
swapped="no" />
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>
diff --git a/plugins/eds/eds.gresource.xml b/plugins/eds/eds.gresource.xml
new file mode 100644
index 0000000..5cc98dd
--- /dev/null
+++ b/plugins/eds/eds.gresource.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<gresources>
+  <gresource prefix="/org/gnome/todo">
+    <file compressed="true"  alias="ui/eds/edit-pane.ui">edit-pane.ui</file>
+  </gresource>
+</gresources>
diff --git a/plugins/eds/eds.plugin.in b/plugins/eds/eds.plugin.in
new file mode 100644
index 0000000..3861a59
--- /dev/null
+++ b/plugins/eds/eds.plugin.in
@@ -0,0 +1,13 @@
+[Plugin]
+Name = Core
+Module = eds
+Description = Evolution-data-server plugin for GNOME To Do
+Version = @VERSION@
+Authors = Georges Basile Stavracas Neto <gbsneto gnome org>
+Copyright = Copyleft © The To Do maintainers
+Website = https://wiki.gnome.org/Apps/Todo
+Builin = true
+Hidden = true
+License = GPL
+Loader = C
+Depends =
diff --git a/plugins/eds/gtd-plugin-eds.c b/plugins/eds/gtd-plugin-eds.c
new file mode 100644
index 0000000..393af12
--- /dev/null
+++ b/plugins/eds/gtd-plugin-eds.c
@@ -0,0 +1,378 @@
+/* gtd-plugin-eds.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-plugin-eds.h"
+#include "gtd-provider-goa.h"
+#include "gtd-provider-local.h"
+
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <gnome-todo/gnome-todo.h>
+
+/**
+ * The #GtdPluginEds is a class that loads all the
+ * essential providers of GNOME To Do.
+ *
+ * It basically loads #ESourceRegistry which provides
+ * #GtdProviderLocal. Immediately after that, it loads
+ * #GoaClient which provides one #GtdProviderGoa per
+ * supported account.
+ *
+ * The currently supported Online Accounts are Google,
+ * ownCloud and Microsoft Exchange ones.
+ */
+
+struct _GtdPluginEds
+{
+  PeasExtensionBaseClass  parent;
+
+  ESourceRegistry        *registry;
+
+  /* Providers */
+  GList                  *providers;
+};
+
+enum
+{
+  PROP_0,
+  PROP_OBJECT,
+  PROP_PROVIDERS,
+  LAST_PROP
+};
+
+const gchar *supported_accounts[] = {
+  "exchange",
+  "google",
+  "owncloud",
+  NULL
+};
+
+static void          gtd_activatable_iface_init                  (GtdActivatableInterface  *iface);
+
+static void          peas_activatable_iface_init                 (PeasActivatableInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (GtdPluginEds, gtd_plugin_eds, PEAS_TYPE_EXTENSION_BASE,
+                                0,
+                                G_IMPLEMENT_INTERFACE_DYNAMIC (PEAS_TYPE_ACTIVATABLE,
+                                                               peas_activatable_iface_init)
+                                G_IMPLEMENT_INTERFACE_DYNAMIC (GTD_TYPE_ACTIVATABLE,
+                                                               gtd_activatable_iface_init))
+
+/*
+ * PeasActivatable interface implementation
+ */
+static void
+gtd_plugin_eds_activate (PeasActivatable *activatable)
+{
+  g_message ("activate");
+}
+
+static void
+gtd_plugin_eds_deactivate (PeasActivatable *activatable)
+{
+  g_message ("deactivate");
+}
+
+static void
+peas_activatable_iface_init (PeasActivatableInterface *iface)
+{
+  iface->activate = gtd_plugin_eds_activate;
+  iface->deactivate = gtd_plugin_eds_deactivate;
+}
+
+/*
+ * GtdActivatable interface implementation
+ */
+static GList*
+gtd_plugin_eds_get_providers (GtdActivatable *activatable)
+{
+  GtdPluginEds *plugin = GTD_PLUGIN_EDS (activatable);
+
+  return plugin->providers;
+}
+
+static void
+gtd_activatable_iface_init (GtdActivatableInterface *iface)
+{
+  iface->get_providers = gtd_plugin_eds_get_providers;
+}
+
+
+/*
+ * Init
+ */
+
+static void
+gtd_plugin_eds_goa_account_removed_cb (GoaClient    *client,
+                                       GoaObject    *object,
+                                       GtdPluginEds *self)
+{
+  GoaAccount *account;
+
+  account = goa_object_peek_account (object);
+
+  if (g_strv_contains (supported_accounts, goa_account_get_provider_type (account)))
+    {
+      GList *l;
+
+      for (l = self->providers; l != NULL; l = l->next)
+        {
+          if (!GTD_IS_PROVIDER_GOA (l->data))
+            continue;
+
+          if (account == gtd_provider_goa_get_account (l->data))
+            {
+              self->providers = g_list_remove (self->providers, l->data);
+
+              g_signal_emit_by_name (self, "provider-removed", l->data);
+              break;
+            }
+        }
+    }
+}
+
+static void
+gtd_plugin_eds_goa_account_added_cb (GoaClient    *client,
+                                     GoaObject    *object,
+                                     GtdPluginEds *self)
+{
+  GoaAccount *account;
+
+  account = goa_object_get_account (object);
+
+  if (g_strv_contains (supported_accounts, goa_account_get_provider_type (account)))
+    {
+      GtdProviderGoa *provider;
+
+      provider = gtd_provider_goa_new (self->registry, account);
+
+      self->providers = g_list_append (self->providers, provider);
+
+      g_signal_emit_by_name (self, "provider-added", provider);
+    }
+}
+
+static void
+gtd_plugin_eds_goa_client_finish_cb (GObject      *client,
+                                     GAsyncResult *result,
+                                     gpointer      user_data)
+{
+  GtdPluginEds *self;
+  GoaClient *goa_client;
+  GError *error;
+
+  self = GTD_PLUGIN_EDS (user_data);
+  error = NULL;
+
+  goa_client = goa_client_new_finish (result, &error);
+
+  if (!error)
+    {
+      GList *accounts;
+      GList *l;
+
+      /* Load each supported GoaAccount into a GtdProviderGoa */
+      accounts = goa_client_get_accounts (goa_client);
+
+      for (l = accounts; l != NULL; l = l->next)
+        {
+          GoaObject *object;
+          GoaAccount *account;
+
+          object = l->data;
+          account = goa_object_get_account (object);
+
+          if (g_strv_contains (supported_accounts, goa_account_get_provider_type (account)))
+            {
+              GtdProviderGoa *provider;
+
+              g_debug ("Creating new provider for account '%s'", goa_account_get_identity (account));
+
+              /* Create the new GOA provider */
+              provider = gtd_provider_goa_new (self->registry, account);
+
+              self->providers = g_list_append (self->providers, provider);
+
+              g_signal_emit_by_name (self, "provider-added", provider);
+            }
+
+          g_object_unref (account);
+        }
+
+      /* Connect GoaClient signals */
+      g_signal_connect (goa_client,
+                        "account-added",
+                        G_CALLBACK (gtd_plugin_eds_goa_account_added_cb),
+                        user_data);
+
+      g_signal_connect (goa_client,
+                        "account-removed",
+                        G_CALLBACK (gtd_plugin_eds_goa_account_removed_cb),
+                        user_data);
+
+      g_list_free_full (accounts, g_object_unref);
+    }
+  else
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error loading GNOME Online Accounts"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error loading GNOME Online Accounts"),
+                                      error->message);
+      g_clear_error (&error);
+    }
+}
+
+
+
+static void
+gtd_plugin_eds_source_registry_finish_cb (GObject      *source_object,
+                                          GAsyncResult *result,
+                                          gpointer      user_data)
+{
+  GtdPluginEds *self = GTD_PLUGIN_EDS (user_data);
+  GtdProviderLocal *provider;
+  ESourceRegistry *registry;
+  GError *error = NULL;
+
+  registry = e_source_registry_new_finish (result, &error);
+  self->registry = registry;
+
+  /* Abort on error */
+  if (error)
+    {
+      g_warning ("%s: %s",
+                 _("Error loading Evolution-Data-Server backend"),
+                 error->message);
+
+      g_clear_error (&error);
+      return;
+    }
+
+  /* Load the local provider */
+  provider = gtd_provider_local_new (registry);
+  g_signal_emit_by_name (self, "provider-added", provider);
+
+  self->providers = g_list_append (self->providers, provider);
+
+  g_object_notify (G_OBJECT (self), "providers");
+
+  /* We only start loading Goa accounts after
+   * ESourceRegistry is get, since it'd be way
+   * too hard to synchronize these two asynchronous
+   * calls.
+   */
+  goa_client_new (NULL,
+                  (GAsyncReadyCallback) gtd_plugin_eds_goa_client_finish_cb,
+                  self);
+}
+
+static void
+gtd_plugin_eds_finalize (GObject *object)
+{
+  GtdPluginEds *self = (GtdPluginEds *)object;
+
+  g_list_free_full (self->providers, g_object_unref);
+
+  G_OBJECT_CLASS (gtd_plugin_eds_parent_class)->finalize (object);
+}
+
+static void
+gtd_plugin_eds_get_property (GObject    *object,
+                             guint       prop_id,
+                             GValue     *value,
+                             GParamSpec *pspec)
+{
+  GtdPluginEds *self = GTD_PLUGIN_EDS (object);
+
+  switch (prop_id)
+    {
+    case PROP_OBJECT:
+      g_value_set_object (value, NULL);
+      break;
+
+    case PROP_PROVIDERS:
+      g_value_set_pointer (value, self->providers);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_plugin_eds_set_property (GObject      *object,
+                             guint         prop_id,
+                             const GValue *value,
+                             GParamSpec   *pspec)
+{
+  switch (prop_id)
+    {
+    case PROP_OBJECT:
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_plugin_eds_class_init (GtdPluginEdsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtd_plugin_eds_finalize;
+  object_class->get_property = gtd_plugin_eds_get_property;
+  object_class->set_property = gtd_plugin_eds_set_property;
+
+  g_object_class_override_property (object_class,
+                                    PROP_OBJECT,
+                                    "object");
+
+  g_object_class_override_property (object_class,
+                                    PROP_PROVIDERS,
+                                    "providers");
+}
+
+static void
+gtd_plugin_eds_init (GtdPluginEds *self)
+{
+  /* load the source registry */
+  e_source_registry_new (NULL,
+                         (GAsyncReadyCallback) gtd_plugin_eds_source_registry_finish_cb,
+                         self);
+}
+
+/* Empty class_finalize method */
+static void
+gtd_plugin_eds_class_finalize (GtdPluginEdsClass *klass)
+{
+}
+
+G_MODULE_EXPORT void
+peas_register_types (PeasObjectModule *module)
+{
+  gtd_plugin_eds_register_type (G_TYPE_MODULE (module));
+
+  peas_object_module_register_extension_type (module,
+                                              GTD_TYPE_ACTIVATABLE,
+                                              GTD_TYPE_PLUGIN_EDS);
+}
diff --git a/src/storage/gtd-storage-local.h b/plugins/eds/gtd-plugin-eds.h
similarity index 65%
copy from src/storage/gtd-storage-local.h
copy to plugins/eds/gtd-plugin-eds.h
index a0efc7a..24ef1d0 100644
--- a/src/storage/gtd-storage-local.h
+++ b/plugins/eds/gtd-plugin-eds.h
@@ -1,4 +1,4 @@
-/* gtd-storage-local.h
+/* gtd-eds-plugin.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,23 +16,20 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_LOCAL_H
-#define GTD_STORAGE_LOCAL_H
-
-#include "gtd-storage.h"
-#include "gtd-types.h"
+#ifndef GTD_EDS_PLUGIN_H
+#define GTD_EDS_PLUGIN_H
 
 #include <glib.h>
-#include <glib-object.h>
+#include <gnome-todo/gtd-activatable.h>
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_LOCAL (gtd_storage_local_get_type())
+#define GTD_TYPE_PLUGIN_EDS (gtd_plugin_eds_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageLocal, gtd_storage_local, GTD, STORAGE_LOCAL, GtdStorage)
+G_DECLARE_FINAL_TYPE (GtdPluginEds, gtd_plugin_eds, GTD, PLUGIN_EDS, PeasExtensionBase)
 
-GtdStorage*          gtd_storage_local_new                       (void);
+G_MODULE_EXPORT void  peas_register_types                        (PeasObjectModule   *module);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_LOCAL_H */
+#endif /* GTD_EDS_PLUGIN_H */
diff --git a/plugins/eds/gtd-provider-eds.c b/plugins/eds/gtd-provider-eds.c
new file mode 100644
index 0000000..ba571ce
--- /dev/null
+++ b/plugins/eds/gtd-provider-eds.c
@@ -0,0 +1,972 @@
+/* gtd-provider-eds.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-provider-eds.h"
+#include "gtd-task-list-eds.h"
+
+#include <glib/gi18n.h>
+
+/**
+ * #GtdProviderEds is the base class of #GtdProviderLocal
+ * and #GtdProviderGoa. It provides the common functionality
+ * shared between these two providers.
+ *
+ * The subclasses basically have to implement GtdProviderEds->should_load_source
+ * which decides whether a given #ESource should be loaded (and added to the
+ * sources list) or not. #GtdProviderLocal for example would filter out
+ * sources whose backend is not "local".
+ */
+
+typedef struct
+{
+  GList                *task_lists;
+
+  ESourceRegistry      *source_registry;
+  ECredentialsPrompter *credentials_prompter;
+
+  GHashTable           *clients;
+  gint                  loaded_sources;
+
+  gint                  lazy_load_id;
+} GtdProviderEdsPrivate;
+
+/* Auxiliary struct for asyncronous task operations */
+typedef struct _TaskData
+{
+  GtdProviderEds     *provider;
+  gpointer           *data;
+} TaskData;
+
+
+G_DEFINE_TYPE_WITH_PRIVATE (GtdProviderEds, gtd_provider_eds, GTD_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_REGISTRY,
+  N_PROPS
+};
+
+static TaskData*
+task_data_new (GtdProviderEds *provider,
+               gpointer       *data)
+{
+  TaskData *tdata;
+
+  tdata = g_new0 (TaskData, 1);
+  tdata->provider = provider;
+  tdata->data = data;
+
+  return tdata;
+}
+
+
+static void
+gtd_provider_eds_fill_task_list (GObject      *client,
+                                 GAsyncResult *result,
+                                 gpointer      user_data)
+{
+  GtdTaskList *list;
+  TaskData *data = user_data;
+  GSList *component_list;
+  GError *error = NULL;
+
+  g_return_if_fail (GTD_IS_PROVIDER_EDS (data->provider));
+
+  list = GTD_TASK_LIST (data->data);
+
+  e_cal_client_get_object_list_as_comps_finish (E_CAL_CLIENT (client),
+                                                result,
+                                                &component_list,
+                                                &error);
+
+  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
+  g_free (data);
+
+  if (!error)
+    {
+      GSList *l;
+
+      for (l = component_list; l != NULL; l = l->next)
+        {
+          GtdTask *task;
+
+          task = gtd_task_new (l->data);
+          gtd_task_set_list (task, list);
+
+          gtd_task_list_save_task (list, task);
+        }
+
+      e_cal_client_free_ecalcomp_slist (component_list);
+    }
+  else
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error fetching tasks from list"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error fetching tasks from list"),
+                                      error->message);
+      g_error_free (error);
+      return;
+    }
+}
+
+static void
+gtd_provider_eds_on_client_connected (GObject      *source_object,
+                                      GAsyncResult *result,
+                                      gpointer      user_data)
+{
+  GtdProviderEdsPrivate *priv;
+  GtdProviderEds *self;
+  ECalClient *client;
+  ESource *source;
+  GError *error = NULL;
+
+  self = GTD_PROVIDER_EDS (user_data);
+  priv = gtd_provider_eds_get_instance_private (self);
+  source = e_client_get_source (E_CLIENT (source_object));
+  client = E_CAL_CLIENT (e_cal_client_connect_finish (result, &error));
+
+  /* Update ready flag */
+  priv->loaded_sources--;
+  gtd_object_set_ready (GTD_OBJECT (user_data), priv->loaded_sources <= 0);
+
+  if (!error)
+    {
+      GtdTaskListEds *list;
+      TaskData *data;
+      ESource *parent;
+
+      /* parent source's display name is list's origin */
+      parent = e_source_registry_ref_source (priv->source_registry, e_source_get_parent (source));
+
+      /* creates a new task list */
+      list = gtd_task_list_eds_new (GTD_PROVIDER (self), source);
+
+      /* it's not ready until we fetch the list of tasks from client */
+      gtd_object_set_ready (GTD_OBJECT (list), FALSE);
+
+      /* async data */
+      data = task_data_new (user_data, (gpointer) list);
+
+      /* asyncronously fetch the task list */
+      e_cal_client_get_object_list_as_comps (client,
+                                             "contains? \"any\" \"\"",
+                                             NULL,
+                                             gtd_provider_eds_fill_task_list,
+                                             data);
+
+      priv->task_lists = g_list_append (priv->task_lists, list);
+
+      g_object_set_data (G_OBJECT (source), "task-list", list);
+      g_hash_table_insert (priv->clients, source, client);
+
+      /* Emit LIST_ADDED signal */
+      g_signal_emit_by_name (self, "list-added", list);
+
+      g_object_unref (parent);
+
+      g_debug ("%s: %s (%s)",
+               G_STRFUNC,
+               _("Task list source successfully connected"),
+               e_source_get_display_name (source));
+    }
+  else
+    {
+      g_debug ("%s: %s (%s): %s",
+               G_STRFUNC,
+               _("Failed to connect to task list source"),
+               e_source_get_uid (source),
+               error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Failed to connect to task list source"),
+                                      error->message);
+
+      g_error_free (error);
+      return;
+    }
+
+}
+
+static void
+gtd_provider_eds_load_source (GtdProviderEds *provider,
+                              ESource        *source)
+{
+  GtdProviderEdsPrivate *priv;
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST) &&
+      !g_hash_table_lookup (priv->clients, source) &&
+      GTD_PROVIDER_EDS_CLASS (G_OBJECT_GET_CLASS (provider))->should_load_source (provider, source))
+    {
+      e_cal_client_connect (source,
+                            E_CAL_CLIENT_SOURCE_TYPE_TASKS,
+                            10, /* seconds to wait */
+                            NULL,
+                            gtd_provider_eds_on_client_connected,
+                            provider);
+    }
+}
+
+static void
+gtd_provider_eds_remove_source (GtdProviderEds *provider,
+                                ESource        *source)
+{
+  GtdProviderEdsPrivate *priv;
+  GtdTaskList *list;
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  list = g_object_get_data (G_OBJECT (source), "task-list");
+
+  g_hash_table_remove (priv->clients, source);
+
+  /* Since all subclasses will have this signal given that they
+   * are all GtdProvider implementations, it's not that bad
+   * to let it stay here.
+   */
+  g_signal_emit_by_name (provider, "list-removed", list);
+}
+
+
+
+
+/************************
+ * Credentials prompter *
+ ************************/
+
+static void
+gtd_manager__invoke_authentication (GObject      *source_object,
+                                    GAsyncResult *result,
+                                    gpointer      user_data)
+{
+  ESource *source = E_SOURCE (source_object);
+  GError *error = NULL;
+  gboolean canceled;
+
+  e_source_invoke_authenticate_finish (source,
+                                       result,
+                                       &error);
+
+  canceled = g_error_matches (error,
+                                   G_IO_ERROR,
+                                   G_IO_ERROR_CANCELLED);
+
+  if (!canceled)
+    {
+      g_warning ("%s: %s (%s): %s",
+                 G_STRFUNC,
+                 _("Failed to prompt for credentials"),
+                 e_source_get_uid (source),
+                 error->message);
+    }
+
+  g_clear_error (&error);
+}
+
+static void
+gtd_provider_local_credentials_prompt_done (GObject      *source_object,
+                                            GAsyncResult *result,
+                                            gpointer      user_data)
+{
+  ETrustPromptResponse response = E_TRUST_PROMPT_RESPONSE_UNKNOWN;
+  ESource *source = E_SOURCE (source_object);
+  GError *error = NULL;
+
+  e_trust_prompt_run_for_source_finish (source, result, &response, &error);
+
+  if (error)
+    {
+      g_warning ("%s: %s '%s': %s",
+                 G_STRFUNC,
+                 _("Failed to prompt for credentials for"),
+                 e_source_get_display_name (source),
+                 error->message);
+
+    }
+  else if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == 
E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY)
+    {
+      /* Use NULL credentials to reuse those from the last time. */
+      e_source_invoke_authenticate (source,
+                                    NULL,
+                                    NULL /* cancellable */,
+                                    gtd_manager__invoke_authentication,
+                                    NULL);
+    }
+
+  g_clear_error (&error);
+}
+
+static void
+gtd_provider_eds_credentials_required (ESourceRegistry          *registry,
+                                       ESource                  *source,
+                                       ESourceCredentialsReason  reason,
+                                       const gchar              *certificate_pem,
+                                       GTlsCertificateFlags      certificate_errors,
+                                       const GError             *error,
+                                       gpointer                  user_data)
+{
+  GtdProviderEdsPrivate *priv;
+  GtdProviderEds *self;
+
+  g_return_if_fail (GTD_IS_PROVIDER_EDS (user_data));
+
+  self = GTD_PROVIDER_EDS (user_data);
+  priv = gtd_provider_eds_get_instance_private (self);
+
+  if (e_credentials_prompter_get_auto_prompt_disabled_for (priv->credentials_prompter, source))
+    return;
+
+  if (reason == E_SOURCE_CREDENTIALS_REASON_SSL_FAILED)
+    {
+      e_trust_prompt_run_for_source (e_credentials_prompter_get_dialog_parent (priv->credentials_prompter),
+                                     source,
+                                     certificate_pem,
+                                     certificate_errors,
+                                     error ? error->message : NULL,
+                                     TRUE, // allow saving sources
+                                     NULL, // we won't cancel the operation
+                                     gtd_provider_local_credentials_prompt_done,
+                                     NULL);
+    }
+  else if (error && reason == E_SOURCE_CREDENTIALS_REASON_ERROR)
+    {
+      g_warning ("%s: %s '%s': %s",
+                 G_STRFUNC,
+                 _("Authentication failure"),
+                 e_source_get_display_name (source),
+                 error->message);
+    }
+}
+
+
+static void
+gtd_provider_eds_finalize (GObject *object)
+{
+  GtdProviderEds *self = (GtdProviderEds *)object;
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (self);
+
+  g_clear_pointer (&priv->clients, g_hash_table_destroy);
+  g_clear_object (&priv->credentials_prompter);
+  g_clear_object (&priv->source_registry);
+
+  G_OBJECT_CLASS (gtd_provider_eds_parent_class)->finalize (object);
+}
+
+static void
+gtd_provider_eds_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GtdProviderEds *self = GTD_PROVIDER_EDS (object);
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (self);
+
+  switch (prop_id)
+    {
+    case PROP_REGISTRY:
+      g_value_set_object (value, priv->source_registry);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_provider_eds_load_registry (GtdProviderEds  *provider)
+{
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (provider);
+  GList *sources;
+  GList *l;
+  GError *error = NULL;
+
+  priv->credentials_prompter = e_credentials_prompter_new (priv->source_registry);
+
+  if (error != NULL)
+    {
+      g_warning ("%s: %s", _("Error loading task manager"), error->message);
+      g_error_free (error);
+      return;
+    }
+
+  /* First of all, disable authentication dialog for non-tasklists sources */
+  sources = e_source_registry_list_sources (priv->source_registry, NULL);
+
+  for (l = sources; l != NULL; l = g_list_next (l))
+    {
+      ESource *source = E_SOURCE (l->data);
+
+      /* Mark for skip also currently disabled sources */
+      e_credentials_prompter_set_auto_prompt_disabled_for (priv->credentials_prompter,
+                                                           source,
+                                                           !e_source_has_extension (source, 
E_SOURCE_EXTENSION_TASK_LIST));
+    }
+
+  g_list_free_full (sources, g_object_unref);
+
+  /* Load task list sources */
+  sources = e_source_registry_list_sources (priv->source_registry, E_SOURCE_EXTENSION_TASK_LIST);
+
+  /* While load_sources > 0, Gtd::ready = FALSE */
+  priv->loaded_sources = g_list_length (sources);
+
+  gtd_object_set_ready (GTD_OBJECT (provider), priv->loaded_sources == 0);
+
+  g_debug ("%s: number of sources to load: %d",
+           G_STRFUNC,
+           priv->loaded_sources);
+
+  for (l = sources; l != NULL; l = l->next)
+    gtd_provider_eds_load_source (provider, l->data);
+
+  g_list_free_full (sources, g_object_unref);
+
+  /* listen to the signals, so new sources don't slip by */
+  g_signal_connect_swapped (priv->source_registry,
+                            "source-added",
+                            G_CALLBACK (gtd_provider_eds_load_source),
+                            provider);
+
+  g_signal_connect_swapped (priv->source_registry,
+                            "source-removed",
+                            G_CALLBACK (gtd_provider_eds_remove_source),
+                            provider);
+
+  g_signal_connect (priv->source_registry,
+                    "credentials-required",
+                    G_CALLBACK (gtd_provider_eds_credentials_required),
+                    provider);
+
+  e_credentials_prompter_process_awaiting_credentials (priv->credentials_prompter);
+}
+
+static gboolean
+gtd_provider_eds_try_load (GtdProviderEds *provider)
+{
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (provider);
+
+  if (gtd_object_get_ready (GTD_OBJECT (provider)))
+    {
+      gtd_provider_eds_load_registry (provider);
+      priv->lazy_load_id = 0;
+
+      return G_SOURCE_REMOVE;
+    }
+
+  return G_SOURCE_CONTINUE;
+}
+
+static void
+gtd_provider_eds_set_registry (GtdProviderEds  *provider,
+                               ESourceRegistry *registry)
+{
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (provider);
+
+  g_set_object (&priv->source_registry, registry);
+
+  priv->lazy_load_id = g_timeout_add (250,
+                                      (GSourceFunc) gtd_provider_eds_try_load,
+                                      provider);
+}
+
+
+static void
+gtd_provider_eds_create_task_finished (GObject      *client,
+                                       GAsyncResult *result,
+                                       gpointer      user_data)
+{
+  TaskData *data = user_data;
+  gchar *new_uid = NULL;
+  GError *error = NULL;
+
+  e_cal_client_create_object_finish (E_CAL_CLIENT (client),
+                                     result,
+                                     &new_uid,
+                                     &error);
+
+  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error creating task"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error creating task"),
+                                      error->message);
+
+      g_error_free (error);
+      g_free (data);
+      return;
+    }
+  else
+    {
+      /*
+       * In the case the task UID changes because of creation proccess,
+       * reapply it to the task.
+       */
+      if (new_uid)
+        {
+          gtd_object_set_uid (GTD_OBJECT (data->data), new_uid);
+          g_free (new_uid);
+        }
+
+      g_free (data);
+    }
+}
+
+static void
+gtd_provider_eds_update_task_finished (GObject      *client,
+                                       GAsyncResult *result,
+                                       gpointer      user_data)
+{
+  TaskData *data = user_data;
+  GError *error = NULL;
+
+  e_cal_client_modify_object_finish (E_CAL_CLIENT (client),
+                                     result,
+                                     &error);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error updating task"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error updating task"),
+                                      error->message);
+
+      g_error_free (error);
+    }
+
+  g_free (data);
+
+  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
+}
+
+static void
+gtd_provider_eds_remove_task_finished (GObject      *client,
+                                       GAsyncResult *result,
+                                       gpointer      user_data)
+{
+  TaskData *data = user_data;
+  GError *error = NULL;
+
+  e_cal_client_remove_object_finish (E_CAL_CLIENT (client),
+                                     result,
+                                     &error);
+
+  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
+
+  g_object_unref ((GtdTask*) data->data);
+  g_free (data);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error removing task"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error removing task"),
+                                      error->message);
+      g_error_free (error);
+      return;
+    }
+}
+
+static void
+gtd_provider_eds_remote_create_source_finished (GObject      *source,
+                                                GAsyncResult *result,
+                                                gpointer      user_data)
+{
+  GError *error;
+
+  error = NULL;
+
+  e_source_remote_create_finish (E_SOURCE (source),
+                                 result,
+                                 &error);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error creating task list"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error creating task list"),
+                                      error->message);
+      g_clear_error (&error);
+    }
+}
+
+static void
+task_list_removal_finished (GtdManager  *manager,
+                            ESource     *source,
+                            GError     **error)
+{
+  gtd_object_set_ready (GTD_OBJECT (manager), TRUE);
+
+  if (*error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error removing task list"),
+                 (*error)->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error removing task list"),
+                                      (*error)->message);
+      g_clear_error (error);
+    }
+}
+
+
+static void
+gtd_provider_eds_remote_delete_finished (GObject      *source,
+                                         GAsyncResult *result,
+                                         gpointer      user_data)
+{
+  GError *error = NULL;
+
+  e_source_remote_delete_finish (E_SOURCE (source),
+                                 result,
+                                 &error);
+
+  task_list_removal_finished (GTD_MANAGER (user_data),
+                              E_SOURCE (source),
+                              &error);
+}
+
+static void
+gtd_provider_eds_remove_source_finished (GObject      *source,
+                                         GAsyncResult *result,
+                                         gpointer      user_data)
+{
+  GError *error = NULL;
+
+  e_source_remove_finish (E_SOURCE (source),
+                          result,
+                          &error);
+
+  task_list_removal_finished (GTD_MANAGER (user_data),
+                              E_SOURCE (source),
+                              &error);
+}
+
+static void
+gtd_provider_eds_commit_source_finished (GObject      *registry,
+                                         GAsyncResult *result,
+                                         gpointer      user_data)
+{
+  GError *error = NULL;
+
+  g_return_if_fail (GTD_IS_MANAGER (user_data));
+
+  gtd_object_set_ready (GTD_OBJECT (user_data), TRUE);
+  e_source_registry_commit_source_finish (E_SOURCE_REGISTRY (registry),
+                                          result,
+                                          &error);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error saving task list"),
+                 error->message);
+
+      gtd_manager_emit_error_message (gtd_manager_get_default (),
+                                      _("Error saving task list"),
+                                      error->message);
+      g_error_free (error);
+      return;
+    }
+}
+
+static void
+gtd_provider_eds_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GtdProviderEds *self = GTD_PROVIDER_EDS (object);
+
+  switch (prop_id)
+    {
+    case PROP_REGISTRY:
+      gtd_provider_eds_set_registry (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_provider_eds_class_init (GtdProviderEdsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtd_provider_eds_finalize;
+  object_class->get_property = gtd_provider_eds_get_property;
+  object_class->set_property = gtd_provider_eds_set_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_REGISTRY,
+                                   g_param_spec_object ("registry",
+                                                        "Source registry",
+                                                        "The EDS source registry object",
+                                                        E_TYPE_SOURCE_REGISTRY,
+                                                        G_PARAM_READABLE | G_PARAM_WRITABLE | 
G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gtd_provider_eds_init (GtdProviderEds *self)
+{
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (self);
+
+  /* While it's not ready, we don't load tasklists */
+  gtd_object_set_ready (GTD_OBJECT (self), FALSE);
+
+  /* hash table */
+  priv->clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
+                                         (GEqualFunc) e_source_equal,
+                                         g_object_unref,
+                                         g_object_unref);
+}
+
+GtdProviderEds*
+gtd_provider_eds_new (ESourceRegistry *registry)
+{
+  return g_object_new (GTD_TYPE_PROVIDER_EDS,
+                       "registry", registry,
+                       NULL);
+}
+
+ESourceRegistry*
+gtd_provider_eds_get_registry (GtdProviderEds *provider)
+{
+  GtdProviderEdsPrivate *priv;
+
+  g_return_val_if_fail (GTD_IS_PROVIDER_EDS (provider), NULL);
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+
+  return priv->source_registry;
+}
+
+void
+gtd_provider_eds_create_task (GtdProviderEds *provider,
+                              GtdTask        *task)
+{
+  GtdProviderEdsPrivate *priv;
+  GtdTaskListEds *tasklist;
+  ECalComponent *component;
+  ECalClient *client;
+  TaskData *data;
+  ESource *source;
+
+  g_return_if_fail (GTD_IS_TASK (task));
+  g_return_if_fail (GTD_IS_TASK_LIST_EDS (gtd_task_get_list (task)));
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task));
+  source = gtd_task_list_eds_get_source (tasklist);
+  client = g_hash_table_lookup (priv->clients, source);
+  component = gtd_task_get_component (task);
+
+  /* Temporary data for async operation */
+  data = task_data_new (provider, (gpointer) task);
+
+  /* The task is not ready until we finish the operation */
+  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
+
+  e_cal_client_create_object (client,
+                              e_cal_component_get_icalcomponent (component),
+                              NULL, // We won't cancel the operation
+                              (GAsyncReadyCallback) gtd_provider_eds_create_task_finished,
+                              data);
+}
+
+void
+gtd_provider_eds_update_task (GtdProviderEds *provider,
+                              GtdTask        *task)
+{
+  GtdProviderEdsPrivate *priv;
+  GtdTaskListEds *tasklist;
+  ECalComponent *component;
+  ECalClient *client;
+  TaskData *data;
+  ESource *source;
+
+  g_return_if_fail (GTD_IS_TASK (task));
+  g_return_if_fail (GTD_IS_TASK_LIST_EDS (gtd_task_get_list (task)));
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task));
+  source = gtd_task_list_eds_get_source (tasklist);
+  client = g_hash_table_lookup (priv->clients, source);
+  component = gtd_task_get_component (task);
+
+  /* Temporary data for async operation */
+  data = task_data_new (provider, (gpointer) task);
+
+  /* The task is not ready until we finish the operation */
+  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
+
+  e_cal_client_modify_object (client,
+                              e_cal_component_get_icalcomponent (component),
+                              E_CAL_OBJ_MOD_THIS,
+                              NULL, // We won't cancel the operation
+                              (GAsyncReadyCallback) gtd_provider_eds_update_task_finished,
+                              data);
+}
+
+void
+gtd_provider_eds_remove_task (GtdProviderEds *provider,
+                              GtdTask        *task)
+{
+
+  GtdProviderEdsPrivate *priv;
+  ECalComponent *component;
+  GtdTaskListEds *tasklist;
+  ECalComponentId *id;
+  ECalClient *client;
+  TaskData *data;
+  ESource *source;
+
+  g_return_if_fail (GTD_IS_TASK (task));
+  g_return_if_fail (GTD_IS_TASK_LIST_EDS (gtd_task_get_list (task)));
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  tasklist = GTD_TASK_LIST_EDS (gtd_task_get_list (task));
+  source = gtd_task_list_eds_get_source (tasklist);
+  client = g_hash_table_lookup (priv->clients, source);
+  component = gtd_task_get_component (task);
+  id = e_cal_component_get_id (component);
+
+  /* Temporary data for async operation */
+  data = task_data_new (provider, (gpointer) task);
+
+  /* The task is not ready until we finish the operation */
+  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
+
+  e_cal_client_remove_object (client,
+                              id->uid,
+                              id->rid,
+                              E_CAL_OBJ_MOD_THIS,
+                              NULL, // We won't cancel the operation
+                              (GAsyncReadyCallback) gtd_provider_eds_remove_task_finished,
+                              data);
+
+  e_cal_component_free_id (id);
+}
+
+void
+gtd_provider_eds_create_task_list (GtdProviderEds *provider,
+                                   GtdTaskList    *list)
+{
+  GtdProviderEdsPrivate *priv;
+  ESource *source;
+  ESource *parent;
+
+  g_return_if_fail (GTD_IS_TASK_LIST_EDS (list));
+  g_return_if_fail (gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list)));
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  source = gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list));
+  parent = e_source_registry_ref_source (priv->source_registry, e_source_get_parent (source));
+
+  e_source_remote_create (parent,
+                          source,
+                          NULL,
+                          (GAsyncReadyCallback) gtd_provider_eds_remote_create_source_finished,
+                          provider);
+
+  g_object_unref (parent);
+}
+
+void
+gtd_provider_eds_update_task_list (GtdProviderEds *provider,
+                                   GtdTaskList    *list)
+{
+
+  GtdProviderEdsPrivate *priv;
+  ESource *source;
+
+  g_return_if_fail (GTD_IS_TASK_LIST (list));
+  g_return_if_fail (gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list)));
+
+  priv = gtd_provider_eds_get_instance_private (provider);
+  source = gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list));
+
+  gtd_object_set_ready (GTD_OBJECT (provider), FALSE);
+  e_source_registry_commit_source (priv->source_registry,
+                                   source,
+                                   NULL,
+                                   (GAsyncReadyCallback) gtd_provider_eds_commit_source_finished,
+                                   provider);
+}
+
+void
+gtd_provider_eds_remove_task_list (GtdProviderEds *provider,
+                                   GtdTaskList    *list)
+{
+  ESource *source;
+
+  g_return_if_fail (GTD_IS_TASK_LIST (list));
+  g_return_if_fail (gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list)));
+
+  source = gtd_task_list_eds_get_source (GTD_TASK_LIST_EDS (list));
+
+  gtd_object_set_ready (GTD_OBJECT (provider), FALSE);
+
+  if (e_source_get_remote_deletable (source))
+    {
+      e_source_remote_delete (source,
+                              NULL,
+                              (GAsyncReadyCallback) gtd_provider_eds_remote_delete_finished,
+                              provider);
+    }
+  else
+    {
+      e_source_remove (source,
+                       NULL,
+                       (GAsyncReadyCallback) gtd_provider_eds_remove_source_finished,
+                       provider);
+    }
+}
+
+GList*
+gtd_provider_eds_get_task_lists (GtdProviderEds *provider)
+{
+  GtdProviderEdsPrivate *priv = gtd_provider_eds_get_instance_private (provider);
+
+  return priv->task_lists;
+}
diff --git a/plugins/eds/gtd-provider-eds.h b/plugins/eds/gtd-provider-eds.h
new file mode 100644
index 0000000..2b53751
--- /dev/null
+++ b/plugins/eds/gtd-provider-eds.h
@@ -0,0 +1,67 @@
+/* gtd-provider-eds.h
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GTD_PROVIDER_EDS_H
+#define GTD_PROVIDER_EDS_H
+
+#include <glib.h>
+#include <gnome-todo/gnome-todo.h>
+#include <libecal/libecal.h>
+#include <libedataserverui/libedataserverui.h>
+
+G_BEGIN_DECLS
+
+#define GTD_TYPE_PROVIDER_EDS (gtd_provider_eds_get_type())
+
+G_DECLARE_DERIVABLE_TYPE (GtdProviderEds, gtd_provider_eds, GTD, PROVIDER_EDS, GtdObject)
+
+struct _GtdProviderEdsClass
+{
+  GtdObjectClass parent;
+
+  gboolean           (*should_load_source)                       (GtdProviderEds     *provider,
+                                                                  ESource            *source);
+};
+
+GtdProviderEds*      gtd_provider_eds_new                        (ESourceRegistry    *registry);
+
+ESourceRegistry*     gtd_provider_eds_get_registry               (GtdProviderEds     *local);
+
+void                 gtd_provider_eds_create_task                (GtdProviderEds     *provider,
+                                                                  GtdTask            *task);
+
+void                 gtd_provider_eds_update_task                (GtdProviderEds     *provider,
+                                                                  GtdTask            *task);
+
+void                 gtd_provider_eds_remove_task                (GtdProviderEds     *provider,
+                                                                  GtdTask            *task);
+
+void                 gtd_provider_eds_create_task_list           (GtdProviderEds     *provider,
+                                                                  GtdTaskList        *list);
+
+void                 gtd_provider_eds_update_task_list           (GtdProviderEds     *provider,
+                                                                  GtdTaskList        *list);
+
+void                 gtd_provider_eds_remove_task_list           (GtdProviderEds     *provider,
+                                                                  GtdTaskList        *list);
+
+GList*               gtd_provider_eds_get_task_lists             (GtdProviderEds     *provider);
+
+G_END_DECLS
+
+#endif /* GTD_PROVIDER_EDS_H */
diff --git a/plugins/eds/gtd-provider-goa.c b/plugins/eds/gtd-provider-goa.c
new file mode 100644
index 0000000..59ef0a3
--- /dev/null
+++ b/plugins/eds/gtd-provider-goa.c
@@ -0,0 +1,379 @@
+/* gtd-provider-goa.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-provider-eds.h"
+#include "gtd-provider-goa.h"
+
+#include <glib/gi18n.h>
+
+struct _GtdProviderGoa
+{
+  GtdProviderEds          parent;
+
+  GoaAccount             *account;
+  GIcon                  *icon;
+};
+
+static void          gtd_provider_iface_init                     (GtdProviderInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtdProviderGoa, gtd_provider_goa, GTD_TYPE_PROVIDER_EDS,
+                         G_IMPLEMENT_INTERFACE (GTD_TYPE_PROVIDER,
+                                                gtd_provider_iface_init))
+
+enum {
+  PROP_0,
+  PROP_ACCOUNT,
+  PROP_ENABLED,
+  PROP_ICON,
+  PROP_ID,
+  PROP_NAME,
+  PROP_DESCRIPTION,
+  N_PROPS
+};
+
+/*
+ * GtdProviderInterface implementation
+ */
+static const gchar*
+gtd_provider_goa_get_id (GtdProvider *provider)
+{
+  GtdProviderGoa *self;
+
+  self = GTD_PROVIDER_GOA (provider);
+
+  return goa_account_get_provider_type (self->account);
+}
+
+static const gchar*
+gtd_provider_goa_get_name (GtdProvider *provider)
+{
+  GtdProviderGoa *self;
+
+  self = GTD_PROVIDER_GOA (provider);
+
+  return goa_account_get_identity (self->account);
+}
+
+static const gchar*
+gtd_provider_goa_get_description (GtdProvider *provider)
+{
+  GtdProviderGoa *self;
+
+  self = GTD_PROVIDER_GOA (provider);
+
+  return goa_account_get_provider_name (self->account);
+}
+
+
+static gboolean
+gtd_provider_goa_get_enabled (GtdProvider *provider)
+{
+  GtdProviderGoa *self;
+
+  self = GTD_PROVIDER_GOA (provider);
+
+  return !goa_account_get_calendar_disabled (self->account);
+}
+
+static GIcon*
+gtd_provider_goa_get_icon (GtdProvider *provider)
+{
+  GtdProviderGoa *self;
+
+  self = GTD_PROVIDER_GOA (provider);
+
+  return self->icon;
+}
+
+static const GtkWidget*
+gtd_provider_goa_get_edit_panel (GtdProvider *provider)
+{
+  return NULL;
+}
+
+static void
+gtd_provider_goa_create_task (GtdProvider *provider,
+                              GtdTask     *task)
+{
+  gtd_provider_eds_create_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_goa_update_task (GtdProvider *provider,
+                              GtdTask     *task)
+{
+  gtd_provider_eds_update_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_goa_remove_task (GtdProvider *provider,
+                              GtdTask     *task)
+{
+  gtd_provider_eds_remove_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_goa_create_task_list (GtdProvider *provider,
+                                   GtdTaskList *list)
+{
+  gtd_provider_eds_create_task_list (GTD_PROVIDER_EDS (provider), list);
+}
+
+static void
+gtd_provider_goa_update_task_list (GtdProvider *provider,
+                                   GtdTaskList *list)
+{
+  gtd_provider_eds_update_task_list (GTD_PROVIDER_EDS (provider), list);
+}
+
+static void
+gtd_provider_goa_remove_task_list (GtdProvider *provider,
+                                   GtdTaskList *list)
+{
+  gtd_provider_eds_remove_task_list (GTD_PROVIDER_EDS (provider), list);
+
+  g_signal_emit_by_name (provider, "list-removed", list);
+}
+
+static GList*
+gtd_provider_goa_get_task_lists (GtdProvider *provider)
+{
+  return gtd_provider_eds_get_task_lists (GTD_PROVIDER_EDS (provider));
+}
+
+static void
+gtd_provider_iface_init (GtdProviderInterface *iface)
+{
+  iface->get_id = gtd_provider_goa_get_id;
+  iface->get_name = gtd_provider_goa_get_name;
+  iface->get_description = gtd_provider_goa_get_description;
+  iface->get_enabled = gtd_provider_goa_get_enabled;
+  iface->get_icon = gtd_provider_goa_get_icon;
+  iface->get_edit_panel = gtd_provider_goa_get_edit_panel;
+  iface->create_task = gtd_provider_goa_create_task;
+  iface->update_task = gtd_provider_goa_update_task;
+  iface->remove_task = gtd_provider_goa_remove_task;
+  iface->create_task_list = gtd_provider_goa_create_task_list;
+  iface->update_task_list = gtd_provider_goa_update_task_list;
+  iface->remove_task_list = gtd_provider_goa_remove_task_list;
+  iface->get_task_lists = gtd_provider_goa_get_task_lists;
+}
+
+static void
+gtd_provider_goa_set_account (GtdProviderGoa *provider,
+                              GoaAccount     *account)
+{
+  gtd_object_set_ready (GTD_OBJECT (provider), account != NULL);
+
+  if (provider->account != account)
+    {
+      gchar *icon_name;
+
+      g_set_object (&provider->account, account);
+      g_object_notify (G_OBJECT (provider), "account");
+
+
+      g_message ("Setting up Online Account: %s (%s)",
+                 goa_account_get_identity (account),
+                 goa_account_get_id (account));
+
+      /* Update icon */
+      icon_name = g_strdup_printf ("goa-account-%s", goa_account_get_provider_type (provider->account));
+      g_set_object (&provider->icon, g_themed_icon_new (icon_name));
+      g_object_notify (G_OBJECT (provider), "icon");
+
+      g_free (icon_name);
+    }
+}
+
+static void
+gtd_provider_goa_finalize (GObject *object)
+{
+  GtdProviderGoa *self = (GtdProviderGoa *)object;
+
+  g_clear_object (&self->account);
+  g_clear_object (&self->icon);
+
+  G_OBJECT_CLASS (gtd_provider_goa_parent_class)->finalize (object);
+}
+
+static void
+gtd_provider_goa_get_property (GObject    *object,
+                               guint       prop_id,
+                               GValue     *value,
+                               GParamSpec *pspec)
+{
+  GtdProviderGoa *self = GTD_PROVIDER_GOA (object);
+  GtdProvider *provider = GTD_PROVIDER (object);
+
+  switch (prop_id)
+    {
+
+    case PROP_ACCOUNT:
+      g_value_set_object (value, self->account);
+      break;
+
+    case PROP_DESCRIPTION:
+      g_value_set_string (value, gtd_provider_goa_get_description (provider));
+      break;
+
+    case PROP_ENABLED:
+      g_value_set_boolean (value, gtd_provider_goa_get_enabled (provider));
+      break;
+
+    case PROP_ICON:
+      g_value_set_object (value, gtd_provider_goa_get_icon (provider));
+      break;
+
+    case PROP_ID:
+      g_value_set_string (value, gtd_provider_goa_get_id (provider));
+      break;
+
+    case PROP_NAME:
+      g_value_set_string (value, gtd_provider_goa_get_name (provider));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_provider_goa_set_property (GObject      *object,
+                               guint         prop_id,
+                               const GValue *value,
+                               GParamSpec   *pspec)
+{
+  GtdProviderGoa *self = GTD_PROVIDER_GOA (object);
+
+  switch (prop_id)
+    {
+    case PROP_ACCOUNT:
+      gtd_provider_goa_set_account (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static gboolean
+gtd_provider_goa_should_load_source (GtdProviderEds *provider,
+                                     ESource        *source)
+{
+  GtdProviderGoa *self;
+  gboolean retval;
+
+  self = GTD_PROVIDER_GOA (provider);
+  retval = FALSE;
+
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST) &&
+      g_strcmp0 (e_source_get_parent (source), "local-stub") != 0)
+    {
+      ESourceRegistry *registry;
+      GList *sources;
+      GList *l;
+
+      registry = gtd_provider_eds_get_registry (provider);
+
+      /*
+       * Search for the ESource whose parent source has an ESourceGoa extension.
+       * The ESourceGoa, then, must have the same account uid that of @storage.
+       */
+      sources = e_source_registry_list_sources (registry, E_SOURCE_EXTENSION_TASK_LIST);
+
+      for (l = sources; l != NULL; l = l->next)
+        {
+          ESource *current_source;
+          ESource *goa_source;
+
+          current_source = l->data;
+          goa_source = e_source_registry_find_extension (registry,
+                                                         current_source,
+                                                         E_SOURCE_EXTENSION_GOA);
+
+          if (goa_source)
+            {
+              ESourceGoa *goa_ext;
+
+              goa_ext = e_source_get_extension (goa_source, E_SOURCE_EXTENSION_GOA);
+
+              /* Found an ESourceGoa with the same uid of storage */
+              if (g_strcmp0 (e_source_goa_get_account_id (goa_ext), goa_account_get_id (self->account)) == 0)
+                {
+                  retval = TRUE;
+                  break;
+                }
+            }
+
+          g_clear_object (&goa_source);
+        }
+
+      g_list_free_full (sources, g_object_unref);
+    }
+
+  return retval;
+}
+
+static void
+gtd_provider_goa_class_init (GtdProviderGoaClass *klass)
+{
+  GtdProviderEdsClass *eds_class = GTD_PROVIDER_EDS_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  eds_class->should_load_source = gtd_provider_goa_should_load_source;
+
+  object_class->finalize = gtd_provider_goa_finalize;
+  object_class->get_property = gtd_provider_goa_get_property;
+  object_class->set_property = gtd_provider_goa_set_property;
+
+  g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
+  g_object_class_override_property (object_class, PROP_ENABLED, "enabled");
+  g_object_class_override_property (object_class, PROP_ICON, "icon");
+  g_object_class_override_property (object_class, PROP_ID, "id");
+  g_object_class_override_property (object_class, PROP_NAME, "name");
+
+  g_object_class_install_property (object_class,
+                                   PROP_ACCOUNT,
+                                   g_param_spec_object ("account",
+                                                        "Account of the provider",
+                                                        "The Online Account of the provider",
+                                                        GOA_TYPE_ACCOUNT,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+gtd_provider_goa_init (GtdProviderGoa *self)
+{
+}
+
+GtdProviderGoa*
+gtd_provider_goa_new (ESourceRegistry *registry,
+                      GoaAccount      *account)
+{
+  return g_object_new (GTD_TYPE_PROVIDER_GOA,
+                       "account", account,
+                       "registry", registry,
+                       NULL);
+}
+
+GoaAccount*
+gtd_provider_goa_get_account (GtdProviderGoa *provider)
+{
+  return provider->account;
+}
diff --git a/src/storage/gtd-storage-dialog.h b/plugins/eds/gtd-provider-goa.h
similarity index 57%
copy from src/storage/gtd-storage-dialog.h
copy to plugins/eds/gtd-provider-goa.h
index 30d43b5..0146d01 100644
--- a/src/storage/gtd-storage-dialog.h
+++ b/plugins/eds/gtd-provider-goa.h
@@ -1,4 +1,4 @@
-/* gtd-storage-dialog.h
+/* gtd-provider-goa.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,26 +16,26 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_DIALOG_H
-#define GTD_STORAGE_DIALOG_H
+#ifndef GTD_PROVIDER_GOA_H
+#define GTD_PROVIDER_GOA_H
 
-#include "gtd-types.h"
+#include "gtd-provider-eds.h"
 
-#include <gtk/gtk.h>
+#include <glib.h>
+#include <gnome-todo/gnome-todo.h>
+#include <goa/goa.h>
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_DIALOG (gtd_storage_dialog_get_type())
+#define GTD_TYPE_PROVIDER_GOA (gtd_provider_goa_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageDialog, gtd_storage_dialog, GTD, STORAGE_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (GtdProviderGoa, gtd_provider_goa, GTD, PROVIDER_GOA, GtdProviderEds)
 
-GtkWidget*         gtd_storage_dialog_new                        (void);
+GtdProviderGoa*      gtd_provider_goa_new                        (ESourceRegistry    *registry,
+                                                                  GoaAccount         *account);
 
-GtdManager*        gtd_storage_dialog_get_manager                (GtdStorageDialog   *dialog);
-
-void               gtd_storage_dialog_set_manager                (GtdStorageDialog   *dialog,
-                                                                  GtdManager         *manager);
+GoaAccount*          gtd_provider_goa_get_account                (GtdProviderGoa     *provider);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_DIALOG_H */
+#endif /* GTD_PROVIDER_GOA_H */
diff --git a/plugins/eds/gtd-provider-local.c b/plugins/eds/gtd-provider-local.c
new file mode 100644
index 0000000..1f43480
--- /dev/null
+++ b/plugins/eds/gtd-provider-local.c
@@ -0,0 +1,247 @@
+/* gtd-provider-local.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-provider-local.h"
+
+#include <glib/gi18n.h>
+
+struct _GtdProviderLocal
+{
+  GtdProviderEds          parent;
+
+  GIcon                  *icon;
+  GList                  *tasklists;
+};
+
+static void          gtd_provider_iface_init                     (GtdProviderInterface *iface);
+
+G_DEFINE_TYPE_WITH_CODE (GtdProviderLocal, gtd_provider_local, GTD_TYPE_PROVIDER_EDS,
+                         G_IMPLEMENT_INTERFACE (GTD_TYPE_PROVIDER,
+                                                gtd_provider_iface_init))
+
+enum {
+  PROP_0,
+  PROP_ENABLED,
+  PROP_ICON,
+  PROP_ID,
+  PROP_NAME,
+  PROP_DESCRIPTION,
+  LAST_PROP
+};
+
+/*
+ * GtdProviderInterface implementation
+ */
+static const gchar*
+gtd_provider_local_get_id (GtdProvider *provider)
+{
+  return "local";
+}
+
+static const gchar*
+gtd_provider_local_get_name (GtdProvider *provider)
+{
+  return _("Local");
+}
+
+static const gchar*
+gtd_provider_local_get_description (GtdProvider *provider)
+{
+  return _("On This Computer");
+}
+
+
+static gboolean
+gtd_provider_local_get_enabled (GtdProvider *provider)
+{
+  return TRUE;
+}
+
+static GIcon*
+gtd_provider_local_get_icon (GtdProvider *provider)
+{
+  GtdProviderLocal *self;
+
+  self = GTD_PROVIDER_LOCAL (provider);
+
+  return self->icon;
+}
+
+static const GtkWidget*
+gtd_provider_local_get_edit_panel (GtdProvider *provider)
+{
+  return NULL;
+}
+
+static void
+gtd_provider_local_create_task (GtdProvider *provider,
+                                GtdTask     *task)
+{
+  gtd_provider_eds_create_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_local_update_task (GtdProvider *provider,
+                                GtdTask     *task)
+{
+  gtd_provider_eds_update_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_local_remove_task (GtdProvider *provider,
+                                GtdTask     *task)
+{
+  gtd_provider_eds_remove_task (GTD_PROVIDER_EDS (provider), task);
+}
+
+static void
+gtd_provider_local_create_task_list (GtdProvider *provider,
+                                     GtdTaskList *list)
+{
+  gtd_provider_eds_create_task_list (GTD_PROVIDER_EDS (provider), list);
+}
+
+static void
+gtd_provider_local_update_task_list (GtdProvider *provider,
+                                     GtdTaskList *list)
+{
+  gtd_provider_eds_update_task_list (GTD_PROVIDER_EDS (provider), list);
+}
+
+static void
+gtd_provider_local_remove_task_list (GtdProvider *provider,
+                                     GtdTaskList *list)
+{
+  gtd_provider_eds_remove_task_list (GTD_PROVIDER_EDS (provider), list);
+
+  g_signal_emit_by_name (provider, "list-removed", list);
+}
+
+static GList*
+gtd_provider_local_get_task_lists (GtdProvider *provider)
+{
+  return gtd_provider_eds_get_task_lists (GTD_PROVIDER_EDS (provider));
+}
+
+static void
+gtd_provider_iface_init (GtdProviderInterface *iface)
+{
+  iface->get_id = gtd_provider_local_get_id;
+  iface->get_name = gtd_provider_local_get_name;
+  iface->get_description = gtd_provider_local_get_description;
+  iface->get_enabled = gtd_provider_local_get_enabled;
+  iface->get_icon = gtd_provider_local_get_icon;
+  iface->get_edit_panel = gtd_provider_local_get_edit_panel;
+  iface->create_task = gtd_provider_local_create_task;
+  iface->update_task = gtd_provider_local_update_task;
+  iface->remove_task = gtd_provider_local_remove_task;
+  iface->create_task_list = gtd_provider_local_create_task_list;
+  iface->update_task_list = gtd_provider_local_update_task_list;
+  iface->remove_task_list = gtd_provider_local_remove_task_list;
+  iface->get_task_lists = gtd_provider_local_get_task_lists;
+}
+
+GtdProviderLocal*
+gtd_provider_local_new (ESourceRegistry *registry)
+{
+  return g_object_new (GTD_TYPE_PROVIDER_LOCAL,
+                       "registry", registry,
+                       NULL);
+}
+
+static void
+gtd_provider_local_finalize (GObject *object)
+{
+  GtdProviderLocal *self = (GtdProviderLocal *)object;
+
+  g_clear_object (&self->icon);
+
+  G_OBJECT_CLASS (gtd_provider_local_parent_class)->finalize (object);
+}
+
+static void
+gtd_provider_local_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  GtdProvider *provider = GTD_PROVIDER (object);
+
+  switch (prop_id)
+    {
+    case PROP_DESCRIPTION:
+      g_value_set_string (value, gtd_provider_local_get_description (provider));
+      break;
+
+    case PROP_ENABLED:
+      g_value_set_boolean (value, gtd_provider_local_get_enabled (provider));
+      break;
+
+    case PROP_ICON:
+      g_value_set_object (value, gtd_provider_local_get_icon (provider));
+      break;
+
+    case PROP_ID:
+      g_value_set_string (value, gtd_provider_local_get_id (provider));
+      break;
+
+    case PROP_NAME:
+      g_value_set_string (value, gtd_provider_local_get_name (provider));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static gboolean
+gtd_provider_local_should_load_source (GtdProviderEds *provider,
+                                       ESource        *source)
+{
+  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST))
+    return g_strcmp0 (e_source_get_parent (source), "local-stub") == 0;
+
+  return FALSE;
+}
+
+static void
+gtd_provider_local_class_init (GtdProviderLocalClass *klass)
+{
+  GtdProviderEdsClass *eds_class = GTD_PROVIDER_EDS_CLASS (klass);
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  eds_class->should_load_source = gtd_provider_local_should_load_source;
+
+  object_class->finalize = gtd_provider_local_finalize;
+  object_class->get_property = gtd_provider_local_get_property;
+
+  g_object_class_override_property (object_class, PROP_DESCRIPTION, "description");
+  g_object_class_override_property (object_class, PROP_ENABLED, "enabled");
+  g_object_class_override_property (object_class, PROP_ICON, "icon");
+  g_object_class_override_property (object_class, PROP_ID, "id");
+  g_object_class_override_property (object_class, PROP_NAME, "name");
+}
+
+static void
+gtd_provider_local_init (GtdProviderLocal *self)
+{
+  gtd_object_set_ready (GTD_OBJECT (self), TRUE);
+
+  /* icon */
+  self->icon = G_ICON (g_themed_icon_new_with_default_fallbacks ("computer-symbolic"));
+}
diff --git a/src/storage/gtd-storage-local.h b/plugins/eds/gtd-provider-local.h
similarity index 60%
rename from src/storage/gtd-storage-local.h
rename to plugins/eds/gtd-provider-local.h
index a0efc7a..fab47d8 100644
--- a/src/storage/gtd-storage-local.h
+++ b/plugins/eds/gtd-provider-local.h
@@ -1,4 +1,4 @@
-/* gtd-storage-local.h
+/* gtd-provider-local.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,23 +16,25 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_LOCAL_H
-#define GTD_STORAGE_LOCAL_H
+#ifndef GTD_PROVIDER_LOCAL_H
+#define GTD_PROVIDER_LOCAL_H
 
-#include "gtd-storage.h"
-#include "gtd-types.h"
+#include "gtd-provider-eds.h"
 
 #include <glib.h>
-#include <glib-object.h>
+
+#include <gnome-todo/gnome-todo.h>
+#include <libecal/libecal.h>
+#include <libedataserverui/libedataserverui.h>
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_LOCAL (gtd_storage_local_get_type())
+#define GTD_TYPE_PROVIDER_LOCAL (gtd_provider_local_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageLocal, gtd_storage_local, GTD, STORAGE_LOCAL, GtdStorage)
+G_DECLARE_FINAL_TYPE (GtdProviderLocal, gtd_provider_local, GTD, PROVIDER_LOCAL, GtdProviderEds)
 
-GtdStorage*          gtd_storage_local_new                       (void);
+GtdProviderLocal*    gtd_provider_local_new                      (ESourceRegistry    *source_registry);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_LOCAL_H */
+#endif /* GTD_PROVIDER_LOCAL_H */
diff --git a/plugins/eds/gtd-task-list-eds.c b/plugins/eds/gtd-task-list-eds.c
new file mode 100644
index 0000000..71c3eca
--- /dev/null
+++ b/plugins/eds/gtd-task-list-eds.c
@@ -0,0 +1,248 @@
+/* gtd-task-list-eds.c
+ *
+ * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "gtd-task-list-eds.h"
+
+#include <glib/gi18n.h>
+
+struct _GtdTaskListEds
+{
+  GtdTaskList         parent;
+
+  ESource            *source;
+
+  GCancellable       *cancellable;
+};
+
+G_DEFINE_TYPE (GtdTaskListEds, gtd_task_list_eds, GTD_TYPE_TASK_LIST)
+
+enum {
+  PROP_0,
+  PROP_SOURCE,
+  N_PROPS
+};
+
+static void
+save_task_list_finished_cb (GObject      *source,
+                            GAsyncResult *result,
+                            gpointer      user_data)
+{
+  GtdTaskListEds *list;
+  GError *error;
+
+  list = user_data;
+  error = NULL;
+
+  gtd_object_set_ready (GTD_OBJECT (list), TRUE);
+
+  e_source_write_finish (E_SOURCE (source),
+                         result,
+                         &error);
+
+  if (error)
+    {
+      g_warning ("%s: %s: %s",
+                 G_STRFUNC,
+                 _("Error saving task list"),
+                 error->message);
+      g_clear_error (&error);
+    }
+}
+
+static void
+save_task_list (GtdTaskListEds *list)
+{
+  if (!list->cancellable)
+    list->cancellable = g_cancellable_new ();
+
+  gtd_object_set_ready (GTD_OBJECT (list), FALSE);
+
+  e_source_write (list->source,
+                  list->cancellable,
+                  save_task_list_finished_cb,
+                  list);
+}
+static gboolean
+color_to_string (GBinding     *binding,
+                 const GValue *from_value,
+                 GValue       *to_value,
+                 gpointer      user_data)
+{
+  GdkRGBA *color;
+  gchar *color_str;
+
+  color = g_value_get_boxed (from_value);
+  color_str = gdk_rgba_to_string (color);
+
+  g_value_set_string (to_value, color_str);
+
+  g_free (color_str);
+
+  return TRUE;
+}
+
+static gboolean
+string_to_color (GBinding     *binding,
+                 const GValue *from_value,
+                 GValue       *to_value,
+                 gpointer      user_data)
+{
+  GdkRGBA color;
+
+  if (!gdk_rgba_parse (&color, g_value_get_string (from_value)))
+    gdk_rgba_parse (&color, "#ffffff"); /* calendar default colour */
+
+  g_value_set_boxed (to_value, &color);
+
+  return TRUE;
+}
+
+static void
+gtd_task_list_eds_finalize (GObject *object)
+{
+  GtdTaskListEds *self = GTD_TASK_LIST_EDS (object);
+
+  g_cancellable_cancel (self->cancellable);
+
+  g_clear_object (&self->cancellable);
+  g_clear_object (&self->source);
+
+  G_OBJECT_CLASS (gtd_task_list_eds_parent_class)->finalize (object);
+}
+
+static void
+gtd_task_list_eds_get_property (GObject    *object,
+                                guint       prop_id,
+                                GValue     *value,
+                                GParamSpec *pspec)
+{
+  GtdTaskListEds *self = GTD_TASK_LIST_EDS (object);
+
+  switch (prop_id)
+    {
+    case PROP_SOURCE:
+      g_value_set_object (value, self->source);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_task_list_eds_set_property (GObject      *object,
+                                guint         prop_id,
+                                const GValue *value,
+                                GParamSpec   *pspec)
+{
+  GtdTaskListEds *self = GTD_TASK_LIST_EDS (object);
+
+  switch (prop_id)
+    {
+    case PROP_SOURCE:
+      gtd_task_list_eds_set_source (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+gtd_task_list_eds_class_init (GtdTaskListEdsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = gtd_task_list_eds_finalize;
+  object_class->get_property = gtd_task_list_eds_get_property;
+  object_class->set_property = gtd_task_list_eds_set_property;
+
+  /**
+   * GtdTaskListEds::source:
+   *
+   * The #ESource of this #GtdTaskListEds
+   */
+  g_object_class_install_property (object_class,
+                                   PROP_SOURCE,
+                                   g_param_spec_object ("source",
+                                                        "ESource of this list",
+                                                        "The ESource of this list",
+                                                        E_TYPE_SOURCE,
+                                                        G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+}
+
+static void
+gtd_task_list_eds_init (GtdTaskListEds *self)
+{
+}
+
+GtdTaskListEds*
+gtd_task_list_eds_new (GtdProvider *provider,
+                       ESource     *source)
+{
+  return g_object_new (GTD_TYPE_TASK_LIST_EDS,
+                       "provider", provider,
+                       "source", source,
+                       NULL);
+}
+
+ESource*
+gtd_task_list_eds_get_source (GtdTaskListEds *list)
+{
+  g_return_val_if_fail (GTD_IS_TASK_LIST_EDS (list), NULL);
+
+  return list->source;
+}
+
+void
+gtd_task_list_eds_set_source (GtdTaskListEds *list,
+                              ESource        *source)
+{
+  g_return_if_fail (GTD_IS_TASK_LIST_EDS (list));
+
+  if (g_set_object (&list->source, source))
+    {
+      ESourceSelectable *selectable;
+
+      selectable = E_SOURCE_SELECTABLE (e_source_get_extension (source, E_SOURCE_EXTENSION_TASK_LIST));
+
+      g_object_bind_property_full (list,
+                                   "color",
+                                   selectable,
+                                   "color",
+                                   G_BINDING_BIDIRECTIONAL,
+                                   color_to_string,
+                                   string_to_color,
+                                   list,
+                                   NULL);
+
+      g_object_bind_property (list,
+                              "name",
+                              source,
+                              "display-name",
+                              G_BINDING_BIDIRECTIONAL);
+
+      /* Save the task list every time something changes */
+      g_signal_connect_swapped (source,
+                                "notify",
+                                G_CALLBACK (save_task_list),
+                                list);
+
+      g_object_notify (G_OBJECT (list), "source");
+    }
+}
diff --git a/src/storage/gtd-storage-row.h b/plugins/eds/gtd-task-list-eds.h
similarity index 54%
copy from src/storage/gtd-storage-row.h
copy to plugins/eds/gtd-task-list-eds.h
index cd585ae..2579f37 100644
--- a/src/storage/gtd-storage-row.h
+++ b/plugins/eds/gtd-task-list-eds.h
@@ -1,4 +1,4 @@
-/* gtd-storage-row.h
+/* gtd-task-list-eds.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,30 +16,27 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_GOA_ROW_H
-#define GTD_GOA_ROW_H
-
-#include "gtd-types.h"
+#ifndef GTD_TASK_LIST_EDS_H
+#define GTD_TASK_LIST_EDS_H
 
 #include <glib-object.h>
-#include <goa/goa.h>
-#include <gtk/gtk.h>
+#include <gnome-todo/gnome-todo.h>
+#include <libecal/libecal.h>
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_ROW (gtd_storage_row_get_type())
-
-G_DECLARE_FINAL_TYPE (GtdStorageRow, gtd_storage_row, GTD, STORAGE_ROW, GtkListBoxRow)
+#define GTD_TYPE_TASK_LIST_EDS (gtd_task_list_eds_get_type())
 
-GtkWidget*                  gtd_storage_row_new                  (GtdStorage          *storage);
+G_DECLARE_FINAL_TYPE (GtdTaskListEds, gtd_task_list_eds, GTD, TASK_LIST_EDS, GtdTaskList)
 
-gboolean                    gtd_storage_row_get_selected         (GtdStorageRow       *row);
+GtdTaskListEds*      gtd_task_list_eds_new                       (GtdProvider        *provider,
+                                                                  ESource            *source);
 
-void                        gtd_storage_row_set_selected         (GtdStorageRow       *row,
-                                                                  gboolean             selected);
+ESource*             gtd_task_list_eds_get_source                (GtdTaskListEds     *list);
 
-GtdStorage*                 gtd_storage_row_get_storage          (GtdStorageRow       *row);
+void                 gtd_task_list_eds_set_source                (GtdTaskListEds     *list,
+                                                                  ESource            *source);
 
 G_END_DECLS
 
-#endif /* GTD_GOA_ROW_H */
+#endif /* GTD_TASK_LIST_EDS_H */
diff --git a/src/Makefile.am b/src/Makefile.am
index a175afc..0ef48d1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,7 @@ AM_CPPFLAGS = \
        -DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
        -DUI_DATA_DIR=\""$(pkgdatadir)/style"\" \
        -DGOA_API_IS_SUBJECT_TO_CHANGE \
-       -I$(srcdir)/storage \
+       -I$(srcdir)/provider \
        -I$(srcdir)/notification
 
 bin_PROGRAMS = gnome-todo
@@ -30,20 +30,14 @@ gnome_todo_SOURCES = \
        notification/gtd-notification.h \
        notification/gtd-notification-widget.c \
        notification/gtd-notification-widget.h \
-       storage/gtd-storage.c \
-       storage/gtd-storage.h \
-       storage/gtd-storage-dialog.c \
-       storage/gtd-storage-dialog.h \
-       storage/gtd-storage-goa.c \
-       storage/gtd-storage-goa.h \
-       storage/gtd-storage-local.c \
-       storage/gtd-storage-local.h \
-       storage/gtd-storage-popover.c \
-       storage/gtd-storage-popover.h \
-       storage/gtd-storage-row.c \
-       storage/gtd-storage-row.h \
-       storage/gtd-storage-selector.c \
-       storage/gtd-storage-selector.h \
+       provider/gtd-provider-dialog.c \
+       provider/gtd-provider-dialog.h \
+       provider/gtd-provider-popover.c \
+       provider/gtd-provider-popover.h \
+       provider/gtd-provider-row.c \
+       provider/gtd-provider-row.h \
+       provider/gtd-provider-selector.c \
+       provider/gtd-provider-selector.h \
        gtd-application.c \
        gtd-application.h \
        gtd-arrow-frame.c \
diff --git a/src/gtd-initial-setup-window.c b/src/gtd-initial-setup-window.c
index 7b155de..a3f4e07 100644
--- a/src/gtd-initial-setup-window.c
+++ b/src/gtd-initial-setup-window.c
@@ -16,9 +16,9 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "interfaces/gtd-provider.h"
 #include "gtd-application.h"
-#include "gtd-storage.h"
-#include "gtd-storage-selector.h"
+#include "gtd-provider-selector.h"
 #include "gtd-initial-setup-window.h"
 #include "gtd-manager.h"
 
@@ -59,7 +59,7 @@ static guint signals[LAST_SIGNAL] = { 0, };
 
 static void
 gtd_initial_setup_window__location_selected (GtdInitialSetupWindow *window,
-                                             GtdStorage            *storage)
+                                             GtdProvider           *provider)
 {
   GtdInitialSetupWindowPrivate *priv;
 
@@ -67,10 +67,10 @@ gtd_initial_setup_window__location_selected (GtdInitialSetupWindow *window,
 
   priv = window->priv;
 
-  gtk_widget_set_sensitive (priv->done_button, storage != NULL);
+  gtk_widget_set_sensitive (priv->done_button, provider != NULL);
 
-  if (storage)
-    gtd_manager_set_default_storage (priv->manager, storage);
+  if (provider)
+    gtd_manager_set_default_provider (priv->manager, provider);
 }
 
 static void
diff --git a/src/gtd-manager.c b/src/gtd-manager.c
index 3a543fb..a5b863c 100644
--- a/src/gtd-manager.c
+++ b/src/gtd-manager.c
@@ -16,10 +16,9 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "interfaces/gtd-provider.h"
 #include "gtd-manager.h"
-#include "gtd-storage-goa.h"
-#include "gtd-storage-local.h"
-#include "gtd-storage.h"
+#include "gtd-plugin-manager.h"
 #include "gtd-task.h"
 #include "gtd-task-list.h"
 
@@ -29,30 +28,18 @@
 
 typedef struct
 {
-  GHashTable            *clients;
-  GList                 *task_lists;
-  ECredentialsPrompter  *credentials_prompter;
-  ESourceRegistry       *source_registry;
-
   /*
    * Today & Scheduled lists
    */
   GtdTaskList           *today_tasks_list;
   GtdTaskList           *scheduled_tasks_list;
 
-  /* Online accounts */
-  GoaClient             *goa_client;
-  gboolean               goa_client_ready;
-  GList                 *storage_locations;
-
   GSettings             *settings;
+  GtdPluginManager      *plugin_manager;
 
-  /*
-   * Small flag that contains the number of sources
-   * that still have to be loaded. When this number
-   * reaches 0, all sources are loaded.
-   */
-  gint                   load_sources;
+  GList                 *tasklists;
+  GList                 *providers;
+  GtdProvider           *default_provider;
 } GtdManagerPrivate;
 
 struct _GtdManager
@@ -63,62 +50,32 @@ struct _GtdManager
   GtdManagerPrivate *priv;
 };
 
-/* Auxiliary struct for asyncronous task operations */
-typedef struct _TaskData
-{
-  GtdManager *manager;
-  gpointer   *data;
-} TaskData;
-
 G_DEFINE_TYPE_WITH_PRIVATE (GtdManager, gtd_manager, GTD_TYPE_OBJECT)
 
-const gchar *supported_providers[] = {
-  "exchange",
-  "google",
-  "owncloud",
-  NULL
-};
-
 /* Singleton instance */
 GtdManager *gtd_manager_instance = NULL;
 
 enum
 {
-  DEFAULT_STORAGE_CHANGED,
+  DEFAULT_PROVIDER_CHANGED,
   LIST_ADDED,
   LIST_CHANGED,
   LIST_REMOVED,
   SHOW_ERROR_MESSAGE,
-  STORAGE_ADDED,
-  STORAGE_CHANGED,
-  STORAGE_REMOVED,
+  PROVIDER_ADDED,
+  PROVIDER_REMOVED,
   NUM_SIGNALS
 };
 
 enum
 {
   PROP_0,
-  PROP_GOA_CLIENT,
-  PROP_GOA_CLIENT_READY,
-  PROP_SOURCE_REGISTRY,
+  PROP_DEFAULT_PROVIDER,
   LAST_PROP
 };
 
 static guint signals[NUM_SIGNALS] = { 0, };
-
-static TaskData*
-task_data_new (GtdManager *manager,
-               gpointer   *data)
-{
-  TaskData *tdata;
-
-  tdata = g_new0 (TaskData, 1);
-  tdata->manager = manager;
-  tdata->data = data;
-
-  return tdata;
-}
-
+/*
 static gboolean
 is_today (GDateTime *dt)
 {
@@ -138,6 +95,8 @@ is_today (GDateTime *dt)
   return FALSE;
 }
 
+ */
+
 static void
 emit_show_error_message (GtdManager  *manager,
                          const gchar *primary_text,
@@ -151,905 +110,10 @@ emit_show_error_message (GtdManager  *manager,
 }
 
 static void
-gtd_manager__setup_url (GtdManager *manager,
-                        GtdStorageGoa *storage)
-{
-  GtdManagerPrivate *priv;
-  GList *sources;
-  GList *l;
-
-  g_return_if_fail (GTD_IS_MANAGER (manager));
-  g_return_if_fail (GTD_IS_STORAGE (storage));
-
-  priv = manager->priv;
-
-  if (!priv->source_registry)
-    return;
-
-  /*
-   * Search for the ESource whose parent source has an ESourceGoa extension.
-   * The ESourceGoa, then, must have the same account uid that of @storage.
-   */
-  sources = e_source_registry_list_sources (priv->source_registry, E_SOURCE_EXTENSION_TASK_LIST);
-
-  for (l = sources; l != NULL; l = l->next)
-    {
-      ESource *source;
-      ESource *goa_source;
-
-      source = l->data;
-      goa_source = e_source_registry_find_extension (priv->source_registry,
-                                                     source,
-                                                     E_SOURCE_EXTENSION_GOA);
-
-      if (goa_source)
-        {
-          ESourceGoa *goa_ext;
-
-          goa_ext = e_source_get_extension (goa_source, E_SOURCE_EXTENSION_GOA);
-
-          /* Found an ESourceGoa with the same uid of storage */
-          if (g_strcmp0 (e_source_goa_get_account_id (goa_ext), gtd_storage_get_id (GTD_STORAGE (storage))) 
== 0)
-            {
-              gtd_storage_goa_set_parent (storage, e_source_get_uid (goa_source));
-              break;
-            }
-        }
-
-      g_clear_object (&goa_source);
-    }
-
-  g_list_free_full (sources, g_object_unref);
-}
-
-static void
-gtd_manager__goa_account_removed_cb (GoaClient  *client,
-                                     GoaObject  *object,
-                                     GtdManager *manager)
-{
-  GtdManagerPrivate *priv;
-  GoaAccount *account;
-
-  g_return_if_fail (GTD_IS_MANAGER (manager));
-
-  priv = manager->priv;
-  account = goa_object_get_account (object);
-
-  if (g_strv_contains (supported_providers, goa_account_get_provider_type (account)))
-    {
-      GList *l;
-
-      for (l = priv->storage_locations; l != NULL; l = l->next)
-        {
-          if (g_strcmp0 (goa_account_get_id (account), gtd_storage_get_id (l->data)) == 0)
-            {
-              GtdStorage *storage = l->data;
-
-              if (gtd_storage_get_is_default (storage))
-                {
-                  g_settings_set_string (priv->settings,
-                                         "storage-location",
-                                         "local");
-                }
-
-              priv->storage_locations = g_list_remove (priv->storage_locations, storage);
-
-              g_object_unref (storage);
-
-              g_signal_emit (manager, signals[STORAGE_REMOVED], 0, storage);
-              break;
-            }
-        }
-    }
-}
-
-static void
-gtd_manager__goa_account_changed_cb (GoaClient  *client,
-                                     GoaObject  *object,
-                                     GtdManager *manager)
-{
-  GtdManagerPrivate *priv;
-  GoaAccount *account;
-
-  g_return_if_fail (GTD_IS_MANAGER (manager));
-
-  priv = manager->priv;
-  account = goa_object_get_account (object);
-
-  if (g_strv_contains (supported_providers, goa_account_get_provider_type (account)))
-    {
-      GList *l;
-
-      for (l = priv->storage_locations; l != NULL; l = l->next)
-        {
-          if (g_strcmp0 (goa_account_get_id (account), gtd_storage_get_id (l->data)) == 0)
-            {
-              g_signal_emit (manager, signals[STORAGE_CHANGED], 0, l->data);
-              break;
-            }
-        }
-    }
-}
-
-static void
-gtd_manager__goa_account_added_cb (GoaClient  *client,
-                                   GoaObject  *object,
-                                   GtdManager *manager)
-{
-  GtdManagerPrivate *priv;
-  GoaAccount *account;
-
-  g_return_if_fail (GTD_IS_MANAGER (manager));
-
-  priv = manager->priv;
-  account = goa_object_get_account (object);
-
-  if (g_strv_contains (supported_providers, goa_account_get_provider_type (account)))
-    {
-      GtdStorage *storage;
-      gchar *default_location;
-
-      default_location = g_settings_get_string (priv->settings, "storage-location");
-
-      storage = gtd_storage_goa_new (object);
-
-      gtd_storage_set_enabled (storage, !goa_account_get_calendar_disabled (account));
-      gtd_storage_set_is_default (storage, g_strcmp0 (gtd_storage_get_id (storage), default_location) == 0);
-
-      gtd_manager__setup_url (manager, GTD_STORAGE_GOA (storage));
-
-      priv->storage_locations = g_list_insert_sorted (priv->storage_locations,
-                                                      storage,
-                                                      (GCompareFunc) gtd_storage_compare);
-
-      g_signal_emit (manager, signals[STORAGE_ADDED], 0, storage);
-
-      g_free (default_location);
-    }
-}
-
-static void
-gtd_manager__goa_client_finish_cb (GObject      *client,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
-{
-  GtdManagerPrivate *priv;
-  GError *error;
-
-  g_return_if_fail (GTD_IS_MANAGER (user_data));
-
-  priv = GTD_MANAGER (user_data)->priv;
-  error = NULL;
-
-  priv->goa_client_ready = TRUE;
-  priv->goa_client = goa_client_new_finish (result, &error);
-
-  if (!error)
-    {
-      GList *accounts;
-      GList *l;
-      gchar *default_location;
-
-      /* Load each supported GoaAccount into a GtdStorage */
-      accounts = goa_client_get_accounts (priv->goa_client);
-      default_location = g_settings_get_string (priv->settings, "storage-location");
-
-      for (l = accounts; l != NULL; l = l->next)
-        {
-          GoaObject *object;
-          GoaAccount *account;
-
-          object = l->data;
-          account = goa_object_peek_account (object);
-
-          if (g_strv_contains (supported_providers, goa_account_get_provider_type (account)))
-            {
-              GtdStorage *storage;
-
-              /* Create the new GOA storage */
-              storage = gtd_storage_goa_new (object);
-              gtd_storage_set_enabled (storage, !goa_account_get_calendar_disabled (account));
-              gtd_storage_set_is_default (storage, g_strcmp0 (gtd_storage_get_id (storage), 
default_location) == 0);
-
-              g_assert (gtd_storage_goa_get_account (GTD_STORAGE_GOA (storage)) == account);
-
-              gtd_manager__setup_url (GTD_MANAGER (user_data), GTD_STORAGE_GOA (storage));
-
-              priv->storage_locations = g_list_insert_sorted (priv->storage_locations,
-                                                              storage,
-                                                              (GCompareFunc) gtd_storage_compare);
-
-              g_signal_emit (user_data, signals[STORAGE_ADDED], 0, storage);
-            }
-        }
-
-      /* Connect GoaClient signals */
-      g_signal_connect (priv->goa_client,
-                        "account-added",
-                        G_CALLBACK (gtd_manager__goa_account_added_cb),
-                        user_data);
-
-      g_signal_connect (priv->goa_client,
-                        "account-changed",
-                        G_CALLBACK (gtd_manager__goa_account_changed_cb),
-                        user_data);
-
-      g_signal_connect (priv->goa_client,
-                        "account-removed",
-                        G_CALLBACK (gtd_manager__goa_account_removed_cb),
-                        user_data);
-
-      g_list_free_full (accounts, g_object_unref);
-      g_free (default_location);
-    }
-  else
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error loading GNOME Online Accounts"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error loading GNOME Online Accounts"),
-                               error->message);
-
-      g_clear_error (&error);
-    }
-
-  g_object_notify (user_data, "goa-client-ready");
-  g_object_notify (user_data, "goa-client");
-}
-
-static void
-gtd_manager__commit_source_finished (GObject      *registry,
-                                     GAsyncResult *result,
-                                     gpointer      user_data)
-{
-  GError *error = NULL;
-
-  g_return_if_fail (GTD_IS_MANAGER (user_data));
-
-  gtd_object_set_ready (GTD_OBJECT (user_data), TRUE);
-  e_source_registry_commit_source_finish (E_SOURCE_REGISTRY (registry),
-                                          result,
-                                          &error);
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error saving task list"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error saving task list"),
-                               error->message);
-
-      g_error_free (error);
-      return;
-    }
-}
-
-static void
-task_list_removal_finished (GtdManager  *manager,
-                            ESource     *source,
-                            GError     **error)
-{
-  gtd_object_set_ready (GTD_OBJECT (manager), TRUE);
-
-  if (*error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error removing task list"),
-                 (*error)->message);
-
-      emit_show_error_message (manager,
-                               _("Error removing task list"),
-                               (*error)->message);
-
-      g_clear_error (error);
-    }
-}
-
-static void
-gtd_manager__remote_create_source_finished (GObject      *source,
-                                            GAsyncResult *result,
-                                            gpointer      user_data)
-{
-  GError *error;
-
-  error = NULL;
-
-  e_source_remote_create_finish (E_SOURCE (source),
-                                 result,
-                                 &error);
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error creating task list"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error creating task list"),
-                               error->message);
-
-      g_clear_error (&error);
-    }
-}
-
-static void
-gtd_manager__remote_delete_finished (GObject      *source,
-                                     GAsyncResult *result,
-                                     gpointer      user_data)
-{
-  GError *error = NULL;
-
-  e_source_remote_delete_finish (E_SOURCE (source),
-                                 result,
-                                 &error);
-
-  task_list_removal_finished (GTD_MANAGER (user_data),
-                              E_SOURCE (source),
-                              &error);
-}
-
-static void
-gtd_manager__remove_source_finished (GObject      *source,
-                                     GAsyncResult *result,
-                                     gpointer      user_data)
-{
-  GError *error = NULL;
-
-  e_source_remove_finish (E_SOURCE (source),
-                          result,
-                          &error);
-
-  task_list_removal_finished (GTD_MANAGER (user_data),
-                              E_SOURCE (source),
-                              &error);
-}
-
-static void
-gtd_manager__create_task_finished (GObject      *client,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
-{
-  GtdManagerPrivate *priv;
-  TaskData *data = user_data;
-  gchar *new_uid = NULL;
-  GError *error = NULL;
-
-  priv = data->manager->priv;
-  e_cal_client_create_object_finish (E_CAL_CLIENT (client),
-                                     result,
-                                     &new_uid,
-                                     &error);
-
-  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error creating task"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error creating task"),
-                               error->message);
-
-      g_error_free (error);
-      g_free (data);
-      return;
-    }
-  else
-    {
-      GDateTime *dt;
-
-      /*
-       * Add in 'Today' and/or 'Scheduled' lists.
-       */
-      dt = gtd_task_get_due_date (GTD_TASK (data->data));
-
-      if (dt)
-        gtd_task_list_save_task (priv->scheduled_tasks_list, (GtdTask*) data->data);
-
-      if (dt && is_today (dt))
-        gtd_task_list_save_task (priv->today_tasks_list, (GtdTask*) data->data);
-
-      /*
-       * In the case the task UID changes because of creation proccess,
-       * reapply it to the task.
-       */
-      if (new_uid)
-        {
-          gtd_object_set_uid (GTD_OBJECT (data->data), new_uid);
-          g_free (new_uid);
-        }
-
-      g_free (data);
-    }
-}
-
-static void
-gtd_manager__remove_task_finished (GObject      *client,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
-{
-  GtdManagerPrivate *priv;
-  TaskData *data = user_data;
-  GError *error = NULL;
-
-  priv = data->manager->priv;
-  e_cal_client_remove_object_finish (E_CAL_CLIENT (client),
-                                     result,
-                                     &error);
-
-  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
-
-  /* Remove from 'Today' or 'Scheduled' as needed */
-  gtd_task_list_remove_task (priv->scheduled_tasks_list, (GtdTask*) data->data);
-  gtd_task_list_remove_task (priv->today_tasks_list, (GtdTask*) data->data);
-
-  g_object_unref ((GtdTask*) data->data);
-  g_free (data);
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error removing task"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error removing task"),
-                               error->message);
-
-      g_error_free (error);
-      return;
-    }
-}
-
-static void
-gtd_manager__update_task_finished (GObject      *client,
-                                   GAsyncResult *result,
-                                   gpointer      user_data)
-{
-  GtdManagerPrivate *priv;
-  GDateTime *dt;
-  TaskData *data = user_data;
-  GtdTask *task;
-  GError *error = NULL;
-
-  priv = data->manager->priv;
-  task = GTD_TASK (data->data);
-  e_cal_client_modify_object_finish (E_CAL_CLIENT (client),
-                                     result,
-                                     &error);
-
-  /* Check if the task still fits internal lists */
-  dt = gtd_task_get_due_date (task);
-
-  if (dt)
-    {
-      gtd_task_list_save_task (priv->scheduled_tasks_list, task);
-
-      if (is_today (dt))
-        gtd_task_list_save_task (priv->today_tasks_list, task);
-      else
-        gtd_task_list_remove_task (priv->today_tasks_list, task);
-    }
-  else
-    {
-      gtd_task_list_remove_task (priv->scheduled_tasks_list, task);
-      gtd_task_list_remove_task (priv->today_tasks_list, task);
-    }
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error updating task"),
-                 error->message);
-
-      emit_show_error_message (data->manager,
-                               _("Error updating task"),
-                               error->message);
-
-      g_error_free (error);
-    }
-
-  g_clear_pointer (&dt, g_date_time_unref);
-  g_free (data);
-
-  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
-}
-
-static void
-gtd_manager__invoke_authentication (GObject      *source_object,
-                                    GAsyncResult *result,
-                                    gpointer      user_data)
-{
-  ESource *source = E_SOURCE (source_object);
-  GError *error = NULL;
-  gboolean canceled;
-
-  e_source_invoke_authenticate_finish (source,
-                                       result,
-                                       &error);
-
-  canceled = g_error_matches (error,
-                                   G_IO_ERROR,
-                                   G_IO_ERROR_CANCELLED);
-
-  if (!canceled)
-    {
-      g_warning ("%s: %s (%s): %s",
-                 G_STRFUNC,
-                 _("Failed to prompt for credentials"),
-                 e_source_get_uid (source),
-                 error->message);
-    }
-
-  g_clear_error (&error);
-}
-
-static void
-gtd_manager__credentials_prompt_done (GObject      *source_object,
-                                      GAsyncResult *result,
-                                      gpointer      user_data)
-{
-  ETrustPromptResponse response = E_TRUST_PROMPT_RESPONSE_UNKNOWN;
-  ESource *source = E_SOURCE (source_object);
-  GError *error = NULL;
-
-  e_trust_prompt_run_for_source_finish (source, result, &response, &error);
-
-  if (error)
-    {
-      g_warning ("%s: %s '%s': %s",
-                 G_STRFUNC,
-                 _("Failed to prompt for credentials for"),
-                 e_source_get_display_name (source),
-                 error->message);
-
-    }
-  else if (response == E_TRUST_PROMPT_RESPONSE_ACCEPT || response == 
E_TRUST_PROMPT_RESPONSE_ACCEPT_TEMPORARILY)
-    {
-      /* Use NULL credentials to reuse those from the last time. */
-      e_source_invoke_authenticate (source,
-                                    NULL,
-                                    NULL /* cancellable */,
-                                    gtd_manager__invoke_authentication,
-                                    NULL);
-    }
-
-  g_clear_error (&error);
-}
-
-static void
-gtd_manager__credentials_required (ESourceRegistry          *registry,
-                                   ESource                  *source,
-                                   ESourceCredentialsReason  reason,
-                                   const gchar              *certificate_pem,
-                                   GTlsCertificateFlags      certificate_errors,
-                                   const GError             *error,
-                                   gpointer                  user_data)
-{
-  GtdManagerPrivate *priv;
-
-  g_return_if_fail (GTD_IS_MANAGER (user_data));
-
-  priv = GTD_MANAGER (user_data)->priv;
-
-  if (e_credentials_prompter_get_auto_prompt_disabled_for (priv->credentials_prompter, source))
-    return;
-
-  if (reason == E_SOURCE_CREDENTIALS_REASON_SSL_FAILED)
-    {
-      e_trust_prompt_run_for_source (e_credentials_prompter_get_dialog_parent (priv->credentials_prompter),
-                                     source,
-                                     certificate_pem,
-                                     certificate_errors,
-                                     error ? error->message : NULL,
-                                     TRUE, // allow saving sources
-                                     NULL, // we won't cancel the operation
-                                     gtd_manager__credentials_prompt_done,
-                                     NULL);
-    }
-  else if (error && reason == E_SOURCE_CREDENTIALS_REASON_ERROR)
-    {
-      g_warning ("%s: %s '%s': %s",
-                 G_STRFUNC,
-                 _("Authentication failure"),
-                 e_source_get_display_name (source),
-                 error->message);
-    }
-}
-
-static void
-gtd_manager__fill_task_list (GObject      *client,
-                             GAsyncResult *result,
-                             gpointer      user_data)
-{
-  GtdManagerPrivate *priv;
-  GtdTaskList *list;
-  TaskData *data = user_data;
-  GSList *component_list;
-  GError *error = NULL;
-
-  g_return_if_fail (GTD_IS_MANAGER (data->manager));
-
-  priv = data->manager->priv;
-  list = GTD_TASK_LIST (data->data);
-
-  e_cal_client_get_object_list_as_comps_finish (E_CAL_CLIENT (client),
-                                                result,
-                                                &component_list,
-                                                &error);
-
-  gtd_object_set_ready (GTD_OBJECT (data->data), TRUE);
-  g_free (data);
-
-  if (!error)
-    {
-      GSList *l;
-
-      for (l = component_list; l != NULL; l = l->next)
-        {
-          GDateTime *dt;
-          GtdTask *task;
-
-          task = gtd_task_new (l->data);
-          gtd_task_set_list (task, list);
-
-          gtd_task_list_save_task (list, task);
-
-          /*
-           * Add in 'Today' and/or 'Scheduled' lists.
-           */
-          dt = gtd_task_get_due_date (task);
-
-          if (dt)
-            gtd_task_list_save_task (priv->scheduled_tasks_list, task);
-
-          if (dt && is_today (dt))
-            gtd_task_list_save_task (priv->today_tasks_list, task);
-
-          g_clear_pointer (&dt, g_date_time_unref);
-        }
-
-      e_cal_client_free_ecalcomp_slist (component_list);
-    }
-  else
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error fetching tasks from list"),
-                 error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Error fetching tasks from list"),
-                               error->message);
-
-      g_error_free (error);
-      return;
-    }
-}
-
-static void
-gtd_manager__on_client_connected (GObject      *source_object,
-                                  GAsyncResult *result,
-                                  gpointer      user_data)
-{
-  GtdManagerPrivate *priv = GTD_MANAGER (user_data)->priv;
-  ECalClient *client;
-  ESource *source;
-  GError *error = NULL;
-
-  source = e_client_get_source (E_CLIENT (source_object));
-  client = E_CAL_CLIENT (e_cal_client_connect_finish (result, &error));
-
-  /* Update ready flag */
-  priv->load_sources--;
-  gtd_object_set_ready (GTD_OBJECT (user_data),
-                        priv->load_sources <= 0);
-
-  if (!error)
-    {
-      GtdTaskList *list;
-      TaskData *data;
-      ESource *parent;
-
-      /* parent source's display name is list's origin */
-      parent = e_source_registry_ref_source (priv->source_registry, e_source_get_parent (source));
-
-      /* creates a new task list */
-      list = gtd_task_list_new (source, e_source_get_display_name (parent));
-
-      /* it's not ready until we fetch the list of tasks from client */
-      gtd_object_set_ready (GTD_OBJECT (list), FALSE);
-
-      /* async data */
-      data = task_data_new (user_data, (gpointer) list);
-
-      /* asyncronously fetch the task list */
-      e_cal_client_get_object_list_as_comps (client,
-                                             "contains? \"any\" \"\"",
-                                             NULL,
-                                             (GAsyncReadyCallback) gtd_manager__fill_task_list,
-                                             data);
-
-
-      priv->task_lists = g_list_append (priv->task_lists, list);
-
-      g_object_set_data (G_OBJECT (source), "task-list", list);
-      g_hash_table_insert (priv->clients, source, client);
-
-      g_signal_emit (user_data,
-                     signals[LIST_ADDED],
-                     0,
-                     list);
-
-      g_object_unref (parent);
-
-      g_debug ("%s: %s (%s)",
-               G_STRFUNC,
-               _("Task list source successfully connected"),
-               e_source_get_display_name (source));
-    }
-  else
-    {
-      g_debug ("%s: %s (%s): %s",
-               G_STRFUNC,
-               _("Failed to connect to task list source"),
-               e_source_get_uid (source),
-               error->message);
-
-      emit_show_error_message (GTD_MANAGER (user_data),
-                               _("Failed to connect to task list source"),
-                               error->message);
-
-      g_error_free (error);
-      return;
-    }
-
-}
-
-static void
-gtd_manager__load__source (GtdManager *manager,
-                           ESource    *source)
-{
-  GtdManagerPrivate *priv = manager->priv;
-
-  if (e_source_has_extension (source, E_SOURCE_EXTENSION_TASK_LIST) &&
-      !g_hash_table_lookup (priv->clients, source))
-    {
-      e_cal_client_connect (source,
-                            E_CAL_CLIENT_SOURCE_TYPE_TASKS,
-                            5, /* seconds to wait */
-                            NULL,
-                            gtd_manager__on_client_connected,
-                            manager);
-    }
-  else
-    {
-      g_warning ("%s: %s %s (%s)",
-                 G_STRFUNC,
-                 _("Skipping already loaded task list "),
-                 e_source_get_display_name (source),
-                 e_source_get_uid (source));
-    }
-}
-
-static void
-gtd_manager__remove_source (GtdManager *manager,
-                            ESource    *source)
-{
-  GtdManagerPrivate *priv = manager->priv;
-  GtdTaskList *list;
-
-  list = g_object_get_data (G_OBJECT (source), "task-list");
-
-  g_hash_table_remove (priv->clients, source);
-
-  g_signal_emit (manager,
-                 signals[LIST_REMOVED],
-                 0,
-                 list);
-}
-
-static void
-gtd_manager__source_registry_finish_cb (GObject      *source_object,
-                                        GAsyncResult *result,
-                                        gpointer      user_data)
-{
-  GtdManagerPrivate *priv = GTD_MANAGER (user_data)->priv;
-  GList *l;
-  GList *sources;
-  GError *error = NULL;
-
-  priv->source_registry = e_source_registry_new_finish (result, &error);
-  priv->credentials_prompter = e_credentials_prompter_new (priv->source_registry);
-
-  if (error != NULL)
-    {
-      g_warning ("%s: %s", _("Error loading task manager"), error->message);
-      g_error_free (error);
-      return;
-    }
-
-  /* First of all, disable authentication dialog for non-tasklists sources */
-  sources = e_source_registry_list_sources (priv->source_registry, NULL);
-
-  for (l = sources; l != NULL; l = g_list_next (l))
-    {
-      ESource *source = E_SOURCE (l->data);
-
-      /* Mark for skip also currently disabled sources */
-      e_credentials_prompter_set_auto_prompt_disabled_for (priv->credentials_prompter,
-                                                           source,
-                                                           !e_source_has_extension (source, 
E_SOURCE_EXTENSION_TASK_LIST));
-    }
-
-  g_list_free_full (sources, g_object_unref);
-
-  /* Load task list sources */
-  sources = e_source_registry_list_sources (priv->source_registry,
-                                            E_SOURCE_EXTENSION_TASK_LIST);
-
-  /* While load_sources > 0, GtdManager::ready = FALSE */
-  priv->load_sources = g_list_length (sources);
-
-
-  /*
-   * When ESourceRegistry is loaded, it enabled loading the GtdStorage::url properties.
-   * Load them now.
-   */
-  for (l = priv->storage_locations; l != NULL; l = l->next)
-    gtd_manager__setup_url (GTD_MANAGER (user_data), l->data);
-
-
-  g_debug ("%s: number of sources to load: %d",
-           G_STRFUNC,
-           priv->load_sources);
-
-  gtd_object_set_ready (GTD_OBJECT (user_data),
-                        priv->load_sources == 0);
-
-  for (l = sources; l != NULL; l = l->next)
-    gtd_manager__load__source (GTD_MANAGER (user_data), l->data);
-
-  g_list_free_full (sources, g_object_unref);
-
-  /* listen to the signals, so new sources don't slip by */
-  g_signal_connect_swapped (priv->source_registry,
-                            "source-added",
-                            G_CALLBACK (gtd_manager__load__source),
-                            user_data);
-
-  g_signal_connect_swapped (priv->source_registry,
-                            "source-removed",
-                            G_CALLBACK (gtd_manager__remove_source),
-                            user_data);
-
-  g_signal_connect (priv->source_registry,
-                    "credentials-required",
-                    G_CALLBACK (gtd_manager__credentials_required),
-                    user_data);
-
-  e_credentials_prompter_process_awaiting_credentials (priv->credentials_prompter);
-}
-
-static void
 gtd_manager_finalize (GObject *object)
 {
   GtdManager *self = (GtdManager *)object;
 
-  g_clear_object (&self->priv->goa_client);
   g_clear_object (&self->priv->scheduled_tasks_list);
   g_clear_object (&self->priv->today_tasks_list);
 
@@ -1086,36 +150,12 @@ static void
 gtd_manager_constructed (GObject *object)
 {
   GtdManagerPrivate *priv = GTD_MANAGER (object)->priv;
-  GtdStorage *local_storage;
   gchar *default_location;
 
   G_OBJECT_CLASS (gtd_manager_parent_class)->constructed (object);
 
   default_location = g_settings_get_string (priv->settings, "storage-location");
 
-  /* hash table */
-  priv->clients = g_hash_table_new_full ((GHashFunc) e_source_hash,
-                                         (GEqualFunc) e_source_equal,
-                                         g_object_unref,
-                                         g_object_unref);
-
-  /* load the source registry */
-  e_source_registry_new (NULL,
-                         (GAsyncReadyCallback) gtd_manager__source_registry_finish_cb,
-                         object);
-
-  /* local storage location */
-  local_storage = gtd_storage_local_new ();
-  gtd_storage_set_enabled (local_storage, TRUE);
-  gtd_storage_set_is_default (local_storage, g_strcmp0 (default_location, "local") == 0);
-
-  priv->storage_locations = g_list_append (priv->storage_locations, local_storage);
-
-  /* online accounts */
-  goa_client_new (NULL,
-                  (GAsyncReadyCallback) gtd_manager__goa_client_finish_cb,
-                  object);
-
   g_free (default_location);
 }
 
@@ -1136,49 +176,21 @@ gtd_manager_class_init (GtdManagerClass *klass)
    */
   g_object_class_install_property (
         object_class,
-        PROP_GOA_CLIENT,
-        g_param_spec_object ("goa-client",
-                            "The online accounts client of the manager",
-                            "The read-only GNOME online accounts client loaded and owned by the manager",
-                            GOA_TYPE_CLIENT,
-                            G_PARAM_READABLE));
-
-  /**
-   * GtdManager::goa-client-ready:
-   *
-   * Whether the GNOME Online Accounts client is loaded.
-   */
-  g_object_class_install_property (
-        object_class,
-        PROP_GOA_CLIENT_READY,
-        g_param_spec_boolean ("goa-client-ready",
-                              "Whether GNOME Online Accounts client is ready",
-                              "Whether the read-only GNOME online accounts client is loaded",
-                              FALSE,
-                              G_PARAM_READABLE));
-
-  /**
-   * GtdManager::source-registry:
-   *
-   * The #ESourceRegistry asyncronously loaded.
-   */
-  g_object_class_install_property (
-        object_class,
-        PROP_SOURCE_REGISTRY,
-        g_param_spec_object ("source-registry",
-                            "The source registry of the manager",
-                            "The read-only source registry loaded and owned by the manager",
-                            E_TYPE_SOURCE_REGISTRY,
-                            G_PARAM_READABLE));
+        PROP_DEFAULT_PROVIDER,
+        g_param_spec_object ("default-provider",
+                            "The default provider of the application",
+                            "The default provider of the application",
+                            GTD_TYPE_PROVIDER,
+                            G_PARAM_READWRITE));
 
   /**
-   * GtdManager::default-storage-changed:
+   * GtdManager::default-provider-changed:
    *
-   * The ::default-storage-changed signal is emmited when a new #GtdStorage
+   * The ::default-provider-changed signal is emmited when a new #GtdStorage
    * is set as default.
    */
-  signals[DEFAULT_STORAGE_CHANGED] =
-                  g_signal_new ("default-storage-changed",
+  signals[DEFAULT_PROVIDER_CHANGED] =
+                  g_signal_new ("default-provider-changed",
                                 GTD_TYPE_MANAGER,
                                 G_SIGNAL_RUN_LAST,
                                 0,
@@ -1187,8 +199,8 @@ gtd_manager_class_init (GtdManagerClass *klass)
                                 NULL,
                                 G_TYPE_NONE,
                                 2,
-                                GTD_TYPE_STORAGE,
-                                GTD_TYPE_STORAGE);
+                                GTD_TYPE_PROVIDER,
+                                GTD_TYPE_PROVIDER);
 
   /**
    * GtdManager::list-added:
@@ -1261,58 +273,64 @@ gtd_manager_class_init (GtdManagerClass *klass)
                                               G_TYPE_STRING);
 
   /**
-   * GtdManager::storage-added:
+   * GtdManager::provider-added:
    *
-   * The ::storage-added signal is emmited after a #GtdStorage
+   * The ::provider-added signal is emmited after a #GtdProvider
    * is added.
    */
-  signals[STORAGE_ADDED] = g_signal_new ("storage-added",
-                                         GTD_TYPE_MANAGER,
-                                         G_SIGNAL_RUN_LAST,
-                                         0,
-                                         NULL,
-                                         NULL,
-                                         NULL,
-                                         G_TYPE_NONE,
-                                         1,
-                                         GTD_TYPE_STORAGE);
-
-  /**
-   * GtdManager::storage-changed:
-   *
-   * The ::storage-changed signal is emmited after a #GtdStorage
-   * is changed.
-   */
-  signals[STORAGE_CHANGED] = g_signal_new ("storage-changed",
-                                           GTD_TYPE_MANAGER,
-                                           G_SIGNAL_RUN_LAST,
-                                           0,
-                                           NULL,
+  signals[PROVIDER_ADDED] = g_signal_new ("provider-added",
+                                          GTD_TYPE_MANAGER,
+                                          G_SIGNAL_RUN_LAST,
+                                          0,
+                                          NULL,
                                           NULL,
                                           NULL,
                                           G_TYPE_NONE,
                                           1,
-                                          GTD_TYPE_STORAGE);
+                                          GTD_TYPE_PROVIDER);
 
   /**
-   * GtdManager::storage-removed:
+   * GtdManager::provider-removed:
    *
-   * The ::storage-removed signal is emmited after a #GtdStorage
+   * The ::provider-removed signal is emmited after a #GtdProvider
    * is removed from the list.
    */
-  signals[STORAGE_REMOVED] = g_signal_new ("storage-removed",
-                                           GTD_TYPE_MANAGER,
-                                           G_SIGNAL_RUN_LAST,
-                                           0,
-                                           NULL,
-                                           NULL,
-                                           NULL,
-                                           G_TYPE_NONE,
-                                           1,
-                                           GTD_TYPE_STORAGE);
+  signals[PROVIDER_REMOVED] = g_signal_new ("provider-removed",
+                                            GTD_TYPE_MANAGER,
+                                            G_SIGNAL_RUN_LAST,
+                                            0,
+                                            NULL,
+                                            NULL,
+                                            NULL,
+                                            G_TYPE_NONE,
+                                            1,
+                                            GTD_TYPE_PROVIDER);
 }
 
 static void
+gtd_manager__provider_added (GtdPluginManager *plugin_manager,
+                             GtdProvider      *provider,
+                             GtdManager       *self)
+{
+  GtdManagerPrivate *priv = gtd_manager_get_instance_private (self);
+
+  priv->providers = g_list_append (priv->providers, provider);
+
+  g_signal_emit (self, signals[PROVIDER_ADDED], 0, provider);
+}
+
+static void
+gtd_manager__provider_removed (GtdPluginManager *plugin_manager,
+                               GtdProvider      *provider,
+                               GtdManager       *self)
+{
+  GtdManagerPrivate *priv = gtd_manager_get_instance_private (self);
+
+  priv->providers = g_list_remove (priv->providers, provider);
+
+  g_signal_emit (self, signals[PROVIDER_REMOVED], 0, provider);
+}
+static void
 gtd_manager_init (GtdManager *self)
 {
   self->priv = gtd_manager_get_instance_private (self);
@@ -1321,6 +339,19 @@ gtd_manager_init (GtdManager *self)
   /* fixed task lists */
   self->priv->scheduled_tasks_list = g_object_new (GTD_TYPE_TASK_LIST, NULL);
   self->priv->today_tasks_list = g_object_new (GTD_TYPE_TASK_LIST, NULL);
+
+  /* plugin manager */
+  self->priv->plugin_manager = gtd_plugin_manager_new ();
+
+  g_signal_connect (self->priv->plugin_manager,
+                    "provider-registered",
+                    G_CALLBACK (gtd_manager__provider_added),
+                    self);
+
+  g_signal_connect (self->priv->plugin_manager,
+                    "provider-unregistered",
+                    G_CALLBACK (gtd_manager__provider_removed),
+                    self);
 }
 
 /**
@@ -1359,30 +390,16 @@ void
 gtd_manager_create_task (GtdManager *manager,
                          GtdTask    *task)
 {
-  GtdManagerPrivate *priv = GTD_MANAGER (manager)->priv;
-  ECalComponent *component;
-  ECalClient *client;
-  TaskData *data;
-  ESource *source;
+  GtdTaskList *list;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK (task));
 
-  source = gtd_task_list_get_source (gtd_task_get_list (task));
-  client = g_hash_table_lookup (priv->clients, source);
-  component = gtd_task_get_component (task);
+  list = gtd_task_get_list (task);
+  provider = gtd_task_list_get_provider (list);
 
-  /* Temporary data for async operation */
-  data = task_data_new (manager, (gpointer) task);
-
-  /* The task is not ready until we finish the operation */
-  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
-
-  e_cal_client_create_object (client,
-                              e_cal_component_get_icalcomponent (component),
-                              NULL, // We won't cancel the operation
-                              (GAsyncReadyCallback) gtd_manager__create_task_finished,
-                              data);
+  gtd_provider_create_task (provider, task);
 }
 
 /**
@@ -1398,36 +415,16 @@ void
 gtd_manager_remove_task (GtdManager *manager,
                          GtdTask    *task)
 {
-  GtdManagerPrivate *priv = GTD_MANAGER (manager)->priv;
-  ECalComponent *component;
-  ECalComponentId *id;
-  ECalClient *client;
-  TaskData *data;
-  ESource *source;
+  GtdTaskList *list;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK (task));
 
-  source = gtd_task_list_get_source (gtd_task_get_list (task));
-  client = g_hash_table_lookup (priv->clients, source);
-  component = gtd_task_get_component (task);
-  id = e_cal_component_get_id (component);
-
-  /* Temporary data for async operation */
-  data = task_data_new (manager, (gpointer) task);
+  list = gtd_task_get_list (task);
+  provider = gtd_task_list_get_provider (list);
 
-  /* The task is not ready until we finish the operation */
-  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
-
-  e_cal_client_remove_object (client,
-                              id->uid,
-                              id->rid,
-                              E_CAL_OBJ_MOD_THIS,
-                              NULL, // We won't cancel the operation
-                              (GAsyncReadyCallback) gtd_manager__remove_task_finished,
-                              data);
-
-  e_cal_component_free_id (id);
+  gtd_provider_remove_task (provider, task);
 }
 
 /**
@@ -1443,31 +440,16 @@ void
 gtd_manager_update_task (GtdManager *manager,
                          GtdTask    *task)
 {
-  GtdManagerPrivate *priv = GTD_MANAGER (manager)->priv;
-  ECalComponent *component;
-  ECalClient *client;
-  TaskData *data;
-  ESource *source;
+  GtdTaskList *list;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK (task));
 
-  source = gtd_task_list_get_source (gtd_task_get_list (task));
-  client = g_hash_table_lookup (priv->clients, source);
-  component = gtd_task_get_component (task);
+  list = gtd_task_get_list (task);
+  provider = gtd_task_list_get_provider (list);
 
-  /* Temporary data for async operation */
-  data = task_data_new (manager, (gpointer) task);
-
-  /* The task is not ready until we finish the operation */
-  gtd_object_set_ready (GTD_OBJECT (task), FALSE);
-
-  e_cal_client_modify_object (client,
-                              e_cal_component_get_icalcomponent (component),
-                              E_CAL_OBJ_MOD_THIS,
-                              NULL, // We won't cancel the operation
-                              (GAsyncReadyCallback) gtd_manager__update_task_finished,
-                              data);
+  gtd_provider_update_task (provider, task);
 }
 
 /**
@@ -1482,25 +464,14 @@ void
 gtd_manager_create_task_list (GtdManager  *manager,
                               GtdTaskList *list)
 {
-  GtdManagerPrivate *priv;
-  ESource *source;
-  ESource *parent;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK_LIST (list));
-  g_return_if_fail (gtd_task_list_get_source (list));
-
-  priv = manager->priv;
-  source = gtd_task_list_get_source (list);
-  parent = e_source_registry_ref_source (priv->source_registry, e_source_get_parent (source));
 
-  e_source_remote_create (parent,
-                          source,
-                          NULL,
-                          (GAsyncReadyCallback) gtd_manager__remote_create_source_finished,
-                          manager);
+  provider = gtd_task_list_get_provider (list);
 
-  g_object_unref (parent);
+  gtd_provider_create_task_list (provider, list);
 }
 
 /**
@@ -1516,30 +487,14 @@ void
 gtd_manager_remove_task_list (GtdManager  *manager,
                               GtdTaskList *list)
 {
-  ESource *source;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK_LIST (list));
-  g_return_if_fail (gtd_task_list_get_source (list));
 
-  source = gtd_task_list_get_source (list);
+  provider = gtd_task_list_get_provider (list);
 
-  gtd_object_set_ready (GTD_OBJECT (manager), FALSE);
-
-  if (e_source_get_remote_deletable (source))
-    {
-      e_source_remote_delete (source,
-                              NULL,
-                              (GAsyncReadyCallback) gtd_manager__remote_delete_finished,
-                              manager);
-    }
-  else
-    {
-      e_source_remove (source,
-                       NULL,
-                       (GAsyncReadyCallback) gtd_manager__remove_source_finished,
-                       manager);
-    }
+  gtd_provider_remove_task_list (provider, list);
 
   g_signal_emit (manager,
                  signals[LIST_REMOVED],
@@ -1560,56 +515,14 @@ void
 gtd_manager_save_task_list (GtdManager  *manager,
                             GtdTaskList *list)
 {
-  ESource *source;
+  GtdProvider *provider;
 
   g_return_if_fail (GTD_IS_MANAGER (manager));
   g_return_if_fail (GTD_IS_TASK_LIST (list));
-  g_return_if_fail (gtd_task_list_get_source (list));
 
-  source = gtd_task_list_get_source (list);
+  provider = gtd_task_list_get_provider (list);
 
-  gtd_object_set_ready (GTD_OBJECT (manager), FALSE);
-  e_source_registry_commit_source (manager->priv->source_registry,
-                                   source,
-                                   NULL,
-                                   (GAsyncReadyCallback) gtd_manager__commit_source_finished,
-                                   manager);
-}
-
-/**
- * gtd_manager_get_goa_client:
- * @manager: a #GtdManager
- *
- * Retrieves the internal @GoaClient from @manager. %NULL doesn't mean
- * that the client is not ready, use @gtd_manager_is_goa_client_ready to
- * check that.
- *
- * Returns: (transfer none): the internal #GoaClient of @manager
- */
-GoaClient*
-gtd_manager_get_goa_client (GtdManager *manager)
-{
-  g_return_val_if_fail (GTD_IS_MANAGER (manager), NULL);
-
-  return manager->priv->goa_client;
-}
-
-/**
- * gtd_manager_is_goa_client_ready:
- *
- * Checks whether @manager's internal #GoaClient is ready. Note that,
- * in the case of failure, it'll return %TRUE and @gtd_manager_get_goa_client
- * will return %NULL.
- *
- * Returns: %TRUE if @manager's internal #GoaClient is already
- * loaded, %FALSE otherwise.
- */
-gboolean
-gtd_manager_is_goa_client_ready (GtdManager *manager)
-{
-  g_return_val_if_fail (GTD_IS_MANAGER (manager), FALSE);
-
-  return manager->priv->goa_client_ready;
+  gtd_provider_update_task_list (provider, list);
 }
 
 /**
@@ -1625,7 +538,7 @@ gtd_manager_get_task_lists (GtdManager *manager)
 {
   g_return_val_if_fail (GTD_IS_MANAGER (manager), NULL);
 
-  return g_list_copy (manager->priv->task_lists);
+  return g_list_copy (manager->priv->tasklists);
 }
 
 /**
@@ -1637,37 +550,27 @@ gtd_manager_get_task_lists (GtdManager *manager)
  * #GtdStorage. Free with @g_list_free after use.
  */
 GList*
-gtd_manager_get_storage_locations (GtdManager *manager)
+gtd_manager_get_providers (GtdManager *manager)
 {
   g_return_val_if_fail (GTD_IS_MANAGER (manager), NULL);
 
-  return g_list_copy (manager->priv->storage_locations);
+  return g_list_copy (manager->priv->providers);
 }
 
 /**
- * gtd_manager_get_default_storage:
+ * gtd_manager_get_default_provider:
  * @manager: a #GtdManager
  *
- * Retrieves the default storage location. Default is "local".
+ * Retrieves the default provider location. Default is "local".
  *
- * Returns: (transfer none): the default storage.
+ * Returns: (transfer none): the default provider.
  */
-GtdStorage*
-gtd_manager_get_default_storage (GtdManager *manager)
+GtdProvider*
+gtd_manager_get_default_provider (GtdManager *manager)
 {
-  GtdManagerPrivate *priv;
-  GtdStorage *storage;
-  gchar *storage_id;
-
   g_return_val_if_fail (GTD_IS_MANAGER (manager), NULL);
 
-  priv = manager->priv;
-  storage = NULL;
-  storage_id = g_settings_get_string (priv->settings, "storage-location");
-
-  g_free (storage_id);
-
-  return storage;
+  return manager->priv->default_provider;
 }
 
 /**
@@ -1680,11 +583,11 @@ gtd_manager_get_default_storage (GtdManager *manager)
  * Returns:
  */
 void
-gtd_manager_set_default_storage (GtdManager *manager,
-                                 GtdStorage *default_storage)
+gtd_manager_set_default_provider (GtdManager  *manager,
+                                  GtdProvider *provider)
 {
   g_return_if_fail (GTD_IS_MANAGER (manager));
-
+/*
   if (!gtd_storage_get_is_default (default_storage))
     {
       GtdStorage *previus_default = NULL;
@@ -1703,11 +606,12 @@ gtd_manager_set_default_storage (GtdManager *manager,
         }
 
       g_signal_emit (manager,
-                     signals[DEFAULT_STORAGE_CHANGED],
+                     signals[DEFAULT_PROVIDER_CHANGED],
                      0,
                      default_storage,
                      previus_default);
     }
+ */
 }
 
 /**
@@ -1795,3 +699,15 @@ gtd_manager_get_today_list (GtdManager *manager)
 
   return manager->priv->today_tasks_list;
 }
+
+void
+gtd_manager_emit_error_message (GtdManager  *manager,
+                                const gchar *primary_message,
+                                const gchar *secondary_message)
+{
+  g_return_if_fail (GTD_IS_MANAGER (manager));
+
+  emit_show_error_message (manager,
+                           primary_message,
+                           secondary_message);
+}
diff --git a/src/gtd-manager.h b/src/gtd-manager.h
index f4625e3..2dc2d0d 100644
--- a/src/gtd-manager.h
+++ b/src/gtd-manager.h
@@ -37,11 +37,9 @@ GtdManager*             gtd_manager_new                   (void);
 
 GtdManager*             gtd_manager_get_default           (void);
 
-ESourceRegistry*        gtd_manager_get_source_registry   (GtdManager           *manager);
-
 GList*                  gtd_manager_get_task_lists        (GtdManager           *manager);
 
-GList*                  gtd_manager_get_storage_locations (GtdManager           *manager);
+GList*                  gtd_manager_get_providers         (GtdManager           *manager);
 
 /* Task lists */
 void                    gtd_manager_create_task_list      (GtdManager           *manager,
@@ -74,10 +72,10 @@ GoaClient*              gtd_manager_get_goa_client        (GtdManager
 gboolean                gtd_manager_is_goa_client_ready   (GtdManager           *manager);
 
 /* Settings */
-GtdStorage*             gtd_manager_get_default_storage   (GtdManager           *manager);
+GtdProvider*            gtd_manager_get_default_provider  (GtdManager           *manager);
 
-void                    gtd_manager_set_default_storage   (GtdManager           *manager,
-                                                           GtdStorage           *default_storage);
+void                    gtd_manager_set_default_provider  (GtdManager           *manager,
+                                                           GtdProvider          *provider);
 
 GSettings*              gtd_manager_get_settings          (GtdManager           *manager);
 
@@ -86,6 +84,10 @@ gboolean                gtd_manager_get_is_first_run      (GtdManager
 void                    gtd_manager_set_is_first_run      (GtdManager           *manager,
                                                            gboolean              is_first_run);
 
+void                    gtd_manager_emit_error_message    (GtdManager           *manager,
+                                                           const gchar          *primary_message,
+                                                           const gchar          *secondary_message);
+
 G_END_DECLS
 
 #endif /* GTD_MANAGER_H */
diff --git a/src/gtd-task-list.c b/src/gtd-task-list.c
index 009abc8..f79bfcf 100644
--- a/src/gtd-task-list.c
+++ b/src/gtd-task-list.c
@@ -16,6 +16,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "interfaces/gtd-provider.h"
 #include "gtd-task.h"
 #include "gtd-task-list.h"
 
@@ -55,68 +56,6 @@ enum
 };
 
 static void
-save_task_list_finished_cb (GObject      *source,
-                            GAsyncResult *result,
-                            gpointer      user_data)
-{
-  GtdTaskList  *list;
-  GError *error;
-
-  list = user_data;
-  error = NULL;
-
-  gtd_object_set_ready (GTD_OBJECT (list), TRUE);
-
-  e_source_write_finish (E_SOURCE (source),
-                         result,
-                         &error);
-
-  if (error)
-    {
-      g_warning ("%s: %s: %s",
-                 G_STRFUNC,
-                 _("Error saving task list"),
-                 error->message);
-      g_clear_error (&error);
-    }
-}
-
-static gboolean
-color_to_string (GBinding     *binding,
-                 const GValue *from_value,
-                 GValue       *to_value,
-                 gpointer      user_data)
-{
-  GdkRGBA *color;
-  gchar *color_str;
-
-  color = g_value_get_boxed (from_value);
-  color_str = gdk_rgba_to_string (color);
-
-  g_value_set_string (to_value, color_str);
-
-  g_free (color_str);
-
-  return TRUE;
-}
-
-static gboolean
-string_to_color (GBinding     *binding,
-                 const GValue *from_value,
-                 GValue       *to_value,
-                 gpointer      user_data)
-{
-  GdkRGBA color;
-
-  if (!gdk_rgba_parse (&color, g_value_get_string (from_value)))
-    gdk_rgba_parse (&color, "#ffffff"); /* calendar default colour */
-
-  g_value_set_boxed (to_value, &color);
-
-  return TRUE;
-}
-
-static void
 gtd_task_list_finalize (GObject *object)
 {
   GtdTaskList *self = (GtdTaskList*) object;
@@ -343,13 +282,17 @@ GdkRGBA*
 gtd_task_list_get_color (GtdTaskList *list)
 {
   GtdTaskListPrivate *priv;
+  GdkRGBA rgba;
 
   g_return_val_if_fail (GTD_IS_TASK_LIST (list), NULL);
 
   priv = gtd_task_list_get_instance_private (list);
 
   if (!priv->color)
-    gdk_rgba_parse (priv->color, "#ffffff");
+    {
+      gdk_rgba_parse (&rgba, "#ffffff");
+      priv->color = gdk_rgba_copy (&rgba);
+    }
 
   return gdk_rgba_copy (priv->color);
 }
diff --git a/src/gtd-task-list.h b/src/gtd-task-list.h
index 18e1ba7..4064747 100644
--- a/src/gtd-task-list.h
+++ b/src/gtd-task-list.h
@@ -20,9 +20,10 @@
 #define GTD_TASK_LIST_H
 
 #include <glib-object.h>
+#include <gtk/gtk.h>
 
-#include "interfaces/gtd-provider.h"
 #include "gtd-object.h"
+#include "gtd-types.h"
 
 G_BEGIN_DECLS
 
diff --git a/src/gtd-types.h b/src/gtd-types.h
index 4d04315..792b1c2 100644
--- a/src/gtd-types.h
+++ b/src/gtd-types.h
@@ -34,6 +34,7 @@ typedef struct _GtdNotification         GtdNotification;
 typedef struct _GtdNotificationWidget   GtdNotificationWidget;
 typedef struct _GtdObject               GtdObject;
 typedef struct _GtdPanel                GtdPanel;
+typedef struct _GtdProvider             GtdProvider;
 typedef struct _GtdStorage              GtdStorage;
 typedef struct _GtdStoragePopover       GtdStoragePopover;
 typedef struct _GtdStorageRow           GtdStorageRow;
diff --git a/src/gtd-window.c b/src/gtd-window.c
index 17fb16c..472cedd 100644
--- a/src/gtd-window.c
+++ b/src/gtd-window.c
@@ -16,13 +16,14 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "interfaces/gtd-provider.h"
 #include "gtd-application.h"
 #include "gtd-enum-types.h"
 #include "gtd-task-list-view.h"
 #include "gtd-manager.h"
 #include "gtd-notification.h"
 #include "gtd-notification-widget.h"
-#include "gtd-storage-dialog.h"
+#include "gtd-provider-dialog.h"
 #include "gtd-task.h"
 #include "gtd-task-list.h"
 #include "gtd-task-list-item.h"
@@ -52,7 +53,7 @@ typedef struct
   GtkWidget                     *select_button;
   GtkStack                      *stack;
   GtkStackSwitcher              *stack_switcher;
-  GtdStorageDialog              *storage_dialog;
+  GtdProviderDialog             *provider_dialog;
   GtdTaskListView               *today_list_view;
   GtdTaskListView               *list_view;
 
@@ -557,7 +558,7 @@ gtd_window__change_storage_action (GSimpleAction *simple,
 
   priv = GTD_WINDOW (user_data)->priv;
 
-  gtk_dialog_run (GTK_DIALOG (priv->storage_dialog));
+  gtk_dialog_run (GTK_DIALOG (priv->provider_dialog));
 }
 
 static void
@@ -609,14 +610,19 @@ gtd_window__flowbox_sort_func (GtdTaskListItem *a,
                                GtdTaskListItem *b,
                                gpointer         user_data)
 {
+  GtdProvider *p1;
+  GtdProvider *p2;
   GtdTaskList *l1;
   GtdTaskList *l2;
   gint retval = 0;
 
   l1 = gtd_task_list_item_get_list (a);
+  p1 = gtd_task_list_get_provider (l1);
+
   l2 = gtd_task_list_item_get_list (b);
+  p2 = gtd_task_list_get_provider (l2);
 
-  retval = g_strcmp0 (gtd_task_list_get_origin (l1), gtd_task_list_get_origin (l2));
+  retval = g_strcmp0 (gtd_provider_get_description (p1), gtd_provider_get_description (p2));
 
   if (retval != 0)
     return retval;
@@ -702,6 +708,7 @@ gtd_window__list_selected (GtkFlowBox      *flowbox,
                            gpointer         user_data)
 {
   GtdWindowPrivate *priv = GTD_WINDOW (user_data)->priv;
+  GtdProvider *provider;
   GtdTaskList *list;
   GdkRGBA *list_color;
 
@@ -717,6 +724,7 @@ gtd_window__list_selected (GtkFlowBox      *flowbox,
 
     case GTD_WINDOW_MODE_NORMAL:
       list = gtd_task_list_item_get_list (item);
+      provider = gtd_task_list_get_provider (list);
       list_color = gtd_task_list_get_color (list);
 
       g_signal_handlers_block_by_func (priv->color_button,
@@ -727,7 +735,7 @@ gtd_window__list_selected (GtkFlowBox      *flowbox,
 
       gtk_stack_set_visible_child_name (priv->main_stack, "tasks");
       gtk_header_bar_set_title (priv->headerbar, gtd_task_list_get_name (list));
-      gtk_header_bar_set_subtitle (priv->headerbar, gtd_task_list_get_origin (list));
+      gtk_header_bar_set_subtitle (priv->headerbar, gtd_provider_get_description (provider));
       gtk_header_bar_set_custom_title (priv->headerbar, NULL);
       gtk_search_bar_set_search_mode (priv->search_bar, FALSE);
       gtd_task_list_view_set_task_list (priv->list_view, list);
@@ -903,7 +911,7 @@ gtd_window_constructed (GObject *object)
                           G_BINDING_DEFAULT);
   g_object_bind_property (object,
                           "manager",
-                          priv->storage_dialog,
+                          priv->provider_dialog,
                           "manager",
                           G_BINDING_DEFAULT);
 }
@@ -1092,6 +1100,7 @@ gtd_window_class_init (GtdWindowClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, new_list_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, new_list_popover);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, notification_widget);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, provider_dialog);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, remove_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, rename_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, rename_entry);
@@ -1104,7 +1113,6 @@ gtd_window_class_init (GtdWindowClass *klass)
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, search_entry);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, select_button);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, stack_switcher);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, storage_dialog);
   gtk_widget_class_bind_template_child_private (widget_class, GtdWindow, today_list_view);
 
   gtk_widget_class_bind_template_callback (widget_class, gtd_window__back_button_clicked);
diff --git a/src/storage/gtd-storage-dialog.c b/src/provider/gtd-provider-dialog.c
similarity index 56%
rename from src/storage/gtd-storage-dialog.c
rename to src/provider/gtd-provider-dialog.c
index 13ea469..30a864a 100644
--- a/src/storage/gtd-storage-dialog.c
+++ b/src/provider/gtd-provider-dialog.c
@@ -1,4 +1,4 @@
-/* gtd-storage-dialog.c
+/* gtd-provider-dialog.c
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -17,29 +17,29 @@
  */
 
 #include "gtd-manager.h"
-#include "gtd-storage.h"
-#include "gtd-storage-dialog.h"
-#include "gtd-storage-selector.h"
+#include "interfaces/gtd-provider.h"
+#include "gtd-provider-dialog.h"
+#include "gtd-provider-selector.h"
 
 #include <glib/gi18n.h>
 
 typedef struct
 {
   GtkWidget       *headerbar;
-  GtkWidget       *storage_selector;
+  GtkWidget       *provider_selector;
 
   GtdManager      *manager;
-} GtdStorageDialogPrivate;
+} GtdProviderDialogPrivate;
 
-struct _GtdStorageDialog
+struct _GtdProviderDialog
 {
   GtkDialog                parent;
 
   /*<private>*/
-  GtdStorageDialogPrivate *priv;
+  GtdProviderDialogPrivate *priv;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtdStorageDialog, gtd_storage_dialog, GTK_TYPE_DIALOG)
+G_DEFINE_TYPE_WITH_PRIVATE (GtdProviderDialog, gtd_provider_dialog, GTK_TYPE_DIALOG)
 
 enum {
   PROP_0,
@@ -48,53 +48,53 @@ enum {
 };
 
 static void
-gtd_storage_dialog__storage_selected (GtdStorageDialog *dialog,
-                                      GtdStorage       *storage)
+gtd_provider_dialog__provider_selected (GtdProviderDialog *dialog,
+                                      GtdProvider       *provider)
 {
-  GtdStorageDialogPrivate *priv;
+  GtdProviderDialogPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_DIALOG (dialog));
+  g_return_if_fail (GTD_IS_PROVIDER_DIALOG (dialog));
   g_return_if_fail (GTD_IS_MANAGER (dialog->priv->manager));
-  g_return_if_fail (GTD_IS_STORAGE (storage));
+  g_return_if_fail (GTD_IS_PROVIDER (provider));
 
   priv = dialog->priv;
 
-  if (storage)
-    gtd_manager_set_default_storage (priv->manager, storage);
+  if (provider)
+    gtd_manager_set_default_provider (priv->manager, provider);
 }
 
 static void
-gtd_storage_dialog_finalize (GObject *object)
+gtd_provider_dialog_finalize (GObject *object)
 {
-  G_OBJECT_CLASS (gtd_storage_dialog_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtd_provider_dialog_parent_class)->finalize (object);
 }
 
 static void
-gtd_storage_dialog_constructed (GObject *object)
+gtd_provider_dialog_constructed (GObject *object)
 {
-  GtdStorageDialogPrivate *priv;
+  GtdProviderDialogPrivate *priv;
 
   /* Chain up */
-  G_OBJECT_CLASS (gtd_storage_dialog_parent_class)->constructed (object);
+  G_OBJECT_CLASS (gtd_provider_dialog_parent_class)->constructed (object);
 
-  priv = GTD_STORAGE_DIALOG (object)->priv;
+  priv = GTD_PROVIDER_DIALOG (object)->priv;
 
   gtk_window_set_titlebar (GTK_WINDOW (object), priv->headerbar);
 
   g_object_bind_property (object,
                           "manager",
-                          priv->storage_selector,
+                          priv->provider_selector,
                           "manager",
                           G_BINDING_DEFAULT);
 }
 
 static void
-gtd_storage_dialog_get_property (GObject    *object,
+gtd_provider_dialog_get_property (GObject    *object,
                                  guint       prop_id,
                                  GValue     *value,
                                  GParamSpec *pspec)
 {
-  GtdStorageDialog *self = GTD_STORAGE_DIALOG (object);
+  GtdProviderDialog *self = GTD_PROVIDER_DIALOG (object);
 
   switch (prop_id)
     {
@@ -108,17 +108,17 @@ gtd_storage_dialog_get_property (GObject    *object,
 }
 
 static void
-gtd_storage_dialog_set_property (GObject      *object,
+gtd_provider_dialog_set_property (GObject      *object,
                                  guint         prop_id,
                                  const GValue *value,
                                  GParamSpec   *pspec)
 {
-  GtdStorageDialog *self = GTD_STORAGE_DIALOG (object);
+  GtdProviderDialog *self = GTD_PROVIDER_DIALOG (object);
 
   switch (prop_id)
     {
     case PROP_MANAGER:
-      gtd_storage_dialog_set_manager (self, g_value_get_object (value));
+      gtd_provider_dialog_set_manager (self, g_value_get_object (value));
       break;
 
     default:
@@ -127,19 +127,19 @@ gtd_storage_dialog_set_property (GObject      *object,
 }
 
 static void
-gtd_storage_dialog_class_init (GtdStorageDialogClass *klass)
+gtd_provider_dialog_class_init (GtdProviderDialogClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->finalize = gtd_storage_dialog_finalize;
-  object_class->constructed = gtd_storage_dialog_constructed;
-  object_class->get_property = gtd_storage_dialog_get_property;
-  object_class->set_property = gtd_storage_dialog_set_property;
+  object_class->finalize = gtd_provider_dialog_finalize;
+  object_class->constructed = gtd_provider_dialog_constructed;
+  object_class->get_property = gtd_provider_dialog_get_property;
+  object_class->set_property = gtd_provider_dialog_set_property;
 
 
   /**
-   * GtdStorageDialog::manager:
+   * GtdProviderDialog::manager:
    *
    * A weak reference to the application's #GtdManager instance.
    */
@@ -152,54 +152,54 @@ gtd_storage_dialog_class_init (GtdStorageDialogClass *klass)
                              GTD_TYPE_MANAGER,
                              G_PARAM_READWRITE));
 
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/storage-dialog.ui");
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/provider-dialog.ui");
 
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageDialog, headerbar);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageDialog, storage_selector);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderDialog, headerbar);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderDialog, provider_selector);
 
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_dialog__storage_selected);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_dialog__provider_selected);
 }
 
 static void
-gtd_storage_dialog_init (GtdStorageDialog *self)
+gtd_provider_dialog_init (GtdProviderDialog *self)
 {
-  self->priv = gtd_storage_dialog_get_instance_private (self);
+  self->priv = gtd_provider_dialog_get_instance_private (self);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 }
 
 /**
- * gtd_storage_dialog_new:
+ * gtd_provider_dialog_new:
  *
- * Creates a new #GtdStorageDialog.
+ * Creates a new #GtdProviderDialog.
  *
- * Returns: (transfer full): the newly allocated #GtdStorageDialog
+ * Returns: (transfer full): the newly allocated #GtdProviderDialog
  */
 GtkWidget*
-gtd_storage_dialog_new (void)
+gtd_provider_dialog_new (void)
 {
-  return g_object_new (GTD_TYPE_STORAGE_DIALOG, NULL);
+  return g_object_new (GTD_TYPE_PROVIDER_DIALOG, NULL);
 }
 
 /**
- * gtd_storage_dialog_get_manager:
- * @dialog: a #GtdStorageDialog
+ * gtd_provider_dialog_get_manager:
+ * @dialog: a #GtdProviderDialog
  *
  * Retrieves @dialog's internal #GtdManager.
  *
  * Returns: (transfer none): the @dialog's #GtdManager
  */
 GtdManager*
-gtd_storage_dialog_get_manager (GtdStorageDialog *dialog)
+gtd_provider_dialog_get_manager (GtdProviderDialog *dialog)
 {
-  g_return_val_if_fail (GTD_IS_STORAGE_DIALOG (dialog), NULL);
+  g_return_val_if_fail (GTD_IS_PROVIDER_DIALOG (dialog), NULL);
 
   return dialog->priv->manager;
 }
 
 /**
- * gtd_storage_dialog_set_manager:
- * @dialog: a #GtdStorageDialog
+ * gtd_provider_dialog_set_manager:
+ * @dialog: a #GtdProviderDialog
  * @manager: a #GtdManager
  *
  * Sets the @dialog's #GtdManager.
@@ -207,12 +207,12 @@ gtd_storage_dialog_get_manager (GtdStorageDialog *dialog)
  * Returns:
  */
 void
-gtd_storage_dialog_set_manager (GtdStorageDialog *dialog,
+gtd_provider_dialog_set_manager (GtdProviderDialog *dialog,
                                 GtdManager       *manager)
 {
-  GtdStorageDialogPrivate *priv;
+  GtdProviderDialogPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_DIALOG (dialog));
+  g_return_if_fail (GTD_IS_PROVIDER_DIALOG (dialog));
 
   priv = dialog->priv;
 
diff --git a/src/storage/gtd-storage-dialog.h b/src/provider/gtd-provider-dialog.h
similarity index 63%
rename from src/storage/gtd-storage-dialog.h
rename to src/provider/gtd-provider-dialog.h
index 30d43b5..cc419b3 100644
--- a/src/storage/gtd-storage-dialog.h
+++ b/src/provider/gtd-provider-dialog.h
@@ -1,4 +1,4 @@
-/* gtd-storage-dialog.h
+/* gtd-provider-dialog.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,8 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_DIALOG_H
-#define GTD_STORAGE_DIALOG_H
+#ifndef GTD_PROVIDER_DIALOG_H
+#define GTD_PROVIDER_DIALOG_H
 
 #include "gtd-types.h"
 
@@ -25,17 +25,17 @@
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_DIALOG (gtd_storage_dialog_get_type())
+#define GTD_TYPE_PROVIDER_DIALOG (gtd_provider_dialog_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageDialog, gtd_storage_dialog, GTD, STORAGE_DIALOG, GtkDialog)
+G_DECLARE_FINAL_TYPE (GtdProviderDialog, gtd_provider_dialog, GTD, PROVIDER_DIALOG, GtkDialog)
 
-GtkWidget*         gtd_storage_dialog_new                        (void);
+GtkWidget*         gtd_provider_dialog_new                       (void);
 
-GtdManager*        gtd_storage_dialog_get_manager                (GtdStorageDialog   *dialog);
+GtdManager*        gtd_provider_dialog_get_manager               (GtdProviderDialog   *dialog);
 
-void               gtd_storage_dialog_set_manager                (GtdStorageDialog   *dialog,
+void               gtd_provider_dialog_set_manager               (GtdProviderDialog   *dialog,
                                                                   GtdManager         *manager);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_DIALOG_H */
+#endif /* GTD_PROVIDER_DIALOG_H */
diff --git a/src/storage/gtd-storage-popover.c b/src/provider/gtd-provider-popover.c
similarity index 56%
rename from src/storage/gtd-storage-popover.c
rename to src/provider/gtd-provider-popover.c
index 787e0f8..9412061 100644
--- a/src/storage/gtd-storage-popover.c
+++ b/src/provider/gtd-provider-popover.c
@@ -1,4 +1,4 @@
-/* gtd-storage-popover.c
+/* gtd-provider-popover.c
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -17,9 +17,10 @@
  */
 
 #include "gtd-manager.h"
-#include "gtd-storage.h"
-#include "gtd-storage-popover.h"
-#include "gtd-storage-selector.h"
+#include "interfaces/gtd-provider.h"
+#include "gtd-provider-popover.h"
+#include "gtd-provider-selector.h"
+#include "gtd-task-list.h"
 
 #include <glib/gi18n.h>
 
@@ -30,20 +31,20 @@ typedef struct
   GtkWidget            *new_list_create_button;
   GtkWidget            *new_list_name_entry;
   GtkWidget            *stack;
-  GtkWidget            *storage_selector;
+  GtkWidget            *provider_selector;
 
   GtdManager           *manager;
-} GtdStoragePopoverPrivate;
+} GtdProviderPopoverPrivate;
 
-struct _GtdStoragePopover
+struct _GtdProviderPopover
 {
   GtkPopover                parent;
 
   /*<private>*/
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtdStoragePopover, gtd_storage_popover, GTK_TYPE_POPOVER)
+G_DEFINE_TYPE_WITH_PRIVATE (GtdProviderPopover, gtd_provider_popover, GTK_TYPE_POPOVER)
 
 enum {
   PROP_0,
@@ -52,24 +53,24 @@ enum {
 };
 
 static void
-clear_and_hide (GtdStoragePopover *popover)
+clear_and_hide (GtdProviderPopover *popover)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
   GList *locations;
   GList *l;
 
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
 
   priv = popover->priv;
 
   /* Select the default source again */
-  locations = gtd_manager_get_storage_locations (priv->manager);
+  locations = gtd_manager_get_providers (priv->manager);
 
   for (l = locations; l != NULL; l = l->next)
     {
-      if (gtd_storage_get_is_default (l->data))
+      if (FALSE)//gtd_provider_get_is_default (l->data))
         {
-          gtd_storage_selector_set_selected_storage (GTD_STORAGE_SELECTOR (priv->storage_selector), l->data);
+          gtd_provider_selector_set_selected_provider (GTD_PROVIDER_SELECTOR (priv->provider_selector), 
l->data);
           break;
         }
     }
@@ -84,32 +85,33 @@ clear_and_hide (GtdStoragePopover *popover)
 }
 
 static void
-gtd_storage_popover__closed (GtdStoragePopover *popover)
+gtd_provider_popover__closed (GtdProviderPopover *popover)
 {
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
 
   gtk_stack_set_visible_child_name (GTK_STACK (popover->priv->stack), "main");
 }
 
 static void
-create_task_list (GtdStoragePopover *popover)
+create_task_list (GtdProviderPopover *popover)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
   GtdTaskList *task_list;
-  GtdStorage *storage;
+  GtdProvider *provider;
   const gchar *name;
 
   priv = popover->priv;
-  storage = gtd_storage_selector_get_selected_storage (GTD_STORAGE_SELECTOR (priv->storage_selector));
+  provider = gtd_provider_selector_get_selected_provider (GTD_PROVIDER_SELECTOR (priv->provider_selector));
   name = gtk_entry_get_text (GTK_ENTRY (priv->new_list_name_entry));
 
-  task_list = gtd_storage_create_task_list (storage, name);
+  task_list = gtd_task_list_new (provider);
+  gtd_task_list_set_name (task_list, name);
 
-  gtd_manager_save_task_list (priv->manager, task_list);
+  gtd_provider_create_task_list (provider, task_list);
 }
 
 static void
-gtd_storage_popover__entry_activate (GtdStoragePopover *popover,
+gtd_provider_popover__entry_activate (GtdProviderPopover *popover,
                                      GtkEntry          *entry)
 {
   if (gtk_entry_get_text_length (entry) > 0)
@@ -120,12 +122,12 @@ gtd_storage_popover__entry_activate (GtdStoragePopover *popover,
 }
 
 static void
-gtd_storage_popover__action_button_clicked (GtdStoragePopover *popover,
+gtd_provider_popover__action_button_clicked (GtdProviderPopover *popover,
                                             GtkWidget         *button)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
 
   priv = popover->priv;
 
@@ -136,13 +138,13 @@ gtd_storage_popover__action_button_clicked (GtdStoragePopover *popover,
 }
 
 static void
-gtd_storage_popover__text_changed_cb (GtdStoragePopover *popover,
+gtd_provider_popover__text_changed_cb (GtdProviderPopover *popover,
                                       GParamSpec        *spec,
                                       GtkEntry          *entry)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
   g_return_if_fail (GTK_IS_ENTRY (entry));
 
   priv = popover->priv;
@@ -151,12 +153,12 @@ gtd_storage_popover__text_changed_cb (GtdStoragePopover *popover,
 }
 
 static void
-gtd_storage_popover__change_location_clicked (GtdStoragePopover *popover,
+gtd_provider_popover__change_location_clicked (GtdProviderPopover *popover,
                                               GtkWidget         *button)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
 
   priv = popover->priv;
 
@@ -167,24 +169,24 @@ gtd_storage_popover__change_location_clicked (GtdStoragePopover *popover,
 }
 
 static void
-gtd_storage_popover__storage_selected (GtdStoragePopover *popover,
-                                       GtdStorage        *storage)
+gtd_provider_popover__provider_selected (GtdProviderPopover *popover,
+                                       GtdProvider        *provider)
 {
-  GtdStoragePopoverPrivate *priv;
+  GtdProviderPopoverPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_POPOVER (popover));
-  g_return_if_fail (GTD_IS_STORAGE (storage));
+  g_return_if_fail (GTD_IS_PROVIDER_POPOVER (popover));
+  g_return_if_fail (GTD_IS_PROVIDER (provider));
 
   priv = popover->priv;
 
-  if (storage)
+  if (provider)
     {
       gtk_image_set_from_gicon (GTK_IMAGE (priv->location_provider_image),
-                                gtd_storage_get_icon (storage),
+                                gtd_provider_get_icon (provider),
                                 GTK_ICON_SIZE_BUTTON);
-      gtk_widget_set_tooltip_text (priv->change_location_button, gtd_storage_get_name (storage));
+      gtk_widget_set_tooltip_text (priv->change_location_button, gtd_provider_get_name (provider));
 
-      /* Go back immediately after selecting a storage */
+      /* Go back immediately after selecting a provider */
       gtk_stack_set_visible_child_name (GTK_STACK (priv->stack), "main");
 
       if (gtk_widget_is_visible (GTK_WIDGET (popover)))
@@ -193,43 +195,43 @@ gtd_storage_popover__storage_selected (GtdStoragePopover *popover,
 }
 
 static void
-gtd_storage_popover_finalize (GObject *object)
+gtd_provider_popover_finalize (GObject *object)
 {
-  G_OBJECT_CLASS (gtd_storage_popover_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtd_provider_popover_parent_class)->finalize (object);
 }
 
 static void
-gtd_storage_popover_constructed (GObject *object)
+gtd_provider_popover_constructed (GObject *object)
 {
-  GtdStoragePopoverPrivate *priv;
-  GtdStorage *storage;
+  GtdProviderPopoverPrivate *priv;
+  GtdProvider *provider;
 
-  G_OBJECT_CLASS (gtd_storage_popover_parent_class)->constructed (object);
+  G_OBJECT_CLASS (gtd_provider_popover_parent_class)->constructed (object);
 
-  priv = GTD_STORAGE_POPOVER (object)->priv;
-  storage = gtd_storage_selector_get_selected_storage (GTD_STORAGE_SELECTOR (priv->storage_selector));
+  priv = GTD_PROVIDER_POPOVER (object)->priv;
+  provider = gtd_provider_selector_get_selected_provider (GTD_PROVIDER_SELECTOR (priv->provider_selector));
 
   g_object_bind_property (object,
                           "manager",
-                          priv->storage_selector,
+                          priv->provider_selector,
                           "manager",
                           G_BINDING_DEFAULT);
 
-  if (storage)
+  if (provider)
     {
       gtk_image_set_from_gicon (GTK_IMAGE (priv->location_provider_image),
-                                gtd_storage_get_icon (storage),
+                                gtd_provider_get_icon (provider),
                                 GTK_ICON_SIZE_BUTTON);
     }
 }
 
 static void
-gtd_storage_popover_get_property (GObject    *object,
+gtd_provider_popover_get_property (GObject    *object,
                                   guint       prop_id,
                                   GValue     *value,
                                   GParamSpec *pspec)
 {
-  GtdStoragePopover *self = GTD_STORAGE_POPOVER (object);
+  GtdProviderPopover *self = GTD_PROVIDER_POPOVER (object);
 
   switch (prop_id)
     {
@@ -243,12 +245,12 @@ gtd_storage_popover_get_property (GObject    *object,
 }
 
 static void
-gtd_storage_popover_set_property (GObject      *object,
+gtd_provider_popover_set_property (GObject      *object,
                                   guint         prop_id,
                                   const GValue *value,
                                   GParamSpec   *pspec)
 {
-  GtdStoragePopover *self = GTD_STORAGE_POPOVER (object);
+  GtdProviderPopover *self = GTD_PROVIDER_POPOVER (object);
 
   switch (prop_id)
     {
@@ -266,18 +268,18 @@ gtd_storage_popover_set_property (GObject      *object,
 }
 
 static void
-gtd_storage_popover_class_init (GtdStoragePopoverClass *klass)
+gtd_provider_popover_class_init (GtdProviderPopoverClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->finalize = gtd_storage_popover_finalize;
-  object_class->constructed = gtd_storage_popover_constructed;
-  object_class->get_property = gtd_storage_popover_get_property;
-  object_class->set_property = gtd_storage_popover_set_property;
+  object_class->finalize = gtd_provider_popover_finalize;
+  object_class->constructed = gtd_provider_popover_constructed;
+  object_class->get_property = gtd_provider_popover_get_property;
+  object_class->set_property = gtd_provider_popover_set_property;
 
   /**
-   * GtdStoragePopover::manager:
+   * GtdProviderPopover::manager:
    *
    * A weak reference to the application's #GtdManager instance.
    */
@@ -290,33 +292,33 @@ gtd_storage_popover_class_init (GtdStoragePopoverClass *klass)
                              GTD_TYPE_MANAGER,
                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/storage-popover.ui");
-
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, change_location_button);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, location_provider_image);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, new_list_create_button);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, new_list_name_entry);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, stack);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStoragePopover, storage_selector);
-
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__action_button_clicked);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__change_location_clicked);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__closed);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__entry_activate);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__storage_selected);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_popover__text_changed_cb);
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/provider-popover.ui");
+
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, change_location_button);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, location_provider_image);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, new_list_create_button);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, new_list_name_entry);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, stack);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderPopover, provider_selector);
+
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__action_button_clicked);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__change_location_clicked);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__closed);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__entry_activate);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__provider_selected);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_popover__text_changed_cb);
 }
 
 static void
-gtd_storage_popover_init (GtdStoragePopover *self)
+gtd_provider_popover_init (GtdProviderPopover *self)
 {
-  self->priv = gtd_storage_popover_get_instance_private (self);
+  self->priv = gtd_provider_popover_get_instance_private (self);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 }
 
 GtkWidget*
-gtd_storage_popover_new (void)
+gtd_provider_popover_new (void)
 {
-  return g_object_new (GTD_TYPE_STORAGE_POPOVER, NULL);
+  return g_object_new (GTD_TYPE_PROVIDER_POPOVER, NULL);
 }
diff --git a/src/storage/gtd-storage-popover.h b/src/provider/gtd-provider-popover.h
similarity index 68%
rename from src/storage/gtd-storage-popover.h
rename to src/provider/gtd-provider-popover.h
index f38ca4e..9b97583 100644
--- a/src/storage/gtd-storage-popover.h
+++ b/src/provider/gtd-provider-popover.h
@@ -1,4 +1,4 @@
-/* gtd-storage-popover.h
+/* gtd-provider-popover.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,19 +16,19 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_POPOVER_H
-#define GTD_STORAGE_POPOVER_H
+#ifndef GTD_PROVIDER_POPOVER_H
+#define GTD_PROVIDER_POPOVER_H
 
 #include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_POPOVER (gtd_storage_popover_get_type())
+#define GTD_TYPE_PROVIDER_POPOVER (gtd_provider_popover_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStoragePopover, gtd_storage_popover, GTD, STORAGE_POPOVER, GtkPopover)
+G_DECLARE_FINAL_TYPE (GtdProviderPopover, gtd_provider_popover, GTD, PROVIDER_POPOVER, GtkPopover)
 
-GtkWidget*         gtd_storage_popover_new                       (void);
+GtkWidget*         gtd_provider_popover_new                       (void);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_POPOVER_H */
+#endif /* GTD_PROVIDER_POPOVER_H */
diff --git a/src/storage/gtd-storage-row.c b/src/provider/gtd-provider-row.c
similarity index 54%
rename from src/storage/gtd-storage-row.c
rename to src/provider/gtd-provider-row.c
index ae6d25c..6bebddd 100644
--- a/src/storage/gtd-storage-row.c
+++ b/src/provider/gtd-provider-row.c
@@ -1,4 +1,4 @@
-/* gtd-storage-row.c
+/* gtd-provider-row.c
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,8 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "gtd-storage.h"
-#include "gtd-storage-row.h"
+#include "interfaces/gtd-provider.h"
+#include "gtd-provider-row.h"
 
 #include <glib/gi18n.h>
 
@@ -25,52 +25,52 @@ typedef struct
 {
   GtkImage        *icon;
   GtkLabel        *name;
-  GtkLabel        *provider;
+  GtkLabel        *description;
   GtkLabel        *enabled;
   GtkImage        *selected;
 
-  GtdStorage      *storage;
-} GtdStorageRowPrivate;
+  GtdProvider     *provider;
+} GtdProviderRowPrivate;
 
-struct _GtdStorageRow
+struct _GtdProviderRow
 {
   GtkListBoxRow         parent;
 
   /*< private >*/
-  GtdStorageRowPrivate *priv;
+  GtdProviderRowPrivate *priv;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtdStorageRow, gtd_storage_row, GTK_TYPE_LIST_BOX_ROW)
+G_DEFINE_TYPE_WITH_PRIVATE (GtdProviderRow, gtd_provider_row, GTK_TYPE_LIST_BOX_ROW)
 
 enum {
   PROP_0,
-  PROP_STORAGE,
+  PROP_PROVIDER,
   LAST_PROP
 };
 
 static void
-gtd_storage_row_finalize (GObject *object)
+gtd_provider_row_finalize (GObject *object)
 {
-  GtdStorageRow *self = (GtdStorageRow *)object;
-  GtdStorageRowPrivate *priv = gtd_storage_row_get_instance_private (self);
+  GtdProviderRow *self = (GtdProviderRow *)object;
+  GtdProviderRowPrivate *priv = gtd_provider_row_get_instance_private (self);
 
-  g_clear_object (&priv->storage);
+  g_clear_object (&priv->provider);
 
-  G_OBJECT_CLASS (gtd_storage_row_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtd_provider_row_parent_class)->finalize (object);
 }
 
 static void
-gtd_storage_row_get_property (GObject    *object,
+gtd_provider_row_get_property (GObject    *object,
                               guint       prop_id,
                               GValue     *value,
                               GParamSpec *pspec)
 {
-  GtdStorageRow *self = GTD_STORAGE_ROW (object);
+  GtdProviderRow *self = GTD_PROVIDER_ROW (object);
 
   switch (prop_id)
     {
-    case PROP_STORAGE:
-      g_value_set_object (value, self->priv->storage);
+    case PROP_PROVIDER:
+      g_value_set_object (value, self->priv->provider);
       break;
 
     default:
@@ -79,42 +79,42 @@ gtd_storage_row_get_property (GObject    *object,
 }
 
 static void
-gtd_storage_row_set_property (GObject      *object,
+gtd_provider_row_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
                               GParamSpec   *pspec)
 {
-  GtdStorageRow *self = GTD_STORAGE_ROW (object);
+  GtdProviderRow *self = GTD_PROVIDER_ROW (object);
 
   switch (prop_id)
     {
-    case PROP_STORAGE:
-      self->priv->storage = g_value_get_object (value);
+    case PROP_PROVIDER:
+      self->priv->provider = g_value_get_object (value);
 
-      if (!self->priv->storage)
+      if (!self->priv->provider)
         break;
 
-      g_object_ref (self->priv->storage);
+      g_object_ref (self->priv->provider);
 
-      g_object_bind_property (self->priv->storage,
+      g_object_bind_property (self->priv->provider,
                               "name",
                               self->priv->name,
                               "label",
                               G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
 
-      g_object_bind_property (self->priv->storage,
-                              "provider",
-                              self->priv->provider,
+      g_object_bind_property (self->priv->provider,
+                              "description",
+                              self->priv->description,
                               "label",
                               G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
 
-      g_object_bind_property (self->priv->storage,
+      g_object_bind_property (self->priv->provider,
                               "enabled",
                               self->priv->enabled,
                               "visible",
                               G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE | G_BINDING_INVERT_BOOLEAN);
 
-      g_object_bind_property (self->priv->storage,
+      g_object_bind_property (self->priv->provider,
                               "icon",
                               self->priv->icon,
                               "gicon",
@@ -127,99 +127,99 @@ gtd_storage_row_set_property (GObject      *object,
 }
 
 static void
-gtd_storage_row_class_init (GtdStorageRowClass *klass)
+gtd_provider_row_class_init (GtdProviderRowClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->finalize = gtd_storage_row_finalize;
-  object_class->get_property = gtd_storage_row_get_property;
-  object_class->set_property = gtd_storage_row_set_property;
+  object_class->finalize = gtd_provider_row_finalize;
+  object_class->get_property = gtd_provider_row_get_property;
+  object_class->set_property = gtd_provider_row_set_property;
 
   /**
-   * GtdStorageRow::storage:
+   * GtdProviderRow::provider:
    *
-   * #GtdStorage related to this row.
+   * #GtdProvider related to this row.
    */
   g_object_class_install_property (
         object_class,
-        PROP_STORAGE,
-        g_param_spec_object ("storage",
-                             "Storage of the row",
-                             "The storage that this row holds",
-                             GTD_TYPE_STORAGE,
+        PROP_PROVIDER,
+        g_param_spec_object ("provider",
+                             "Provider of the row",
+                             "The provider that this row holds",
+                             GTD_TYPE_PROVIDER,
                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 
 
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/storage-row.ui");
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/provider-row.ui");
 
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageRow, icon);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageRow, name);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageRow, provider);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageRow, enabled);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageRow, selected);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderRow, icon);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderRow, name);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderRow, description);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderRow, enabled);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderRow, selected);
 }
 
 static void
-gtd_storage_row_init (GtdStorageRow *self)
+gtd_provider_row_init (GtdProviderRow *self)
 {
-  self->priv = gtd_storage_row_get_instance_private (self);
+  self->priv = gtd_provider_row_get_instance_private (self);
 
   gtk_widget_init_template (GTK_WIDGET (self));
 }
 
 
 /**
- * gtd_storage_row_new:
- * @storage: a #GtdStorage
+ * gtd_provider_row_new:
+ * @provider: a #GtdProvider
  *
- * Created a new #GtdStorageRow with @account information.
+ * Created a new #GtdProviderRow with @account information.
  *
- * Returns: (transfer full): a new #GtdStorageRow
+ * Returns: (transfer full): a new #GtdProviderRow
  */
 GtkWidget*
-gtd_storage_row_new (GtdStorage *storage)
+gtd_provider_row_new (GtdProvider *provider)
 {
-  return g_object_new (GTD_TYPE_STORAGE_ROW,
-                       "storage", storage,
+  return g_object_new (GTD_TYPE_PROVIDER_ROW,
+                       "provider", provider,
                        NULL);
 }
 
 /**
- * gtd_storage_row_get_storage:
- * @row: a #GtdStorageRow
+ * gtd_provider_row_get_provider:
+ * @row: a #GtdProviderRow
  *
- * Retrieves the #GtdStorage associated with @row.
+ * Retrieves the #GtdProvider associated with @row.
  *
- * Returns: (transfer none): the #GtdStorage associated with @row.
+ * Returns: (transfer none): the #GtdProvider associated with @row.
  */
-GtdStorage*
-gtd_storage_row_get_storage (GtdStorageRow *row)
+GtdProvider*
+gtd_provider_row_get_provider (GtdProviderRow *row)
 {
-  g_return_val_if_fail (GTD_IS_STORAGE_ROW (row), NULL);
+  g_return_val_if_fail (GTD_IS_PROVIDER_ROW (row), NULL);
 
-  return row->priv->storage;
+  return row->priv->provider;
 }
 
 /**
- * gtd_storage_row_get_selected:
- * @row: a #GtdStorageRow
+ * gtd_provider_row_get_selected:
+ * @row: a #GtdProviderRow
  *
  * Whether @row is the currently selected row or not.
  *
  * Returns: %TRUE if the row is currently selected, %FALSE otherwise.
  */
 gboolean
-gtd_storage_row_get_selected (GtdStorageRow *row)
+gtd_provider_row_get_selected (GtdProviderRow *row)
 {
-  g_return_val_if_fail (GTD_IS_STORAGE_ROW (row), FALSE);
+  g_return_val_if_fail (GTD_IS_PROVIDER_ROW (row), FALSE);
 
   return gtk_widget_get_visible (GTK_WIDGET (row->priv->selected));
 }
 
 /**
- * gtd_storage_row_set_selected:
- * @row: a #GtdStorageRow
+ * gtd_provider_row_set_selected:
+ * @row: a #GtdProviderRow
  * @selected: %TRUE if row is selected (i.e. the selection
  * mark is visible)
  *
@@ -228,10 +228,10 @@ gtd_storage_row_get_selected (GtdStorageRow *row)
  * Returns:
  */
 void
-gtd_storage_row_set_selected (GtdStorageRow *row,
+gtd_provider_row_set_selected (GtdProviderRow *row,
                               gboolean       selected)
 {
-  g_return_if_fail (GTD_IS_STORAGE_ROW (row));
+  g_return_if_fail (GTD_IS_PROVIDER_ROW (row));
 
   if (selected != gtk_widget_get_visible (GTK_WIDGET (row->priv->selected)))
     {
diff --git a/src/storage/gtd-storage-row.h b/src/provider/gtd-provider-row.h
similarity index 64%
rename from src/storage/gtd-storage-row.h
rename to src/provider/gtd-provider-row.h
index cd585ae..d7e2da6 100644
--- a/src/storage/gtd-storage-row.h
+++ b/src/provider/gtd-provider-row.h
@@ -1,4 +1,4 @@
-/* gtd-storage-row.h
+/* gtd-provider-row.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -27,18 +27,18 @@
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_ROW (gtd_storage_row_get_type())
+#define GTD_TYPE_PROVIDER_ROW (gtd_provider_row_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageRow, gtd_storage_row, GTD, STORAGE_ROW, GtkListBoxRow)
+G_DECLARE_FINAL_TYPE (GtdProviderRow, gtd_provider_row, GTD, PROVIDER_ROW, GtkListBoxRow)
 
-GtkWidget*                  gtd_storage_row_new                  (GtdStorage          *storage);
+GtkWidget*                  gtd_provider_row_new                  (GtdProvider          *provider);
 
-gboolean                    gtd_storage_row_get_selected         (GtdStorageRow       *row);
+gboolean                    gtd_provider_row_get_selected         (GtdProviderRow       *row);
 
-void                        gtd_storage_row_set_selected         (GtdStorageRow       *row,
+void                        gtd_provider_row_set_selected         (GtdProviderRow       *row,
                                                                   gboolean             selected);
 
-GtdStorage*                 gtd_storage_row_get_storage          (GtdStorageRow       *row);
+GtdProvider*                 gtd_provider_row_get_provider          (GtdProviderRow       *row);
 
 G_END_DECLS
 
diff --git a/src/storage/gtd-storage-selector.c b/src/provider/gtd-provider-selector.c
similarity index 54%
rename from src/storage/gtd-storage-selector.c
rename to src/provider/gtd-provider-selector.c
index 59d0afa..f8e5af8 100644
--- a/src/storage/gtd-storage-selector.c
+++ b/src/provider/gtd-provider-selector.c
@@ -1,4 +1,4 @@
-/* gtd-storage-selector.c
+/* gtd-provider-selector.c
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -18,10 +18,9 @@
 
 #include "gtd-application.h"
 #include "gtd-manager.h"
-#include "gtd-storage.h"
-#include "gtd-storage-goa.h"
-#include "gtd-storage-row.h"
-#include "gtd-storage-selector.h"
+#include "interfaces/gtd-provider.h"
+#include "gtd-provider-row.h"
+#include "gtd-provider-selector.h"
 
 #include <glib/gi18n.h>
 
@@ -39,19 +38,19 @@ typedef struct
   GtdManager                *manager;
 
   gint                      select_default : 1;
-  gint                      show_local_storage : 1;
+  gint                      show_local_provider : 1;
   gint                      show_stub_rows : 1;
-} GtdStorageSelectorPrivate;
+} GtdProviderSelectorPrivate;
 
-struct _GtdStorageSelector
+struct _GtdProviderSelector
 {
   GtkBox                     parent;
 
   /*< private >*/
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 };
 
-G_DEFINE_TYPE_WITH_PRIVATE (GtdStorageSelector, gtd_storage_selector, GTK_TYPE_BOX)
+G_DEFINE_TYPE_WITH_PRIVATE (GtdProviderSelector, gtd_provider_selector, GTK_TYPE_BOX)
 
 enum {
   PROP_0,
@@ -63,7 +62,7 @@ enum {
 };
 
 enum {
-  STORAGE_SELECTED,
+  PROVIDER_SELECTED,
   LAST_SIGNAL
 };
 
@@ -99,17 +98,17 @@ display_header_func (GtkListBoxRow *row,
 }
 
 static void
-gtd_storage_selector__default_storage_changed (GtdStorageSelector *selector,
-                                               GtdStorage         *current,
-                                               GtdStorage         *previous)
+gtd_provider_selector__default_provider_changed (GtdProviderSelector *selector,
+                                               GtdProvider         *current,
+                                               GtdProvider         *previous)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
   GList *children;
   GList *l;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
-  g_return_if_fail (GTD_IS_STORAGE (previous));
-  g_return_if_fail (GTD_IS_STORAGE (current));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER (previous));
+  g_return_if_fail (GTD_IS_PROVIDER (current));
 
   priv = selector->priv;
 
@@ -120,28 +119,28 @@ gtd_storage_selector__default_storage_changed (GtdStorageSelector *selector,
 
   for (l = children; l != NULL; l = l->next)
     {
-      GtdStorage *storage;
+      GtdProvider *provider;
 
-      if (!GTD_IS_STORAGE_ROW (l->data))
+      if (!GTD_IS_PROVIDER_ROW (l->data))
         continue;
 
-      storage = gtd_storage_row_get_storage (l->data);
+      provider = gtd_provider_row_get_provider (l->data);
 
-      gtd_storage_row_set_selected (l->data, storage == current);
+      gtd_provider_row_set_selected (l->data, provider == current);
     }
 
   g_list_free (children);
 
-  g_signal_emit (selector, signals[STORAGE_SELECTED], 0, current);
+  g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, current);
 }
 
 static void
-gtd_storage_selector__listbox_row_activated (GtdStorageSelector *selector,
+gtd_provider_selector__listbox_row_activated (GtdProviderSelector *selector,
                                              GtkWidget          *row)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
@@ -160,32 +159,32 @@ gtd_storage_selector__listbox_row_activated (GtdStorageSelector *selector,
     }
   else
     {
-      GtdStorage *storage;
+      GtdProvider *provider;
       GList *children;
       GList *l;
 
       children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
-      storage = gtd_storage_row_get_storage (GTD_STORAGE_ROW (row));
+      provider = gtd_provider_row_get_provider (GTD_PROVIDER_ROW (row));
 
       for (l = children; l != NULL; l = l->next)
         {
-          if (GTD_IS_STORAGE_ROW (l->data))
-            gtd_storage_row_set_selected (l->data, FALSE);
+          if (GTD_IS_PROVIDER_ROW (l->data))
+            gtd_provider_row_set_selected (l->data, FALSE);
         }
 
       /*
        * If the account has it's calendars disabled, we cannot let it
-       * be a default storage location. Instead, open the Control Center
+       * be a default provider location. Instead, open the Control Center
        * to give the user the ability to change it.
        */
-      if (gtd_storage_get_enabled (storage))
+      if (gtd_provider_get_enabled (provider))
         {
-          gtd_storage_row_set_selected (GTD_STORAGE_ROW (row), TRUE);
-          g_signal_emit (selector, signals[STORAGE_SELECTED], 0, storage);
+          gtd_provider_row_set_selected (GTD_PROVIDER_ROW (row), TRUE);
+          g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, provider);
         }
       else
         {
-          spawn ((gchar*) gtd_storage_get_id (storage), NULL);
+          spawn ((gchar*) gtd_provider_get_id (provider), NULL);
         }
 
       g_list_free (children);
@@ -193,62 +192,62 @@ gtd_storage_selector__listbox_row_activated (GtdStorageSelector *selector,
 }
 
 static void
-gtd_storage_selector__check_toggled (GtdStorageSelector *selector,
+gtd_provider_selector__check_toggled (GtdProviderSelector *selector,
                                      GtkToggleButton    *check)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
   /*
-   * Unset the currently selected storage location row when the check button is
+   * Unset the currently selected provider location row when the check button is
    * activated. No need to do this when deactivated, since we already did.
    */
 
   if (gtk_toggle_button_get_active (check))
     {
-      GtdStorage *local_storage;
+      GtdProvider *local_provider;
       GList *children;
       GList *l;
 
       children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
-      local_storage = gtd_storage_row_get_storage (GTD_STORAGE_ROW (priv->local_row));
+      local_provider = gtd_provider_row_get_provider (GTD_PROVIDER_ROW (priv->local_row));
 
       for (l = children; l != NULL; l = l->next)
         {
-          if (GTD_IS_STORAGE_ROW (l->data))
-            gtd_storage_row_set_selected (l->data, FALSE);
+          if (GTD_IS_PROVIDER_ROW (l->data))
+            gtd_provider_row_set_selected (l->data, FALSE);
         }
 
       g_list_free (children);
 
       /*
-       * Sets the storage location to "local", and don't unset it if the
+       * Sets the provider location to "local", and don't unset it if the
        * check gets deactivated.
        */
-      g_signal_emit (selector, signals[STORAGE_SELECTED], 0, local_storage);
+      g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, local_provider);
     }
   else
     {
-      g_signal_emit (selector, signals[STORAGE_SELECTED], 0, NULL);
+      g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, NULL);
     }
 }
 
 static void
-gtd_storage_selector__remove_storage (GtdStorageSelector *selector,
-                                      GtdStorage         *storage)
+gtd_provider_selector__remove_provider (GtdProviderSelector *selector,
+                                        GtdProvider         *provider)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
   GList *children;
   GList *l;
   gint exchange;
   gint google;
   gint owncloud;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
-  g_return_if_fail (GTD_IS_STORAGE (storage));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER (provider));
 
   priv = selector->priv;
   children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
@@ -256,26 +255,26 @@ gtd_storage_selector__remove_storage (GtdStorageSelector *selector,
 
   for (l = children; l != NULL; l = l->next)
     {
-      GtdStorage *row_storage;
-      const gchar *provider;
+      GtdProvider *row_provider;
+      const gchar *provider_id;
 
-      if (!GTD_IS_STORAGE_ROW (l->data))
+      if (!GTD_IS_PROVIDER_ROW (l->data))
         continue;
 
-      row_storage = gtd_storage_row_get_storage (l->data);
-      provider = gtd_storage_get_provider (row_storage);
+      row_provider = gtd_provider_row_get_provider (l->data);
+      provider_id = gtd_provider_get_id (row_provider);
 
-      if (row_storage == storage)
+      if (row_provider == provider)
         {
           gtk_widget_destroy (l->data);
         }
       else
         {
-          if (g_strcmp0 (provider, "exchange") == 0)
+          if (g_strcmp0 (provider_id, "exchange") == 0)
             exchange++;
-          else if (g_strcmp0 (provider, "google") == 0)
+          else if (g_strcmp0 (provider_id, "google") == 0)
             google++;
-          else if (g_strcmp0 (provider, "owncloud") == 0)
+          else if (g_strcmp0 (provider_id, "owncloud") == 0)
             owncloud++;
         }
     }
@@ -288,65 +287,65 @@ gtd_storage_selector__remove_storage (GtdStorageSelector *selector,
 }
 
 static void
-gtd_storage_selector__add_storage (GtdStorageSelector *selector,
-                                   GtdStorage         *storage)
+gtd_provider_selector__add_provider (GtdProviderSelector *selector,
+                                     GtdProvider         *provider)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
   GtkWidget *row;
-  const gchar *provider;
+  const gchar *provider_id;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
-  g_return_if_fail (GTD_IS_STORAGE (storage));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER (provider));
 
   priv = selector->priv;
 
-  row = gtd_storage_row_new (storage);
-  provider = gtd_storage_get_provider (storage);
+  row = gtd_provider_row_new (provider);
+  provider_id = gtd_provider_get_id (provider);
 
   gtk_container_add (GTK_CONTAINER (priv->listbox), row);
 
   /* track the local provider row */
-  if (g_strcmp0 (provider, "local") == 0)
+  if (g_strcmp0 (provider_id, "local") == 0)
     {
-      gtk_widget_set_visible (row, priv->show_local_storage);
+      gtk_widget_set_visible (row, priv->show_local_provider);
       priv->local_row = row;
     }
 
-  /* Auto selects the default storage row when needed */
+  /* Auto selects the default provider row when needed */
   if (priv->select_default &&
-      gtd_storage_get_is_default (storage) &&
-      !gtd_storage_selector_get_selected_storage (selector))
+      //gtd_provider_get_is_default (provider) &&
+      !gtd_provider_selector_get_selected_provider (selector))
     {
-      gtd_storage_selector_set_selected_storage (selector, storage);
+      gtd_provider_selector_set_selected_provider (selector, provider);
     }
 
   /* hide the related stub row */
-  if (g_strcmp0 (provider, "exchange") == 0)
+  if (g_strcmp0 (provider_id, "exchange") == 0)
     gtk_widget_hide (priv->exchange_stub_row);
-  else if (g_strcmp0 (provider, "google") == 0)
+  else if (g_strcmp0 (provider_id, "google") == 0)
     gtk_widget_hide (priv->google_stub_row);
-  else if (g_strcmp0 (provider, "owncloud") == 0)
+  else if (g_strcmp0 (provider_id, "owncloud") == 0)
     gtk_widget_hide (priv->owncloud_stub_row);
 }
 
 static void
-gtd_storage_selector__fill_accounts (GtdStorageSelector *selector)
+gtd_provider_selector__fill_accounts (GtdProviderSelector *selector)
 {
-  GtdStorageSelectorPrivate *priv;
-  GList *storage_locations;
+  GtdProviderSelectorPrivate *priv;
+  GList *providers;
   GList *l;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
   /* load accounts */
-  storage_locations = gtd_manager_get_storage_locations (priv->manager);
+  providers = gtd_manager_get_providers (priv->manager);
 
-  for (l = storage_locations; l != NULL; l = l->next)
-    gtd_storage_selector__add_storage (selector, l->data);
+  for (l = providers; l != NULL; l = l->next)
+    gtd_provider_selector__add_provider (selector, l->data);
 
-  g_list_free (storage_locations);
+  g_list_free (providers);
 }
 
 static gint
@@ -354,28 +353,28 @@ sort_func (GtkListBoxRow *row1,
            GtkListBoxRow *row2,
            gpointer       user_data)
 {
-  GtdStorage *storage1;
-  GtdStorage *storage2;
+  GtdProvider *provider1;
+  GtdProvider *provider2;
 
-  if (!GTD_IS_STORAGE_ROW (row1))
+  if (!GTD_IS_PROVIDER_ROW (row1))
     return 1;
-  else if (!GTD_IS_STORAGE_ROW (row2))
+  else if (!GTD_IS_PROVIDER_ROW (row2))
     return -1;
 
-  storage1 = gtd_storage_row_get_storage (GTD_STORAGE_ROW (row1));
-  storage2 = gtd_storage_row_get_storage (GTD_STORAGE_ROW (row2));
+  provider1 = gtd_provider_row_get_provider (GTD_PROVIDER_ROW (row1));
+  provider2 = gtd_provider_row_get_provider (GTD_PROVIDER_ROW (row2));
 
-  return gtd_storage_compare (storage1, storage2);
+  return provider2 != provider1;//gtd_provider_compare (provider1, provider2);
 }
 
 static void
-gtd_storage_selector_constructed (GObject *object)
+gtd_provider_selector_constructed (GObject *object)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  G_OBJECT_CLASS (gtd_storage_selector_parent_class)->constructed (object);
+  G_OBJECT_CLASS (gtd_provider_selector_parent_class)->constructed (object);
 
-  priv = GTD_STORAGE_SELECTOR (object)->priv;
+  priv = GTD_PROVIDER_SELECTOR (object)->priv;
 
   gtk_list_box_set_header_func (GTK_LIST_BOX (priv->listbox),
                                 display_header_func,
@@ -388,18 +387,18 @@ gtd_storage_selector_constructed (GObject *object)
 }
 
 static void
-gtd_storage_selector_finalize (GObject *object)
+gtd_provider_selector_finalize (GObject *object)
 {
-  G_OBJECT_CLASS (gtd_storage_selector_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtd_provider_selector_parent_class)->finalize (object);
 }
 
 static void
-gtd_storage_selector_get_property (GObject    *object,
+gtd_provider_selector_get_property (GObject    *object,
                                    guint       prop_id,
                                    GValue     *value,
                                    GParamSpec *pspec)
 {
-  GtdStorageSelector *self = GTD_STORAGE_SELECTOR (object);
+  GtdProviderSelector *self = GTD_PROVIDER_SELECTOR (object);
 
   switch (prop_id)
     {
@@ -412,7 +411,7 @@ gtd_storage_selector_get_property (GObject    *object,
       break;
 
     case PROP_SHOW_LOCAL:
-      g_value_set_boolean (value, self->priv->show_local_storage);
+      g_value_set_boolean (value, self->priv->show_local_provider);
       break;
 
     case PROP_SHOW_STUB_ROWS:
@@ -425,12 +424,12 @@ gtd_storage_selector_get_property (GObject    *object,
 }
 
 static void
-gtd_storage_selector_set_property (GObject      *object,
+gtd_provider_selector_set_property (GObject      *object,
                                    guint         prop_id,
                                    const GValue *value,
                                    GParamSpec   *pspec)
 {
-  GtdStorageSelector *self = GTD_STORAGE_SELECTOR (object);
+  GtdProviderSelector *self = GTD_PROVIDER_SELECTOR (object);
 
   switch (prop_id)
     {
@@ -440,36 +439,36 @@ gtd_storage_selector_set_property (GObject      *object,
       if (!self->priv->manager)
         break;
 
-      gtd_storage_selector__fill_accounts (self);
+      gtd_provider_selector__fill_accounts (self);
 
       g_signal_connect_swapped (self->priv->manager,
-                                "default-storage-changed",
-                                G_CALLBACK (gtd_storage_selector__default_storage_changed),
+                                "default-provider-changed",
+                                G_CALLBACK (gtd_provider_selector__default_provider_changed),
                                 object);
 
       g_signal_connect_swapped (self->priv->manager,
-                                "storage-added",
-                                G_CALLBACK (gtd_storage_selector__add_storage),
+                                "provider-added",
+                                G_CALLBACK (gtd_provider_selector__add_provider),
                                 object);
 
       g_signal_connect_swapped (self->priv->manager,
-                                "storage-removed",
-                                G_CALLBACK (gtd_storage_selector__remove_storage),
+                                "provider-removed",
+                                G_CALLBACK (gtd_provider_selector__remove_provider),
                                 object);
 
       g_object_notify (object, "manager");
       break;
 
     case PROP_SELECT_DEFAULT:
-      gtd_storage_selector_set_select_default (self, g_value_get_boolean (value));
+      gtd_provider_selector_set_select_default (self, g_value_get_boolean (value));
       break;
 
     case PROP_SHOW_LOCAL:
-      gtd_storage_selector_show_local (self, g_value_get_boolean (value));
+      gtd_provider_selector_show_local (self, g_value_get_boolean (value));
       break;
 
     case PROP_SHOW_STUB_ROWS:
-      gtd_storage_selector_set_show_stub_rows (self, g_value_get_boolean (value));
+      gtd_provider_selector_set_show_stub_rows (self, g_value_get_boolean (value));
       break;
 
     default:
@@ -478,23 +477,23 @@ gtd_storage_selector_set_property (GObject      *object,
 }
 
 static void
-gtd_storage_selector_class_init (GtdStorageSelectorClass *klass)
+gtd_provider_selector_class_init (GtdProviderSelectorClass *klass)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
-  object_class->finalize = gtd_storage_selector_finalize;
-  object_class->constructed = gtd_storage_selector_constructed;
-  object_class->get_property = gtd_storage_selector_get_property;
-  object_class->set_property = gtd_storage_selector_set_property;
+  object_class->finalize = gtd_provider_selector_finalize;
+  object_class->constructed = gtd_provider_selector_constructed;
+  object_class->get_property = gtd_provider_selector_get_property;
+  object_class->set_property = gtd_provider_selector_set_property;
 
   /**
-   * GtdStorageSelector::location-selected:
+   * GtdProviderSelector::location-selected:
    *
-   * Emitted when a storage location is selected.
+   * Emitted when a provider location is selected.
    */
-  signals[STORAGE_SELECTED] = g_signal_new ("storage-selected",
-                                             GTD_TYPE_STORAGE_SELECTOR,
+  signals[PROVIDER_SELECTED] = g_signal_new ("provider-selected",
+                                             GTD_TYPE_PROVIDER_SELECTOR,
                                              G_SIGNAL_RUN_LAST,
                                              0,
                                              NULL,
@@ -502,10 +501,10 @@ gtd_storage_selector_class_init (GtdStorageSelectorClass *klass)
                                              NULL,
                                              G_TYPE_NONE,
                                              1,
-                                             GTD_TYPE_STORAGE);
+                                             GTD_TYPE_PROVIDER);
 
   /**
-   * GtdStorageSelector::manager:
+   * GtdProviderSelector::manager:
    *
    * A weak reference to the application's #GtdManager instance.
    */
@@ -519,21 +518,21 @@ gtd_storage_selector_class_init (GtdStorageSelectorClass *klass)
                              G_PARAM_READWRITE));
 
   /**
-   * GtdStorageSelector::show-local-storage:
+   * GtdProviderSelector::show-local-provider:
    *
-   * Whether it should show a row for the local storage.
+   * Whether it should show a row for the local provider.
    */
   g_object_class_install_property (
         object_class,
         PROP_SHOW_LOCAL,
         g_param_spec_boolean ("show-local",
-                              "Show local storage row",
-                              "Whether should show a local storage row instead of a checkbox",
+                              "Show local provider row",
+                              "Whether should show a local provider row instead of a checkbox",
                               FALSE,
                               G_PARAM_READWRITE));
 
   /**
-   * GtdStorageSelector::show-stub-rows:
+   * GtdProviderSelector::show-stub-rows:
    *
    * Whether it should show stub rows for non-added accounts.
    */
@@ -547,73 +546,73 @@ gtd_storage_selector_class_init (GtdStorageSelectorClass *klass)
                               G_PARAM_READWRITE));
 
   /**
-   * GtdStorageSelector::select-default:
+   * GtdProviderSelector::select-default:
    *
-   * Whether it should auto selects the default storage location row.
+   * Whether it should auto selects the default provider location row.
    */
   g_object_class_install_property (
         object_class,
         PROP_SELECT_DEFAULT,
         g_param_spec_boolean ("select-default",
-                              "Selects default storage row",
-                              "Whether should select the default storage row",
+                              "Selects default provider row",
+                              "Whether should select the default provider row",
                               FALSE,
                               G_PARAM_READWRITE));
 
-  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/storage-selector.ui");
+  gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/todo/ui/provider-selector.ui");
 
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageSelector, exchange_stub_row);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageSelector, google_stub_row);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageSelector, listbox);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageSelector, local_check);
-  gtk_widget_class_bind_template_child_private (widget_class, GtdStorageSelector, owncloud_stub_row);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderSelector, exchange_stub_row);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderSelector, google_stub_row);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderSelector, listbox);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderSelector, local_check);
+  gtk_widget_class_bind_template_child_private (widget_class, GtdProviderSelector, owncloud_stub_row);
 
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_selector__check_toggled);
-  gtk_widget_class_bind_template_callback (widget_class, gtd_storage_selector__listbox_row_activated);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_selector__check_toggled);
+  gtk_widget_class_bind_template_callback (widget_class, gtd_provider_selector__listbox_row_activated);
 }
 
 static void
-gtd_storage_selector_init (GtdStorageSelector *self)
+gtd_provider_selector_init (GtdProviderSelector *self)
 {
-  self->priv = gtd_storage_selector_get_instance_private (self);
+  self->priv = gtd_provider_selector_get_instance_private (self);
   self->priv->show_stub_rows = TRUE;
 
   gtk_widget_init_template (GTK_WIDGET (self));
 }
 
 /**
- * gtd_storage_selector_new:
+ * gtd_provider_selector_new:
  *
- * Creates a new #GtdStorageSelector.
+ * Creates a new #GtdProviderSelector.
  *
- * Returns: (transfer full): a new #GtdStorageSelector
+ * Returns: (transfer full): a new #GtdProviderSelector
  */
 GtkWidget*
-gtd_storage_selector_new (void)
+gtd_provider_selector_new (void)
 {
-  return g_object_new (GTD_TYPE_STORAGE_SELECTOR, NULL);
+  return g_object_new (GTD_TYPE_PROVIDER_SELECTOR, NULL);
 }
 
 /**
- * gtd_storage_selector_show_local:
+ * gtd_provider_selector_show_local:
  *
- * Shows a row for local storage item.
+ * Shows a row for local provider item.
  *
  * Returns:
  */
 void
-gtd_storage_selector_show_local (GtdStorageSelector *selector,
+gtd_provider_selector_show_local (GtdProviderSelector *selector,
                                  gboolean            show)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
-  if (priv->show_local_storage != show)
+  if (priv->show_local_provider != show)
     {
-      priv->show_local_storage = show;
+      priv->show_local_provider = show;
 
       gtk_widget_set_visible (priv->local_check, !show);
 
@@ -625,38 +624,38 @@ gtd_storage_selector_show_local (GtdStorageSelector *selector,
 }
 
 /**
- * gtd_storage_selector_get_select_default:
- * @selector: a #GtdStorageSelector
+ * gtd_provider_selector_get_select_default:
+ * @selector: a #GtdProviderSelector
  *
- * Whether the default storage location is selected by default.
+ * Whether the default provider location is selected by default.
  *
- * Returns: %TRUE if the default storage location is selected automatically,
+ * Returns: %TRUE if the default provider location is selected automatically,
  * %FALSE otherwise.
  */
 gboolean
-gtd_storage_selector_get_select_default (GtdStorageSelector *selector)
+gtd_provider_selector_get_select_default (GtdProviderSelector *selector)
 {
-  g_return_val_if_fail (GTD_IS_STORAGE_SELECTOR (selector), FALSE);
+  g_return_val_if_fail (GTD_IS_PROVIDER_SELECTOR (selector), FALSE);
 
   return selector->priv->select_default;
 }
 
 /**
- * gtd_storage_selector_set_select_default:
- * @selector: a #GtdStorageSelector
- * @select_default: %TRUE to auto select the default storage location.
+ * gtd_provider_selector_set_select_default:
+ * @selector: a #GtdProviderSelector
+ * @select_default: %TRUE to auto select the default provider location.
  *
- * Whether @selector should select the default storage location by default.
+ * Whether @selector should select the default provider location by default.
  *
  * Returns:
  */
 void
-gtd_storage_selector_set_select_default (GtdStorageSelector *selector,
+gtd_provider_selector_set_select_default (GtdProviderSelector *selector,
                                          gboolean            select_default)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
@@ -674,14 +673,14 @@ gtd_storage_selector_set_select_default (GtdStorageSelector *selector,
 
           for (l = children; l != NULL; l = l->next)
             {
-              if (GTD_IS_STORAGE_ROW (l->data))
+              if (GTD_IS_PROVIDER_ROW (l->data))
                 {
-                  GtdStorage *storage = gtd_storage_row_get_storage (l->data);
+                  GtdProvider *provider = gtd_provider_row_get_provider (l->data);
 
-                  if (gtd_storage_get_is_default (storage))
+                  if (FALSE)//gtd_provider_get_is_default (provider))
                     {
-                      gtd_storage_row_set_selected (l->data, TRUE);
-                      g_signal_emit (selector, signals[STORAGE_SELECTED], 0, storage);
+                      gtd_provider_row_set_selected (l->data, TRUE);
+                      g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, provider);
                     }
                 }
             }
@@ -694,70 +693,70 @@ gtd_storage_selector_set_select_default (GtdStorageSelector *selector,
 }
 
 /**
- * gtd_storage_selector_get_selected_storage:
- * @selector: a #GtdStorageSelector
+ * gtd_provider_selector_get_selected_provider:
+ * @selector: a #GtdProviderSelector
  *
- * Retrieves the currently selected #GtdStorage, or %NULL if
+ * Retrieves the currently selected #GtdProvider, or %NULL if
  * none is selected.
  *
- * Returns: (transfer none): the selected #GtdStorage
+ * Returns: (transfer none): the selected #GtdProvider
  */
-GtdStorage*
-gtd_storage_selector_get_selected_storage (GtdStorageSelector *selector)
+GtdProvider*
+gtd_provider_selector_get_selected_provider (GtdProviderSelector *selector)
 {
-  GtdStorageSelectorPrivate *priv;
-  GtdStorage *storage;
+  GtdProviderSelectorPrivate *priv;
+  GtdProvider *provider;
   GList *children;
   GList *l;
 
-  g_return_val_if_fail (GTD_IS_STORAGE_SELECTOR (selector), NULL);
+  g_return_val_if_fail (GTD_IS_PROVIDER_SELECTOR (selector), NULL);
 
   priv = selector->priv;
-  storage = NULL;
+  provider = NULL;
   children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
 
   for (l = children; l != NULL; l = l->next)
     {
-      if (GTD_IS_STORAGE_ROW (l->data) && gtd_storage_row_get_selected (l->data))
+      if (GTD_IS_PROVIDER_ROW (l->data) && gtd_provider_row_get_selected (l->data))
         {
-          storage = gtd_storage_row_get_storage (l->data);
+          provider = gtd_provider_row_get_provider (l->data);
           break;
         }
     }
 
   g_list_free (children);
 
-  return storage;
+  return provider;
 }
 
 /**
- * gtd_storage_selector_set_selected_storage:
- * @selector: a #GtdStorageSelector
- * @storage: a #GtdStorage
+ * gtd_provider_selector_set_selected_provider:
+ * @selector: a #GtdProviderSelector
+ * @provider: a #GtdProvider
  *
- * Selects @storage in the given #GtdStorageSelector.
+ * Selects @provider in the given #GtdProviderSelector.
  *
  * Returns:
  */
 void
-gtd_storage_selector_set_selected_storage (GtdStorageSelector *selector,
-                                           GtdStorage         *storage)
+gtd_provider_selector_set_selected_provider (GtdProviderSelector *selector,
+                                           GtdProvider         *provider)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
   GList *children;
   GList *l;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
   children = gtk_container_get_children (GTK_CONTAINER (priv->listbox));
 
   for (l = children; l != NULL; l = l->next)
     {
-      if (GTD_IS_STORAGE_ROW (l->data))
+      if (GTD_IS_PROVIDER_ROW (l->data))
         {
-          gtd_storage_row_set_selected (l->data, gtd_storage_row_get_storage (l->data) == storage);
-          g_signal_emit (selector, signals[STORAGE_SELECTED], 0, storage);
+          gtd_provider_row_set_selected (l->data, gtd_provider_row_get_provider (l->data) == provider);
+          g_signal_emit (selector, signals[PROVIDER_SELECTED], 0, provider);
         }
     }
 
@@ -765,37 +764,37 @@ gtd_storage_selector_set_selected_storage (GtdStorageSelector *selector,
 }
 
 /**
- * gtd_storage_selector_get_show_stub_rows:
- * @selector: a #GtdStorageSelector
+ * gtd_provider_selector_get_show_stub_rows:
+ * @selector: a #GtdProviderSelector
  *
  * Retrieves the ::show-stub-rows property.
  *
  * Returns: %TRUE if it shows stub rows, %FALSE if it hides them.
  */
 gboolean
-gtd_storage_selector_get_show_stub_rows (GtdStorageSelector *selector)
+gtd_provider_selector_get_show_stub_rows (GtdProviderSelector *selector)
 {
-  g_return_val_if_fail (GTD_IS_STORAGE_SELECTOR (selector), FALSE);
+  g_return_val_if_fail (GTD_IS_PROVIDER_SELECTOR (selector), FALSE);
 
   return selector->priv->show_stub_rows;
 }
 
 /**
- * gtd_storage_selector_set_show_stub_rows:
- * @selector: a #GtdStorageSelector
+ * gtd_provider_selector_set_show_stub_rows:
+ * @selector: a #GtdProviderSelector
  * @show_stub_rows: %TRUE to show stub rows, %FALSE to hide them.
  *
- * Sets the #GtdStorageSelector::show-stub-rows property.
+ * Sets the #GtdProviderSelector::show-stub-rows property.
  *
  * Returns:
  */
 void
-gtd_storage_selector_set_show_stub_rows (GtdStorageSelector *selector,
+gtd_provider_selector_set_show_stub_rows (GtdProviderSelector *selector,
                                          gboolean            show_stub_rows)
 {
-  GtdStorageSelectorPrivate *priv;
+  GtdProviderSelectorPrivate *priv;
 
-  g_return_if_fail (GTD_IS_STORAGE_SELECTOR (selector));
+  g_return_if_fail (GTD_IS_PROVIDER_SELECTOR (selector));
 
   priv = selector->priv;
 
@@ -822,17 +821,12 @@ gtd_storage_selector_set_show_stub_rows (GtdStorageSelector *selector,
 
           for (l = children; l != NULL; l = l->next)
             {
-              if (GTD_IS_STORAGE_ROW (l->data))
+              if (GTD_IS_PROVIDER_ROW (l->data))
                 {
-                  GtdStorage *storage = gtd_storage_row_get_storage (l->data);
-                  GoaAccount *account;
+                  GtdProvider *provider = gtd_provider_row_get_provider (l->data);
                   const gchar *type;
 
-                  if (!GTD_IS_STORAGE_GOA (storage))
-                    continue;
-
-                  account = gtd_storage_goa_get_account (GTD_STORAGE_GOA (storage));
-                  type = goa_account_get_provider_type (account);
+                  type = gtd_provider_get_id (provider);
 
                   if (g_strcmp0 (type, "google") == 0)
                     google_counter++;
diff --git a/src/storage/gtd-storage-selector.h b/src/provider/gtd-provider-selector.h
similarity index 52%
rename from src/storage/gtd-storage-selector.h
rename to src/provider/gtd-provider-selector.h
index be34f60..ca53a61 100644
--- a/src/storage/gtd-storage-selector.h
+++ b/src/provider/gtd-provider-selector.h
@@ -1,4 +1,4 @@
-/* gtd-storage-selector.h
+/* gtd-provider-selector.h
  *
  * Copyright (C) 2015 Georges Basile Stavracas Neto <georges stavracas gmail com>
  *
@@ -16,8 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef GTD_STORAGE_SELECTOR_H
-#define GTD_STORAGE_SELECTOR_H
+#ifndef GTD_PROVIDER_SELECTOR_H
+#define GTD_PROVIDER_SELECTOR_H
 
 #include "gtd-types.h"
 
@@ -26,30 +26,30 @@
 
 G_BEGIN_DECLS
 
-#define GTD_TYPE_STORAGE_SELECTOR (gtd_storage_selector_get_type())
+#define GTD_TYPE_PROVIDER_SELECTOR (gtd_provider_selector_get_type())
 
-G_DECLARE_FINAL_TYPE (GtdStorageSelector, gtd_storage_selector, GTD, STORAGE_SELECTOR, GtkBox)
+G_DECLARE_FINAL_TYPE (GtdProviderSelector, gtd_provider_selector, GTD, PROVIDER_SELECTOR, GtkBox)
 
-GtkWidget*         gtd_storage_selector_new                      (void);
+GtkWidget*         gtd_provider_selector_new                      (void);
 
-void               gtd_storage_selector_show_local               (GtdStorageSelector *selector,
+void               gtd_provider_selector_show_local               (GtdProviderSelector *selector,
                                                                   gboolean            show);
 
-gboolean           gtd_storage_selector_get_select_default       (GtdStorageSelector *selector);
+gboolean           gtd_provider_selector_get_select_default       (GtdProviderSelector *selector);
 
-void               gtd_storage_selector_set_select_default       (GtdStorageSelector *selector,
+void               gtd_provider_selector_set_select_default       (GtdProviderSelector *selector,
                                                                   gboolean            select_default);
 
-GtdStorage*        gtd_storage_selector_get_selected_storage     (GtdStorageSelector *selector);
+GtdProvider*        gtd_provider_selector_get_selected_provider     (GtdProviderSelector *selector);
 
-void               gtd_storage_selector_set_selected_storage     (GtdStorageSelector *selector,
-                                                                  GtdStorage         *storage);
+void               gtd_provider_selector_set_selected_provider     (GtdProviderSelector *selector,
+                                                                  GtdProvider         *provider);
 
-gboolean           gtd_storage_selector_get_show_stub_rows       (GtdStorageSelector *selector);
+gboolean           gtd_provider_selector_get_show_stub_rows       (GtdProviderSelector *selector);
 
-void               gtd_storage_selector_set_show_stub_rows       (GtdStorageSelector *selector,
+void               gtd_provider_selector_set_show_stub_rows       (GtdProviderSelector *selector,
                                                                   gboolean            show_stub_rows);
 
 G_END_DECLS
 
-#endif /* GTD_STORAGE_SELECTOR_H */
+#endif /* GTD_PROVIDER_SELECTOR_H */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]