diff --git a/examples/pactree.vala b/examples/pactree.vala
index d738d7f28af6494fb8eaa72b4d0053fc1ebc7e2d..a76c69d6076f85cfd1a9692f46da101800540778 100644
--- a/examples/pactree.vala
+++ b/examples/pactree.vala
@@ -18,7 +18,7 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-// Compile with: valac --pkg=libalpm --vapidir=../vapi --Xcc=-I../util ../util/alpm-util.c pactree.vala -o pactree
+// Compile with: valac --pkg=libalpm --vapidir=../vapi pactree.vala
 
 using Alpm;
 
@@ -37,10 +37,10 @@ string leaf2_color;
 string color_off;
 
 /* globals */
-unowned Handle? handle;
+Handle handle;
 unowned DB localdb;
-Alpm.List<string?> walked = null;
-Alpm.List<string?> provisions = null;
+Alpm.List<string> walked;
+Alpm.List<string> provisions;
 
 /* options */
 bool color;
@@ -127,7 +127,7 @@ static int parse_options(ref unowned string[] args) {
 
 static void local_init() {
   Alpm.Errno error;
-  handle = Handle.new ("/", dbpath, out error);
+  handle = new Handle ("/", dbpath, out error);
   assert (error == 0);
   localdb = handle.localdb;
   assert (localdb != null);
@@ -187,11 +187,11 @@ static void walk_reverse_deps(Package pkg, int depth) {
   if((max_depth >= 0) && (depth > max_depth)) return;
 
   walked.add(pkg.name);
-  Alpm.List<string?> *required_by = pkg.compute_requiredby();
+  Alpm.List<string> required_by = pkg.compute_requiredby();
 
-  int i = 0;
-  while (i < required_by->length) {
-    string? pkgname = required_by->nth_data(i);
+  unowned Alpm.List<string> list = required_by;
+  while (list != null) {
+    unowned string pkgname = list.data;
     if (walked.find_str(pkgname) != null) {
       /* if we've already seen this package, don't print in "unique" output
        * and don't recurse */
@@ -202,9 +202,9 @@ static void walk_reverse_deps(Package pkg, int depth) {
       print(pkg.name, pkgname, null, depth);
       walk_reverse_deps(localdb.get_pkg(pkgname), depth + 1);
     }
-    i++;
+    list.next ();
   }
-  Alpm.List.free_all(required_by);
+  required_by.free_inner(GLib.free);
 }
 
 /**
@@ -216,8 +216,10 @@ static void walk_deps(Package pkg, int depth)
 
   walked.add(pkg.name);
 
-  foreach (unowned Depend depend in pkg.depends) {
-    string depname = depend.name;
+  unowned Alpm.List<unowned Depend> depends = pkg.depends;
+  while (depends != null) {
+    unowned Alpm.Depend depend = depends.data;
+    unowned string depname = depend.name;
     unowned Package? provider = find_satisfier (localdb.pkgcache, depname);
 
     if (provider != null) {
@@ -237,6 +239,7 @@ static void walk_deps(Package pkg, int depth)
       /* unresolvable package */
       print(pkg.name, null, depname, depth);
     }
+    depends.next ();
   }
 }
 
diff --git a/po/pamac.pot b/po/pamac.pot
index f987d85124d879122f57d8bf18410cc3e6a4d1a5..dfe17732fd5652fb5cd92d96b08d4273af93f74f 100644
--- a/po/pamac.pot
+++ b/po/pamac.pot
@@ -21,7 +21,7 @@ msgstr ""
 msgid "Authentication is required"
 msgstr ""
 
-#: ../src/daemon.vala ../src/transaction.vala
+#: ../src/daemon.vala
 msgid "Failed to initialize alpm library"
 msgstr ""
 
@@ -29,6 +29,26 @@ msgstr ""
 msgid "Failed to synchronize any databases"
 msgstr ""
 
+#: ../src/daemon.vala
+msgid "Unknown"
+msgstr ""
+
+#: ../src/daemon.vala
+msgid "Explicitly installed"
+msgstr ""
+
+#: ../src/daemon.vala
+msgid "Installed as a dependency for another package"
+msgstr ""
+
+#: ../src/daemon.vala
+msgid "Yes"
+msgstr ""
+
+#: ../src/daemon.vala
+msgid "No"
+msgstr ""
+
 #: ../src/daemon.vala
 msgid "Failed to init transaction"
 msgstr ""
@@ -120,7 +140,7 @@ msgstr ""
 msgid "Transaction Summary"
 msgstr ""
 
-#: ../src/transaction.vala ../src/manager_window.vala
+#: ../src/transaction.vala
 msgid "To remove"
 msgstr ""
 
@@ -132,7 +152,7 @@ msgstr ""
 msgid "To build"
 msgstr ""
 
-#: ../src/transaction.vala ../src/manager_window.vala
+#: ../src/transaction.vala
 msgid "To install"
 msgstr ""
 
@@ -153,11 +173,7 @@ msgid "Building packages"
 msgstr ""
 
 #: ../src/transaction.vala
-msgid "Running pre-transaction hooks"
-msgstr ""
-
-#: ../src/transaction.vala
-msgid "Running post-transaction hooks"
+msgid "Transaction cancelled"
 msgstr ""
 
 #: ../src/transaction.vala
@@ -183,36 +199,28 @@ msgstr ""
 
 #: ../src/transaction.vala
 #, c-format
-msgid "Reinstalling %s"
+msgid "Upgrading %s"
 msgstr ""
 
 #: ../src/transaction.vala
 #, c-format
-msgid "Removing %s"
+msgid "Reinstalling %s"
 msgstr ""
 
 #: ../src/transaction.vala
 #, c-format
-msgid "Upgrading %s"
+msgid "Downgrading %s"
 msgstr ""
 
 #: ../src/transaction.vala
 #, c-format
-msgid "Downgrading %s"
+msgid "Removing %s"
 msgstr ""
 
 #: ../src/transaction.vala
 msgid "Checking integrity"
 msgstr ""
 
-#: ../src/transaction.vala
-msgid "Checking keyring"
-msgstr ""
-
-#: ../src/transaction.vala
-msgid "Downloading required keys"
-msgstr ""
-
 #: ../src/transaction.vala
 msgid "Loading packages files"
 msgstr ""
@@ -247,6 +255,11 @@ msgstr ""
 msgid "Downloading"
 msgstr ""
 
+#: ../src/transaction.vala
+#, c-format
+msgid "Downloading %s"
+msgstr ""
+
 #: ../src/transaction.vala
 msgid "Checking available disk space"
 msgstr ""
@@ -261,6 +274,14 @@ msgstr ""
 msgid "Database file for %s does not exist"
 msgstr ""
 
+#: ../src/transaction.vala
+msgid "Checking keyring"
+msgstr ""
+
+#: ../src/transaction.vala
+msgid "Downloading required keys"
+msgstr ""
+
 #: ../src/transaction.vala
 #, c-format
 msgid "%s installed as %s.pacnew"
@@ -272,13 +293,11 @@ msgid "%s installed as %s.pacsave"
 msgstr ""
 
 #: ../src/transaction.vala
-#, c-format
-msgid "Refreshing %s"
+msgid "Running pre-transaction hooks"
 msgstr ""
 
 #: ../src/transaction.vala
-#, c-format
-msgid "Downloading %s"
+msgid "Running post-transaction hooks"
 msgstr ""
 
 #: ../src/transaction.vala
@@ -294,7 +313,8 @@ msgstr[0] ""
 msgstr[1] ""
 
 #: ../src/transaction.vala
-msgid "Warning"
+#, c-format
+msgid "Refreshing %s"
 msgstr ""
 
 #: ../src/transaction.vala
@@ -302,7 +322,7 @@ msgid "Error"
 msgstr ""
 
 #: ../src/transaction.vala
-msgid "Transaction cancelled"
+msgid "Warning"
 msgstr ""
 
 #: ../src/transaction.vala
@@ -369,8 +389,11 @@ msgid "Mark as explicitly installed"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "local"
-msgstr ""
+#, c-format
+msgid "%u pending operation"
+msgid_plural "%u pending operations"
+msgstr[0] ""
+msgstr[1] ""
 
 #: ../src/manager_window.vala
 msgid "Installed"
@@ -381,95 +404,76 @@ msgid "Orphans"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Licenses"
-msgstr ""
-
-#: ../src/manager_window.vala
-msgid "Unknown"
-msgstr ""
-
-#: ../src/manager_window.vala
-msgid "Depends On"
+msgid "Foreign"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Optional Dependencies"
-msgstr ""
-
-#: ../src/manager_window.vala
-msgid "Required By"
+msgid "Pending"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Optional For"
+msgid "Licenses"
 msgstr ""
 
-#: ../src/manager_window.vala
-msgid "Provides"
+#: ../src/manager_window.vala ../resources/manager_window.ui
+#: ../resources/updater_window.ui
+msgid "Repository"
 msgstr ""
 
-#: ../src/manager_window.vala
-msgid "Replaces"
+#: ../src/manager_window.vala ../resources/manager_window.ui
+msgid "Groups"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Conflicts With"
+msgid "Packager"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Make Dependencies"
+msgid "Build Date"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Check Dependencies"
-msgstr ""
-
-#: ../src/manager_window.vala ../resources/manager_window.ui
-msgid "Repository"
-msgstr ""
-
-#: ../src/manager_window.vala ../resources/manager_window.ui
-msgid "Groups"
+msgid "Install Date"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Packager"
+msgid "Install Reason"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Build Date"
+msgid "Signatures"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Install Date"
+msgid "Backup files"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Explicitly installed"
+msgid "Depends On"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Installed as a dependency for another package"
+msgid "Optional Dependencies"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Install Reason"
+msgid "Required By"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Yes"
+msgid "Optional For"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "No"
+msgid "Provides"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Signatures"
+msgid "Replaces"
 msgstr ""
 
 #: ../src/manager_window.vala
-msgid "Backup files"
+msgid "Conflicts With"
 msgstr ""
 
 #: ../src/manager_window.vala
@@ -488,7 +492,7 @@ msgstr ""
 msgid "Last Modified"
 msgstr ""
 
-#: ../src/manager_window.vala ../resources/manager_window.ui
+#: ../src/manager_window.vala
 msgid "Votes"
 msgstr ""
 
@@ -496,6 +500,11 @@ msgstr ""
 msgid "Out of Date"
 msgstr ""
 
+#: ../src/manager_window.vala ../resources/manager_window.ui
+#: ../resources/updater_window.ui
+msgid "Name"
+msgstr ""
+
 #: ../src/manager_window.vala
 #, c-format
 msgid ""
@@ -507,17 +516,13 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: ../src/manager_window.vala
-msgid "Uninstalled"
-msgstr ""
-
 #: ../src/manager_window.vala ../resources/manager_window.ui
 msgid "Install Local Packages"
 msgstr ""
 
 #: ../src/manager_window.vala ../resources/progress_dialog.ui
 #: ../resources/transaction_sum_dialog.ui ../resources/choose_dep_dialog.ui
-#: ../resources/choose_ignorepkgs_dialog.ui
+#: ../resources/manager_window.ui ../resources/choose_ignorepkgs_dialog.ui
 msgid "_Cancel"
 msgstr ""
 
@@ -571,10 +576,8 @@ msgstr ""
 msgid "Progress"
 msgstr ""
 
-#: ../resources/progress_dialog.ui ../resources/history_dialog.ui
-#: ../resources/transaction_info_dialog.ui ../resources/updater_window.ui
-#: ../resources/preferences_dialog.ui
-msgid "_Close"
+#: ../resources/progress_dialog.ui
+msgid "_Hide"
 msgstr ""
 
 #: ../resources/progress_dialog.ui ../resources/transaction_info_dialog.ui
@@ -586,6 +589,11 @@ msgstr ""
 msgid "Pamac History"
 msgstr ""
 
+#: ../resources/history_dialog.ui ../resources/transaction_info_dialog.ui
+#: ../resources/updater_window.ui ../resources/preferences_dialog.ui
+msgid "_Close"
+msgstr ""
+
 #: ../resources/choose_dep_dialog.ui
 msgid "Choose Optional Dependencies"
 msgstr ""
@@ -606,14 +614,6 @@ msgstr ""
 msgid "Refresh databases"
 msgstr ""
 
-#: ../resources/manager_window.ui
-msgid "Apply changes"
-msgstr ""
-
-#: ../resources/manager_window.ui
-msgid "Cancel all planned changes"
-msgstr ""
-
 #: ../resources/manager_window.ui
 msgid "Search in AUR"
 msgstr ""
@@ -622,7 +622,7 @@ msgstr ""
 msgid "Search"
 msgstr ""
 
-#: ../resources/manager_window.ui
+#: ../resources/manager_window.ui ../resources/updater_window.ui
 msgid "State"
 msgstr ""
 
@@ -630,16 +630,16 @@ msgstr ""
 msgid "Repositories"
 msgstr ""
 
-#: ../resources/manager_window.ui
-msgid "Name"
+#: ../resources/manager_window.ui ../resources/updater_window.ui
+msgid "Version"
 msgstr ""
 
-#: ../resources/manager_window.ui
-msgid "Version"
+#: ../resources/manager_window.ui ../resources/updater_window.ui
+msgid "Size"
 msgstr ""
 
 #: ../resources/manager_window.ui
-msgid "Size"
+msgid "Popularity"
 msgstr ""
 
 #: ../resources/manager_window.ui ../resources/updater_window.ui
@@ -647,8 +647,12 @@ msgstr ""
 msgid "AUR"
 msgstr ""
 
+#: ../resources/manager_window.ui ../resources/updater_window.ui
+msgid "_Apply"
+msgstr ""
+
 #: ../resources/manager_window.ui
-msgid "Description"
+msgid "Browse"
 msgstr ""
 
 #: ../resources/manager_window.ui
@@ -663,10 +667,6 @@ msgstr ""
 msgid "_Refresh"
 msgstr ""
 
-#: ../resources/updater_window.ui
-msgid "_Apply"
-msgstr ""
-
 #: ../resources/preferences_dialog.ui
 msgid "Preferences"
 msgstr ""
@@ -689,6 +689,10 @@ msgstr ""
 msgid "Check for updates"
 msgstr ""
 
+#: ../resources/preferences_dialog.ui
+msgid "6"
+msgstr ""
+
 #: ../resources/preferences_dialog.ui
 msgid "Hide tray icon when no update available"
 msgstr ""
diff --git a/resources/Makefile b/resources/Makefile
index 898cd7c5da9d31f8f6aa65284d0ed91c7f5774b9..ba1e352449f6a258457347fda9479e333c0470f0 100644
--- a/resources/Makefile
+++ b/resources/Makefile
@@ -3,6 +3,7 @@ MANAGER_RESOURCES_FILES = 	manager_window.ui \
 							choose_dep_dialog.ui \
 							history_dialog.ui \
 							package-available.png \
+							package-available-locked.png \
 							package-install.png \
 							package-installed-locked.png \
 							package-installed-updated.png \
diff --git a/resources/choose_dep_dialog.ui b/resources/choose_dep_dialog.ui
index 5262dc0792c46578501302681ad1026dfba5c0a6..e98fb2bc76ecc23c6fb0fe50650dd964de05be96 100644
--- a/resources/choose_dep_dialog.ui
+++ b/resources/choose_dep_dialog.ui
@@ -1,13 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacChooseDependenciesDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Choose Optional Dependencies</property>
     <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
+    <property name="urgency_hint">True</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
@@ -23,25 +26,28 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
-                <property name="use_underline">True</property>
                 <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
               <object class="GtkButton" id="valid_button">
                 <property name="label" translatable="yes">_OK</property>
-                <property name="use_underline">True</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
@@ -49,6 +55,7 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -59,6 +66,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -112,6 +120,7 @@
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
diff --git a/resources/choose_ignorepkgs_dialog.ui b/resources/choose_ignorepkgs_dialog.ui
index d8ce4a794dc861dc103d07aef65d65b5020aaf68..472f70098a266088dae4f4abee87a4d6e5cae8da 100644
--- a/resources/choose_ignorepkgs_dialog.ui
+++ b/resources/choose_ignorepkgs_dialog.ui
@@ -10,6 +10,7 @@
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
+    <property name="urgency_hint">True</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="can_focus">False</property>
diff --git a/resources/choose_provider_dialog.ui b/resources/choose_provider_dialog.ui
index 42ee77d5e9d85727a4b9ee1290ca581b88a089ca..f5caa288f4b26041db3f78fad084000d49c047f7 100644
--- a/resources/choose_provider_dialog.ui
+++ b/resources/choose_provider_dialog.ui
@@ -1,13 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.19.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacChooseProviderDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Choose a Provider</property>
     <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
+    <property name="urgency_hint">True</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox2">
         <property name="can_focus">False</property>
@@ -20,14 +23,16 @@
             <child>
               <object class="GtkButton" id="valid_button">
                 <property name="label" translatable="yes">_OK</property>
-                <property name="use_underline">True</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">True</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
           </object>
@@ -35,6 +40,7 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -52,6 +58,7 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
@@ -62,12 +69,14 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
diff --git a/resources/history_dialog.ui b/resources/history_dialog.ui
index d922853d7f4d6ef3ab988c2c61dcd6c0b2079f4d..688087b51793f1068bb1ecb021199afa321f7018 100644
--- a/resources/history_dialog.ui
+++ b/resources/history_dialog.ui
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacHistoryDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Pamac History</property>
+    <property name="window_position">center-on-parent</property>
     <property name="default_width">600</property>
     <property name="default_height">500</property>
     <property name="icon_name">system-software-install</property>
@@ -20,14 +23,16 @@
             <child>
               <object class="GtkButton" id="close_button">
                 <property name="label" translatable="yes">_Close</property>
-                <property name="use_underline">True</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
           </object>
@@ -35,6 +40,7 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -58,6 +64,7 @@
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
       </object>
diff --git a/resources/manager_window.ui b/resources/manager_window.ui
index d7950d86c2638e8130c9aa1d07e5abd9796c3c61..968b4331dbdb47c7f987395b6c98991ef5102c0a 100644
--- a/resources/manager_window.ui
+++ b/resources/manager_window.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.19.0 -->
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <object class="GtkMenu" id="main_menu">
@@ -44,173 +44,119 @@
     <property name="visible">True</property>
     <property name="can_focus">False</property>
     <property name="title" translatable="yes">Package Manager</property>
-    <property name="window_position">center</property>
     <property name="default_height">600</property>
     <property name="icon_name">system-software-install</property>
+    <property name="gravity">center</property>
     <child>
-      <object class="GtkBox" id="box0">
+      <object class="GtkStack" id="main_stack">
         <property name="visible">True</property>
         <property name="can_focus">False</property>
-        <property name="orientation">vertical</property>
-        <property name="spacing">6</property>
+        <property name="transition_type">slide-left-right</property>
         <child>
-          <object class="GtkBox" id="box1">
+          <object class="GtkBox" id="box2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="spacing">6</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">3</property>
             <child>
-              <object class="GtkButton" id="refresh_button">
+              <object class="GtkBox" id="box1">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Refresh databases</property>
-                <signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/>
+                <property name="can_focus">False</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkImage" id="refresh_icon">
+                  <object class="GtkButton" id="refresh_button">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">view-refresh-symbolic</property>
-                    <property name="icon_size">1</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="tooltip_text" translatable="yes">Refresh databases</property>
+                    <signal name="clicked" handler="on_refresh_button_clicked" swapped="no"/>
+                    <child>
+                      <object class="GtkImage" id="refresh_icon">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">view-refresh-symbolic</property>
+                        <property name="icon_size">1</property>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="image-button"/>
+                    </style>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
+                  </packing>
                 </child>
-                <style>
-                  <class name="image-button"/>
-                </style>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="valid_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Apply changes</property>
-                <signal name="clicked" handler="on_valid_button_clicked" swapped="no"/>
                 <child>
-                  <object class="GtkImage" id="valid_icon">
+                  <object class="GtkMenuButton" id="menu_button">
                     <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">emblem-ok-symbolic</property>
-                    <property name="icon_size">1</property>
-                  </object>
-                </child>
-                <style>
-                  <class name="image-button"/>
-                </style>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="cancel_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="tooltip_text" translatable="yes">Cancel all planned changes</property>
-                <signal name="clicked" handler="on_cancel_button_clicked" swapped="no"/>
-                <child>
-                  <object class="GtkImage" id="cancel_icon">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">edit-delete-symbolic</property>
-                    <property name="icon_size">1</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="popup">main_menu</property>
+                    <child>
+                      <object class="GtkImage" id="menu_icon">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="icon_name">emblem-system-symbolic</property>
+                        <property name="icon_size">1</property>
+                      </object>
+                    </child>
+                    <style>
+                      <class name="image-button"/>
+                    </style>
                   </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="pack_type">end</property>
+                    <property name="position">3</property>
+                  </packing>
                 </child>
-                <style>
-                  <class name="image-button"/>
-                </style>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">2</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkMenuButton" id="menu_button">
+              <object class="GtkStackSwitcher" id="filters_stackswitcher">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="popup">main_menu</property>
-                <child>
-                  <object class="GtkImage" id="menu_icon">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">emblem-system-symbolic</property>
-                    <property name="icon_size">1</property>
-                  </object>
-                </child>
-                <style>
-                  <class name="image-button"/>
-                </style>
+                <property name="can_focus">False</property>
+                <property name="stack">filters_stack</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="pack_type">end</property>
-                <property name="position">3</property>
+                <property name="position">1</property>
               </packing>
             </child>
-          </object>
-          <packing>
-            <property name="expand">False</property>
-            <property name="fill">True</property>
-            <property name="position">0</property>
-          </packing>
-        </child>
-        <child>
-          <object class="GtkPaned" id="paned1">
-            <property name="visible">True</property>
-            <property name="can_focus">True</property>
             <child>
-              <object class="GtkNotebook" id="filters_notebook">
+              <object class="GtkBox" id="box3">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <signal name="switch-page" handler="on_filters_notebook_switch_page" after="yes" swapped="no"/>
+                <property name="can_focus">False</property>
+                <property name="spacing">3</property>
                 <child>
-                  <object class="GtkBox" id="box3">
+                  <object class="GtkStack" id="filters_stack">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="orientation">vertical</property>
-                    <property name="spacing">6</property>
-                    <child>
-                      <object class="GtkSearchEntry" id="search_entry">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="has_focus">True</property>
-                        <property name="receives_default">True</property>
-                        <property name="caps_lock_warning">False</property>
-                        <property name="primary_icon_name">edit-find-symbolic</property>
-                        <signal name="activate" handler="on_search_entry_activate" swapped="no"/>
-                        <signal name="changed" handler="on_search_entry_changed" swapped="no"/>
-                      </object>
-                      <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">0</property>
-                      </packing>
-                    </child>
                     <child>
-                      <object class="GtkBox" id="search_aur_box">
+                      <object class="GtkBox" id="box5">
+                        <property name="width_request">200</property>
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="spacing">12</property>
-                        <property name="homogeneous">True</property>
+                        <property name="orientation">vertical</property>
+                        <property name="spacing">6</property>
                         <child>
-                          <object class="GtkLabel" id="search_aur_label">
+                          <object class="GtkSearchEntry" id="search_entry">
                             <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <property name="margin_start">6</property>
-                            <property name="hexpand">True</property>
-                            <property name="label" translatable="yes">Search in AUR</property>
-                            <property name="xalign">0</property>
+                            <property name="can_focus">True</property>
+                            <property name="receives_default">True</property>
+                            <property name="caps_lock_warning">False</property>
+                            <property name="primary_icon_name">edit-find-symbolic</property>
+                            <signal name="activate" handler="on_search_entry_activate" swapped="no"/>
+                            <signal name="changed" handler="on_search_entry_changed" swapped="no"/>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -219,11 +165,39 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkSwitch" id="search_aur_button">
+                          <object class="GtkBox" id="search_aur_box">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
-                            <property name="tooltip_text" translatable="yes">Search in AUR</property>
-                            <property name="halign">end</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkLabel" id="search_aur_label">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="margin_left">6</property>
+                                <property name="margin_start">6</property>
+                                <property name="hexpand">True</property>
+                                <property name="label" translatable="yes">Search in AUR</property>
+                                <property name="xalign">0</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkSwitch" id="search_aur_button">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="tooltip_text" translatable="yes">Search in AUR</property>
+                                <property name="halign">end</property>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -231,20 +205,59 @@
                             <property name="position">1</property>
                           </packing>
                         </child>
+                        <child>
+                          <object class="GtkScrolledWindow" id="scrolledwindow3">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="search_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="headers_visible">False</property>
+                                <property name="headers_clickable">False</property>
+                                <property name="enable_search">False</property>
+                                <property name="show_expanders">False</property>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="search_treeview_selection">
+                                    <signal name="changed" handler="on_search_treeview_selection_changed" after="yes" swapped="no"/>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="Terms">
+                                    <child>
+                                      <object class="GtkCellRendererText" id="cellrenderertext8"/>
+                                      <attributes>
+                                        <attribute name="text">0</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">True</property>
+                            <property name="fill">True</property>
+                            <property name="position">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <placeholder/>
+                        </child>
                       </object>
                       <packing>
-                        <property name="expand">False</property>
-                        <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="name">search</property>
+                        <property name="title" translatable="yes">Search</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkScrolledWindow" id="scrolledwindow3">
+                      <object class="GtkScrolledWindow" id="scrolledwindow1">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="shadow_type">in</property>
                         <child>
-                          <object class="GtkTreeView" id="search_treeview">
+                          <object class="GtkTreeView" id="groups_treeview">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="headers_visible">False</property>
@@ -252,14 +265,14 @@
                             <property name="enable_search">False</property>
                             <property name="show_expanders">False</property>
                             <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="search_treeview_selection">
-                                <signal name="changed" handler="on_search_treeview_selection_changed" after="yes" swapped="no"/>
+                              <object class="GtkTreeSelection" id="groups_treeview_selection">
+                                <signal name="changed" handler="on_groups_treeview_selection_changed" after="yes" swapped="no"/>
                               </object>
                             </child>
                             <child>
-                              <object class="GtkTreeViewColumn" id="Terms">
+                              <object class="GtkTreeViewColumn" id="Groups">
                                 <child>
-                                  <object class="GtkCellRendererText" id="cellrenderertext8"/>
+                                  <object class="GtkCellRendererText" id="cellrenderertext2"/>
                                   <attributes>
                                     <attribute name="text">0</attribute>
                                   </attributes>
@@ -270,561 +283,622 @@
                         </child>
                       </object>
                       <packing>
-                        <property name="expand">True</property>
-                        <property name="fill">True</property>
-                        <property name="position">2</property>
+                        <property name="name">groups</property>
+                        <property name="title" translatable="yes">Groups</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
-                  </object>
-                </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="tab1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Search</property>
-                  </object>
-                  <packing>
-                    <property name="tab_fill">False</property>
-                  </packing>
-                </child>
-                <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow1">
-                    <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="shadow_type">in</property>
                     <child>
-                      <object class="GtkTreeView" id="groups_treeview">
+                      <object class="GtkScrolledWindow" id="scrolledwindow2">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="headers_clickable">False</property>
-                        <property name="enable_search">False</property>
-                        <property name="show_expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection" id="groups_treeview_selection">
-                            <signal name="changed" handler="on_groups_treeview_selection_changed" after="yes" swapped="no"/>
+                        <property name="shadow_type">in</property>
+                        <child>
+                          <object class="GtkTreeView" id="states_treeview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="headers_visible">False</property>
+                            <property name="headers_clickable">False</property>
+                            <property name="enable_search">False</property>
+                            <property name="show_expanders">False</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection" id="states_treeview_selection">
+                                <signal name="changed" handler="on_states_treeview_selection_changed" after="yes" swapped="no"/>
+                              </object>
+                            </child>
+                            <child>
+                              <object class="GtkTreeViewColumn" id="State">
+                                <child>
+                                  <object class="GtkCellRendererText" id="cellrenderertext9"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
+                            </child>
                           </object>
                         </child>
+                      </object>
+                      <packing>
+                        <property name="name">states</property>
+                        <property name="title" translatable="yes">State</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkScrolledWindow" id="scrolledwindow8">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="shadow_type">in</property>
                         <child>
-                          <object class="GtkTreeViewColumn" id="Groups">
+                          <object class="GtkTreeView" id="repos_treeview">
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="headers_visible">False</property>
+                            <property name="headers_clickable">False</property>
+                            <property name="enable_search">False</property>
+                            <property name="show_expanders">False</property>
+                            <child internal-child="selection">
+                              <object class="GtkTreeSelection" id="repos_treeview_selection">
+                                <signal name="changed" handler="on_repos_treeview_selection_changed" after="yes" swapped="no"/>
+                              </object>
+                            </child>
                             <child>
-                              <object class="GtkCellRendererText" id="cellrenderertext2"/>
-                              <attributes>
-                                <attribute name="text">0</attribute>
-                              </attributes>
+                              <object class="GtkTreeViewColumn" id="Repos">
+                                <child>
+                                  <object class="GtkCellRendererText" id="cellrenderertext10"/>
+                                  <attributes>
+                                    <attribute name="text">0</attribute>
+                                  </attributes>
+                                </child>
+                              </object>
                             </child>
                           </object>
                         </child>
                       </object>
+                      <packing>
+                        <property name="name">repos</property>
+                        <property name="title" translatable="yes">Repositories</property>
+                        <property name="position">3</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">1</property>
                   </packing>
                 </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="tab2">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Groups</property>
-                  </object>
-                  <packing>
-                    <property name="position">1</property>
-                    <property name="tab_fill">False</property>
-                  </packing>
-                </child>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow2">
+                  <object class="GtkBox" id="box7">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="shadow_type">in</property>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">3</property>
                     <child>
-                      <object class="GtkTreeView" id="states_treeview">
+                      <object class="GtkStackSwitcher" id="packages_stackswitcher">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="headers_clickable">False</property>
-                        <property name="enable_search">False</property>
-                        <property name="show_expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection" id="states_treeview_selection">
-                            <signal name="changed" handler="on_states_treeview_selection_changed" after="yes" swapped="no"/>
+                        <property name="can_focus">False</property>
+                        <property name="stack">packages_stack</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkStack" id="packages_stack">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <child>
+                          <object class="GtkScrolledWindow" id="packages_scrolledwindow">
+                            <property name="width_request">700</property>
+                            <property name="height_request">200</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="vexpand">True</property>
+                            <property name="shadow_type">in</property>
+                            <child>
+                              <object class="GtkTreeView" id="packages_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="search_column">1</property>
+                                <property name="fixed_height_mode">True</property>
+                                <property name="show_expanders">False</property>
+                                <property name="rubber_banding">True</property>
+                                <signal name="button-press-event" handler="on_packages_treeview_button_press_event" swapped="no"/>
+                                <signal name="row-activated" handler="on_packages_treeview_row_activated" swapped="no"/>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="packages_treeview_selection">
+                                    <property name="mode">multiple</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="packages_state_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">40</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">State</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">0</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="packages_name_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">200</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Name</property>
+                                    <property name="expand">True</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">1</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="packages_name_renderertext">
+                                        <property name="wrap_mode">word</property>
+                                      </object>
+                                      <attributes>
+                                        <attribute name="markup">2</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="packages_version_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">90</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Version</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">3</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="packages_version_renderertext"/>
+                                      <attributes>
+                                        <attribute name="text">3</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="packages_repo_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">90</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Repository</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">4</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="packages_repo_renderertext"/>
+                                      <attributes>
+                                        <attribute name="text">4</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="packages_size_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">90</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Size</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">5</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="packages_size_renderertext"/>
+                                      <attributes>
+                                        <attribute name="text">6</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                            </child>
                           </object>
+                          <packing>
+                            <property name="name">repos</property>
+                            <property name="title" translatable="yes">Repositories</property>
+                          </packing>
                         </child>
                         <child>
-                          <object class="GtkTreeViewColumn" id="State">
+                          <object class="GtkScrolledWindow" id="aur_scrolledwindow">
+                            <property name="width_request">500</property>
+                            <property name="height_request">200</property>
+                            <property name="visible">True</property>
+                            <property name="can_focus">True</property>
+                            <property name="hexpand">True</property>
+                            <property name="vexpand">True</property>
+                            <property name="shadow_type">in</property>
                             <child>
-                              <object class="GtkCellRendererText" id="cellrenderertext9"/>
-                              <attributes>
-                                <attribute name="text">0</attribute>
-                              </attributes>
+                              <object class="GtkTreeView" id="aur_treeview">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="hexpand">True</property>
+                                <property name="vexpand">True</property>
+                                <property name="search_column">1</property>
+                                <property name="fixed_height_mode">True</property>
+                                <property name="show_expanders">False</property>
+                                <property name="rubber_banding">True</property>
+                                <property name="enable_grid_lines">horizontal</property>
+                                <signal name="button-press-event" handler="on_aur_treeview_button_press_event" swapped="no"/>
+                                <signal name="row-activated" handler="on_aur_treeview_row_activated" swapped="no"/>
+                                <child internal-child="selection">
+                                  <object class="GtkTreeSelection" id="aur_treeview_selection">
+                                    <property name="mode">multiple</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="aur_state_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">40</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">State</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">0</property>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="aur_name_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">200</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Name</property>
+                                    <property name="expand">True</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">1</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="aur_name_renderertext">
+                                        <property name="wrap_mode">word</property>
+                                      </object>
+                                      <attributes>
+                                        <attribute name="markup">2</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="aur_version_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">90</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Version</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">3</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="aur_version_renderertext"/>
+                                      <attributes>
+                                        <attribute name="text">3</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                                <child>
+                                  <object class="GtkTreeViewColumn" id="aur_popularity_column">
+                                    <property name="resizable">True</property>
+                                    <property name="sizing">fixed</property>
+                                    <property name="fixed_width">90</property>
+                                    <property name="min_width">20</property>
+                                    <property name="title" translatable="yes">Popularity</property>
+                                    <property name="clickable">True</property>
+                                    <property name="sort_column_id">4</property>
+                                    <child>
+                                      <object class="GtkCellRendererText" id="aur_popularity_renderertext"/>
+                                      <attributes>
+                                        <attribute name="text">5</attribute>
+                                      </attributes>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
                             </child>
                           </object>
+                          <packing>
+                            <property name="name">aur</property>
+                            <property name="title" translatable="yes">AUR</property>
+                            <property name="position">1</property>
+                          </packing>
                         </child>
                       </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
                     <property name="position">2</property>
                   </packing>
                 </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="tab3">
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkBox" id="transaction_infobox">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <child>
+                  <object class="GtkLabel" id="transaction_infos_label">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">State</property>
+                    <property name="halign">start</property>
+                    <property name="margin_left">6</property>
                   </object>
                   <packing>
-                    <property name="position">2</property>
-                    <property name="tab_fill">False</property>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkScrolledWindow" id="scrolledwindow8">
+                  <object class="GtkButtonBox" id="transaction_infos_buttonbox">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <property name="shadow_type">in</property>
+                    <property name="can_focus">False</property>
+                    <property name="spacing">6</property>
+                    <property name="homogeneous">True</property>
+                    <property name="layout_style">start</property>
                     <child>
-                      <object class="GtkTreeView" id="repos_treeview">
+                      <object class="GtkButton" id="transaction_infos_details_button">
+                        <property name="label" translatable="yes">Details</property>
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="headers_visible">False</property>
-                        <property name="headers_clickable">False</property>
-                        <property name="enable_search">False</property>
-                        <property name="show_expanders">False</property>
-                        <child internal-child="selection">
-                          <object class="GtkTreeSelection" id="repos_treeview_selection">
-                            <signal name="changed" handler="on_repos_treeview_selection_changed" after="yes" swapped="no"/>
-                          </object>
-                        </child>
-                        <child>
-                          <object class="GtkTreeViewColumn" id="Repos">
-                            <child>
-                              <object class="GtkCellRendererText" id="cellrenderertext10"/>
-                              <attributes>
-                                <attribute name="text">0</attribute>
-                              </attributes>
-                            </child>
-                          </object>
-                        </child>
+                        <property name="receives_default">True</property>
+                        <signal name="clicked" handler="on_transaction_infos_details_button_clicked" swapped="no"/>
                       </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="transaction_infos_apply_button">
+                        <property name="label" translatable="yes">_Apply</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_underline">True</property>
+                        <property name="yalign">0.55000001192092896</property>
+                        <signal name="clicked" handler="on_transaction_infos_apply_button_clicked" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkButton" id="transaction_infos_cancel_button">
+                        <property name="label" translatable="yes">_Cancel</property>
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                        <property name="receives_default">True</property>
+                        <property name="use_underline">True</property>
+                        <signal name="clicked" handler="on_transaction_infos_cancel_button_clicked" swapped="no"/>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
+                      </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="position">3</property>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
                   </packing>
                 </child>
-                <child type="tab">
-                  <object class="GtkLabel" id="tab4">
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">4</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="name">browse</property>
+            <property name="title" translatable="yes">Browse</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box4">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">6</property>
+            <child>
+              <object class="GtkButton" id="button_back">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="halign">start</property>
+                <signal name="clicked" handler="on_button_back_clicked" swapped="no"/>
+                <child>
+                  <object class="GtkImage" id="back_image">
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
-                    <property name="label" translatable="yes">Repositories</property>
+                    <property name="icon_name">go-previous-symbolic</property>
+                    <property name="icon_size">1</property>
                   </object>
-                  <packing>
-                    <property name="position">3</property>
-                    <property name="tab_fill">False</property>
-                  </packing>
                 </child>
+                <style>
+                  <class name="image-button"/>
+                </style>
               </object>
               <packing>
-                <property name="resize">False</property>
-                <property name="shrink">False</property>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
-              <object class="GtkPaned" id="paned2">
+              <object class="GtkBox" id="box6">
                 <property name="visible">True</property>
-                <property name="can_focus">True</property>
+                <property name="can_focus">False</property>
                 <property name="orientation">vertical</property>
+                <property name="spacing">6</property>
                 <child>
-                  <object class="GtkNotebook" id="packages_notebook">
+                  <object class="GtkBox" id="box8">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <signal name="switch-page" handler="on_packages_notebook_switch_page" after="yes" swapped="no"/>
+                    <property name="can_focus">False</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="packages_scrolledwindow">
-                        <property name="width_request">500</property>
-                        <property name="height_request">200</property>
+                      <object class="GtkLabel" id="name_label">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="vexpand">True</property>
-                        <property name="shadow_type">in</property>
-                        <child>
-                          <object class="GtkTreeView" id="packages_treeview">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="hexpand">True</property>
-                            <property name="vexpand">True</property>
-                            <property name="search_column">0</property>
-                            <property name="show_expanders">False</property>
-                            <signal name="button-press-event" handler="on_packages_treeview_button_press_event" swapped="no"/>
-                            <signal name="row-activated" handler="on_packages_treeview_row_activated" swapped="no"/>
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection">
-                                <property name="mode">multiple</property>
-                                <signal name="changed" handler="on_packages_treeview_selection_changed" swapped="no"/>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="packages_state_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">40</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">State</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_packages_state_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererPixbuf" id="packages_state_rendererpixbuf"/>
-                                  <attributes>
-                                    <attribute name="pixbuf">1</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="packages_name_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">150</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Name</property>
-                                <property name="expand">True</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_packages_name_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="packages_name_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">0</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="packages_version_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">90</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Version</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_packages_version_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="packages_version_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">2</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="packages_repo_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">90</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Repository</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_packages_repo_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="packages_repo_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">3</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="packages_size_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">90</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Size</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_packages_size_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="packages_size_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">4</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
+                        <property name="can_focus">False</property>
+                        <property name="halign">start</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_start">6</property>
+                        <property name="margin_end">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="selectable">True</property>
                       </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
                     </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="label1">
+                    <child>
+                      <object class="GtkLabel" id="desc_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Repositories</property>
+                        <property name="halign">start</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_start">6</property>
+                        <property name="margin_end">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="selectable">True</property>
                       </object>
                       <packing>
-                        <property name="tab_fill">False</property>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkScrolledWindow" id="aur_scrolledwindow">
-                        <property name="width_request">500</property>
-                        <property name="height_request">200</property>
+                      <object class="GtkLabel" id="link_label">
                         <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="hexpand">True</property>
-                        <property name="vexpand">True</property>
-                        <property name="shadow_type">in</property>
-                        <child>
-                          <object class="GtkTreeView" id="aur_treeview">
-                            <property name="visible">True</property>
-                            <property name="can_focus">True</property>
-                            <property name="hexpand">True</property>
-                            <property name="vexpand">True</property>
-                            <property name="search_column">0</property>
-                            <property name="show_expanders">False</property>
-                            <signal name="button-press-event" handler="on_aur_treeview_button_press_event" swapped="no"/>
-                            <signal name="row-activated" handler="on_aur_treeview_row_activated" swapped="no"/>
-                            <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection12">
-                                <property name="mode">multiple</property>
-                                <signal name="changed" handler="on_aur_treeview_selection_changed" swapped="no"/>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="aur_state_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">40</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">State</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_aur_state_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererPixbuf" id="aur_state_rendererpixbuf"/>
-                                  <attributes>
-                                    <attribute name="pixbuf">1</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="aur_name_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">150</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Name</property>
-                                <property name="expand">True</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_aur_name_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="aur_name_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">0</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="aur_version_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">90</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Version</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_aur_version_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="aur_version_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">2</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                            <child>
-                              <object class="GtkTreeViewColumn" id="aur_votes_column">
-                                <property name="resizable">True</property>
-                                <property name="fixed_width">90</property>
-                                <property name="min_width">20</property>
-                                <property name="title" translatable="yes">Votes</property>
-                                <property name="clickable">True</property>
-                                <signal name="clicked" handler="on_aur_votes_column_clicked" swapped="no"/>
-                                <child>
-                                  <object class="GtkCellRendererText" id="aur_votes_renderertext"/>
-                                  <attributes>
-                                    <attribute name="text">3</attribute>
-                                  </attributes>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
+                        <property name="can_focus">False</property>
+                        <property name="halign">start</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_start">6</property>
+                        <property name="margin_end">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="margin_bottom">6</property>
                       </object>
                       <packing>
-                        <property name="position">1</property>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="label5">
+                    <child>
+                      <object class="GtkLabel" id="licenses_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">AUR</property>
+                        <property name="halign">start</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
+                        <property name="margin_start">6</property>
+                        <property name="margin_end">6</property>
+                        <property name="margin_top">6</property>
+                        <property name="margin_bottom">6</property>
+                        <property name="selectable">True</property>
                       </object>
                       <packing>
-                        <property name="position">1</property>
-                        <property name="tab_fill">False</property>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="position">3</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="resize">True</property>
-                    <property name="shrink">True</property>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">0</property>
                   </packing>
                 </child>
                 <child>
-                  <object class="GtkNotebook" id="properties_notebook">
-                    <property name="width_request">500</property>
-                    <property name="height_request">150</property>
+                  <object class="GtkStackSwitcher" id="properties_stackswitcher">
                     <property name="visible">True</property>
-                    <property name="can_focus">True</property>
-                    <signal name="switch-page" handler="on_properties_notebook_switch_page" after="yes" swapped="no"/>
-                    <child>
-                      <object class="GtkScrolledWindow" id="infos_scrolledwindow">
-                        <property name="visible">True</property>
-                        <property name="can_focus">True</property>
-                        <property name="shadow_type">in</property>
-                        <child>
-                          <object class="GtkViewport" id="viewport2">
-                            <property name="visible">True</property>
-                            <property name="can_focus">False</property>
-                            <child>
-                              <object class="GtkBox" id="box4">
-                                <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="orientation">vertical</property>
-                                <property name="spacing">6</property>
-                                <child>
-                                  <object class="GtkLabel" id="name_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">start</property>
-                                    <property name="margin_left">6</property>
-                                    <property name="margin_right">6</property>
-                                    <property name="margin_start">6</property>
-                                    <property name="margin_end">6</property>
-                                    <property name="margin_top">6</property>
-                                    <property name="margin_bottom">6</property>
-                                    <property name="selectable">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">0</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="desc_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">start</property>
-                                    <property name="margin_left">6</property>
-                                    <property name="margin_right">6</property>
-                                    <property name="margin_start">6</property>
-                                    <property name="margin_end">6</property>
-                                    <property name="margin_top">6</property>
-                                    <property name="margin_bottom">6</property>
-                                    <property name="selectable">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">1</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="link_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">start</property>
-                                    <property name="margin_left">6</property>
-                                    <property name="margin_right">6</property>
-                                    <property name="margin_start">6</property>
-                                    <property name="margin_end">6</property>
-                                    <property name="margin_top">6</property>
-                                    <property name="margin_bottom">6</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">2</property>
-                                  </packing>
-                                </child>
-                                <child>
-                                  <object class="GtkLabel" id="licenses_label">
-                                    <property name="visible">True</property>
-                                    <property name="can_focus">False</property>
-                                    <property name="halign">start</property>
-                                    <property name="margin_left">6</property>
-                                    <property name="margin_right">6</property>
-                                    <property name="margin_start">6</property>
-                                    <property name="margin_end">6</property>
-                                    <property name="margin_top">6</property>
-                                    <property name="margin_bottom">6</property>
-                                    <property name="selectable">True</property>
-                                  </object>
-                                  <packing>
-                                    <property name="expand">False</property>
-                                    <property name="fill">True</property>
-                                    <property name="position">3</property>
-                                  </packing>
-                                </child>
-                              </object>
-                            </child>
-                          </object>
-                        </child>
-                      </object>
-                    </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="label7">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Description</property>
-                      </object>
-                      <packing>
-                        <property name="tab_fill">False</property>
-                      </packing>
-                    </child>
+                    <property name="can_focus">False</property>
+                    <property name="stack">properties_stack</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkStack" id="properties_stack">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
                     <child>
-                      <object class="GtkScrolledWindow" id="deps_scrolledwindow">
+                      <object class="GtkScrolledWindow" id="details_scrolledwindow">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="shadow_type">in</property>
                         <child>
-                          <object class="GtkTreeView" id="deps_treeview">
+                          <object class="GtkTreeView" id="details_treeview">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="headers_visible">False</property>
                             <property name="headers_clickable">False</property>
                             <property name="enable_search">False</property>
+                            <property name="search_column">0</property>
                             <property name="show_expanders">False</property>
                             <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection8">
+                              <object class="GtkTreeSelection" id="treeview-selection9">
                                 <property name="mode">none</property>
                               </object>
                             </child>
                             <child>
-                              <object class="GtkTreeViewColumn" id="dep_type">
+                              <object class="GtkTreeViewColumn" id="infotype">
                                 <property name="sizing">autosize</property>
                                 <child>
-                                  <object class="GtkCellRendererText" id="cellrenderertext3">
+                                  <object class="GtkCellRendererText" id="cellrenderertext6">
                                     <property name="yalign">0</property>
-                                    <property name="weight">600</property>
+                                    <property name="wrap_mode">word</property>
                                   </object>
                                   <attributes>
-                                    <attribute name="text">0</attribute>
+                                    <attribute name="markup">0</attribute>
                                   </attributes>
                                 </child>
                               </object>
                             </child>
                             <child>
-                              <object class="GtkTreeViewColumn" id="deps">
+                              <object class="GtkTreeViewColumn" id="info">
                                 <property name="sizing">autosize</property>
                                 <child>
-                                  <object class="GtkCellRendererText" id="cellrenderertext5"/>
+                                  <object class="GtkCellRendererText" id="cellrenderertext7">
+                                    <property name="wrap_mode">word</property>
+                                  </object>
                                   <attributes>
                                     <attribute name="text">1</attribute>
                                   </attributes>
@@ -835,61 +909,46 @@
                         </child>
                       </object>
                       <packing>
-                        <property name="position">1</property>
-                      </packing>
-                    </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="label8">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Dependencies</property>
-                      </object>
-                      <packing>
-                        <property name="position">1</property>
-                        <property name="tab_fill">False</property>
+                        <property name="name">details</property>
+                        <property name="title" translatable="yes">Details</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkScrolledWindow" id="details_scrolledwindow">
+                      <object class="GtkScrolledWindow" id="deps_scrolledwindow">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
                         <property name="shadow_type">in</property>
                         <child>
-                          <object class="GtkTreeView" id="details_treeview">
+                          <object class="GtkTreeView" id="deps_treeview">
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="headers_visible">False</property>
                             <property name="headers_clickable">False</property>
                             <property name="enable_search">False</property>
-                            <property name="search_column">0</property>
                             <property name="show_expanders">False</property>
+                            <property name="activate_on_single_click">True</property>
+                            <signal name="row-activated" handler="on_deps_treeview_row_activated" swapped="no"/>
                             <child internal-child="selection">
-                              <object class="GtkTreeSelection" id="treeview-selection10">
-                                <property name="mode">none</property>
-                              </object>
+                              <object class="GtkTreeSelection" id="deps_treeview_selection"/>
                             </child>
                             <child>
-                              <object class="GtkTreeViewColumn" id="infotype">
+                              <object class="GtkTreeViewColumn" id="dep_type_treeview_column">
                                 <property name="sizing">autosize</property>
                                 <child>
-                                  <object class="GtkCellRendererText" id="cellrenderertext6">
+                                  <object class="GtkCellRendererText" id="cellrenderertext3">
                                     <property name="yalign">0</property>
-                                    <property name="weight">600</property>
-                                    <property name="wrap_mode">word</property>
                                   </object>
                                   <attributes>
-                                    <attribute name="text">0</attribute>
+                                    <attribute name="markup">0</attribute>
                                   </attributes>
                                 </child>
                               </object>
                             </child>
                             <child>
-                              <object class="GtkTreeViewColumn" id="info">
+                              <object class="GtkTreeViewColumn" id="deps_treeview_column">
                                 <property name="sizing">autosize</property>
                                 <child>
-                                  <object class="GtkCellRendererText" id="cellrenderertext7">
-                                    <property name="wrap_mode">word</property>
-                                  </object>
+                                  <object class="GtkCellRendererText" id="cellrenderertext5"/>
                                   <attributes>
                                     <attribute name="text">1</attribute>
                                   </attributes>
@@ -900,18 +959,9 @@
                         </child>
                       </object>
                       <packing>
-                        <property name="position">2</property>
-                      </packing>
-                    </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="label9">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Details</property>
-                      </object>
-                      <packing>
-                        <property name="position">2</property>
-                        <property name="tab_fill">False</property>
+                        <property name="name">deps</property>
+                        <property name="title" translatable="yes">Dependencies</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
@@ -933,36 +983,29 @@
                         </child>
                       </object>
                       <packing>
-                        <property name="position">3</property>
-                      </packing>
-                    </child>
-                    <child type="tab">
-                      <object class="GtkLabel" id="files_label">
-                        <property name="visible">True</property>
-                        <property name="can_focus">False</property>
-                        <property name="label" translatable="yes">Files</property>
-                      </object>
-                      <packing>
-                        <property name="position">3</property>
-                        <property name="tab_fill">False</property>
+                        <property name="name">files</property>
+                        <property name="title" translatable="yes">Files</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
                   <packing>
-                    <property name="resize">True</property>
-                    <property name="shrink">False</property>
+                    <property name="expand">True</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
               </object>
               <packing>
-                <property name="resize">True</property>
-                <property name="shrink">True</property>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
               </packing>
             </child>
           </object>
           <packing>
-            <property name="expand">True</property>
-            <property name="fill">True</property>
+            <property name="name">details</property>
+            <property name="title" translatable="yes">Details</property>
             <property name="position">1</property>
           </packing>
         </child>
diff --git a/resources/package-available-locked.png b/resources/package-available-locked.png
new file mode 100644
index 0000000000000000000000000000000000000000..12e824e52f0443a01648453f850f2d366149312e
Binary files /dev/null and b/resources/package-available-locked.png differ
diff --git a/resources/pamac.manager.gresource.xml b/resources/pamac.manager.gresource.xml
index e66adf513e5bc9cedd151a291db08352031bb3d5..bff4ac1b9b1fc138a00243b38ceebbe8cb352ff4 100644
--- a/resources/pamac.manager.gresource.xml
+++ b/resources/pamac.manager.gresource.xml
@@ -5,6 +5,7 @@
     <file preprocess="xml-stripblanks">history_dialog.ui</file>
     <file preprocess="xml-stripblanks">choose_dep_dialog.ui</file>
     <file preprocess="to-pixdata">package-available.png</file>
+    <file preprocess="to-pixdata">package-available-locked.png</file>
     <file preprocess="to-pixdata">package-install.png</file>
     <file preprocess="to-pixdata">package-installed-locked.png</file>
     <file preprocess="to-pixdata">package-installed-updated.png</file>
diff --git a/resources/preferences_dialog.ui b/resources/preferences_dialog.ui
index cf77c790da3ca3f90dccf3ecb648cb0d466d0860..bf2615c37a37a2e01b35212f7399409e0be9c786 100644
--- a/resources/preferences_dialog.ui
+++ b/resources/preferences_dialog.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.19.0 -->
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.14"/>
   <object class="GtkAdjustment" id="adjustment">
@@ -9,19 +9,13 @@
     <property name="step_increment">1</property>
     <property name="page_increment">10</property>
   </object>
-  <object class="GtkListStore" id="ignorepkgs_liststore">
-    <columns>
-      <!-- column-name name -->
-      <column type="gchararray"/>
-    </columns>
-  </object>
   <template class="PamacPreferencesDialog" parent="GtkDialog">
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Preferences</property>
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
-    <property name="type_hint">normal</property>
+    <property name="type_hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox">
         <property name="can_focus">False</property>
@@ -54,13 +48,28 @@
           </packing>
         </child>
         <child>
-          <object class="GtkNotebook" id="notebook1">
+          <object class="GtkStackSwitcher" id="stackswitcher">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">center</property>
+            <property name="stack">stack</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStack" id="stack">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <child>
               <object class="GtkBox" id="general_config_box">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="margin_left">6</property>
+                <property name="margin_right">6</property>
                 <property name="margin_start">6</property>
                 <property name="margin_end">6</property>
                 <property name="margin_top">6</property>
@@ -168,6 +177,7 @@
                       <object class="GtkSwitch" id="check_updates_button">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
+                        <property name="tooltip_text" translatable="yes">Check for updates</property>
                         <property name="halign">end</property>
                       </object>
                       <packing>
@@ -192,6 +202,7 @@
                       <object class="GtkLabel" id="refresh_period_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_left">24</property>
                         <property name="margin_start">24</property>
                         <property name="hexpand">True</property>
                         <property name="xalign">0</property>
@@ -208,6 +219,7 @@
                         <property name="can_focus">True</property>
                         <property name="tooltip_text" translatable="yes">How often to check for updates, value in hours</property>
                         <property name="halign">end</property>
+                        <property name="text" translatable="yes">6</property>
                         <property name="caps_lock_warning">False</property>
                         <property name="input_purpose">number</property>
                         <property name="adjustment">adjustment</property>
@@ -234,8 +246,10 @@
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
+                    <property name="margin_left">22</property>
                     <property name="margin_start">22</property>
                     <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
                     <property name="draw_indicator">True</property>
                   </object>
                   <packing>
@@ -255,6 +269,7 @@
                         <property name="can_focus">False</property>
                         <property name="halign">start</property>
                         <property name="valign">start</property>
+                        <property name="margin_left">26</property>
                         <property name="margin_start">26</property>
                         <property name="label" translatable="yes">Ignore upgrades for:</property>
                         <property name="xalign">0</property>
@@ -269,6 +284,7 @@
                       <object class="GtkBox" id="box10">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_left">12</property>
                         <property name="margin_start">12</property>
                         <property name="hexpand">True</property>
                         <property name="vexpand">True</property>
@@ -284,12 +300,11 @@
                               <object class="GtkTreeView" id="ignorepkgs_treeview">
                                 <property name="visible">True</property>
                                 <property name="can_focus">True</property>
-                                <property name="model">ignorepkgs_liststore</property>
                                 <property name="headers_visible">False</property>
                                 <property name="search_column">0</property>
                                 <property name="show_expanders">False</property>
                                 <child internal-child="selection">
-                                  <object class="GtkTreeSelection" id="treeview-selection1"/>
+                                  <object class="GtkTreeSelection" id="treeview-selection"/>
                                 </child>
                                 <child>
                                   <object class="GtkTreeViewColumn" id="treeviewcolumn1">
@@ -368,21 +383,17 @@
                   </packing>
                 </child>
               </object>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="tab_label1">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">General</property>
-              </object>
               <packing>
-                <property name="tab_fill">False</property>
+                <property name="name">general</property>
+                <property name="title" translatable="yes">General</property>
               </packing>
             </child>
             <child>
               <object class="GtkBox" id="mirrors_config_box">
                 <property name="visible">True</property>
                 <property name="can_focus">False</property>
+                <property name="margin_left">6</property>
+                <property name="margin_right">6</property>
                 <property name="margin_start">6</property>
                 <property name="margin_end">6</property>
                 <property name="margin_top">6</property>
@@ -483,20 +494,11 @@
                 </child>
               </object>
               <packing>
+                <property name="name">official_repositories</property>
+                <property name="title" translatable="yes">Official Repositories</property>
                 <property name="position">1</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="tab_label2">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Official Repositories</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
             <child>
               <object class="GtkBox" id="aur_config_box">
                 <property name="visible">True</property>
@@ -568,6 +570,8 @@ All AUR users should be familiar with the build process.</property>
                       <object class="GtkLabel" id="enable_aur_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
                         <property name="margin_start">6</property>
                         <property name="margin_end">6</property>
                         <property name="hexpand">True</property>
@@ -586,6 +590,8 @@ All AUR users should be familiar with the build process.</property>
                         <property name="can_focus">True</property>
                         <property name="tooltip_text" translatable="yes">Allow Pamac to search and install packages from AUR</property>
                         <property name="halign">end</property>
+                        <property name="margin_left">6</property>
+                        <property name="margin_right">6</property>
                         <property name="margin_start">6</property>
                         <property name="margin_end">6</property>
                       </object>
@@ -608,8 +614,10 @@ All AUR users should be familiar with the build process.</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
+                    <property name="margin_left">24</property>
                     <property name="margin_start">24</property>
                     <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
                     <property name="draw_indicator">True</property>
                   </object>
                   <packing>
@@ -624,8 +632,10 @@ All AUR users should be familiar with the build process.</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
+                    <property name="margin_left">24</property>
                     <property name="margin_start">24</property>
                     <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
                     <property name="draw_indicator">True</property>
                   </object>
                   <packing>
@@ -640,8 +650,10 @@ All AUR users should be familiar with the build process.</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
+                    <property name="margin_left">24</property>
                     <property name="margin_start">24</property>
                     <property name="hexpand">True</property>
+                    <property name="xalign">0</property>
                     <property name="draw_indicator">True</property>
                   </object>
                   <packing>
@@ -652,25 +664,16 @@ All AUR users should be familiar with the build process.</property>
                 </child>
               </object>
               <packing>
+                <property name="name">aur</property>
+                <property name="title" translatable="yes">AUR</property>
                 <property name="position">2</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="tab_label3">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">AUR</property>
-              </object>
-              <packing>
-                <property name="position">2</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
           </object>
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
diff --git a/resources/progress_dialog.ui b/resources/progress_dialog.ui
index 9691885666dec9a3976448ef71a31409709bd5d3..d5a171d734485ef5b61bfbaef5048d9a9c011155 100644
--- a/resources/progress_dialog.ui
+++ b/resources/progress_dialog.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.19.0 -->
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacProgressDialog" parent="GtkDialog">
@@ -7,11 +7,9 @@
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Progress</property>
-    <property name="modal">True</property>
     <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
-    <property name="deletable">False</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox1">
         <property name="visible">True</property>
@@ -39,7 +37,7 @@
             </child>
             <child>
               <object class="GtkButton" id="close_button">
-                <property name="label" translatable="yes">_Close</property>
+                <property name="label" translatable="yes">_Hide</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="receives_default">False</property>
diff --git a/resources/transaction_info_dialog.ui b/resources/transaction_info_dialog.ui
index 31287c8f67974da2e393ece040bd9538183400de..69b66ff8cfe3fb15c4eb7bd91b75570fc27d9891 100644
--- a/resources/transaction_info_dialog.ui
+++ b/resources/transaction_info_dialog.ui
@@ -1,11 +1,16 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacTransactionInfoDialog" parent="GtkDialog">
+    <property name="can_focus">False</property>
     <property name="border_width">6</property>
+    <property name="modal">True</property>
+    <property name="window_position">center-on-parent</property>
     <property name="default_width">300</property>
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
+    <property name="urgency_hint">True</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox4">
         <property name="can_focus">False</property>
@@ -21,11 +26,13 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
+                <property name="receives_default">False</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">True</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
           </object>
@@ -33,6 +40,7 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -43,6 +51,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -83,6 +92,7 @@
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
+            <property name="position">2</property>
           </packing>
         </child>
       </object>
diff --git a/resources/transaction_sum_dialog.ui b/resources/transaction_sum_dialog.ui
index a237e8919579f9d6dcb2f2e211b459519624ab5d..104573fa0a046aab240161830251dbf4584fb7e0 100644
--- a/resources/transaction_sum_dialog.ui
+++ b/resources/transaction_sum_dialog.ui
@@ -1,11 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacTransactionSumDialog" parent="GtkDialog">
-    <property name="title" translatable="yes">Transaction Summary</property>
+    <property name="can_focus">False</property>
     <property name="border_width">6</property>
-    <property name="type_hint">dialog</property>
+    <property name="title" translatable="yes">Transaction Summary</property>
+    <property name="window_position">center-on-parent</property>
     <property name="icon_name">system-software-install</property>
+    <property name="type_hint">dialog</property>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox6">
         <property name="can_focus">False</property>
@@ -21,12 +24,13 @@
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
                 <property name="has_focus">True</property>
-                <property name="use_underline">True</property>
                 <property name="receives_default">False</property>
+                <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">0</property>
               </packing>
             </child>
             <child>
@@ -34,11 +38,13 @@
                 <property name="label" translatable="yes">_OK</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
                 <property name="use_underline">True</property>
               </object>
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
+                <property name="position">1</property>
               </packing>
             </child>
           </object>
@@ -46,6 +52,7 @@
             <property name="expand">False</property>
             <property name="fill">True</property>
             <property name="pack_type">end</property>
+            <property name="position">0</property>
           </packing>
         </child>
         <child>
@@ -56,6 +63,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
+            <property name="position">1</property>
           </packing>
         </child>
         <child>
@@ -65,7 +73,7 @@
             <property name="hexpand">True</property>
             <property name="vexpand">True</property>
             <property name="shadow_type">in</property>
-            <property name="min_content_width">330</property>
+            <property name="min_content_width">450</property>
             <property name="min_content_height">250</property>
             <child>
               <object class="GtkTreeView" id="treeview">
@@ -75,7 +83,6 @@
                 <property name="vexpand">True</property>
                 <property name="headers_visible">False</property>
                 <property name="headers_clickable">False</property>
-                <property name="enable_search">False</property>
                 <property name="search_column">0</property>
                 <property name="show_expanders">False</property>
                 <child internal-child="selection">
@@ -87,12 +94,11 @@
                   <object class="GtkTreeViewColumn" id="_action">
                     <property name="sizing">autosize</property>
                     <child>
-                      <object class="GtkCellRendererText" id="cellrenderertext5">
+                      <object class="GtkCellRendererText" id="cellrenderertext1">
                         <property name="yalign">0</property>
-                        <property name="weight">600</property>
                       </object>
                       <attributes>
-                        <attribute name="text">0</attribute>
+                        <attribute name="markup">0</attribute>
                       </attributes>
                     </child>
                   </object>
@@ -101,19 +107,38 @@
                   <object class="GtkTreeViewColumn" id="_packages">
                     <property name="sizing">autosize</property>
                     <child>
-                      <object class="GtkCellRendererText" id="cellrenderertext6"/>
+                      <object class="GtkCellRendererText" id="cellrenderertext2"/>
                       <attributes>
                         <attribute name="text">1</attribute>
                       </attributes>
                     </child>
                   </object>
                 </child>
+                <child>
+                  <object class="GtkTreeViewColumn" id="_version">
+                    <property name="sizing">autosize</property>
+                    <property name="title" translatable="yes">column</property>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext3"/>
+                      <attributes>
+                        <attribute name="text">2</attribute>
+                      </attributes>
+                    </child>
+                    <child>
+                      <object class="GtkCellRendererText" id="cellrenderertext4"/>
+                      <attributes>
+                        <attribute name="text">3</attribute>
+                      </attributes>
+                    </child>
+                  </object>
+                </child>
               </object>
             </child>
           </object>
           <packing>
             <property name="expand">True</property>
             <property name="fill">True</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <child>
@@ -124,6 +149,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
+            <property name="position">3</property>
           </packing>
         </child>
       </object>
diff --git a/resources/updater_window.ui b/resources/updater_window.ui
index d09ed27e9c1114100f22936cd5482aa26198d8ee..9dc6604c1e876c3372afff054a17300f990385c0 100644
--- a/resources/updater_window.ui
+++ b/resources/updater_window.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.19.0 -->
+<!-- Generated with glade 3.20.0 -->
 <interface>
   <requires lib="gtk+" version="3.12"/>
   <template class="PamacUpdaterWindow" parent="GtkApplicationWindow">
@@ -7,9 +7,9 @@
     <property name="can_focus">False</property>
     <property name="border_width">6</property>
     <property name="title" translatable="yes">Update Manager</property>
-    <property name="window_position">center</property>
-    <property name="default_width">500</property>
+    <property name="default_width">600</property>
     <property name="icon_name">system-software-update</property>
+    <property name="gravity">center</property>
     <child>
       <object class="GtkBox" id="box1">
         <property name="visible">True</property>
@@ -30,25 +30,35 @@
           </packing>
         </child>
         <child>
-          <object class="GtkNotebook" id="notebook">
+          <object class="GtkStackSwitcher" id="stackswitcher">
             <property name="visible">True</property>
-            <property name="can_focus">True</property>
+            <property name="can_focus">False</property>
+            <property name="halign">center</property>
+            <property name="stack">stack</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStack" id="stack">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
             <child>
               <object class="GtkScrolledWindow" id="repos_scrolledwindow">
-                <property name="width_request">400</property>
-                <property name="height_request">400</property>
+                <property name="width_request">600</property>
+                <property name="height_request">450</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="hexpand">True</property>
-                <property name="vexpand">True</property>
                 <child>
                   <object class="GtkTreeView" id="repos_updates_treeview">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="vexpand">True</property>
-                    <property name="headers_visible">False</property>
                     <property name="headers_clickable">False</property>
-                    <property name="search_column">0</property>
+                    <property name="search_column">1</property>
+                    <property name="show_expanders">False</property>
                     <child internal-child="selection">
                       <object class="GtkTreeSelection" id="treeview-selection">
                         <property name="mode">none</property>
@@ -56,6 +66,11 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn3">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">40</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">State</property>
                         <child>
                           <object class="GtkCellRendererToggle" id="repos_select_update">
                             <signal name="toggled" handler="on_repos_select_update_toggled" swapped="no"/>
@@ -68,6 +83,11 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">200</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Name</property>
                         <property name="expand">True</property>
                         <child>
                           <object class="GtkCellRendererText" id="repos_update_name"/>
@@ -78,45 +98,77 @@
                       </object>
                     </child>
                     <child>
-                      <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn6">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">150</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Version</property>
                         <child>
-                          <object class="GtkCellRendererText" id="repos_update_download_size"/>
+                          <object class="GtkCellRendererText" id="repos_new_update_version"/>
                           <attributes>
                             <attribute name="text">2</attribute>
                           </attributes>
                         </child>
+                        <child>
+                          <object class="GtkCellRendererText" id="repos_old_update_version"/>
+                          <attributes>
+                            <attribute name="text">3</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn10">
+                        <property name="resizable">True</property>
+                        <property name="fixed_width">90</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Repository</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="repos_update_repo"/>
+                          <attributes>
+                            <attribute name="text">4</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">90</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Size</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="repos_update_size"/>
+                          <attributes>
+                            <attribute name="text">5</attribute>
+                          </attributes>
+                        </child>
                       </object>
                     </child>
                   </object>
                 </child>
               </object>
-            </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label1">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">Repositories</property>
-              </object>
               <packing>
-                <property name="tab_fill">False</property>
+                <property name="name">repos</property>
+                <property name="title" translatable="yes">Repositories</property>
               </packing>
             </child>
             <child>
               <object class="GtkScrolledWindow" id="aur_scrolledwindow">
-                <property name="width_request">400</property>
-                <property name="height_request">400</property>
+                <property name="width_request">600</property>
+                <property name="height_request">450</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="hexpand">True</property>
-                <property name="vexpand">True</property>
                 <child>
                   <object class="GtkTreeView" id="aur_updates_treeview">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="vexpand">True</property>
-                    <property name="headers_visible">False</property>
                     <property name="headers_clickable">False</property>
-                    <property name="search_column">0</property>
+                    <property name="search_column">1</property>
+                    <property name="show_expanders">False</property>
                     <child internal-child="selection">
                       <object class="GtkTreeSelection" id="treeview-selection2">
                         <property name="mode">none</property>
@@ -124,6 +176,11 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">40</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">State</property>
                         <child>
                           <object class="GtkCellRendererToggle" id="aur_select_update">
                             <signal name="toggled" handler="on_aur_select_update_toggled" swapped="no"/>
@@ -136,6 +193,11 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn5">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">200</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Name</property>
                         <property name="expand">True</property>
                         <child>
                           <object class="GtkCellRendererText" id="aur_update_name"/>
@@ -145,29 +207,35 @@
                         </child>
                       </object>
                     </child>
+                    <child>
+                      <object class="GtkTreeViewColumn" id="treeviewcolumn8">
+                        <property name="resizable">True</property>
+                        <property name="sizing">fixed</property>
+                        <property name="fixed_width">150</property>
+                        <property name="min_width">20</property>
+                        <property name="title" translatable="yes">Version</property>
+                        <child>
+                          <object class="GtkCellRendererText" id="aur_update_version"/>
+                          <attributes>
+                            <attribute name="text">2</attribute>
+                          </attributes>
+                        </child>
+                      </object>
+                    </child>
                   </object>
                 </child>
               </object>
               <packing>
+                <property name="name">aur</property>
+                <property name="title" translatable="yes">AUR</property>
                 <property name="position">1</property>
               </packing>
             </child>
-            <child type="tab">
-              <object class="GtkLabel" id="label2">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-                <property name="label" translatable="yes">AUR</property>
-              </object>
-              <packing>
-                <property name="position">1</property>
-                <property name="tab_fill">False</property>
-              </packing>
-            </child>
           </object>
           <packing>
-            <property name="expand">False</property>
+            <property name="expand">True</property>
             <property name="fill">True</property>
-            <property name="position">1</property>
+            <property name="position">2</property>
           </packing>
         </child>
         <child>
@@ -178,7 +246,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">2</property>
+            <property name="position">3</property>
           </packing>
         </child>
         <child>
@@ -277,7 +345,7 @@
           <packing>
             <property name="expand">False</property>
             <property name="fill">True</property>
-            <property name="position">3</property>
+            <property name="position">4</property>
           </packing>
         </child>
       </object>
diff --git a/src/Makefile b/src/Makefile
index cd818265bb106acd1764dc2fdde14c9b6bdac003..65d4f26c5dfd2ecee964e74ebfae81f2544f7dac 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,30 +1,30 @@
 
-COMMON_VALA_FLAGS = 	-X -w \
-						--pkg=libalpm \
+ALPM_VALA_FLAGS = 		--pkg=libalpm \
 						--pkg=gio-2.0 \
-						--pkg=posix \
-						--vapidir=./ \
 						--vapidir=../vapi \
-						-X -I../util \
-						-X -D_FILE_OFFSET_BITS=64 \
+						-X -D_FILE_OFFSET_BITS=64
+
+COMMON_VALA_FLAGS = 	-X -w \
+						--pkg=posix \
 						-X -DGETTEXT_PACKAGE="pamac" \
 						--target-glib=2.38
 
-TRANSACTION_VALA_FLAGS = 	--pkg=json-glib-1.0 \
-							--pkg=libsoup-2.4 \
-							--pkg=gtk+-3.0 \
+TRANSACTION_VALA_FLAGS = 	--pkg=gtk+-3.0 \
 							--pkg=gdk-3.0 \
 							--pkg=vte-2.91 \
 							-X -lm
 
-COMMON_SOURCES = 	../util/alpm-util.c \
-					common.vala \
-					pamac_config.vala \
-					alpm_config.vala \
+PAMAC_LIB_FLAGS = 	-X -I. \
+					-X -L. \
+					-X -lpamac \
+					--vapidir=./ \
+					--pkg=pamac \
+
+COMMON_SOURCES = 	common.vala \
+					pamac_config.vala
 
-TRANSACTION_SOURCES = 	transaction.vala \
-						alpm_utils.vala \
-						aur.vala \
+TRANSACTION_SOURCES = 	package.vala \
+						transaction.vala \
 						choose_provider_dialog.vala \
 						transaction_sum_dialog.vala \
 						transaction_info_dialog.vala \
@@ -42,7 +42,7 @@ UPDATER_GRESOURCE_FILE = ../resources/pamac.updater.gresource.xml
 
 INSTALLER_GRESOURCE_FILE = ../resources/pamac.installer.gresource.xml
 
-binaries: pamac-refresh pamac-daemon pamac-tray libpamac.so pamac-updater pamac-manager pamac-install
+binaries: pamac-refresh pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install
 
 clean:
 	rm -f *.c pamac.h pamac.vapi libpamac.so pamac-refresh pamac-daemon pamac-tray pamac-updater pamac-manager pamac-install
@@ -55,7 +55,7 @@ pamac-refresh: pamac_config.vala refresh.vala
 			pamac_config.vala \
 			refresh.vala
 
-pamac-tray: ../vapi/libalpm.vapi $(COMMON_SOURCES) tray.vala
+pamac-tray: $(COMMON_SOURCES) alpm_config.vala tray.vala
 	valac 	-o pamac-tray \
 			$(COMMON_VALA_FLAGS) \
 			--pkg=gtk+-3.0 \
@@ -63,20 +63,23 @@ pamac-tray: ../vapi/libalpm.vapi $(COMMON_SOURCES) tray.vala
 			$(COMMON_SOURCES) \
 			tray.vala
 
-pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi $(COMMON_SOURCES) aur.vala mirrors_config.vala daemon.vala
+pamac-daemon: ../vapi/libalpm.vapi ../vapi/polkit-gobject-1.vapi ../vapi/libcurl.vapi alpm_config.vala $(COMMON_SOURCES) package.vala aur.vala mirrors_config.vala daemon.vala
 	valac 	-o pamac-daemon \
 			$(COMMON_VALA_FLAGS) \
+			$(ALPM_VALA_FLAGS) \
 			--pkg=polkit-gobject-1 \
 			--pkg=libcurl \
 			--pkg=json-glib-1.0 \
 			--pkg=libsoup-2.4 \
 			--thread \
+			alpm_config.vala \
 			$(COMMON_SOURCES) \
+			package.vala \
 			aur.vala \
 			mirrors_config.vala \
 			daemon.vala
 
-libpamac.so: ../vapi/libalpm.vapi $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../resources/transaction_resources.c
+libpamac.so: $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PREFERENCES_SOURCES) ../resources/transaction_resources.c
 	valac	-o libpamac.so \
 			-X -fPIC \
 			-X --shared \
@@ -91,33 +94,24 @@ libpamac.so: ../vapi/libalpm.vapi $(COMMON_SOURCES) $(TRANSACTION_SOURCES) $(PRE
 			$(TRANSACTION_SOURCES) \
 			$(PREFERENCES_SOURCES)
 
-pamac-manager: libpamac.so choose_dep_dialog.vala history_dialog.vala transaction_info_dialog.vala ../resources/manager_resources.c ../util/alpm-util.c packages_model.vala aur_model.vala manager_window.vala manager.vala
+pamac-manager: libpamac.so choose_dep_dialog.vala history_dialog.vala transaction_info_dialog.vala ../resources/manager_resources.c manager_window.vala manager.vala
 	valac 	-o pamac-manager \
 			$(COMMON_VALA_FLAGS) \
-			-X -I. \
-			-X -L. \
-			-X -lpamac \
-			--pkg=pamac \
+			$(PAMAC_LIB_FLAGS) \
 			--pkg=json-glib-1.0 \
 			--pkg=gtk+-3.0 \
 			--pkg=gdk-3.0 \
 			--gresources=$(MANAGER_GRESOURCE_FILE) \
 			../resources/manager_resources.c \
-			../util/alpm-util.c \
 			choose_dep_dialog.vala \
 			history_dialog.vala \
-			packages_model.vala \
-			aur_model.vala \
 			manager_window.vala \
 			manager.vala
 
 pamac-updater: libpamac.so ../resources/updater_resources.c updater_window.vala updater.vala
 	valac 	-o pamac-updater \
 			$(COMMON_VALA_FLAGS) \
-			-X -I. \
-			-X -L. \
-			-X -lpamac \
-			--pkg=pamac \
+			$(PAMAC_LIB_FLAGS) \
 			--pkg=json-glib-1.0 \
 			--pkg=gtk+-3.0 \
 			--pkg=gdk-3.0 \
@@ -129,10 +123,7 @@ pamac-updater: libpamac.so ../resources/updater_resources.c updater_window.vala
 pamac-install: libpamac.so installer.vala
 	valac 	-o pamac-install \
 			$(COMMON_VALA_FLAGS) \
-			-X -I. \
-			-X -L. \
-			-X -lpamac \
-			--pkg=pamac \
+			$(PAMAC_LIB_FLAGS) \
 			--pkg=json-glib-1.0 \
 			--pkg=gtk+-3.0 \
 			installer.vala
diff --git a/src/alpm_config.vala b/src/alpm_config.vala
index e50bb64edd1567eb6f6911d3708c56d67cdf4f59..a3128d9e33072bc32d76a846a07cc41a30a0e535 100644
--- a/src/alpm_config.vala
+++ b/src/alpm_config.vala
@@ -1,5 +1,5 @@
 /*
- *  pamac-vala
+ *  alpm_config
  *
  *  Copyright (C) 2014-2016 Guillaume Benoit <guillaume@manjaro.org>
  *
@@ -18,7 +18,7 @@
  */
 
 [Compact]
-public class AlpmRepo {
+class AlpmRepo {
 	public string name;
 	public Alpm.Signature.Level siglevel;
 	public Alpm.Signature.Level siglevel_mask;
@@ -42,68 +42,55 @@ public class AlpmRepo {
 
 }
 
-[Compact]
-public class AlpmConfig {
-	public string conf_path;
-	public string? rootdir;
-	public string? dbpath;
-	public string? logfile;
-	public string? gpgdir;
-	public string? arch;
-	public double deltaratio;
-	public int usesyslog;
-	public int checkspace;
-	public Alpm.List<string?>? cachedirs;
-	public Alpm.List<string?>? hookdirs;
-	public Alpm.List<string?>? ignoregroups;
-	public Alpm.List<string?>? ignorepkgs;
-	public Alpm.List<string?>? noextracts;
-	public Alpm.List<string?>? noupgrades;
-	public GLib.List<string>? holdpkgs;
-	public GLib.List<string>? syncfirsts;
-	public Alpm.Signature.Level siglevel;
-	public Alpm.Signature.Level localfilesiglevel;
-	public Alpm.Signature.Level remotefilesiglevel;
-	public Alpm.Signature.Level siglevel_mask;
-	public Alpm.Signature.Level localfilesiglevel_mask;
-	public Alpm.Signature.Level remotefilesiglevel_mask;
-	public GLib.List<AlpmRepo> repo_order;
-	public Alpm.Handle? handle;
+class AlpmConfig {
+	string conf_path;
+	string? rootdir;
+	string? dbpath;
+	string? logfile;
+	string? gpgdir;
+	string? arch;
+	double deltaratio;
+	int usesyslog;
+	int checkspace;
+	GLib.List<string> cachedirs;
+	GLib.List<string> hookdirs;
+	GLib.List<string> ignoregroups;
+	GLib.List<string> ignorepkgs;
+	GLib.List<string> noextracts;
+	GLib.List<string> noupgrades;
+	GLib.List<string> holdpkgs;
+	GLib.List<string> syncfirsts;
+	Alpm.Signature.Level siglevel;
+	Alpm.Signature.Level localfilesiglevel;
+	Alpm.Signature.Level remotefilesiglevel;
+	Alpm.Signature.Level siglevel_mask;
+	Alpm.Signature.Level localfilesiglevel_mask;
+	Alpm.Signature.Level remotefilesiglevel_mask;
+	GLib.List<AlpmRepo> repo_order;
 
 	public AlpmConfig (string path) {
 		conf_path = path;
 		reload ();
 	}
 
+	public unowned GLib.List<string> get_holdpkgs () {
+		return holdpkgs;
+	}
+
+	public unowned GLib.List<string> get_syncfirsts () {
+		return syncfirsts;
+	}
+
 	public void reload () {
 		// set default options
+		cachedirs = new GLib.List<string> ();
+		hookdirs = new GLib.List<string> ();
+		ignoregroups = new GLib.List<string> ();
+		ignorepkgs = new GLib.List<string> ();
+		noextracts = new GLib.List<string> ();
+		noupgrades = new GLib.List<string> ();
 		holdpkgs = new GLib.List<string> ();
 		syncfirsts = new GLib.List<string> ();
-		// free internal data of alpm lists
-		if (cachedirs != null) {
-			cachedirs.free_data ();
-			cachedirs = new Alpm.List<string> ();
-		}
-		if (hookdirs != null) {
-			hookdirs.free_data ();
-			hookdirs = new Alpm.List<string?> ();
-		}
-		if (ignoregroups != null) {
-			ignoregroups.free_data ();
-			ignoregroups = new Alpm.List<string> ();
-		}
-		if (ignorepkgs != null) {
-			ignorepkgs.free_data ();
-			ignorepkgs = new Alpm.List<string> ();
-		}
-		if (noextracts != null) {
-			noextracts.free_data ();
-			noextracts = new Alpm.List<string> ();
-		}
-		if (noupgrades != null) {
-			noupgrades.free_data ();
-			noupgrades = new Alpm.List<string> ();
-		}
 		usesyslog = 0;
 		checkspace = 0;
 		deltaratio = 0.7;
@@ -131,11 +118,11 @@ public class AlpmConfig {
 				logfile = "/var/log/pacman.log";
 			}
 		}
-		if (cachedirs.length == 0) {
-			cachedirs.add ("/var/cache/pacman/pkg/");
+		if (cachedirs.length () == 0) {
+			cachedirs.append ("/var/cache/pacman/pkg/");
 		}
-		if (hookdirs.length == 0) {
-			hookdirs.add ("/etc/pacman.d/hooks/");
+		if (hookdirs.length () == 0) {
+			hookdirs.append ("/etc/pacman.d/hooks/");
 		}
 		if (gpgdir == null) {
 			// gpgdir it is not relative to rootdir, even if
@@ -147,12 +134,12 @@ public class AlpmConfig {
 		}
 	}
 
-	public void set_handle () {
+	public Alpm.Handle? get_handle () {
 		Alpm.Errno error;
-		handle = Alpm.Handle.new (rootdir, dbpath, out error);
+		Alpm.Handle? handle = new Alpm.Handle (rootdir, dbpath, out error);
 		if (handle == null) {
-			stderr.printf ("Failed to initialize alpm library" + " (%s)\n".printf(Alpm.strerror (error)));
-			return;
+			stderr.printf ("Failed to initialize alpm library" + " (%s)\n".printf (Alpm.strerror (error)));
+			return null;
 		}
 		// define options
 		handle.logfile = logfile;
@@ -166,15 +153,24 @@ public class AlpmConfig {
 		remotefilesiglevel = merge_siglevel (siglevel, remotefilesiglevel, remotefilesiglevel_mask);
 		handle.localfilesiglevel = localfilesiglevel;
 		handle.remotefilesiglevel = remotefilesiglevel;
-		handle.cachedirs = cachedirs;
-		// add hook directories 1-by-1 to avoid overwriting the system directory
+		foreach (unowned string cachedir in cachedirs) {
+			handle.add_cachedir (cachedir);
+		}
 		foreach (unowned string hookdir in hookdirs) {
 			handle.add_hookdir (hookdir);
 		}
-		handle.ignoregroups = ignoregroups;
-		handle.ignorepkgs = ignorepkgs;
-		handle.noextracts = noextracts;
-		handle.noupgrades = noupgrades;
+		foreach (unowned string ignoregroup in ignoregroups) {
+			handle.add_ignoregroup (ignoregroup);
+		}
+		foreach (unowned string ignorepkg in ignorepkgs) {
+			handle.add_ignorepkg (ignorepkg);
+		}
+		foreach (unowned string noextract in noextracts) {
+			handle.add_noextract (noextract);
+		}
+		foreach (unowned string noupgrade in noupgrades) {
+			handle.add_noupgrade (noupgrade);
+		}
 		// register dbs
 		foreach (unowned AlpmRepo repo in repo_order) {
 			repo.siglevel = merge_siglevel (siglevel, repo.siglevel, repo.siglevel_mask);
@@ -188,9 +184,10 @@ public class AlpmConfig {
 				db.usage = repo.usage;
 			}
 		}
+		return handle;
 	}
 
-	public void parse_file (string path, string? section = null) {
+	void parse_file (string path, string? section = null) {
 		string? current_section = section;
 		var file = GLib.File.new_for_path (path);
 		if (file.query_exists ()) {
@@ -236,11 +233,11 @@ public class AlpmConfig {
 							dbpath = val;
 						} else if (key == "CacheDir") {
 							foreach (unowned string dir in val.split (" ")) {
-								cachedirs.add (dir);
+								cachedirs.append (dir);
 							}
 						} else if (key == "HookDir") {
 							foreach (unowned string dir in val.split (" ")) {
-								hookdirs.add (dir);
+								hookdirs.append (dir);
 							}
 						} else if (key == "LogFile") {
 							logfile = val;
@@ -276,19 +273,19 @@ public class AlpmConfig {
 							}
 						} else if (key == "IgnoreGroup") {
 							foreach (unowned string name in val.split (" ")) {
-								ignoregroups.add (name);
+								ignoregroups.append (name);
 							}
 						} else if (key == "IgnorePkg") {
 							foreach (unowned string name in val.split (" ")) {
-								ignorepkgs.add (name);
+								ignorepkgs.append (name);
 							}
 						} else if (key == "Noextract") {
 							foreach (unowned string name in val.split (" ")) {
-								noextracts.add (name);
+								noextracts.append (name);
 							}
 						} else if (key == "NoUpgrade") {
 							foreach (unowned string name in val.split (" ")) {
-								noupgrades.add (name);
+								noupgrades.append (name);
 							}
 						}
 					} else {
@@ -364,6 +361,7 @@ public class AlpmConfig {
 					// writing a short string to the stream
 					dos.put_string (new_line);
 				}
+				reload ();
 			} catch (GLib.Error e) {
 				GLib.stderr.printf("%s\n", e.message);
 			}
@@ -372,7 +370,7 @@ public class AlpmConfig {
 		}
 	}
 
-	public Alpm.DB.Usage define_usage (string conf_string) {
+	Alpm.DB.Usage define_usage (string conf_string) {
 		Alpm.DB.Usage usage = 0;
 		foreach (unowned string directive in conf_string.split(" ")) {
 			if (directive == "Sync") {
@@ -390,7 +388,7 @@ public class AlpmConfig {
 		return usage;
 	}
 
-	public void process_siglevel (string conf_string, ref Alpm.Signature.Level siglevel, ref Alpm.Signature.Level siglevel_mask) {
+	void process_siglevel (string conf_string, ref Alpm.Signature.Level siglevel, ref Alpm.Signature.Level siglevel_mask) {
 		foreach (unowned string directive in conf_string.split(" ")) {
 			bool affect_package = false;
 			bool affect_database = false;
@@ -458,7 +456,7 @@ public class AlpmConfig {
 		siglevel &= ~Alpm.Signature.Level.USE_DEFAULT;
 	}
 
-	public Alpm.Signature.Level merge_siglevel(Alpm.Signature.Level sigbase, Alpm.Signature.Level sigover, Alpm.Signature.Level sigmask) {
+	Alpm.Signature.Level merge_siglevel(Alpm.Signature.Level sigbase, Alpm.Signature.Level sigover, Alpm.Signature.Level sigmask) {
 		return (sigmask != 0) ? (sigover & sigmask) | (sigbase & ~sigmask) : sigover;
 	}
 }
diff --git a/src/aur.vala b/src/aur.vala
index 19d2703e4f7fdac72902d2fabefd7d96ca13d6b9..c7b4046689ba68eda16c42b543a605fe2a9423fa 100644
--- a/src/aur.vala
+++ b/src/aur.vala
@@ -25,107 +25,66 @@ namespace AUR {
 	const string rpc_multiinfo = "&type=info";
 	const string rpc_multiinfo_arg = "&arg[]=";
 
-	public Json.Array search (string[] needles) {
-		var prev_inter = new Json.Array ();
-		string uri = rpc_url + rpc_search + Uri.escape_string (needles[0]);
+	Json.Array rpc_query (string uri) {
+		var results = new Json.Array ();
 		var session = new Soup.Session ();
+		// set a 15 seconds timeout because it is also the dbus daemon timeout
+		session.timeout = 15;
 		var message = new Soup.Message ("GET", uri);
 		var parser = new Json.Parser ();
 		session.send_message (message);
 		try {
 			parser.load_from_data ((string) message.response_body.flatten ().data, -1);
 		} catch (Error e) {
-			print (e.message);
+			critical (e.message);
 		}
 		unowned Json.Node? root = parser.get_root ();
 		if (root != null) {
 			if (root.get_object ().get_string_member ("type") == "error") {
-				stderr.printf ("Failed to search %s from AUR\n", needles[0]);
+				critical ("Failed to query %s from AUR", uri);
 			} else {
-				prev_inter = root.get_object ().get_array_member ("results");
+				results = root.get_object ().get_array_member ("results");
 			}
 		}
-		int needles_length = needles.length;
-		if (needles_length == 1) {
-			return prev_inter;
-		}
-		int i = 1;
-		var inter = new Json.Array ();
-		var found = new Json.Array ();
-		while (i < needles_length) {
-			inter = new Json.Array ();
-			uri = rpc_url + rpc_search + Uri.escape_string (needles[i]);
-			message = new Soup.Message ("GET", uri);
-			session.send_message (message);
-			try {
-				parser.load_from_data ((string) message.response_body.flatten ().data, -1);
-			} catch (Error e) {
-				print (e.message);
-			}
-			root = parser.get_root ();
-			if (root != null) {
-				if (root.get_object ().get_string_member ("type") == "error") {
-					stderr.printf ("Failed to search %s from AUR\n", needles[i]);
-				} else {
-					found = root.get_object ().get_array_member ("results");
-					uint j = 0;
-					uint k;
-					uint found_length = found.get_length ();
-					while (j < found_length) {
-						unowned Json.Node found_node = found.get_element (j);
-						k = 0;
-						uint prev_inter_length = prev_inter.get_length ();
-						while (k < prev_inter_length) {
-							unowned Json.Node prev_inter_node = prev_inter.get_element (k);
-							if (strcmp (found_node.get_object ().get_string_member ("Name"),
-										prev_inter_node.get_object ().get_string_member ("Name")) == 0) {
-								inter.add_element (prev_inter_node);
-								prev_inter.remove_element (k);
-								break;
-							}
-							k++;
+		return results;
+	}
+
+	public async Json.Array search (string[] needles) {
+		if (needles.length == 0) {
+			return new Json.Array ();
+		} else if (needles.length == 1) {
+			return rpc_query (rpc_url + rpc_search + Uri.escape_string (needles[0]));
+		} else {
+			var inter = new Json.Array ();
+			var prev_inter = new Json.Array ();
+			foreach (unowned string needle in needles) {
+				inter = new Json.Array ();
+				var found = rpc_query (rpc_url + rpc_search + Uri.escape_string (needle));
+				prev_inter.foreach_element ((prev_inter_array, prev_inter_index, prev_inter_node) => {
+					found.foreach_element ((found_array, found_index, found_node) => {
+						if (strcmp (prev_inter_node.get_object ().get_string_member ("Name"),
+									found_node.get_object ().get_string_member ("Name")) == 0) {
+							inter.add_element (prev_inter_node);
 						}
-						j++;
-					}
-				}
+					});
+				});
+				prev_inter = (owned) inter;
 			}
-			if (i != (needles_length -1)) {
-				prev_inter = inter;
-			}
-			i++;
+			return inter;
 		}
-		return inter;
 	}
 
-	public Json.Array multiinfo (string[] pkgnames) {
-		Json.Array results = new Json.Array ();
+	public async Json.Array multiinfo (string[] pkgnames) {
 		if (pkgnames.length == 0) {
-			return results;
+			return new Json.Array ();
 		}
 		var builder = new StringBuilder ();
 		builder.append (rpc_url);
 		builder.append (rpc_multiinfo);
-		foreach (string pkgname in pkgnames) {
+		foreach (unowned string pkgname in pkgnames) {
 			builder.append (rpc_multiinfo_arg);
 			builder.append (Uri.escape_string (pkgname));
 		}
-		var session = new Soup.Session ();
-		var message = new Soup.Message ("GET", builder.str);
-		session.send_message (message);
-		var parser = new Json.Parser ();
-		try {
-			parser.load_from_data ((string) message.response_body.flatten ().data, -1);
-		} catch (Error e) {
-			print (e.message);
-		}
-		unowned Json.Node? root = parser.get_root ();
-		if (root != null) {
-			if (root.get_object ().get_string_member ("type") == "error") {
-				stderr.printf ("Failed to multiinfo %s from AUR\n", builder.str);
-			} else {
-				results = root.get_object ().get_array_member ("results");
-			}
-		}
-		return results;
+		return rpc_query (builder.str);
 	}
 }
diff --git a/src/choose_dep_dialog.vala b/src/choose_dep_dialog.vala
index 40e503e4d023482b98739048283ffa4c35447ab2..5d5e77672ac820cc3cfa7fa02169307fd99e10ff 100644
--- a/src/choose_dep_dialog.vala
+++ b/src/choose_dep_dialog.vala
@@ -32,17 +32,17 @@ namespace Pamac {
 		public ChooseDependenciesDialog (Gtk.ApplicationWindow? window) {
 			Object (transient_for: window, use_header_bar: 0);
 
-			deps_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string));
+			deps_list = new Gtk.ListStore (2, typeof (bool), typeof (string));
 			treeview.set_model (deps_list);
 		}
 
 		[GtkCallback]
 		void on_renderertoggle_toggled (string path) {
 			Gtk.TreeIter iter;
-			GLib.Value selected;
+			bool selected;
 			if (deps_list.get_iter_from_string (out iter, path)) {;
-				deps_list.get_value (iter, 0, out selected);
-				deps_list.set_value (iter, 0, !((bool) selected));
+				deps_list.get (iter, 0, out selected);
+				deps_list.set (iter, 0, !selected);
 			}
 		}
 	}
diff --git a/src/common.vala b/src/common.vala
index 0cfdb767f7bc735f2621ca3892e5ed187d5d6ca3..3dc81ce62ed8d15297f17123b91ddd090a991598 100644
--- a/src/common.vala
+++ b/src/common.vala
@@ -18,17 +18,26 @@
  */
 
 namespace Pamac {
-	public struct PackageInfos {
+	public struct UpdateInfos {
 		public string name;
-		public string version;
-		public string db_name;
+		public string old_version;
+		public string new_version;
+		public string repo;
 		public uint64 download_size;
 	}
 
+	public struct TransactionSummary {
+		public UpdateInfos[] to_install;
+		public UpdateInfos[] to_upgrade;
+		public UpdateInfos[] to_downgrade;
+		public UpdateInfos[] to_reinstall;
+		public UpdateInfos[] to_remove;
+	}
+
 	public struct Updates {
 		public bool is_syncfirst;
-		public PackageInfos[] repos_updates;
-		public PackageInfos[] aur_updates;
+		public UpdateInfos[] repos_updates;
+		public UpdateInfos[] aur_updates;
 	}
 
 	public struct ErrorInfos {
diff --git a/src/daemon.vala b/src/daemon.vala
index 65fd953270e19a0ee38bc2fe2f8b4a42991b1314..7fcaa8d1a82c61a614443a4ab5e23a0922edf2fb 100644
--- a/src/daemon.vala
+++ b/src/daemon.vala
@@ -36,10 +36,15 @@ public class AlpmAction {
 	}
 }
 
+private int alpm_pkg_compare_name (Alpm.Package pkg_a, Alpm.Package pkg_b) {
+	return strcmp (pkg_a.name, pkg_b.name);
+}
+
 namespace Pamac {
 	[DBus (name = "org.manjaro.pamac")]
 	public class Daemon: Object {
 		private AlpmConfig alpm_config;
+		private Alpm.Handle? alpm_handle;
 		public Cond provider_cond;
 		public Mutex provider_mutex;
 		public int? choosen_provider;
@@ -47,6 +52,8 @@ namespace Pamac {
 		private ThreadPool<AlpmAction> thread_pool;
 		private Mutex databases_lock_mutex;
 		private Json.Array aur_updates_results;
+		private HashTable<string, Json.Array> aur_search_results;
+		private HashTable<string, Json.Object> aur_infos;
 		private bool intern_lock;
 		private bool extern_lock;
 		private GLib.File lockfile;
@@ -54,6 +61,7 @@ namespace Pamac {
 		public Timer timer;
 		public Cancellable cancellable;
 		public Curl.Easy curl;
+		private GLib.List<string> aur_dep_list;
 
 		public signal void emit_event (uint primary_event, uint secondary_event, string[] details);
 		public signal void emit_providers (string depend, string[] providers);
@@ -79,6 +87,8 @@ namespace Pamac {
 			alpm_config = new AlpmConfig ("/etc/pacman.conf");
 			databases_lock_mutex = Mutex ();
 			aur_updates_results = new Json.Array ();
+			aur_search_results = new HashTable<string, Json.Array> (str_hash, str_equal);
+			aur_infos = new HashTable<string, Json.Object> (str_hash, str_equal);
 			timer = new Timer ();
 			intern_lock = false;
 			extern_lock = false;
@@ -131,20 +141,20 @@ namespace Pamac {
 		}
 
 		private void refresh_handle () {
-			alpm_config.set_handle ();
-			if (alpm_config.handle == null) {
+			alpm_handle = alpm_config.get_handle ();
+			if (alpm_handle == null) {
 				current_error = ErrorInfos () {
 					message = _("Failed to initialize alpm library")
 				};
 				trans_commit_finished (false);
 			} else {
-				alpm_config.handle.eventcb = (Alpm.EventCallBack) cb_event;
-				alpm_config.handle.progresscb = (Alpm.ProgressCallBack) cb_progress;
-				alpm_config.handle.questioncb = (Alpm.QuestionCallBack) cb_question;
-				alpm_config.handle.fetchcb = (Alpm.FetchCallBack) cb_fetch;
-				alpm_config.handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload;
-				alpm_config.handle.logcb = (Alpm.LogCallBack) cb_log;
-				lockfile = GLib.File.new_for_path (alpm_config.handle.lockfile);
+				alpm_handle.eventcb = (Alpm.EventCallBack) cb_event;
+				alpm_handle.progresscb = (Alpm.ProgressCallBack) cb_progress;
+				alpm_handle.questioncb = (Alpm.QuestionCallBack) cb_question;
+				alpm_handle.fetchcb = (Alpm.FetchCallBack) cb_fetch;
+				alpm_handle.totaldlcb = (Alpm.TotalDownloadCallBack) cb_totaldownload;
+				alpm_handle.logcb = (Alpm.LogCallBack) cb_log;
+				lockfile = GLib.File.new_for_path (alpm_handle.lockfile);
 			}
 		}
 
@@ -201,8 +211,8 @@ namespace Pamac {
 		}
 
 		public void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf, GLib.BusName sender) {
-			var pamac_config = new Pamac.Config ("/etc/pamac.conf");
 			check_authorization.begin (sender, (obj, res) => {
+				var pamac_config = new Pamac.Config ("/etc/pamac.conf");
 				bool authorized = check_authorization.end (res);
 				if (authorized ) {
 					pamac_config.write (new_pamac_conf);
@@ -222,7 +232,7 @@ namespace Pamac {
 					alpm_config.reload ();
 					refresh_handle ();
 				}
-				write_alpm_config_finished ((alpm_config.checkspace == 1));
+				write_alpm_config_finished ((alpm_handle.checkspace == 1));
 			});
 		}
 
@@ -271,7 +281,6 @@ namespace Pamac {
 				ChildWatch.add (child_pid, (pid, status) => {
 					// Triggered when the child indicated by child_pid exits
 					Process.close_pid (pid);
-					alpm_config.reload ();
 					refresh_handle ();
 					generate_mirrors_list_finished ();
 				});
@@ -297,7 +306,7 @@ namespace Pamac {
 			check_authorization.begin (sender, (obj, res) => {
 				bool authorized = check_authorization.end (res);
 				if (authorized) {
-					unowned Alpm.Package? pkg = alpm_config.handle.localdb.get_pkg (pkgname);
+					unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
 					if (pkg != null) {
 						pkg.reason = (Alpm.Package.Reason) reason;
 						refresh_handle ();
@@ -307,31 +316,15 @@ namespace Pamac {
 			});
 		}
 
-		public PackageInfos get_installed_pkg (string pkgname) {
-			unowned Alpm.Package? pkg = alpm_config.handle.localdb.get_pkg (pkgname);
-			if (pkg == null) {
-				return PackageInfos () {
-					name = "",
-					version = "",
-					db_name = "",
-					download_size = 0
-				};
-			}
-			return PackageInfos () {
-				name = pkg.name,
-				version = pkg.version,
-				db_name = pkg.db.name,
-				download_size = pkg.download_size
-			};
-		}
-
 		private void refresh () {
 			intern_lock = true;
 			current_error = ErrorInfos ();
 			int force = (force_refresh) ? 1 : 0;
 			uint success = 0;
 			cancellable.reset ();
-			foreach (var db in alpm_config.handle.syncdbs) {
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
 				if (cancellable.is_cancelled ()) {
 					refresh_handle ();
 					refresh_finished (false);
@@ -341,12 +334,13 @@ namespace Pamac {
 				if (db.update (force) >= 0) {
 					success++;
 				}
+				syncdbs.next ();
 			}
 			refresh_handle ();
 			// We should always succeed if at least one DB was upgraded - we may possibly
 			// fail later with unresolved deps, but that should be rare, and would be expected
 			if (success == 0) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to synchronize any databases");
 				current_error.details = { Alpm.strerror (errno) };
@@ -366,27 +360,767 @@ namespace Pamac {
 			}
 		}
 
+		public bool get_checkspace () {
+			return alpm_handle.checkspace == 1 ? true : false;
+		}
+
+		public string get_lockfile () {
+			return alpm_handle.lockfile;
+		}
+
+		public string[] get_ignorepkgs () {
+			string[] result = {};
+			unowned Alpm.List<unowned string> ignorepkgs = alpm_handle.ignorepkgs;
+			while (ignorepkgs != null) {
+				unowned string ignorepkg = ignorepkgs.data;
+				result += ignorepkg;
+				ignorepkgs.next ();
+			}
+			return result;
+		}
+
 		public void add_ignorepkg (string pkgname) {
-			alpm_config.handle.add_ignorepkg (pkgname);
+			alpm_handle.add_ignorepkg (pkgname);
 		}
 
 		public void remove_ignorepkg (string pkgname) {
-			alpm_config.handle.remove_ignorepkg (pkgname);
+			alpm_handle.remove_ignorepkg (pkgname);
+		}
+
+		public bool should_hold (string pkgname) {
+			if (alpm_config.get_holdpkgs ().find_custom (pkgname, strcmp) != null) {
+				return true;
+			}
+			return false;
+		}
+
+		public uint get_pkg_reason (string pkgname) {
+			unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
+			if (pkg != null) {
+				return pkg.reason;
+			}
+			return 0;
+		}
+
+		public uint get_pkg_origin (string pkgname) {
+			unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
+			if (pkg != null) {
+				return pkg.origin;
+			} else {
+				pkg = get_syncpkg (pkgname);
+				if (pkg != null) {
+					return pkg.origin;
+				}
+			}
+			return 0;
+		}
+
+		private AlpmPackage initialise_pkg_struct (Alpm.Package? alpm_pkg) {
+			if (alpm_pkg != null) {
+				string repo_name = "";
+				if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
+					unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
+					if (sync_pkg != null) {
+						repo_name = sync_pkg.db.name;
+					}
+				} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
+					repo_name = alpm_pkg.db.name;
+				}
+				return AlpmPackage () {
+					name = alpm_pkg.name,
+					version = alpm_pkg.version,
+					// desc can be null
+					desc = alpm_pkg.desc != null ? Markup.escape_text (alpm_pkg.desc) : "",
+					repo = (owned) repo_name,
+					size = alpm_pkg.isize,
+					origin = (uint) alpm_pkg.origin
+				};
+			} else {
+				return AlpmPackage () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = ""
+				};
+			}
+		}
+
+		public async AlpmPackage[] get_installed_pkgs () {
+			AlpmPackage[] pkgs = {};
+			unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
+			while (pkgcache != null) {
+				unowned Alpm.Package alpm_pkg = pkgcache.data;
+				pkgs += initialise_pkg_struct (alpm_pkg);
+				pkgcache.next ();
+			}
+			return pkgs;
+		}
+
+		public async AlpmPackage[] get_foreign_pkgs () {
+			AlpmPackage[] pkgs = {};
+			unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
+			while (pkgcache != null) {
+				unowned Alpm.Package alpm_pkg = pkgcache.data;
+				bool sync_found = false;
+				unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+				while (syncdbs != null) {
+					unowned Alpm.DB db = syncdbs.data;
+					unowned Alpm.Package? sync_pkg = db.get_pkg (alpm_pkg.name);
+					if (sync_pkg != null) {
+						sync_found = true;
+						break;
+					}
+					syncdbs.next ();
+				}
+				if (sync_found == false) {
+					pkgs += initialise_pkg_struct (alpm_pkg);
+				}
+				pkgcache.next ();
+			}
+			return pkgs;
+		}
+
+		public async AlpmPackage[] get_orphans () {
+			AlpmPackage[] pkgs = {};
+			unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
+			while (pkgcache != null) {
+				unowned Alpm.Package alpm_pkg = pkgcache.data;
+				if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) {
+					Alpm.List<string> requiredby = alpm_pkg.compute_requiredby ();
+					if (requiredby.length == 0) {
+						Alpm.List<string> optionalfor = alpm_pkg.compute_optionalfor ();
+						if (optionalfor.length == 0) {
+							pkgs += initialise_pkg_struct (alpm_pkg);
+						} else {
+							optionalfor.free_inner (GLib.free);
+						}
+					} else {
+						requiredby.free_inner (GLib.free);
+					}
+				}
+				pkgcache.next ();
+			}
+			return pkgs;
+		}
+
+		public AlpmPackage get_installed_pkg (string pkgname) {
+			return initialise_pkg_struct (alpm_handle.localdb.get_pkg (pkgname));
+		}
+
+		public AlpmPackage find_installed_satisfier (string depstring) {
+			return initialise_pkg_struct (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring));
+		}
+
+		private unowned Alpm.Package? get_syncpkg (string name) {
+			unowned Alpm.Package? pkg = null;
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				pkg = db.get_pkg (name);
+				if (pkg != null) {
+					break;
+				}
+				syncdbs.next ();
+			}
+			return pkg;
+		}
+
+		public AlpmPackage get_sync_pkg (string pkgname) {
+			return initialise_pkg_struct (get_syncpkg (pkgname));
+		}
+
+		public AlpmPackage find_sync_satisfier (string depstring) {
+			return initialise_pkg_struct (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring));
+		}
+
+		private Alpm.List<unowned Alpm.Package> search_all_dbs (string search_string) {
+			Alpm.List<unowned string> needles = null;
+			string[] splitted = search_string.split (" ");
+			foreach (unowned string part in splitted) {
+				needles.add (part);
+			}
+			Alpm.List<unowned Alpm.Package> result = alpm_handle.localdb.search (needles);
+			Alpm.List<unowned Alpm.Package> syncpkgs = null;
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				if (syncpkgs.length == 0) {
+					syncpkgs = db.search (needles);
+				} else {
+					syncpkgs.join (db.search (needles).diff (syncpkgs, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
+				}
+				syncdbs.next ();
+			}
+			result.join (syncpkgs.diff (result, (Alpm.List.CompareFunc) alpm_pkg_compare_name));
+			//result.sort ((Alpm.List.CompareFunc) alpm_pkg_compare_name);
+			return result;
+		}
+
+		public async AlpmPackage[] search_pkgs (string search_string) {
+			AlpmPackage[] result = {};
+			Alpm.List<unowned Alpm.Package> alpm_pkgs = search_all_dbs (search_string);
+			unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs;
+			while (list != null) {
+				unowned Alpm.Package alpm_pkg = list.data;
+				result += initialise_pkg_struct (alpm_pkg);
+				list.next ();
+			}
+			return result;
+		}
+
+		AURPackage initialise_aur_struct (Json.Object json_object) {
+			return AURPackage () {
+				name = json_object.get_string_member ("Name"),
+				version = json_object.get_string_member ("Version"),
+				// desc can be null
+				desc = json_object.get_null_member ("Description") ? "" : Markup.escape_text (json_object.get_string_member ("Description")),
+				popularity = json_object.get_double_member ("Popularity")
+			};
+		}
+
+		public async AURPackage[] search_in_aur (string search_string) {
+			if (!aur_search_results.contains (search_string)) {
+				Json.Array pkgs = yield AUR.search (search_string.split (" "));
+				aur_search_results.insert (search_string, pkgs);
+			}
+			AURPackage[] result = {};
+			Json.Array aur_pkgs = aur_search_results.get (search_string);
+			aur_pkgs.foreach_element ((array, index, node) => {
+				Json.Object aur_pkg = node.get_object ();
+				// remove results which exist in repos
+				if (get_syncpkg (aur_pkg.get_string_member ("Name")) == null) {
+					result += initialise_aur_struct (node.get_object ());
+				}
+			});
+			return result;
+		}
+
+		public async AURPackageDetails get_aur_details (string pkgname) {
+			string name = "";
+			string version = "";
+			string desc = "";
+			double popularity = 0;
+			string packagebase = "";
+			string url = "";
+			string maintainer = "";
+			int64 firstsubmitted = 0;
+			int64 lastmodified = 0;
+			int64 outofdate = 0;
+			int64 numvotes = 0;
+			string[] licenses = {};
+			string[] depends = {};
+			string[] makedepends = {};
+			string[] checkdepends = {};
+			string[] optdepends = {};
+			string[] provides = {};
+			string[] replaces = {};
+			string[] conflicts = {};
+			var details = AURPackageDetails ();
+			if (!aur_infos.contains (pkgname)) {
+				Json.Array results = yield AUR.multiinfo ({pkgname});
+				if (results.get_length () > 0) {
+					aur_infos.insert (pkgname, results.get_object_element (0));
+				}
+			}
+			unowned Json.Object? json_object = aur_infos.lookup (pkgname);
+			if (json_object != null) {
+				// name
+				name = json_object.get_string_member ("Name");
+				// version
+				version = json_object.get_string_member ("Version");
+				// desc can be null
+				if (!json_object.get_null_member ("Description")) {
+					desc = Markup.escape_text (json_object.get_string_member ("Description"));
+				}
+				popularity = json_object.get_double_member ("Popularity");
+				// packagebase
+				packagebase = json_object.get_string_member ("PackageBase");
+				// url can be null
+				unowned Json.Node? node = json_object.get_member ("URL");
+				if (!node.is_null ()) {
+					url = Markup.escape_text (node.get_string ());
+				}
+				// maintainer can be null
+				node = json_object.get_member ("Maintainer");
+				if (!node.is_null ()) {
+					maintainer = node.get_string ();
+				}
+				// firstsubmitted
+				firstsubmitted = json_object.get_int_member ("FirstSubmitted");
+				// lastmodified
+				lastmodified = json_object.get_int_member ("LastModified");
+				// outofdate can be null
+				node = json_object.get_member ("OutOfDate");
+				if (!node.is_null ()) {
+					outofdate = node.get_int ();
+				}
+				//numvotes
+				numvotes = json_object.get_int_member ("NumVotes");
+				// licenses
+				node = json_object.get_member ("License");
+				if (!node.is_null ()) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						licenses += _node.get_string ();
+					});
+				} else {
+					licenses += _("Unknown");
+				}
+				// depends
+				node = json_object.get_member ("Depends");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						depends += _node.get_string ();
+					});
+				}
+				// optdepends
+				node = json_object.get_member ("OptDepends");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						optdepends += _node.get_string ();
+					});
+				}
+				// makedepends
+				node = json_object.get_member ("MakeDepends");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						makedepends += _node.get_string ();
+					});
+				}
+				// checkdepends
+				node = json_object.get_member ("CheckDepends");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						checkdepends += _node.get_string ();
+					});
+				}
+				// provides
+				node = json_object.get_member ("Provides");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						provides += _node.get_string ();
+					});
+				}
+				// replaces
+				node = json_object.get_member ("Replaces");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						replaces += _node.get_string ();
+					});
+				}
+				// conflicts
+				node = json_object.get_member ("Conflicts");
+				if (node != null) {
+					node.get_array ().foreach_element ((array, index, _node) => {
+						conflicts += _node.get_string ();
+					});
+				}
+			}
+			details.name = (owned) name;
+			details.version = (owned) version ;
+			details.desc = (owned) desc;
+			details.popularity = popularity;
+			details.packagebase = (owned) packagebase;
+			details.url = (owned) url;
+			details.maintainer = (owned) maintainer ;
+			details.firstsubmitted = firstsubmitted;
+			details.lastmodified = lastmodified;
+			details.outofdate = outofdate;
+			details.numvotes = numvotes;
+			details.licenses = (owned) licenses;
+			details.depends = (owned) depends;
+			details.optdepends = (owned) optdepends;
+			details.checkdepends = (owned) checkdepends;
+			details.makedepends = (owned) makedepends;
+			details.provides = (owned) provides;
+			details.replaces = (owned) replaces;
+			details.conflicts = (owned) conflicts;
+			return details;
+		}
+
+		public async string[] get_aur_build_list (string pkgname) {
+			string[] results = {};
+			aur_dep_list = new GLib.List<string> ();
+			bool success = yield set_aur_dep_list (pkgname);
+			if (success) {
+				foreach (unowned string name in aur_dep_list) {
+					results += name;
+				}
+			}
+			return results;
+		}
+
+		private async bool set_aur_dep_list (string pkgname) {
+			bool success = false;
+			Json.Array results = yield AUR.multiinfo ({pkgname});
+			Json.Object json_object = results.get_object_element (0);
+			if (json_object != null) {
+				success = true;
+				// add aur pkg to global list or move it to the end of the list;
+				unowned GLib.List<string> element = aur_dep_list.find_custom (pkgname, strcmp);
+				if (element == null) {
+					aur_dep_list.append (pkgname);
+				} else {
+					aur_dep_list.delete_link (element);
+					aur_dep_list.append (pkgname);
+				}
+				unowned Json.Node? node = json_object.get_member ("MakeDepends");
+				if (node != null) {
+					GLib.List<unowned Json.Node> list = node.get_array ().get_elements ();
+					foreach (unowned Json.Node? _node in list) {
+						unowned string depstring = _node.get_string ();
+						if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) {
+							if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) {
+								success = yield set_aur_dep_list (depstring);
+							}
+						}
+						if (!success) {
+							break;
+						}
+					}
+				}
+				if (success) {
+					node = json_object.get_member ("Depends");
+					if (node != null) {
+						GLib.List<unowned Json.Node> list = node.get_array ().get_elements ();
+						foreach (unowned Json.Node? _node in list) {
+							unowned string depstring = _node.get_string ();
+							if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) {
+								if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) {
+									success = yield set_aur_dep_list (depstring);
+								}
+							}
+							if (!success) {
+								break;
+							}
+						}
+					}
+				}
+				if (success) {
+					node = json_object.get_member ("CheckDepends");
+					if (node != null) {
+						GLib.List<unowned Json.Node> list = node.get_array ().get_elements ();
+						foreach (unowned Json.Node? _node in list) {
+							unowned string depstring = _node.get_string ();
+							if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, depstring) == null) {
+								if (alpm_handle.find_dbs_satisfier (alpm_handle.syncdbs, depstring) == null) {
+									success = yield set_aur_dep_list (depstring);
+								}
+							}
+							if (!success) {
+								break;
+							}
+						}
+					}
+				}
+			} else {
+				stdout.printf ("can't find %s in AUR\n", pkgname);
+			}
+			return success;
+		}
+
+		public string[] get_repos_names () {
+			string[] repos_names = {};
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				repos_names += db.name;
+				syncdbs.next ();
+			}
+			return repos_names;
+		}
+
+		public async AlpmPackage[] get_repo_pkgs (string repo) {
+			AlpmPackage[] pkgs = {};
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				if (db.name == repo) {
+					unowned Alpm.List<unowned Alpm.Package> pkgcache = db.pkgcache;
+					while (pkgcache != null) {
+						unowned Alpm.Package sync_pkg = pkgcache.data;
+						unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (sync_pkg.name);
+						if (local_pkg != null) {
+							pkgs += initialise_pkg_struct (local_pkg);
+						} else {
+							pkgs += initialise_pkg_struct (sync_pkg);
+						}
+						pkgcache.next ();
+					}
+					break;
+				}
+				syncdbs.next ();
+			}
+			return pkgs;
+		}
+
+		public string[] get_groups_names () {
+			string[] groups_names = {};
+			unowned Alpm.List<unowned Alpm.Group> groupcache = alpm_handle.localdb.groupcache;
+			while (groupcache != null) {
+				unowned Alpm.Group group = groupcache.data;
+				if (!(group.name in groups_names)) { 
+					groups_names += group.name;
+				}
+				groupcache.next ();
+			}
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				groupcache = db.groupcache;
+				while (groupcache != null) {
+					unowned Alpm.Group group = groupcache.data;
+					if (!(group.name in groups_names)) { 
+						groups_names += group.name;
+					}
+					groupcache.next ();
+				}
+				syncdbs.next ();
+			}
+			return groups_names;
+		}
+
+		private Alpm.List<unowned Alpm.Package> group_pkgs (string group_name) {
+			Alpm.List<unowned Alpm.Package> result = null;
+			unowned Alpm.Group? grp = alpm_handle.localdb.get_group (group_name);
+			if (grp != null) {
+				unowned Alpm.List<unowned Alpm.Package> packages = grp.packages;
+				while (packages != null) {
+					unowned Alpm.Package pkg = packages.data;
+					result.add (pkg);
+					packages.next ();
+				}
+			}
+			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+			while (syncdbs != null) {
+				unowned Alpm.DB db = syncdbs.data;
+				grp = db.get_group (group_name);
+				if (grp != null) {
+					unowned Alpm.List<unowned Alpm.Package> packages = grp.packages;
+					while (packages != null) {
+						unowned Alpm.Package pkg = packages.data;
+						if (result.find (pkg, (Alpm.List.CompareFunc) alpm_pkg_compare_name) == null) {
+							result.add (pkg);
+						}
+						packages.next ();
+					}
+				}
+				syncdbs.next ();
+			}
+			return result;
+		}
+
+		public async AlpmPackage[] get_group_pkgs (string groupname) {
+			AlpmPackage[] pkgs = {};
+			Alpm.List<unowned Alpm.Package> alpm_pkgs = group_pkgs (groupname);
+			unowned Alpm.List<unowned Alpm.Package> list = alpm_pkgs;
+			while (list != null) {
+				unowned Alpm.Package alpm_pkg = list.data;
+				pkgs += initialise_pkg_struct (alpm_pkg);
+				list.next ();
+			}
+			return pkgs;
+		}
+
+		public string[] get_pkg_uninstalled_optdeps (string pkgname) {
+			string[] optdeps = {};
+			unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
+			if (alpm_pkg == null) {
+				alpm_pkg = get_syncpkg (pkgname);
+			}
+			if (alpm_pkg != null) {
+				unowned Alpm.List<unowned Alpm.Depend> optdepends = alpm_pkg.optdepends;
+				while (optdepends != null) {
+					unowned Alpm.Depend optdep = optdepends.data;
+					if (Alpm.find_satisfier (alpm_handle.localdb.pkgcache, optdep.name) == null) {
+						optdeps += optdep.compute_string ();
+					}
+					optdepends.next ();
+				}
+			}
+			return optdeps;
+		}
+
+		public AlpmPackageDetails get_pkg_details (string pkgname) {
+			string name = "";
+			string version = "";
+			string desc = "";
+			string url = "";
+			string repo = "";
+			string has_signature = "";
+			string reason = "";
+			string packager = "";
+			string builddate = "";
+			string installdate = "";
+			string[] groups = {};
+			string[] backups = {};
+			string[] files = {};
+			string[] licenses = {};
+			string[] depends = {};
+			string[] optdepends = {};
+			string[] requiredby = {};
+			string[] optionalfor = {};
+			string[] provides = {};
+			string[] replaces = {};
+			string[] conflicts = {};
+			var details = AlpmPackageDetails ();
+			unowned Alpm.Package? alpm_pkg = alpm_handle.localdb.get_pkg (pkgname);
+			if (alpm_pkg == null) {
+				alpm_pkg = get_syncpkg (pkgname);
+			}
+			if (alpm_pkg != null) {
+				// name
+				name = alpm_pkg.name;
+				// version
+				version = alpm_pkg.version;
+				// desc can be null
+				if (alpm_pkg.desc != null) {
+					desc = Markup.escape_text (alpm_pkg.desc);
+				}
+				// url can be null
+				if (alpm_pkg.url != null) {
+					url = Markup.escape_text (alpm_pkg.url);
+				}
+				// packager can be null
+				packager = alpm_pkg.packager ?? "";
+				// groups
+				unowned Alpm.List list = alpm_pkg.groups;
+				while (list != null) {
+					groups += ((Alpm.List<unowned string>) list).data;
+					list.next ();
+				}
+				// licenses
+				list = alpm_pkg.licenses;
+				while (list != null) {
+					licenses += ((Alpm.List<unowned string>) list).data;
+					list.next ();
+				}
+				// build_date
+				GLib.Time time = GLib.Time.local ((time_t) alpm_pkg.builddate);
+				builddate = time.format ("%a %d %b %Y %X %Z");
+				// local pkg
+				if (alpm_pkg.origin == Alpm.Package.From.LOCALDB) {
+					// repo
+					unowned Alpm.Package? sync_pkg = get_syncpkg (alpm_pkg.name);
+					if (sync_pkg != null) {
+						repo = sync_pkg.db.name;
+					}
+					// reason
+					if (alpm_pkg.reason == Alpm.Package.Reason.EXPLICIT) {
+						reason = _("Explicitly installed");
+					} else if (alpm_pkg.reason == Alpm.Package.Reason.DEPEND) {
+						reason = _("Installed as a dependency for another package");
+					} else {
+						reason = _("Unknown");
+					}
+					// install_date
+					time = GLib.Time.local ((time_t) alpm_pkg.installdate);
+					installdate = time.format ("%a %d %b %Y %X %Z");
+					// backups
+					list = alpm_pkg.backups;
+					while (list != null) {
+						backups += "/" + ((Alpm.List<unowned Alpm.Backup>) list).data.name;
+						list.next ();
+					}
+					// requiredby
+					Alpm.List<string> pkg_requiredby = alpm_pkg.compute_requiredby ();
+					list = pkg_requiredby;
+					while (list != null) {
+						requiredby += ((Alpm.List<unowned string>) list).data;
+						list.next ();
+					}
+					pkg_requiredby.free_inner (GLib.free);
+					// optionalfor
+					Alpm.List<string> pkg_optionalfor = alpm_pkg.compute_optionalfor ();
+					list = pkg_optionalfor;
+					while (list != null) {
+						optionalfor += ((Alpm.List<unowned string>) list).data;
+						list.next ();
+					}
+					pkg_optionalfor.free_inner (GLib.free);
+					// files
+					unowned Alpm.FileList filelist = alpm_pkg.files;
+					Alpm.File* file_ptr = filelist.files;
+					for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
+						if (!file_ptr->name.has_suffix ("/")) {
+							files += "/" + file_ptr->name;
+						}
+					}
+				// sync pkg
+				} else if (alpm_pkg.origin == Alpm.Package.From.SYNCDB) {
+					// repos
+					repo = alpm_pkg.db.name;
+					// signature
+					has_signature = alpm_pkg.base64_sig != null ? _("Yes") : _("No");
+				}
+				// depends
+				list = alpm_pkg.depends;
+				while (list != null) {
+					depends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
+					list.next ();
+				}
+				// optdepends
+				list = alpm_pkg.optdepends;
+				while (list != null) {
+					optdepends += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
+					list.next ();
+				}
+				// provides
+				list = alpm_pkg.provides;
+				while (list != null) {
+					provides += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
+					list.next ();
+				}
+				// replaces
+				list = alpm_pkg.replaces;
+				while (list != null) {
+					replaces += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
+					list.next ();
+				}
+				// conflicts
+				list = alpm_pkg.conflicts;
+				while (list != null) {
+					conflicts += ((Alpm.List<unowned Alpm.Depend>) list).data.compute_string ();
+					list.next ();
+				}
+			}
+			details.name = (owned) name;
+			details.version = (owned) version;
+			details.desc = (owned) desc;
+			details.repo = (owned) repo;
+			details.url = (owned) url;
+			details.packager = (owned) packager;
+			details.builddate = (owned) builddate;
+			details.installdate = (owned) installdate;
+			details.reason = (owned) reason;
+			details.has_signature = (owned) has_signature;
+			details.licenses = (owned) licenses;
+			details.depends = (owned) depends;
+			details.optdepends = (owned) optdepends;
+			details.requiredby = (owned) requiredby;
+			details.optionalfor = (owned) optionalfor;
+			details.provides = (owned) provides;
+			details.replaces = (owned) replaces;
+			details.conflicts = (owned) conflicts;
+			details.groups = (owned) groups;
+			details.backups = (owned) backups;
+			details.files = (owned) files;
+			return details;
 		}
 
 		public void start_get_updates (bool check_aur_updates) {
-			PackageInfos[] updates_infos = {};
+			UpdateInfos[] updates_infos = {};
 			unowned Alpm.Package? pkg = null;
 			unowned Alpm.Package? candidate = null;
-			foreach (var name in alpm_config.syncfirsts) {
-				pkg = Alpm.find_satisfier (alpm_config.handle.localdb.pkgcache, name);
+			foreach (unowned string name in alpm_config.get_syncfirsts ()) {
+				pkg = Alpm.find_satisfier (alpm_handle.localdb.pkgcache, name);
 				if (pkg != null) {
-					candidate = pkg.sync_newversion (alpm_config.handle.syncdbs);
+					candidate = pkg.sync_newversion (alpm_handle.syncdbs);
 					if (candidate != null) {
-						var infos = PackageInfos () {
+						var infos = UpdateInfos () {
 							name = candidate.name,
-							version = candidate.version,
-							db_name = candidate.db.name,
+							old_version = pkg.version,
+							new_version = candidate.version,
+							repo = candidate.db.name,
 							download_size = candidate.download_size
 						};
 						updates_infos += (owned) infos;
@@ -403,26 +1137,32 @@ namespace Pamac {
 				return;
 			} else {
 				string[] local_pkgs = {};
-				foreach (var installed_pkg in alpm_config.handle.localdb.pkgcache) {
+				unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
+				while (pkgcache != null) {
+					unowned Alpm.Package installed_pkg = pkgcache.data;
 					// check if installed_pkg is in IgnorePkg or IgnoreGroup
-					if (alpm_config.handle.should_ignore (installed_pkg) == 0) {
-						candidate = installed_pkg.sync_newversion (alpm_config.handle.syncdbs);
+					if (alpm_handle.should_ignore (installed_pkg) == 0) {
+						candidate = installed_pkg.sync_newversion (alpm_handle.syncdbs);
 						if (candidate != null) {
-							var infos = PackageInfos () {
+							var infos = UpdateInfos () {
 								name = candidate.name,
-								version = candidate.version,
-								db_name = candidate.db.name,
+								old_version = installed_pkg.version,
+								new_version = candidate.version,
+								repo = candidate.db.name,
 								download_size = candidate.download_size
 							};
 							updates_infos += (owned) infos;
 						} else {
-							if (check_aur_updates) {
+							if (check_aur_updates && (aur_updates_results.get_length () == 0)) {
 								// check if installed_pkg is a local pkg
-								foreach (var db in alpm_config.handle.syncdbs) {
+								unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
+								while (syncdbs != null) {
+									unowned Alpm.DB db = syncdbs.data;
 									pkg = Alpm.find_satisfier (db.pkgcache, installed_pkg.name);
 									if (pkg != null) {
 										break;
 									}
+									syncdbs.next ();
 								}
 								if (pkg == null) {
 									local_pkgs += installed_pkg.name;
@@ -430,43 +1170,64 @@ namespace Pamac {
 							}
 						}
 					}
+					pkgcache.next ();
 				}
-				PackageInfos[] aur_updates_infos = {};
 				if (check_aur_updates) {
 					// get aur updates
 					if (aur_updates_results.get_length () == 0) {
-						aur_updates_results = AUR.multiinfo (local_pkgs);
-					}
-					aur_updates_results.foreach_element ((array, index,node) => {
-						unowned Json.Object pkg_info = node.get_object ();
-						string version = pkg_info.get_string_member ("Version");
-						string name = pkg_info.get_string_member ("Name");
-						int cmp = Alpm.pkg_vercmp (version, alpm_config.handle.localdb.get_pkg (name).version);
-						if (cmp == 1) {
-							var infos = PackageInfos () {
-								name = name,
-								version = version,
-								db_name = "AUR",
-								download_size = 0
+						AUR.multiinfo.begin (local_pkgs, (obj, res) => {
+							aur_updates_results = AUR.multiinfo.end (res);
+							var updates = Updates () {
+								is_syncfirst = false,
+								repos_updates = (owned) updates_infos,
+								aur_updates = get_aur_updates_infos ()
 							};
-							aur_updates_infos += (owned) infos;
-						}
-					});
+							get_updates_finished (updates);
+						});
+					} else {
+						var updates = Updates () {
+							is_syncfirst = false,
+							repos_updates = (owned) updates_infos,
+							aur_updates = get_aur_updates_infos ()
+						};
+						get_updates_finished (updates);
+					}
+				} else {
+					var updates = Updates () {
+						is_syncfirst = false,
+						repos_updates = (owned) updates_infos,
+						aur_updates = {}
+					};
+					get_updates_finished (updates);
 				}
-				var updates = Updates () {
-					is_syncfirst = false,
-					repos_updates = (owned) updates_infos,
-					aur_updates = (owned) aur_updates_infos
-				};
-				get_updates_finished (updates);
 			}
 		}
 
+		private UpdateInfos[] get_aur_updates_infos () {
+			UpdateInfos[] aur_updates_infos = {};
+			aur_updates_results.foreach_element ((array, index, node) => {
+				unowned Json.Object pkg_info = node.get_object ();
+				unowned string name = pkg_info.get_string_member ("Name");
+				unowned string new_version = pkg_info.get_string_member ("Version");
+				unowned string old_version = alpm_handle.localdb.get_pkg (name).version;
+				if (Alpm.pkg_vercmp (new_version, old_version) == 1) {
+					var infos = UpdateInfos () {
+						name = name,
+						old_version = old_version,
+						new_version = new_version,
+						repo = ""
+					};
+					aur_updates_infos += (owned) infos;
+				}
+			});
+			return aur_updates_infos;
+		}
+
 		public bool trans_init (Alpm.TransFlag transflags) {
 			current_error = ErrorInfos ();
 			cancellable.reset ();
-			if (alpm_config.handle.trans_init (transflags) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			if (alpm_handle.trans_init (transflags) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to init transaction");
 				current_error.details = { Alpm.strerror (errno) };
@@ -479,8 +1240,8 @@ namespace Pamac {
 
 		public bool trans_sysupgrade (bool enable_downgrade) {
 			current_error = ErrorInfos ();
-			if (alpm_config.handle.trans_sysupgrade ((enable_downgrade) ? 1 : 0) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			if (alpm_handle.trans_sysupgrade ((enable_downgrade) ? 1 : 0) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { Alpm.strerror (errno) };
@@ -491,8 +1252,8 @@ namespace Pamac {
 
 		private bool trans_add_pkg_real (Alpm.Package pkg) {
 			current_error = ErrorInfos ();
-			if (alpm_config.handle.trans_add_pkg (pkg) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			if (alpm_handle.trans_add_pkg (pkg) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				if (errno == Alpm.Errno.TRANS_DUP_TARGET || errno == Alpm.Errno.PKG_IGNORED) {
 					// just skip duplicate or ignored targets
 					return true;
@@ -506,20 +1267,9 @@ namespace Pamac {
 			return true;
 		}
 
-		private unowned Alpm.Package? get_sync_pkg (string pkgname) {
-			unowned Alpm.Package? pkg = null;
-			foreach (var db in alpm_config.handle.syncdbs) {
-				pkg = db.get_pkg (pkgname);
-				if (pkg != null) {
-					break;
-				}
-			}
-			return pkg;
-		}
-
 		public bool trans_add_pkg (string pkgname) {
 			current_error = ErrorInfos ();
-			unowned Alpm.Package? pkg = get_sync_pkg (pkgname);
+			unowned Alpm.Package? pkg = get_syncpkg (pkgname);
 			if (pkg == null) {
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { _("target not found: %s").printf (pkgname) };
@@ -530,7 +1280,9 @@ namespace Pamac {
 					if (("linux31" in pkg.name) || ("linux4" in pkg.name)) {
 						string[] installed_kernels = {};
 						string[] installed_modules = {};
-						foreach (var local_pkg in alpm_config.handle.localdb.pkgcache) {
+						unowned Alpm.List<unowned Alpm.Package> pkgcache = alpm_handle.localdb.pkgcache;
+						while (pkgcache != null) {
+							unowned Alpm.Package local_pkg = pkgcache.data;
 							if (("linux31" in local_pkg.name) || ("linux4" in local_pkg.name)) {
 								string[] local_pkg_splitted = local_pkg.name.split ("-", 2);
 								if ((local_pkg_splitted[0] in installed_kernels) == false) {
@@ -542,6 +1294,7 @@ namespace Pamac {
 									}
 								}
 							}
+							pkgcache.next ();
 						}
 						string[] splitted = pkg.name.split ("-", 2);
 						if (splitted.length == 2) {
@@ -549,7 +1302,7 @@ namespace Pamac {
 							// add the same module for other installed kernels
 							foreach (unowned string installed_kernel in installed_kernels) {
 								string module = installed_kernel + "-" + splitted[1];
-								unowned Alpm.Package? module_pkg = get_sync_pkg (module);
+								unowned Alpm.Package? module_pkg = get_syncpkg (module);
 								if (module_pkg != null) {
 									trans_add_pkg_real (module_pkg);
 								}
@@ -559,7 +1312,7 @@ namespace Pamac {
 							// add all installed modules for other kernels
 							foreach (unowned string installed_module in installed_modules) {
 								string module = splitted[0] + "-" + installed_module;
-								unowned Alpm.Package? module_pkg = get_sync_pkg (module);
+								unowned Alpm.Package? module_pkg = get_syncpkg (module);
 								if (module_pkg != null) {
 									trans_add_pkg_real (module_pkg);
 								}
@@ -573,15 +1326,15 @@ namespace Pamac {
 
 		public bool trans_load_pkg (string pkgpath) {
 			current_error = ErrorInfos ();
-			Alpm.Package* pkg = alpm_config.handle.load_file (pkgpath, 1, alpm_config.handle.localfilesiglevel);
-			if (pkg == null) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			Alpm.Package* pkg;
+			if (alpm_handle.load_tarball (pkgpath, 1, alpm_handle.localfilesiglevel, out pkg) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { "%s: %s".printf (pkgpath, Alpm.strerror (errno)) };
 				return false;
-			} else if (alpm_config.handle.trans_add_pkg (pkg) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			} else if (alpm_handle.trans_add_pkg (pkg) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { "%s: %s".printf (pkg->name, Alpm.strerror (errno)) };
@@ -594,13 +1347,13 @@ namespace Pamac {
 
 		public bool trans_remove_pkg (string pkgname) {
 			current_error = ErrorInfos ();
-			unowned Alpm.Package? pkg =  alpm_config.handle.localdb.get_pkg (pkgname);
+			unowned Alpm.Package? pkg =  alpm_handle.localdb.get_pkg (pkgname);
 			if (pkg == null) {
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { _("target not found: %s").printf (pkgname) };
 				return false;
-			} else if (alpm_config.handle.trans_remove_pkg (pkg) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			} else if (alpm_handle.trans_remove_pkg (pkg) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to prepare transaction");
 				current_error.details = { "%s: %s".printf (pkg.name, Alpm.strerror (errno)) };
@@ -612,9 +1365,9 @@ namespace Pamac {
 		private void trans_prepare () {
 			current_error = ErrorInfos ();
 			string[] details = {};
-			Alpm.List<void*> err_data;
-			if (alpm_config.handle.trans_prepare (out err_data) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			Alpm.List err_data;
+			if (alpm_handle.trans_prepare (out err_data) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to prepare transaction");
 				string detail = Alpm.strerror (errno);
@@ -622,26 +1375,31 @@ namespace Pamac {
 					case Alpm.Errno.PKG_INVALID_ARCH:
 						detail += ":";
 						details += (owned) detail;
-						foreach (void* i in err_data) {
-							string* pkgname = i;
+						unowned Alpm.List<string*> list = err_data;
+						while (list != null) {
+							string* pkgname = list.data;
 							details += _("package %s does not have a valid architecture").printf (pkgname);
 							delete pkgname;
+							list.next ();
 						}
 						break;
 					case Alpm.Errno.UNSATISFIED_DEPS:
 						detail += ":";
 						details += (owned) detail;
-						foreach (void* i in err_data) {
-							Alpm.DepMissing* miss = i;
+						unowned Alpm.List<Alpm.DepMissing*> list = err_data;
+						while (list != null) {
+							Alpm.DepMissing* miss = list.data;
 							details += _("%s: requires %s").printf (miss->target, miss->depend.compute_string ());
 							delete miss;
+							list.next ();
 						}
 						break;
 					case Alpm.Errno.CONFLICTING_DEPS:
 						detail += ":";
 						details += (owned) detail;
-						foreach (void* i in err_data) {
-							Alpm.Conflict* conflict = i;
+						unowned Alpm.List<Alpm.Conflict*> list = err_data;
+						while (list != null) {
+							Alpm.Conflict* conflict = list.data;
 							string conflict_detail = _("%s and %s are in conflict").printf (conflict->package1, conflict->package2);
 							// only print reason if it contains new information
 							if (conflict->reason.mod != Alpm.Depend.Mode.ANY) {
@@ -649,6 +1407,7 @@ namespace Pamac {
 							}
 							details += (owned) conflict_detail;
 							delete conflict;
+							list.next ();
 						}
 						break;
 					default:
@@ -661,12 +1420,15 @@ namespace Pamac {
 			} else {
 				// Search for holdpkg in target list
 				bool found_locked_pkg = false;
-				foreach (var pkg in alpm_config.handle.trans_to_remove ()) {
-					if (alpm_config.holdpkgs.find_custom (pkg.name, strcmp) != null) {
+				unowned Alpm.List<unowned Alpm.Package> to_remove = alpm_handle.trans_to_remove ();
+				while (to_remove != null) {
+					unowned Alpm.Package pkg = to_remove.data;
+					if (alpm_config.get_holdpkgs ().find_custom (pkg.name, strcmp) != null) {
 						details += _("%s needs to be removed but it is a locked package").printf (pkg.name);
 						found_locked_pkg = true;
 						break;
 					}
+					to_remove.next ();
 				}
 				if (found_locked_pkg) {
 					current_error.message = _("Failed to prepare transaction");
@@ -694,41 +1456,67 @@ namespace Pamac {
 			provider_mutex.unlock ();
 		}
 
-		public PackageInfos[] trans_to_add () {
-			PackageInfos[] to_add = {};
-			foreach (var pkg in alpm_config.handle.trans_to_add ()) {
-				var infos = PackageInfos () {
-					name = pkg.name,
-					version = pkg.version,
+		public TransactionSummary get_transaction_summary () {
+			UpdateInfos[] to_install = {};
+			UpdateInfos[] to_upgrade = {};
+			UpdateInfos[] to_downgrade = {};
+			UpdateInfos[] to_reinstall = {};
+			UpdateInfos[] to_remove = {};
+			unowned Alpm.List<unowned Alpm.Package> pkgs_to_add = alpm_handle.trans_to_add ();
+			while (pkgs_to_add != null) {
+				unowned Alpm.Package trans_pkg = pkgs_to_add.data;
+				unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (trans_pkg.name);
+				var infos = UpdateInfos () {
+					name = trans_pkg.name,
+					old_version = local_pkg != null ? local_pkg.version : "",
+					new_version = trans_pkg.version,
 					// if pkg was load from a file, pkg.db is null
-					db_name = pkg.db != null ? pkg.db.name : "",
-					download_size = pkg.download_size
+					repo =trans_pkg.db != null ? trans_pkg.db.name : "",
+					download_size = trans_pkg.download_size
 				};
-				to_add += (owned) infos;
+				if (local_pkg == null) {
+					to_install += (owned) infos;
+				} else {
+					int cmp = Alpm.pkg_vercmp (trans_pkg.version, local_pkg.version);
+					if (cmp == 1) {
+						to_upgrade += (owned) infos;
+					} else if (cmp == 0) {
+						to_reinstall += (owned) infos;
+					} else {
+						to_downgrade += (owned) infos;
+					}
+				}
+				pkgs_to_add.next ();
 			}
-			return to_add;
-		}
-
-		public PackageInfos[] trans_to_remove () {
-			PackageInfos[] to_remove = {};
-			foreach (var pkg in alpm_config.handle.trans_to_remove ()) {
-				var infos = PackageInfos () {
-					name = pkg.name,
-					version = pkg.version,
-					db_name = pkg.db.name,
-					download_size = pkg.download_size
+			unowned Alpm.List<unowned Alpm.Package> pkgs_to_remove = alpm_handle.trans_to_remove ();
+			while (pkgs_to_remove != null) {
+				unowned Alpm.Package trans_pkg = pkgs_to_remove.data;
+				var infos = UpdateInfos () {
+					name = trans_pkg.name,
+					old_version = trans_pkg.version,
+					new_version = "",
+					repo = trans_pkg.db.name
 				};
 				to_remove += (owned) infos;
+				pkgs_to_remove.next ();
 			}
-			return to_remove;
+			var summary = TransactionSummary () {
+				to_install = (owned) to_install,
+				to_upgrade = (owned) to_upgrade,
+				to_downgrade = (owned) to_downgrade,
+				to_reinstall = (owned) to_reinstall,
+				to_remove = (owned) to_remove
+			};
+			return summary;
 		}
 
 		private void trans_commit () {
 			current_error = ErrorInfos ();
 			bool success = true;
-			Alpm.List<void*> err_data;
-			if (alpm_config.handle.trans_commit (out err_data) == -1) {
-				Alpm.Errno errno = alpm_config.handle.errno ();
+			Alpm.List err_data;
+			if (alpm_handle.trans_commit (out err_data) == -1) {
+				Alpm.Errno errno = alpm_handle.errno ();
+				current_error.errno = (uint) errno;
 				// cancel the download return an EXTERNAL_DOWNLOAD error
 				if (errno == Alpm.Errno.EXTERNAL_DOWNLOAD && cancellable.is_cancelled ()) {
 					trans_release ();
@@ -736,7 +1524,6 @@ namespace Pamac {
 					trans_commit_finished (false);
 					return;
 				}
-				current_error.errno = (uint) errno;
 				current_error.message = _("Failed to commit transaction");
 				string detail = Alpm.strerror (errno);
 				string[] details = {};
@@ -744,12 +1531,13 @@ namespace Pamac {
 					case Alpm.Errno.FILE_CONFLICTS:
 						detail += ":";
 						details += (owned) detail;
-						//TransFlag flags = alpm_config.handle.trans_get_flags ();
+						//TransFlag flags = alpm_handle.trans_get_flags ();
 						//if ((flags & TransFlag.FORCE) != 0) {
 							//details += _("unable to %s directory-file conflicts").printf ("--force");
 						//}
-						foreach (void* i in err_data) {
-							Alpm.FileConflict* conflict = i;
+						unowned Alpm.List<Alpm.FileConflict*> list = err_data;
+						while (list != null) {
+							Alpm.FileConflict* conflict = list.data;
 							switch (conflict->type) {
 								case Alpm.FileConflict.Type.TARGET:
 									details += _("%s exists in both %s and %s").printf (conflict->file, conflict->target, conflict->ctarget);
@@ -759,6 +1547,7 @@ namespace Pamac {
 									break;
 							}
 							delete conflict;
+							list.next ();
 						}
 						break;
 					case Alpm.Errno.PKG_INVALID:
@@ -767,10 +1556,12 @@ namespace Pamac {
 					case Alpm.Errno.DLT_INVALID:
 						detail += ":";
 						details += (owned) detail;
-						foreach (void* i in err_data) {
-							string* filename = i;
+						unowned Alpm.List<string*> list = err_data;
+						while (list != null) {
+							string* filename = list.data;
 							details += _("%s is invalid or corrupted").printf (filename);
 							delete filename;
+							list.next ();
 						}
 						break;
 					default:
@@ -806,13 +1597,13 @@ namespace Pamac {
 		}
 
 		public void trans_release () {
-			alpm_config.handle.trans_release ();
+			alpm_handle.trans_release ();
 			intern_lock = false;
 		}
 
 		[DBus (no_reply = true)]
 		public void trans_cancel () {
-			if (alpm_config.handle.trans_interrupt () == 0) {
+			if (alpm_handle.trans_interrupt () == 0) {
 				// a transaction is being interrupted
 				// it will end the normal way
 				return;
@@ -826,7 +1617,7 @@ namespace Pamac {
 			// the above function will wait for all task in queue
 			// to be processed before return; 
 			ThreadPool.free ((owned) thread_pool, false, true);
-			alpm_config.handle.unlock ();
+			alpm_handle.unlock ();
 			loop.quit ();
 		}
 	// End of Daemon Object
@@ -977,8 +1768,11 @@ private void cb_question (Alpm.Question.Data data) {
 		case Alpm.Question.Type.SELECT_PROVIDER:
 			string depend_str = data.select_provider_depend.compute_string ();
 			string[] providers_str = {};
-			foreach (unowned Alpm.Package pkg in data.select_provider_providers) {
+			unowned Alpm.List<unowned Alpm.Package> list = data.select_provider_providers;
+			while (list != null) {
+				unowned Alpm.Package pkg = list.data;
 				providers_str += pkg.name;
+				list.next ();
 			}
 			pamac_daemon.provider_cond = Cond ();
 			pamac_daemon.provider_mutex = Mutex ();
@@ -1040,6 +1834,10 @@ private int cb_download (void* data, uint64 dltotal, uint64 dlnow, uint64 ultota
 	} else if (unlikely (dlnow == 0)) {
 		pamac_daemon.emit_download (filename, dlnow, dltotal);
 		pamac_daemon.timer.start ();
+	} else if (unlikely (prevprogress == 0)) {
+		pamac_daemon.emit_download (filename, 0, dltotal);
+		pamac_daemon.emit_download (filename, dlnow, dltotal);
+		pamac_daemon.timer.start ();
 	} else if (unlikely (dlnow == dltotal)) {
 		pamac_daemon.emit_download (filename, dlnow, dltotal);
 		pamac_daemon.timer.stop ();
diff --git a/src/manager_window.vala b/src/manager_window.vala
index cdd199c58a3580ca407aacaa11273835c37384ef..202c945a6bfb10951218da10bbc293ccec607892 100644
--- a/src/manager_window.vala
+++ b/src/manager_window.vala
@@ -17,13 +17,23 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-const string VERSION = "3.2.1";
+const string VERSION = "4.0.0";
 
 namespace Pamac {
 
-	struct SortInfo {
-		public int column_number;
-		public Gtk.SortType sort_type;
+	class ActivableCellRendererPixbuf : Gtk.CellRendererPixbuf {
+		public signal void activated (Gtk.TreePath path);
+
+		public ActivableCellRendererPixbuf () {
+			Object ();
+			this.mode = Gtk.CellRendererMode.ACTIVATABLE;
+		}
+
+		public override bool activate (Gdk.Event event, Gtk.Widget widget, string path, Gdk.Rectangle background_area,
+										Gdk.Rectangle cell_area, Gtk.CellRendererState flags) {
+			activated (new Gtk.TreePath.from_string (path));
+			return true;
+		}
 	}
 
 	[GtkTemplate (ui = "/org/manjaro/pamac/manager/manager_window.ui")]
@@ -34,35 +44,22 @@ namespace Pamac {
 		public Gdk.Pixbuf? to_install_icon;
 		public Gdk.Pixbuf? to_reinstall_icon;
 		public Gdk.Pixbuf? to_remove_icon;
-		public Gdk.Pixbuf? locked_icon;
+		public Gdk.Pixbuf? installed_locked_icon;
+		public Gdk.Pixbuf? available_locked_icon;
 
 		// manager objects
 		[GtkChild]
-		Gtk.TreeView packages_treeview;
-		[GtkChild]
-		public Gtk.TreeViewColumn packages_state_column;
-		[GtkChild]
-		public Gtk.TreeViewColumn packages_name_column;
+		Gtk.Stack main_stack;
 		[GtkChild]
-		public Gtk.TreeViewColumn packages_version_column;
-		[GtkChild]
-		public Gtk.TreeViewColumn packages_repo_column;
+		Gtk.TreeView packages_treeview;
 		[GtkChild]
-		public Gtk.TreeViewColumn packages_size_column;
+		Gtk.TreeViewColumn packages_state_column;
 		[GtkChild]
 		Gtk.TreeView aur_treeview;
 		[GtkChild]
-		Gtk.ScrolledWindow aur_scrolledwindow;
-		[GtkChild]
-		public Gtk.TreeViewColumn aur_state_column;
-		[GtkChild]
-		public Gtk.TreeViewColumn aur_name_column;
+		Gtk.TreeViewColumn aur_state_column;
 		[GtkChild]
-		public Gtk.TreeViewColumn aur_version_column;
-		[GtkChild]
-		public Gtk.TreeViewColumn aur_votes_column;
-		[GtkChild]
-		Gtk.Notebook filters_notebook;
+		Gtk.Stack filters_stack;
 		[GtkChild]
 		Gtk.SearchEntry search_entry;
 		[GtkChild]
@@ -74,12 +71,14 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.TreeView repos_treeview;
 		[GtkChild]
-		Gtk.Notebook packages_notebook;
+		Gtk.Stack packages_stack;
 		[GtkChild]
-		Gtk.Notebook properties_notebook;
+		Gtk.StackSwitcher packages_stackswitcher;
 		[GtkChild]
 		Gtk.TreeView deps_treeview;
 		[GtkChild]
+		Gtk.TreeViewColumn deps_treeview_column;
+		[GtkChild]
 		Gtk.TreeView details_treeview;
 		[GtkChild]
 		Gtk.ScrolledWindow files_scrolledwindow;
@@ -98,9 +97,13 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.Switch search_aur_button;
 		[GtkChild]
-		Gtk.Button valid_button;
+		Gtk.Box transaction_infobox;
 		[GtkChild]
-		Gtk.Button cancel_button;
+		Gtk.Label transaction_infos_label;
+		[GtkChild]
+		Gtk.Button transaction_infos_apply_button;
+		[GtkChild]
+		Gtk.Button transaction_infos_cancel_button;
 
 		// menu
 		Gtk.Menu right_click_menu;
@@ -110,29 +113,26 @@ namespace Pamac {
 		Gtk.MenuItem reinstall_item;
 		Gtk.MenuItem install_optional_deps_item;
 		Gtk.MenuItem explicitly_installed_item;
-		Alpm.List<unowned Alpm.Package?> selected_pkgs;
-		GLib.List<unowned Json.Object> selected_aur;
+		GLib.List<string> selected_pkgs;
+		GLib.List<string> selected_aur;
 
-		// liststore
+		// liststores
 		Gtk.ListStore search_list;
 		Gtk.ListStore groups_list;
 		Gtk.ListStore states_list;
 		Gtk.ListStore repos_list;
 		Gtk.ListStore deps_list;
 		Gtk.ListStore details_list;
+		Gtk.ListStore packages_list;
+		Gtk.ListStore aur_list;
 
-		PackagesModel packages_list;
-		AURModel aur_list;
-
-		HashTable<string,Json.Array> aur_search_results;
-		string current_package_path;
-		string current_aur_path;
+		Queue<string> display_package_queue;
+		string current_package_displayed;
 
 		public Transaction transaction;
 
-		public SortInfo sortinfo;
-
 		bool refreshing;
+		public bool transaction_running;
 
 		uint search_entry_timeout_id;
 
@@ -140,7 +140,9 @@ namespace Pamac {
 			Object (application: application);
 
 			support_aur (false, false);
+			transaction_infobox.visible = false;;
 			refreshing = false;
+			transaction_running = false;
 
 			Timeout.add (100, populate_window);
 		}
@@ -181,51 +183,133 @@ namespace Pamac {
 			repos_treeview.set_model (repos_list);
 			deps_list = new Gtk.ListStore (2, typeof (string), typeof (string));
 			deps_treeview.set_model (deps_list);
+			// title is not visible, it is just defined to find it
+			deps_treeview_column.title = "deps";
 			details_list = new Gtk.ListStore (2, typeof (string), typeof (string));
 			details_treeview.set_model (details_list);
 
+			packages_list = new Gtk.ListStore (7, 
+											typeof (uint), //origin
+											typeof (string), //name
+											typeof (string), //name+desc
+											typeof (string), //version
+											typeof (string), //repo
+											typeof (uint64), //isize
+											typeof (string)); //GLib.format (isize)
+			// sort packages by name by default
+			packages_list.set_sort_column_id (1, Gtk.SortType.ASCENDING);
+			packages_treeview.set_model (packages_list);
+			// add custom cellrenderer to packages_treeview and aur_treewiew
+			var packages_state_renderer = new ActivableCellRendererPixbuf ();
+			packages_state_column.pack_start (packages_state_renderer, true);
+			packages_state_column.set_cell_data_func (packages_state_renderer, (celllayout, cellrenderer, treemodel, treeiter) => {
+				Gdk.Pixbuf pixbuf;
+				uint origin;
+				string pkgname;
+				treemodel.get (treeiter, 0, out origin, 1, out pkgname);
+				if (origin == 2 ) { //origin == Alpm.Package.From.LOCALDB)
+					if (unlikely (transaction.transaction_summary.contains (pkgname))) {
+						pixbuf = installed_locked_icon;
+					} else if (unlikely (transaction.should_hold (pkgname))) {
+						pixbuf = installed_locked_icon;
+					} else if (unlikely (transaction.to_install.contains (pkgname))) {
+						pixbuf = to_reinstall_icon;
+					} else if (unlikely (transaction.to_remove.contains (pkgname))) {
+						pixbuf = to_remove_icon;
+					} else {
+						pixbuf = installed_icon;
+					}
+				} else if (unlikely (transaction.transaction_summary.contains (pkgname))) {
+					pixbuf = available_locked_icon;
+				} else if (unlikely (transaction.to_install.contains (pkgname))) {
+					pixbuf = to_install_icon;
+				} else {
+					pixbuf = uninstalled_icon;
+				}
+				cellrenderer.set ("pixbuf", pixbuf);
+			});
+			packages_state_renderer.activated.connect (on_packages_state_icon_activated);
+
+			aur_list = new Gtk.ListStore (6, 
+											typeof (uint), //origin
+											typeof (string), //name
+											typeof (string), //name+desc
+											typeof (string), //version
+											typeof (double), //popularity
+											typeof (string)); //populariy to string
+			// sort packages by popularity by default
+			aur_list.set_sort_column_id (4, Gtk.SortType.DESCENDING);
+			aur_treeview.set_model (aur_list);
+			// add custom cellrenderer to aur_treewiew
+			var aur_state_renderer = new ActivableCellRendererPixbuf ();
+			aur_state_column.pack_start (aur_state_renderer, true);
+			aur_state_column.set_cell_data_func (aur_state_renderer, (celllayout, cellrenderer, treemodel, treeiter) => {
+				Gdk.Pixbuf pixbuf;
+				uint origin;
+				string pkgname;
+				treemodel.get (treeiter, 0, out origin, 1, out pkgname);
+				if ((uint) origin == 2 ) { //origin == Alpm.Package.From.LOCALDB)
+					if (unlikely (transaction.transaction_summary.contains (pkgname))) {
+						pixbuf = installed_locked_icon;
+					} else if (unlikely (transaction.should_hold (pkgname))) {
+						pixbuf = installed_locked_icon;
+					} else if (unlikely (transaction.to_install.contains (pkgname))) {
+						pixbuf = to_reinstall_icon;
+					} else if (unlikely (transaction.to_remove.contains (pkgname))) {
+						pixbuf = to_remove_icon;
+					} else {
+						pixbuf = installed_icon;
+					}
+				} else if (unlikely (transaction.to_build.contains (pkgname))) {
+					pixbuf = to_install_icon;
+				} else {
+					pixbuf = uninstalled_icon;
+				}
+				cellrenderer.set ("pixbuf", pixbuf);
+			});
+			aur_state_renderer.activated.connect (on_aur_state_icon_activated);
+
 			try {
 				installed_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-updated.png");
 				uninstalled_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available.png");
 				to_install_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-install.png");
 				to_reinstall_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-reinstall.png");
 				to_remove_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-remove.png");
-				locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png");
+				installed_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-installed-locked.png");
+				available_locked_icon = new Gdk.Pixbuf.from_resource ("/org/manjaro/pamac/manager/package-available-locked.png");
 			} catch (GLib.Error e) {
 				stderr.printf (e.message);
 			}
 
 			transaction = new Transaction (this as Gtk.ApplicationWindow);
 			transaction.mode = Mode.MANAGER;
+			transaction.start_transaction.connect (on_start_transaction);
+			transaction.emit_action.connect (on_emit_action);
 			transaction.finished.connect (on_transaction_finished);
 			transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished);
 			transaction.set_pkgreason_finished.connect (on_set_pkgreason_finished);
 
-			unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt");
-			if (pkg != null) {
-				support_aur (transaction.pamac_config.enable_aur, transaction.pamac_config.search_aur);
+			AlpmPackage pkg = transaction.find_installed_satisfier ("yaourt");
+			if (pkg.name != "") {
+				support_aur (transaction.enable_aur, transaction.search_aur);
 			}
 
-			set_buttons_sensitive (false);
-
-			// sort by name by default
-			sortinfo = {0, Gtk.SortType.ASCENDING};
-
-			aur_search_results = new HashTable<string,Json.Array> (str_hash, str_equal);
+			display_package_queue = new Queue<string> ();
 
 			update_lists ();
 			show_default_pkgs ();
+			search_entry.grab_focus ();
+
+			filters_stack.notify["visible-child"].connect (on_filters_stack_visible_child_changed);
+			packages_stack.notify["visible-child"].connect (on_packages_stack_visible_child_changed);
 
 			return false;
 		}
 
 		void on_write_pamac_config_finished (bool recurse, uint64 refresh_period, bool no_update_hide_icon,
 											bool enable_aur, bool search_aur) {
-			if (recurse) {
-				transaction.flags |= Alpm.TransFlag.RECURSE;
-			}
-			unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt");
-			if (pkg != null) {
+			AlpmPackage pkg = transaction.find_installed_satisfier ("yaourt");
+			if (pkg.name != "") {
 				support_aur (enable_aur, search_aur);
 			}
 		}
@@ -236,57 +320,53 @@ namespace Pamac {
 
 		void support_aur (bool enable_aur, bool search_aur) {
 			if (enable_aur) {
-				search_aur_button.set_active (search_aur);
-				search_aur_box.set_visible (true);
-				aur_scrolledwindow.set_visible (true);
+				search_aur_button.active = search_aur;
+				search_aur_box.visible = true;
+				if (filters_stack.visible_child_name == "search") {
+					packages_stackswitcher.visible = true;
+				}
 			} else {
-				search_aur_button.set_active (false);
-				search_aur_box.set_visible (false);
-				aur_scrolledwindow.set_visible (false);
+				search_aur_button.active  = false;
+				search_aur_box.visible = false;
+				packages_stackswitcher.visible = false;
 			}
 		}
 
-		void set_buttons_sensitive (bool sensitive) {
-			valid_button.set_sensitive (sensitive);
-			cancel_button.set_sensitive (sensitive);
+		void set_pendings_operations () {
+			if (!transaction_running) {
+				uint total_pending = transaction.to_install.length + transaction.to_remove.length + transaction.to_build.length;
+				if (total_pending == 0) {
+					transaction_infobox.visible = false;
+				} else {
+					string info = dngettext (null, "%u pending operation", "%u pending operations", total_pending).printf (total_pending);
+					transaction_infos_label.label = info;
+					transaction_infobox.visible = true;
+				}
+			}
 		}
 
 		void show_default_pkgs () {
 			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-			get_installed_pkgs.begin ((obj, res) => {
-				var pkgs = get_installed_pkgs.end (res);
-				populate_packages_list ((owned) pkgs);
+			transaction.get_installed_pkgs.begin ((obj, res) => {
+				populate_packages_list (transaction.get_installed_pkgs.end (res));
 			});
 		}
 
 		void update_lists () {
 			Gtk.TreeIter iter;
-			Gtk.TreeSelection selection;
-			selection = repos_treeview.get_selection ();
+			Gtk.TreeSelection selection = repos_treeview.get_selection ();
 			selection.changed.disconnect (on_repos_treeview_selection_changed);
-			var groups_names = new GLib.List<string> ();
-			foreach (var db in transaction.alpm_utils.get_syncdbs ()) {
-				repos_list.insert_with_values (out iter, -1, 0, db.name);
-				foreach (var group in db.groupcache) {
-					if (groups_names.find_custom (group.name, strcmp) == null) {
-						groups_names.append (group.name);
-					}
-				}
+			foreach (unowned string repo in transaction.get_repos_names ()) {
+				repos_list.insert_with_values (null, -1, 0, repo);
 			}
-			repos_list.insert_with_values (out iter, -1, 0, dgettext (null, "local"));
 			repos_list.get_iter_first (out iter);
 			selection.select_iter (iter);
 			selection.changed.connect_after (on_repos_treeview_selection_changed);
 
 			selection = groups_treeview.get_selection ();
 			selection.changed.disconnect (on_groups_treeview_selection_changed);
-			foreach (var group in transaction.alpm_utils.get_localdb ().groupcache) {
-				if (groups_names.find_custom (group.name, strcmp) == null) {
-					groups_names.append (group.name);
-				}
-			}
-			foreach (unowned string group_name in groups_names) {
-				groups_list.insert_with_values (out iter, -1, 0, group_name);
+			foreach (unowned string group in transaction.get_groups_names ()) {
+				groups_list.insert_with_values (null, -1, 0, group);
 			}
 			groups_list.set_sort_column_id (0, Gtk.SortType.ASCENDING);
 			groups_list.get_iter_first (out iter);
@@ -295,484 +375,341 @@ namespace Pamac {
 
 			selection = states_treeview.get_selection ();
 			selection.changed.disconnect (on_states_treeview_selection_changed);
-			states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Installed"));
-			//states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Uninstalled"));
-			states_list.insert_with_values (out iter, -1, 0, dgettext (null, "Orphans"));
-			states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To install"));
-			states_list.insert_with_values (out iter, -1, 0, dgettext (null, "To remove"));
+			states_list.insert_with_values (null, -1, 0, dgettext (null, "Installed"));
+			states_list.insert_with_values (null, -1, 0, dgettext (null, "Orphans"));
+			states_list.insert_with_values (null, -1, 0, dgettext (null, "Foreign"));
+			states_list.insert_with_values (null, -1, 0, dgettext (null, "Pending"));
 			states_list.get_iter_first (out iter);
 			selection.select_iter (iter);
 			selection.changed.connect_after (on_states_treeview_selection_changed);
 		}
 
-		void set_package_infos_list (Alpm.Package pkg) {
-			name_label.set_markup ("<big><b>%s  %s</b></big>".printf (pkg.name, pkg.version));
-			desc_label.set_markup (Markup.escape_text (pkg.desc));
-			string url = Markup.escape_text (pkg.url);
-			link_label.set_markup ("<a href=\"%s\">%s</a>".printf (url, url));
+		void set_package_details (string pkgname) {
+			AlpmPackageDetails details = transaction.get_pkg_details (pkgname);
+			// infos
+			name_label.set_markup ("<big><b>%s  %s</b></big>".printf (details.name, details.version));
+			desc_label.set_markup (details.desc);
+			link_label.set_markup ("<a href=\"%s\">%s</a>".printf (details.url, details.url));
 			StringBuilder licenses = new StringBuilder ();
 			licenses.append (dgettext (null, "Licenses"));
 			licenses.append (":");
-			foreach (unowned string license in pkg.licenses) {
+			foreach (unowned string license in details.licenses) {
 				licenses.append (" ");
 				licenses.append (license);
 			}
 			licenses_label.set_markup (licenses.str);
-		}
-
-		async void set_aur_infos_list (Json.Object pkg_info) {
-			unowned Json.Node? node;
-			node = pkg_info.get_member ("Name");
-			unowned string name = node.get_string ();
-			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-			Json.Object all_infos = yield transaction.get_aur_infos (name);
-			this.get_window ().set_cursor (null);
-			node = all_infos.get_member ("Version");
-			name_label.set_markup ("<big><b>%s  %s</b></big>".printf (name, node.get_string ()));
-			node = all_infos.get_member ("Description");
-			desc_label.set_markup (Markup.escape_text (node.get_string ()));
-			string url = "";
-			node = all_infos.get_member ("URL");
-			if (!node.is_null ()) {
-				url = Markup.escape_text (node.get_string ());
-			}
-			string aur_url = "http://aur.archlinux.org/packages/" + name;
-			link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (url, url, aur_url, aur_url));
-			StringBuilder licenses = new StringBuilder ();
-			licenses.append (dgettext (null, "Licenses"));
-			licenses.append (":");
-			node = all_infos.get_member ("License");
-			if (node != null) {
-				unowned Json.Array array = node.get_array ();
-				uint i = 0;
-				uint length = array.get_length ();
-				while (i < length) {
-					licenses.append (" ");
-					licenses.append (array.get_string_element (i));
-					i++;
+			// details
+			details_list.clear ();
+			details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Repository") + ":"),
+												1, details.repo);
+			var iter = Gtk.TreeIter ();
+			if (details.groups.length > 0) {
+				foreach (unowned string name in details.groups) {
+					details_list.insert_with_values (out iter, -1,
+												1, name);
+				}
+				Gtk.TreePath path = details_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.groups.length - 1);
+				details_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				details_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Groups") + ":"));
+			}
+			details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Packager") + ":"),
+												1, details.packager);
+			details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Build Date") + ":"),
+												1, details.builddate);
+			if (details.installdate != "") {
+				details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Install Date") + ":"),
+												1, details.installdate);
+			}
+			if (details.reason != "") {
+				details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Install Reason") + ":"),
+												1, details.reason);
+			}
+			if (details.has_signature != "") {
+				details_list.insert_with_values (null, -1,
+												0, "<b>%s</b>".printf (dgettext (null, "Signatures") + ":"),
+												1, details.has_signature);
+			}
+			if (details.backups.length > 0) {
+				foreach (unowned string name in details.backups) {
+					details_list.insert_with_values (out iter, -1,
+												1, name);
 				}
-			} else {
-				licenses.append (dgettext (null, "Unknown"));
+				Gtk.TreePath path = details_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.backups.length - 1);
+				details_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				details_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Backup files") + ":"));
 			}
-			licenses_label.set_markup (licenses.str);
-		}
-
-		void set_package_deps_list (Alpm.Package pkg) {
+			// deps
 			deps_list.clear ();
-			Gtk.TreeIter iter;
-			unowned Alpm.List<unowned Alpm.Depend> deps = pkg.depends;
-			unowned Alpm.List<unowned Alpm.Depend>? list;
-			if (deps.length != 0) {
-				list = deps;
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Depends On") + ":",
-												1, list.data.compute_string ());
-				for (list = list.next (); list != null; list = list.next ()) {
+			if (details.depends.length > 0) {
+				foreach (unowned string name in details.depends) {
 					deps_list.insert_with_values (out iter, -1,
-												1, list.data.compute_string ());
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.depends.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Depends On") + ":"));
 			}
-			deps = pkg.optdepends;
-			if (deps.length != 0) {
-				list = deps;
-				string optdep_str = list.data.compute_string ();
-				var optdep = new StringBuilder (optdep_str);
-				if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) {
-					optdep.append (" [");
-					optdep.append (dgettext (null, "Installed"));
-					optdep.append ("]");
-				}
-				deps_list.insert_with_values (out iter, -1,
-											0, dgettext (null, "Optional Dependencies") + ":",
-											1, optdep.str);
-				for (list = list.next (); list != null; list = list.next ()) {
-					optdep_str = list.data.compute_string ();
-					optdep = new StringBuilder (optdep_str);
-					if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) {
+			if (details.optdepends.length > 0) {
+				foreach (unowned string name in details.optdepends) {
+					var optdep = new StringBuilder (name);
+					if (transaction.find_installed_satisfier (optdep.str).name != "") {
 						optdep.append (" [");
 						optdep.append (dgettext (null, "Installed"));
 						optdep.append ("]");
 					}
-					deps_list.insert_with_values (out iter, -1, 1, optdep.str);
-				}
-			}
-			if (pkg.origin == Alpm.Package.From.LOCALDB) {
-				Alpm.List<string> requiredby = pkg.compute_requiredby ();
-				unowned Alpm.List<string>? list2;
-				if (requiredby.length != 0) {
-					list2 = requiredby;
-					deps_list.insert_with_values (out iter, -1,
-													0, dgettext (null, "Required By") + ":",
-													1, list2.data);
-					for (list2 = list2.next (); list2 != null; list2 = list2.next ()) {
-						deps_list.insert_with_values (out iter, -1,
-													1, list2.data);
-					}
-				}
-				requiredby.free_data ();
-				Alpm.List<string> optionalfor = pkg.compute_optionalfor ();
-				if (optionalfor.length != 0) {
-					list2 = optionalfor;
-					deps_list.insert_with_values (out iter, -1,
-													0, dgettext (null, "Optional For") + ":",
-													1, list2.data);
-					for (list2 = list2.next (); list2 != null; list2 = list2.next ()) {
-						deps_list.insert_with_values (out iter, -1,
-													1, list2.data);
-					}
-				}
-				optionalfor.free_data ();
-			}
-			deps = pkg.provides;
-			if (deps.length != 0) {
-				list = deps;
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Provides") + ":",
-												1, list.data.compute_string ());
-				for (list = list.next (); list != null; list = list.next ()) {
 					deps_list.insert_with_values (out iter, -1,
-												1, list.data.compute_string ());
+												1, optdep.str);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.optdepends.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional Dependencies") + ":"));
 			}
-			deps = pkg.replaces;
-			if (deps.length != 0) {
-				list = deps;
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Replaces") + ":",
-												1, list.data.compute_string ());
-				for (list = list.next (); list != null; list = list.next ()) {
+			if (details.requiredby.length > 0) {
+				foreach (unowned string name in details.requiredby) {
 					deps_list.insert_with_values (out iter, -1,
-												1, list.data.compute_string ());
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.requiredby.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Required By") + ":"));
 			}
-			deps = pkg.conflicts;
-			if (deps.length != 0) {
-				list = deps;
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Conflicts With") + ":",
-												1, list.data.compute_string ());
-				for (list = list.next (); list != null; list = list.next ()) {
+			if (details.optionalfor.length > 0) {
+				foreach (unowned string name in details.optionalfor) {
 					deps_list.insert_with_values (out iter, -1,
-												1, list.data.compute_string ());
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.optionalfor.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional For") + ":"));
 			}
-		}
-
-		async void set_aur_deps_list (Json.Object pkg_info) {
-			deps_list.clear ();
-			Gtk.TreeIter iter;
-			unowned Json.Node? node;
-			node = pkg_info.get_member ("Name");
-			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-			Json.Object all_infos = yield transaction.get_aur_infos (node.get_string ());
-			this.get_window ().set_cursor (null);
-			unowned Json.Array deps;
-			uint i;
-			uint length;
-			node = all_infos.get_member ("Depends");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Depends On") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
+			if (details.provides.length > 0) {
+				foreach (unowned string name in details.provides) {
 					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (i));
-					i++;
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.provides.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Provides") + ":"));
 			}
-			node = all_infos.get_member ("MakeDepends");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Make Dependencies") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
+			if (details.replaces.length > 0) {
+				foreach (unowned string name in details.replaces) {
 					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (i));
-					i++;
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.replaces.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Replaces") + ":"));
 			}
-			node = all_infos.get_member ("CheckDepends");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Check Dependencies") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
+			if (details.conflicts.length > 0) {
+				foreach (unowned string name in details.conflicts) {
 					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (i));
-					i++;
+												1, name);
 				}
+				Gtk.TreePath path = deps_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (details.conflicts.length - 1);
+				deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Conflicts With") + ":"));
 			}
-			node = all_infos.get_member ("OptDepends");
-			if (node != null) {
-				deps = node.get_array ();
-				string optdep_str = deps.get_string_element (0);
-				var optdep = new StringBuilder (optdep_str);
-				if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str) != null) {
-					optdep.append (" [");
-					optdep.append (dgettext (null, "Installed"));
-					optdep.append ("]");
-				}
-				deps_list.insert_with_values (out iter, -1,
-											0, dgettext (null, "Optional Dependencies") + ":",
-											1, optdep.str);
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
-					optdep_str = deps.get_string_element (i);
-					optdep = new StringBuilder (optdep_str);
-					if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep_str.split (": ", 2)[0]) != null) {
-						optdep.append (" [");
-						optdep.append (dgettext (null, "Installed"));
-						optdep.append ("]");
-					}
-					deps_list.insert_with_values (out iter, -1, 1, optdep.str);
-					i++;
-				}
-			}
-			node = all_infos.get_member ("Provides");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Provides") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
-					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (i));
-					i++;
-				}
-			}
-			node = all_infos.get_member ("Replaces");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Replaces") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
-					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (i));
-					i++;
-				}
-			}
-			node = all_infos.get_member ("Conflicts");
-			if (node != null) {
-				deps = node.get_array ();
-				deps_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Conflicts With") + ":",
-												1, deps.get_string_element (0));
-				i = 1;
-				length = deps.get_length ();
-				while (i < length) {
-					deps_list.insert_with_values (out iter, -1,
-												1, deps.get_string_element (1));
-					i++;
+			// files
+			if (details.files.length > 0) {
+				files_scrolledwindow.visible = true;
+				StringBuilder text = new StringBuilder ();
+				foreach (unowned string file in details.files) {
+					text.append (file);
+					text.append ("\n");
 				}
+				files_textview.buffer.set_text (text.str, (int) text.len);
+			} else {
+				files_scrolledwindow.visible = false;
 			}
 		}
 
-		void set_package_details_list (Alpm.Package pkg) {
+		void set_aur_details (string pkgname) {
+			name_label.set_text ("");
+			desc_label.set_text ("");
+			link_label.set_text ("");
+			licenses_label.set_text ("");
 			details_list.clear ();
-			Gtk.TreeIter iter;
-			if (pkg.origin == Alpm.Package.From.SYNCDB) {
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Repository") + ":",
-												1, pkg.db.name);
-			}
-			unowned Alpm.List<unowned string> groups = pkg.groups;
-			if (groups.length != 0) {
-				unowned Alpm.List<unowned string>? list = groups;
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Groups") + ":",
-												1, list.data);
-				for (list = list.next (); list != null; list = list.next ()) {
-					details_list.insert_with_values (out iter, -1,
-												1, list.data);
+			deps_list.clear ();
+			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+			while (Gtk.events_pending ()) {
+				Gtk.main_iteration ();
+			}
+			transaction.get_aur_details.begin (pkgname, (obj, res) => {
+				AURPackageDetails details = transaction.get_aur_details.end (res);
+				// infos
+				name_label.set_markup ("<big><b>%s  %s</b></big>".printf (details.name, details.version));
+				desc_label.set_text (details.desc);
+				string aur_url = "http://aur.archlinux.org/packages/" + details.name;
+				link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (details.url, details.url, aur_url, aur_url));
+				StringBuilder licenses = new StringBuilder ();
+				licenses.append (dgettext (null, "Licenses"));
+				licenses.append (":");
+				foreach (unowned string license in details.licenses) {
+					licenses.append (" ");
+					licenses.append (license);
+				}
+				licenses_label.set_text (licenses.str);
+				// details
+				details_list.clear ();
+				if (details.packagebase != details.name) {
+					details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "Package Base") + ":"),
+													1, details.packagebase);
+				}
+				if (details.maintainer != "") {
+					details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "Maintainer") + ":"),
+													1, details.maintainer);
+				}
+				GLib.Time time = GLib.Time.local ((time_t) details.firstsubmitted);
+				details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "First Submitted") + ":"),
+													1, time.format ("%a %d %b %Y %X %Z"));
+				time = GLib.Time.local ((time_t) details.lastmodified);
+				details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "Last Modified") + ":"),
+													1, time.format ("%a %d %b %Y %X %Z"));
+				details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "Votes") + ":"),
+													1, details.numvotes.to_string ());
+				if (details.outofdate != 0) {
+					time = GLib.Time.local ((time_t) details.outofdate);
+					details_list.insert_with_values (null, -1,
+													0, "<b>%s</b>".printf (dgettext (null, "Out of Date") + ":"),
+													1, time.format ("%a %d %b %Y %X %Z"));
+				}
+				// deps
+				deps_list.clear ();
+				var iter = Gtk.TreeIter ();
+				if (details.depends.length > 0) {
+					foreach (unowned string name in details.depends) {
+						deps_list.insert_with_values (out iter, -1,
+													1, name);
+					}
+					Gtk.TreePath path = deps_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (details.depends.length - 1);
+					deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Depends On") + ":"));
+				}
+				if (details.optdepends.length > 0) {
+					foreach (unowned string name in details.optdepends) {
+						var optdep = new StringBuilder (name);
+						if (transaction.find_installed_satisfier (optdep.str).name != "") {
+							optdep.append (" [");
+							optdep.append (dgettext (null, "Installed"));
+							optdep.append ("]");
+						}
+						deps_list.insert_with_values (out iter, -1,
+													1, optdep.str);
+					}
+					Gtk.TreePath path = deps_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (details.optdepends.length - 1);
+					deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Optional Dependencies") + ":"));
 				}
-			}
-			details_list.insert_with_values (out iter, -1,
-											0, dgettext (null, "Packager") + ":",
-											1, pkg.packager);
-			GLib.Time time = GLib.Time.local ((time_t) pkg.builddate);
-			string build_date = time.format ("%a %d %b %Y %X %Z");
-			details_list.insert_with_values (out iter, -1,
-											0, dgettext (null, "Build Date") + ":",
-											1, build_date);
-			if (pkg.origin == Alpm.Package.From.LOCALDB) {
-				time = GLib.Time.local ((time_t) pkg.installdate);
-				string install_date = time.format ("%a %d %b %Y %X %Z");
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Install Date") + ":",
-												1, install_date);
-				string reason;
-				if (pkg.reason == Alpm.Package.Reason.EXPLICIT) {
-					reason = dgettext (null, "Explicitly installed");
-				} else if (pkg.reason == Alpm.Package.Reason.DEPEND) {
-					reason = dgettext (null, "Installed as a dependency for another package");
-				} else {
-					reason = dgettext (null, "Unknown");
+				if (details.provides.length > 0) {
+					foreach (unowned string name in details.provides) {
+						deps_list.insert_with_values (out iter, -1,
+													1, name);
+					}
+					Gtk.TreePath path = deps_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (details.provides.length - 1);
+					deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Provides") + ":"));
 				}
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Install Reason") + ":",
-												1, reason);
-			}
-			if (pkg.origin == Alpm.Package.From.SYNCDB) {
-				string has_signature = pkg.base64_sig != null ? dgettext (null, "Yes") : dgettext (null, "No");
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Signatures") + ":",
-												1, has_signature);
-			}
-			if (pkg.origin == Alpm.Package.From.LOCALDB) {
-				unowned Alpm.List<unowned Alpm.Backup> backups = pkg.backups;
-				if (backups.length != 0) {
-					unowned Alpm.List<unowned Alpm.Backup>? list = backups;
-					details_list.insert_with_values (out iter, -1,
-													0, dgettext (null, "Backup files") + ":",
-													1, "/" + list.data.name);
-					for (list = list.next (); list != null; list = list.next ()) {
-						details_list.insert_with_values (out iter, -1,
-													1, "/" + list.data.name);
+				if (details.replaces.length > 0) {
+					foreach (unowned string name in details.replaces) {
+						deps_list.insert_with_values (out iter, -1,
+													1, name);
 					}
+					Gtk.TreePath path = deps_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (details.replaces.length - 1);
+					deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Replaces") + ":"));
 				}
-			}
-		}
-
-		void set_aur_details_list (Json.Object pkg_info) {
-			details_list.clear ();
-			Gtk.TreeIter iter;
-			unowned Json.Node? node;
-			node = pkg_info.get_member ("PackageBase");
-			unowned string package_base = node.get_string ();
-			node = pkg_info.get_member ("Name");
-			if (package_base != node.get_string ()) {
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Package Base") + ":",
-												1, package_base);
-			}
-			node = pkg_info.get_member ("Maintainer");
-			details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Maintainer") + ":",
-												1, node.get_string());
-			node = pkg_info.get_member ("FirstSubmitted");
-			GLib.Time time = GLib.Time.local ((time_t) node.get_int ());
-			details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "First Submitted") + ":",
-												1, time.format ("%a %d %b %Y %X %Z"));
-			node = pkg_info.get_member ("LastModified");
-			time = GLib.Time.local ((time_t) node.get_int ());
-			details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Last Modified") + ":",
-												1, time.format ("%a %d %b %Y %X %Z"));
-			node = pkg_info.get_member ("NumVotes");
-			details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Votes") + ":",
-												1, node.get_int ().to_string ());
-			node = pkg_info.get_member ("OutOfDate");
-			if (!node.is_null ()) {
-				time = GLib.Time.local ((time_t) node.get_int ());
-				details_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "Out of Date") + ":",
-												1, time.format ("%a %d %b %Y %X %Z"));
-			}
-		}
-
-		void set_package_files_list (Alpm.Package pkg) {
-			StringBuilder text = new StringBuilder (); 
-			foreach (var file in pkg.files) {
-				if (text.len != 0) {
-					text.append ("\n");
+				if (details.conflicts.length > 0) {
+					foreach (unowned string name in details.conflicts) {
+						deps_list.insert_with_values (out iter, -1,
+													1, name);
+					}
+					Gtk.TreePath path = deps_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (details.conflicts.length - 1);
+					deps_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					deps_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "Conflicts With") + ":"));
 				}
-				text.append ("/");
-				text.append (file.name);
-			}
-			files_textview.buffer.set_text (text.str, (int) text.len);
+				this.get_window ().set_cursor (null);
+			});
 		}
 
-		void populate_packages_list (owned Alpm.List<unowned Alpm.Package?>? pkgs) {
-			Gtk.TreeSelection selection = packages_treeview.get_selection ();
-			selection.changed.disconnect (on_packages_treeview_selection_changed);
-
+		void populate_packages_list (AlpmPackage[] pkgs) {
 			// populate liststore
-			packages_list = new PackagesModel ((owned) pkgs, this);
-
-			// sort liststore
-			int column = sortinfo.column_number;
-			switch (column) {
-				case 0:
-					packages_list.sort_by_name (sortinfo.sort_type);
-					break;
-				case 1:
-					packages_list.sort_by_state (sortinfo.sort_type);
-					break;
-				case 2:
-					packages_list.sort_by_version (sortinfo.sort_type);
-					break;
-				case 3:
-					packages_list.sort_by_repo (sortinfo.sort_type);
-					break;
-				case 4:
-					packages_list.sort_by_size (sortinfo.sort_type);
-					break;
-				default:
-					break;
-			}
-
-			packages_treeview.set_model (packages_list);
-			selection.changed.connect (on_packages_treeview_selection_changed);
-
-			display_package_properties ();
+			packages_treeview.freeze_notify ();
+			packages_treeview.freeze_child_notify ();
+			packages_list.clear ();
+			foreach (unowned AlpmPackage pkg in pkgs) {
+				packages_list.insert_with_values (null, -1,
+												0, pkg.origin,
+												1, pkg.name,
+												2, "<b>%s</b>\n%s".printf (pkg.name, pkg.desc),
+												3, pkg.version,
+												4, pkg.repo,
+												5, pkg.size,
+												6, GLib.format_size (pkg.size));
+			}
+			packages_treeview.thaw_child_notify ();
+			packages_treeview.thaw_notify ();
 			this.get_window ().set_cursor (null);
 		}
 
-		void populate_aur_list (Json.Array? pkgs_infos) {
-			Gtk.TreeSelection selection = aur_treeview.get_selection ();
-			selection.changed.disconnect (on_aur_treeview_selection_changed);
-
+		void populate_aur_list (AURPackage[] pkgs) {
 			// populate liststore
-			aur_list = new AURModel (pkgs_infos, this);
-
-			// sort liststore
-			int column = sortinfo.column_number;
-			switch (column) {
-				case 0:
-					aur_list.sort_by_name (sortinfo.sort_type);
-					break;
-				case 1:
-					aur_list.sort_by_state (sortinfo.sort_type);
-					break;
-				case 2:
-					aur_list.sort_by_version (sortinfo.sort_type);
-					break;
-				case 3:
-					aur_list.sort_by_votes (sortinfo.sort_type);
-					break;
-				default:
-					break;
+			aur_treeview.freeze_notify ();
+			aur_treeview.freeze_child_notify ();
+			aur_list.clear ();
+			foreach (unowned AURPackage aur_pkg in pkgs) {
+				AlpmPackage alpm_pkg = transaction.get_installed_pkg (aur_pkg.name);
+				if (alpm_pkg.name != "") {
+					aur_list.insert_with_values (null, -1,
+													0, alpm_pkg.origin,
+													1, alpm_pkg.name,
+													2, "<b>%s</b>\n%s".printf (alpm_pkg.name, alpm_pkg.desc),
+													3, alpm_pkg.version,
+													4, aur_pkg.popularity,
+													5, "%.2f".printf (aur_pkg.popularity));
+				} else {
+					aur_list.insert_with_values (null, -1,
+													0, 0,
+													1, aur_pkg.name,
+													2, "<b>%s</b>\n%s".printf (aur_pkg.name, aur_pkg.desc),
+													3, aur_pkg.version,
+													4, aur_pkg.popularity,
+													5, "%.2f".printf (aur_pkg.popularity));
+				}
 			}
-
-			aur_treeview.set_model (aur_list);
-			selection.changed.connect (on_aur_treeview_selection_changed);
-
-			display_package_properties();
+			aur_treeview.thaw_child_notify ();
+			aur_treeview.thaw_notify ();
 			this.get_window ().set_cursor (null);
 		}
 
 		void refresh_packages_list () {
-			switch (filters_notebook.get_current_page ()) {
-				case 0:
-					if (search_aur_button.get_active ()) {
-						aur_scrolledwindow.set_visible (true);
+			switch (filters_stack.visible_child_name) {
+				case "search":
+					if (search_aur_box.visible) {
+						packages_stackswitcher.visible = true;
 					}
 					Gtk.TreeSelection selection = search_treeview.get_selection ();
 					if (selection.get_selected (null, null)) {
@@ -781,16 +718,19 @@ namespace Pamac {
 						show_default_pkgs ();
 					}
 					break;
-				case 1:
-					aur_scrolledwindow.set_visible (false);
+				case "groups":
+					packages_stack.visible_child_name = "repos";
+					packages_stackswitcher.visible = false;
 					on_groups_treeview_selection_changed ();
 					break;
-				case 2:
-					aur_scrolledwindow.set_visible (false);
+				case "states":
+					packages_stack.visible_child_name = "repos";
+					packages_stackswitcher.visible = false;
 					on_states_treeview_selection_changed ();
 					break;
-				case 3:
-					aur_scrolledwindow.set_visible (false);
+				case "repos":
+					packages_stack.visible_child_name = "repos";
+					packages_stackswitcher.visible = false;
 					on_repos_treeview_selection_changed ();
 					break;
 				default:
@@ -798,282 +738,232 @@ namespace Pamac {
 			}
 		}
 
-		void display_package_properties () {
-			switch (packages_notebook.get_current_page ()) {
-				case 0:
-					Gtk.TreeSelection selection = packages_treeview.get_selection ();
-					GLib.List<Gtk.TreePath> selected = selection.get_selected_rows (null);
-					unowned GLib.List<Gtk.TreePath>? first_element = selected.nth (0);
-					if (first_element == null) {
-						Gtk.TreeIter? iter;
-						if (current_package_path == null) {
-							packages_list.get_iter_first (out iter);
-							selection.select_iter (iter);
-							current_package_path = packages_list.get_path (iter).to_string ();
-						} else {
-							// check if current_package_path is valid else select first iter
-							if (packages_list.get_iter_from_string (out iter, current_package_path)) {
-								selection.select_iter (iter);
-							} else {
-								packages_list.get_iter_first (out iter);
-								selection.select_iter (iter);
-								current_package_path = packages_list.get_path (iter).to_string ();
-							}
-						}
-					} else {
-						// display info for the first package of the selection
-						current_package_path = first_element.data.to_string ();
-					}
-					unowned Alpm.Package? pkg = packages_list.get_pkg_at_path (new Gtk.TreePath.from_string (current_package_path));
-					if (pkg == null) {
-						return;
-					}
-					if (pkg.origin == Alpm.Package.From.LOCALDB) {
-						files_scrolledwindow.visible = true;
-					} else {
-						files_scrolledwindow.visible = false;
-					}
-					switch (properties_notebook.get_current_page ()) {
-						case 0:
-							set_package_infos_list (pkg);
-							break;
-						case 1:
-							set_package_deps_list (pkg);
-							break;
-						case 2:
-							set_package_details_list (pkg);
-							break;
-						case 3:
-							if (pkg.origin == Alpm.Package.From.LOCALDB) {
-								set_package_files_list (pkg);
-							}
-							break;
-						default:
-							break;
-					}
-					break;
-				case 1:
-					Gtk.TreeSelection selection = aur_treeview.get_selection ();
-					GLib.List<Gtk.TreePath> selected = selection.get_selected_rows (null);
-					unowned GLib.List<Gtk.TreePath>? first_element = selected.nth (0);
-					if (first_element == null) {
-						Gtk.TreeIter? iter;
-						if (current_aur_path == null) {
-							aur_list.get_iter_first (out iter);
-							selection.select_iter (iter);
-							current_aur_path = aur_list.get_path (iter).to_string ();
-						} else {
-							// check if current_package_path is valid else select first iter
-							if (aur_list.get_iter_from_string (out iter, current_aur_path)) {
-								selection.select_iter (iter);
-							} else {
-								aur_list.get_iter_first (out iter);
-								selection.select_iter (iter);
-								current_aur_path = aur_list.get_path (iter).to_string ();
-							}
-						}
-					} else {
-						// display info for the first package of the selection
-						current_aur_path = first_element.data.to_string ();
-					}
-					unowned Json.Object? pkg_info = aur_list.get_pkg_at_path (new Gtk.TreePath.from_string (current_aur_path));
-					if (pkg_info == null) {
-						return;
-					}
-					unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkg_info.get_string_member ("Name"));
-					if (pkg == null) {
-						files_scrolledwindow.visible = false;
-						switch (properties_notebook.get_current_page ()) {
-							case 0:
-								set_aur_infos_list.begin (pkg_info);
-								break;
-							case 1:
-								set_aur_deps_list.begin (pkg_info);
-								break;
-							case 2:
-								set_aur_details_list (pkg_info);
-								break;
-							case 3:
-								break;
-							default:
-								break;
-						}
-					} else {
-						files_scrolledwindow.visible = true;
-						switch (properties_notebook.get_current_page ()) {
-							case 0:
-								set_package_infos_list (pkg);
-								break;
-							case 1:
-								set_package_deps_list (pkg);
-								break;
-							case 2:
-								set_package_details_list (pkg);
-								break;
-							case 3:
-								set_package_files_list (pkg);
-								break;
-							default:
-								break;
-						}
-					}
-					break;
-				default:
-					break;
-			}
+		void display_package_properties (string pkgname) {
+			current_package_displayed = pkgname; 
+			set_package_details (pkgname);
 		}
 
-		[GtkCallback]
-		void on_packages_treeview_selection_changed () {
-			display_package_properties ();
+		void display_aur_properties (string pkgname) {
+			current_package_displayed = pkgname;
+			files_scrolledwindow.visible = false;
+			set_aur_details (pkgname);
 		}
 
 		[GtkCallback]
-		void on_aur_treeview_selection_changed () {
-			display_package_properties ();
+		void on_packages_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) {
+			if (column.title == dgettext (null, "Name")) {
+				main_stack.visible_child_name = "details";
+				Gtk.TreeIter iter;
+				packages_list.get_iter (out iter, path);
+				string pkgname;
+				packages_list.get (iter, 1, out pkgname);
+				display_package_properties (pkgname);
+			}
 		}
 
 		[GtkCallback]
-		void on_properties_notebook_switch_page (Gtk.Widget page, uint page_num) {
-			display_package_properties ();
+		void on_deps_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) {
+			if (column.title == "deps") {
+				if (display_package_queue.find_custom (current_package_displayed, strcmp) == null) {
+					display_package_queue.push_tail (current_package_displayed);
+				}
+				var treemodel = treeview.get_model ();
+				Gtk.TreeIter iter;
+				treemodel.get_iter (out iter, path);
+				string val;
+				treemodel.get (iter, 1, out val);
+				string pkgname = val.split (":", 2)[0].replace (" [" + dgettext (null, "Installed") + "]", "");
+				// just search for the name first to search for AUR after
+				AlpmPackage pkg = transaction.get_installed_pkg (pkgname);
+				if (pkg.name == "") {
+					pkg = transaction.get_sync_pkg (pkgname);
+				}
+				if (pkg.name == "") {
+					this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+					while (Gtk.events_pending ()) {
+						Gtk.main_iteration ();
+					}
+					transaction.get_aur_details.begin (pkgname, (obj, res) => {
+						this.get_window ().set_cursor (null);
+						if (transaction.get_aur_details.end (res).name != "") {
+							display_aur_properties (pkgname);
+						} else {
+							pkg = transaction.find_installed_satisfier (pkgname);
+							if (pkg.name == "") {
+								pkg = transaction.find_sync_satisfier (pkgname);
+							}
+							if (pkg.name != "") {
+								display_package_properties (pkgname);
+							}
+						}
+					});
+				} else {
+					display_package_properties (pkgname);
+				}
+			}
 		}
 
-		[GtkCallback]
-		void on_packages_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) {
-			unowned Alpm.Package? pkg = packages_list.get_pkg_at_path (path);
-			if (pkg != null) {
-				if (transaction.to_add.remove (pkg.name)) {
-				} else if (transaction.to_remove.remove (pkg.name)) {
+		void on_packages_state_icon_activated (Gtk.TreePath path) {
+			Gtk.TreeIter iter;
+			packages_list.get_iter (out iter, path);
+			uint origin;
+			string pkgname;
+			packages_list.get (iter, 0, out origin, 1, out pkgname);
+			if (!transaction.transaction_summary.contains (pkgname)) {
+				if (transaction.to_install.remove (pkgname)) {
+				} else if (transaction.to_remove.remove (pkgname)) {
 				} else {
-					if (pkg.origin == Alpm.Package.From.LOCALDB) {
-						if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) {
-							transaction.to_remove.add (pkg.name);
+					if (origin == 2) { //Alpm.Package.From.LOCALDB
+						if (!transaction.should_hold (pkgname)) {
+							transaction.to_remove.add (pkgname);
 						}
 					} else {
-						transaction.to_add.add (pkg.name);
+						transaction.to_install.add (pkgname);
 					}
 				}
 			}
-			if ((transaction.to_add.length == 0) && (transaction.to_remove.length == 0)) {
-				set_buttons_sensitive (false);
-			} else {
-				set_buttons_sensitive (true);
-			}
-			// force a display refresh
 			packages_treeview.queue_draw ();
+			set_pendings_operations ();
 		}
 
 		[GtkCallback]
 		void on_aur_treeview_row_activated (Gtk.TreeView treeview, Gtk.TreePath path, Gtk.TreeViewColumn column) {
-			unowned Json.Object? pkg_info = aur_list.get_pkg_at_path (path);
-			if (pkg_info != null) {
-				unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkg_info.get_string_member ("Name"));
-				if (pkg != null) {
-					if (pkg.origin == Alpm.Package.From.LOCALDB) {
-						if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) {
-							transaction.to_remove.add (pkg.name);
-						}
-					}
-				} else if (transaction.to_build.remove (pkg_info.get_string_member ("Name"))) {
+			if (column.title == dgettext (null, "Name")) {
+				main_stack.visible_child_name = "details";
+				Gtk.TreeIter iter;
+				aur_list.get_iter (out iter, path);
+				uint origin;
+				string pkgname;
+				aur_list.get (iter, 0, out origin, 1, out pkgname);
+				if (origin == 2) { //Alpm.Package.From.LOCALDB
+					display_package_properties (pkgname);
 				} else {
-					transaction.to_build.add (pkg_info.get_string_member ("Name"));
+					display_aur_properties (pkgname);
 				}
 			}
-			if ((transaction.to_build.length == 0) && (transaction.to_remove.length == 0)) {
-				set_buttons_sensitive (false);
+		}
+
+		void on_aur_state_icon_activated (Gtk.TreePath path) {
+			Gtk.TreeIter iter;
+			aur_list.get_iter (out iter, path);
+			uint origin;
+			string pkgname;
+			aur_list.get (iter, 0, out origin, 1, out pkgname);
+			if (origin == 2) { //Alpm.Package.From.LOCALDB
+				if (!transaction.transaction_summary.contains (pkgname)) {
+					if (transaction.to_remove.remove (pkgname)) {
+					} else if (!transaction.should_hold (pkgname)) {
+						transaction.to_remove.add (pkgname);
+					}
+				}
+			} else if (transaction.to_build.remove (pkgname)) {
 			} else {
-				set_buttons_sensitive (true);
+				transaction.to_build.add (pkgname);
 			}
-			// force a display refresh
-			aur_treeview.queue_draw ();
+			set_pendings_operations ();
 		}
 
-		void on_install_item_activate () {
-			foreach (var pkg in selected_pkgs) {
-				if (pkg.origin == Alpm.Package.From.SYNCDB) {
-					transaction.to_add.add (pkg.name);
+		[GtkCallback]
+		void on_button_back_clicked () {
+			string? pkgname = display_package_queue.pop_tail ();
+			if (pkgname != null) {
+				AlpmPackage pkg = transaction.get_installed_pkg (pkgname);
+				if (pkg.name == "") {
+					pkg = transaction.get_sync_pkg (pkgname);
+				}
+				if (pkg.name == "") {
+					transaction.get_aur_details.begin (pkgname, (obj, res) => {
+						if (transaction.get_aur_details.end (res).name != "") {
+							display_aur_properties (pkgname);
+						} else {
+							pkg = transaction.find_installed_satisfier (pkgname);
+							if (pkg.name == "") {
+								pkg = transaction.find_sync_satisfier (pkgname);
+							}
+							if (pkg.name != "") {
+								display_package_properties (pkgname);
+							}
+						}
+					});
+				} else {
+					display_package_properties (pkgname);
 				}
+			} else {
+				main_stack.visible_child_name = "browse";
 			}
-			foreach (var pkg_info in selected_aur) {
-				transaction.to_build.add (pkg_info.get_string_member ("Name"));
+		}
+
+		void on_install_item_activate () {
+			foreach (unowned string pkgname in selected_pkgs) {
+				if (transaction.get_pkg_origin (pkgname) == 3) { //Alpm.Package.From.SYNCDB
+					transaction.to_install.add (pkgname);
+				}
 			}
-			if (transaction.to_add.length != 0 || transaction.to_build.length != 0) {
-				set_buttons_sensitive (true);
+			foreach (unowned string pkgname in selected_aur) {
+				transaction.to_build.add (pkgname);
 			}
+			set_pendings_operations ();
 		}
 
 		void on_reinstall_item_activate () {
-			foreach (var pkg in selected_pkgs) {
-				transaction.to_remove.remove (pkg.name);
-				if (pkg.origin == Alpm.Package.From.LOCALDB) {
-					transaction.to_add.add (pkg.name);
+			foreach (unowned string pkgname in selected_pkgs) {
+				transaction.to_remove.remove (pkgname);
+				if (transaction.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB
+					transaction.to_install.add (pkgname);
 				}
 			}
-			if (transaction.to_add.length != 0) {
-				set_buttons_sensitive (true);
-			}
+			set_pendings_operations ();
 		}
 
 		void on_remove_item_activate () {
-			foreach (var pkg in selected_pkgs) {
-				transaction.to_add.remove (pkg.name);
-				if (transaction.alpm_utils.get_holdpkgs ().find_custom (pkg.name, strcmp) == null) {
-					if (pkg.origin == Alpm.Package.From.LOCALDB) {
-						transaction.to_remove.add (pkg.name);
+			foreach (unowned string pkgname in selected_pkgs) {
+				transaction.to_install.remove (pkgname);
+				if (!transaction.should_hold (pkgname)) {
+					if (transaction.get_pkg_origin (pkgname) == 2) { //Alpm.Package.From.LOCALDB
+						transaction.to_remove.add (pkgname);
 					}
 				}
 			}
-			if (transaction.to_remove.length != 0) {
-				set_buttons_sensitive (true);
-			}
+			set_pendings_operations ();
 		}
 
 		void on_deselect_item_activate () {
-			foreach (var pkg in selected_pkgs) {
-				if (transaction.to_add.remove (pkg.name)) {
+			foreach (unowned string pkgname in selected_pkgs) {
+				if (transaction.to_install.remove (pkgname)) {
 				} else {
-					transaction.to_remove.remove (pkg.name);
+					transaction.to_remove.remove (pkgname);
 				}
 			}
-			foreach (var pkg_info in selected_aur) {
-				transaction.to_build.remove (pkg_info.get_string_member ("Name"));
-			}
-			if ((transaction.to_add.length == 0)
-				&& (transaction.to_remove.length == 0)
-				&& (transaction.to_load.length == 0)
-				&& (transaction.to_build.length == 0)) {
-				set_buttons_sensitive (false);
+			foreach (unowned string pkgname in selected_aur) {
+				transaction.to_build.remove (pkgname);
 			}
+			set_pendings_operations ();
 		}
 
-		void choose_opt_dep (Alpm.List<unowned Alpm.Package?> pkgs) {
-			foreach (var pkg in pkgs) {
+		void choose_opt_dep (GLib.List<string> pkgnames) {
+			foreach (unowned string pkgname in pkgnames) {
 				var choose_dep_dialog = new ChooseDependenciesDialog (this);
-				Gtk.TreeIter iter;
 				int length = 0;
-				foreach (var optdep in pkg.optdepends) {
-					if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep.name) == null) {
-						length++;
-						choose_dep_dialog.deps_list.insert_with_values (out iter, -1,
-											0, false,
-											1, optdep.name,
-											2, optdep.desc);
-					}
+				foreach (unowned string optdep in transaction.get_pkg_uninstalled_optdeps (pkgname)) {
+					length++;
+					choose_dep_dialog.deps_list.insert_with_values (null, -1,
+																	0, false,
+																	1, optdep);
 				}
 				choose_dep_dialog.label.set_markup ("<b>%s</b>".printf (
 					ngettext ("%s has %u uninstalled optional dependency.\nChoose if you would like to install it",
-							"%s has %u uninstalled optional dependencies.\nChoose those you would like to install", length).printf (pkg.name, length)));
+							"%s has %u uninstalled optional dependencies.\nChoose those you would like to install", length).printf (pkgname, length)));
 				if (choose_dep_dialog.run () == Gtk.ResponseType.OK) {
 					choose_dep_dialog.deps_list.foreach ((model, path, iter) => {
-						GLib.Value val;
+						bool selected;
+						string name;
 						// get value at column 0 to know if it is selected
-						choose_dep_dialog.deps_list.get_value (iter, 0, out val);
-						if ((bool) val) {
-							// get value at column 1 to get the pkg name
-							choose_dep_dialog.deps_list.get_value (iter, 1, out val);
-							unowned Alpm.Package? sync_pkg = transaction.alpm_utils.get_sync_pkg ((string) val);
-							if (sync_pkg != null) {
-								transaction.to_add.add (sync_pkg.name);
+						choose_dep_dialog.deps_list.get (iter, 0, out selected, 1, out name);
+						if (selected) {
+							// get value at column 1 to get the pkgname
+							AlpmPackage sync_pkg = transaction.get_sync_pkg (name);
+							if (sync_pkg.name != "") {
+								transaction.to_install.add (sync_pkg.name);
 							}
 						}
 						return false;
@@ -1088,124 +978,135 @@ namespace Pamac {
 
 		void on_install_optional_deps_item_activate () {
 			choose_opt_dep (selected_pkgs);
-			if (transaction.to_add.length != 0) {
-				set_buttons_sensitive (true);
-			}
+			set_pendings_operations ();
 		}
 
 		void on_explicitly_installed_item_activate () {
-			foreach (var pkg in selected_pkgs) {
-				transaction.start_set_pkgreason (pkg.name, Alpm.Package.Reason.EXPLICIT);
+			foreach (unowned string pkgname in selected_pkgs) {
+				transaction.start_set_pkgreason (pkgname, 0); //Alpm.Package.Reason.EXPLICIT
 			}
 		}
 
-		async void search_in_aur (string search_string) {
-			if (!aur_search_results.contains (search_string)) {
-				Json.Array results = AUR.search (search_string.split (" "));
-				aur_search_results.insert (search_string, results);
+		void on_packages_stack_visible_child_changed () {
+			// do nothing if it we want to see pendings AUR operations
+			switch (filters_stack.visible_child_name) {
+				case "search":
+					Gtk.TreeIter iter;
+					Gtk.TreeSelection selection = search_treeview.get_selection ();
+					if (selection.get_selected (null, out iter)) {
+						this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+						while (Gtk.events_pending ()) {
+							Gtk.main_iteration ();
+						}
+						string search_string;
+						search_list.get (iter, 0, out search_string);
+						switch (packages_stack.visible_child_name) {
+							case "repos":
+								transaction.search_pkgs.begin (search_string, (obj, res) => {
+									populate_packages_list (transaction.search_pkgs.end (res));
+								});
+								break;
+							case "aur":
+								transaction.search_in_aur.begin (search_string, (obj, res) => {
+									populate_aur_list (transaction.search_in_aur.end (res));
+								});
+								break;
+							default:
+								break;
+						}
+					}
+					break;
+				default:
+					break;
 			}
-		}
-
-		[GtkCallback]
-		void on_packages_notebook_switch_page (Gtk.Widget page, uint page_num) {
-			Gtk.TreeModel model;
-			Gtk.TreeIter? iter;
-			Gtk.TreeSelection selection = search_treeview.get_selection ();
-			if (selection.get_selected (out model, out iter)) {
-				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-				GLib.Value val;
-				model.get_value (iter, 0, out val);
-				string search_string = val.get_string ();
-				switch (packages_notebook.get_current_page ()) {
-					case 0:
-						search_all_dbs.begin (search_string, (obj, res) => {
-							var pkgs = search_all_dbs.end (res);
-							populate_packages_list ((owned) pkgs);
-						});
-						break;
-					case 1:
-						search_in_aur.begin (search_string, (obj, res) => {
-							populate_aur_list (aur_search_results.lookup (search_string));
-						});
-						break;
-					default:
-						break;
-				}
+			if (packages_stack.visible_child_name == "aur") {
+				var attention_val = GLib.Value (typeof (bool));
+				attention_val.set_boolean (false);
+				packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"),
+													"needs-attention",
+													attention_val);
 			}
 		}
 
 		[GtkCallback]
 		bool on_packages_treeview_button_press_event (Gdk.EventButton event) {
-			packages_treeview.grab_focus ();
 			// Check if right mouse button was clicked
 			if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) {
-				Gtk.TreePath? treepath;
-				unowned Alpm.Package? clicked_pkg;
-				Gtk.TreeSelection selection = packages_treeview.get_selection ();
-				packages_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null);
-				clicked_pkg = packages_list.get_pkg_at_path (treepath);
-				if (clicked_pkg == null) {
-					return true;
-				}
-				if (!selection.path_is_selected (treepath)) {
-					selection.unselect_all ();
-					selection.select_path (treepath);
-				}
-				GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null);
-				deselect_item.set_sensitive (false);
-				install_item.set_sensitive (false);
-				remove_item.set_sensitive (false);
-				reinstall_item.set_sensitive (false);
-				install_optional_deps_item.set_sensitive (false);
-				explicitly_installed_item.set_sensitive (false);
-				selected_pkgs = new Alpm.List<unowned Alpm.Package?> ();
-				foreach (unowned Gtk.TreePath path in selected_paths) {
-					selected_pkgs.add (packages_list.get_pkg_at_path (path));
-				}
-				foreach (var pkg in selected_pkgs) {
-					if (transaction.to_add.contains (pkg.name)
-							|| transaction.to_remove.contains (pkg.name)) {
-						deselect_item.set_sensitive (true);
-						break;
-					}
-				}
-				foreach (var pkg in selected_pkgs) {
-					if (pkg.origin == Alpm.Package.From.SYNCDB) {
-						install_item.set_sensitive (true);
-						break;
-					}
-				}
-				foreach (var pkg in selected_pkgs) {
-					if (pkg.origin == Alpm.Package.From.LOCALDB) {
-						remove_item.set_sensitive (true);
-						break;
+				Gtk.TreePath treepath;
+				if (packages_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null)) {
+					packages_treeview.grab_focus ();
+					Gtk.TreeSelection selection = packages_treeview.get_selection ();
+					if (!selection.path_is_selected (treepath)) {
+						selection.unselect_all ();
+						selection.select_path (treepath);
 					}
-				}
-				if (selected_pkgs.length == 1) {
-					clicked_pkg = selected_pkgs.data;
-					if (clicked_pkg.origin == Alpm.Package.From.LOCALDB) {
-						foreach (var optdep in clicked_pkg.optdepends) {
-							if (Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), optdep.name) == null) {
-								install_optional_deps_item.set_sensitive (true);
-								break;
+					GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null);
+					selected_pkgs = new GLib.List<string> ();
+					deselect_item.sensitive = false;
+					install_item.sensitive = false;
+					remove_item.sensitive = false;
+					reinstall_item.sensitive = false;
+					install_optional_deps_item.sensitive = false;
+					explicitly_installed_item.sensitive = false;
+					if (selected_paths.length () == 1) {
+						Gtk.TreePath path = selected_paths.data;
+						Gtk.TreeIter iter;
+						packages_list.get_iter (out iter, path);
+						uint origin;
+						string pkgname;
+						string pkgversion;
+						packages_list.get (iter, 0, out origin, 1, out pkgname, 3, out pkgversion);
+						selected_pkgs.append (pkgname);
+						if (transaction.to_install.contains (pkgname)
+								|| transaction.to_remove.contains (pkgname)) {
+							deselect_item.sensitive = true;
+						} else if (origin == 2) { //Alpm.Package.From.LOCALDB
+							remove_item.sensitive = true;
+							foreach (unowned string optdep in transaction.get_pkg_uninstalled_optdeps (pkgname)) {
+								if (transaction.find_installed_satisfier (optdep).name == "") {
+									install_optional_deps_item.sensitive = true;
+									break;
+								}
 							}
+							if (transaction.get_pkg_reason (pkgname) == 1) { //Alpm.Package.Reason.DEPEND
+								explicitly_installed_item.sensitive = true;
+							}
+							AlpmPackage find_pkg = transaction.get_sync_pkg (pkgname);
+							if (find_pkg.name != "") {
+								if (find_pkg.version == pkgversion) {
+									reinstall_item.sensitive = true;
+								}
+							}
+						} else if (origin == 3) { //Alpm.Package.From.SYNCDB
+							install_item.sensitive = true;
 						}
-						if (clicked_pkg.reason == Alpm.Package.Reason.DEPEND) {
-							explicitly_installed_item.set_sensitive (true);
-						}
-						unowned Alpm.Package? find_pkg = transaction.alpm_utils.get_sync_pkg (clicked_pkg.name);
-						if (find_pkg != null) {
-							if (Alpm.pkg_vercmp (find_pkg.version, clicked_pkg.version) == 0) {
-								reinstall_item.set_sensitive (true);
+					} else {
+						foreach (unowned Gtk.TreePath path in selected_paths) {
+							Gtk.TreeIter iter;
+							packages_list.get_iter (out iter, path);
+							uint origin;
+							string pkgname;
+							packages_list.get (iter, 0, out origin, 1, out pkgname);
+							selected_pkgs.append (pkgname);
+							if (!deselect_item.sensitive) {
+								if (transaction.to_install.contains (pkgname)
+										|| transaction.to_remove.contains (pkgname)) {
+									deselect_item.sensitive = true;
+								}
+							}
+							if (origin == 3) { //Alpm.Package.From.SYNCDB
+								install_item.sensitive = true;
+							}
+							if (origin == 2) { //Alpm.Package.From.LOCALDB
+								remove_item.sensitive = true;
 							}
 						}
 					}
+					right_click_menu.popup (null, null, null, event.button, event.time);
+					return true;
 				}
-				right_click_menu.popup (null, null, null, event.button, event.time);
-				return true;
-			} else {
-				return false;
-			}
+			} 
+			return false;
 		}
 
 		[GtkCallback]
@@ -1214,212 +1115,53 @@ namespace Pamac {
 			// Check if right mouse button was clicked
 			if (event.type == Gdk.EventType.BUTTON_PRESS && event.button == 3) {
 				Gtk.TreePath? treepath;
-				unowned Json.Object? clicked_pkg_info;
 				Gtk.TreeSelection selection = aur_treeview.get_selection ();
-				aur_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null);
-				clicked_pkg_info = aur_list.get_pkg_at_path (treepath);
-				if (clicked_pkg_info == null) {
-					return true;
-				}
-				if (!selection.path_is_selected (treepath)) {
-					selection.unselect_all ();
-					selection.select_path (treepath);
-				}
-				GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null);
-				deselect_item.set_sensitive (false);
-				install_item.set_sensitive (false);
-				remove_item.set_sensitive (false);
-				reinstall_item.set_sensitive (false);
-				install_optional_deps_item.set_sensitive (false);
-				explicitly_installed_item.set_sensitive (false);
-				selected_pkgs = new Alpm.List<unowned Alpm.Package?> ();
-				selected_aur = new GLib.List<unowned Json.Object> ();
-				foreach (unowned Gtk.TreePath path in selected_paths) {
-					unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (clicked_pkg_info.get_string_member ("Name"));
-					if (pkg != null) {
-						selected_pkgs.add (pkg);
-						// there is for sure a pkg to remove
-						remove_item.set_sensitive (true);
-					} else {
-						selected_aur.append (aur_list.get_pkg_at_path (path));
+				if (aur_treeview.get_path_at_pos ((int) event.x, (int) event.y, out treepath, null, null, null)) {
+					if (!selection.path_is_selected (treepath)) {
+						selection.unselect_all ();
+						selection.select_path (treepath);
 					}
-				}
-				foreach (var pkg_info in selected_aur) {
-					if (transaction.to_build.contains (pkg_info.get_string_member ("Name"))) {
-						deselect_item.set_sensitive (true);
-						break;
+					GLib.List<Gtk.TreePath> selected_paths = selection.get_selected_rows (null);
+					selected_pkgs = new GLib.List<string> ();
+					selected_aur = new GLib.List<string> ();
+					deselect_item.sensitive = false;
+					install_item.sensitive = false;
+					remove_item.sensitive = false;
+					reinstall_item.sensitive = false;
+					install_optional_deps_item.sensitive = false;
+					explicitly_installed_item.sensitive = false;
+					foreach (unowned Gtk.TreePath path in selected_paths) {
+						Gtk.TreeIter iter;
+						aur_list.get_iter (out iter, path);
+						string pkgname;
+						aur_list.get (iter, 1, out pkgname);
+						AlpmPackage pkg = transaction.get_installed_pkg (pkgname);
+						if (pkg.name != "") {
+							selected_pkgs.append (pkgname);
+							// there is for sure a pkg to remove
+							remove_item.sensitive = true;
+						} else {
+							selected_aur.append (pkgname);
+						}
 					}
-				}
-				foreach (var pkg_info in selected_aur) {
-					if (!transaction.to_build.contains (pkg_info.get_string_member ("Name"))) {
-						install_item.set_sensitive (true);
-						break;
+					foreach (unowned string pkgname in selected_aur) {
+						if (transaction.to_build.contains (pkgname)) {
+							deselect_item.sensitive = true;
+						} else {
+							install_item.sensitive = true;
+						}
 					}
-				}
-				foreach (var pkg in selected_pkgs) {
-					if (transaction.to_remove.contains (pkg.name)) {
-						deselect_item.set_sensitive (true);
-						break;
+					foreach (unowned string pkgname in selected_pkgs) {
+						if (transaction.to_remove.contains (pkgname)) {
+							deselect_item.sensitive = true;
+							break;
+						}
 					}
-				}
-				right_click_menu.popup (null, null, null, event.button, event.time);
-				return true;
-			} else {
-				return false;
-			}
-		}
-
-		[GtkCallback]
-		void on_packages_name_column_clicked () {
-			Gtk.SortType new_order;
-			if (!packages_name_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			packages_list.sort_by_name (new_order);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_aur_name_column_clicked () {
-			Gtk.SortType new_order;
-			if (!aur_name_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			aur_list.sort_by_name (new_order);
-			// force a display refresh
-			aur_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_packages_state_column_clicked () {
-			Gtk.SortType new_order;
-			if (!packages_state_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			packages_list.sort_by_state (new_order);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_aur_state_column_clicked () {
-			Gtk.SortType new_order;
-			if (!aur_state_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			aur_list.sort_by_state (new_order);
-			// force a display refresh
-			aur_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_packages_version_column_clicked () {
-			Gtk.SortType new_order;
-			if (!packages_version_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			packages_list.sort_by_version (new_order);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_aur_version_column_clicked () {
-			Gtk.SortType new_order;
-			if (!aur_version_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			aur_list.sort_by_version (new_order);
-			// force a display refresh
-			aur_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_packages_repo_column_clicked () {
-			Gtk.SortType new_order;
-			if (!packages_repo_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			packages_list.sort_by_repo (new_order);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_packages_size_column_clicked () {
-			Gtk.SortType new_order;
-			if (!packages_size_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
-				}
-			}
-			packages_list.sort_by_size (new_order);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-		}
-
-		[GtkCallback]
-		void on_aur_votes_column_clicked () {
-			Gtk.SortType new_order;
-			if (!aur_votes_column.sort_indicator) {
-				new_order = Gtk.SortType.ASCENDING;
-			} else {
-				if (sortinfo.sort_type == Gtk.SortType.ASCENDING) {
-					new_order =  Gtk.SortType.DESCENDING;
-				} else {
-					new_order =  Gtk.SortType.ASCENDING;
+					right_click_menu.popup (null, null, null, event.button, event.time);
+					return true;
 				}
 			}
-			aur_list.sort_by_votes (new_order);
-			// force a display refresh
-			aur_treeview.queue_draw ();
+			return false;
 		}
 
 		[GtkCallback]
@@ -1428,15 +1170,15 @@ namespace Pamac {
 			if (search_string != "") {
 				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
 				Gtk.TreeModel model;
-				Gtk.TreeIter? iter;
+				Gtk.TreeIter iter;
 				Gtk.TreeSelection selection = search_treeview.get_selection ();
 				// add search string in search_list if needed
 				bool found = false;
 				// check if search string is already selected in search list
 				if (selection.get_selected (out model, out iter)) {
-					GLib.Value selected_string;
-					model.get_value (iter, 0, out selected_string);
-					if ((string) selected_string == search_string) {
+					string selected_string;
+					model.get (iter, 0, out selected_string);
+					if (selected_string == search_string) {
 						on_search_treeview_selection_changed ();
 						found = true;
 					}
@@ -1444,9 +1186,9 @@ namespace Pamac {
 				// check if search string exists in search list
 				if (!found) {
 					search_list.foreach ((_model, _path, _iter) => {
-						GLib.Value line;
-						_model.get_value (_iter, 0, out line);
-						if ((string) line == search_string) {
+						string line;
+						_model.get (_iter, 0, out line);
+						if (line == search_string) {
 							found = true;
 							// we select the iter in search_list
 							// it will populate the list with the selection changed signal
@@ -1480,65 +1222,46 @@ namespace Pamac {
 			}
 		}
 
-		async Alpm.List<unowned Alpm.Package?> search_all_dbs (string search_string) {
-			return transaction.alpm_utils.search_all_dbs (search_string);
-		}
-
-		async Alpm.List<unowned Alpm.Package?> get_group_pkgs (string group_name) {
-			return transaction.alpm_utils.get_group_pkgs (group_name);
-		}
-
-		async Alpm.List<unowned Alpm.Package?> get_installed_pkgs () {
-			return transaction.alpm_utils.get_installed_pkgs ();
-		}
-
-		async Alpm.List<unowned Alpm.Package?> get_orphans () {
-			return transaction.alpm_utils.get_orphans ();
-		}
-
-		async Alpm.List<unowned Alpm.Package?> get_local_pkgs () {
-			return transaction.alpm_utils.get_local_pkgs ();
-		}
-
-		async Alpm.List<unowned Alpm.Package?> get_repo_pkgs (string repo_name) {
-			return transaction.alpm_utils.get_repo_pkgs (repo_name);
-		}
-
 		[GtkCallback]
 		void on_search_treeview_selection_changed () {
-			Gtk.TreeModel model;
-			Gtk.TreeIter? iter;
+			Gtk.TreeIter iter;
 			Gtk.TreeSelection selection = search_treeview.get_selection ();
-			if (selection.get_selected (out model, out iter)) {
+			if (selection.get_selected (null, out iter)) {
 				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-				GLib.Value val;
-				model.get_value (iter, 0, out val);
-				string search_string = val.get_string ();
-				switch (packages_notebook.get_current_page ()) {
-					case 0:
-						search_all_dbs.begin (search_string, (obj, res) => {
-							var pkgs = search_all_dbs.end (res);
+				string search_string;
+				search_list.get (iter, 0, out search_string);
+				switch (packages_stack.visible_child_name) {
+					case "repos":
+						transaction.search_pkgs.begin (search_string, (obj, res) => {
+							var pkgs = transaction.search_pkgs.end (res);
+							populate_packages_list (pkgs);
 							if (search_aur_button.get_active ()) {
-								search_in_aur.begin (search_string, (obj, res) => {
-									if (pkgs.length == 0) {
-										if (aur_search_results.lookup (search_string) != null) {
-											packages_notebook.set_current_page (1);
+								if (pkgs.length == 0) {
+									transaction.search_in_aur.begin (search_string, (obj, res) => {
+										if (transaction.search_in_aur.end (res).length != 0) {
+											packages_stack.visible_child_name = "aur";
 										}
-									} else {
-										if (aur_search_results.lookup (search_string) != null) {
+									});
+								} else {
+									transaction.search_in_aur.begin (search_string, (obj, res) => {
+										if (transaction.search_in_aur.end (res).length != 0) {
+											var attention_val = GLib.Value (typeof (bool));
+											attention_val.set_boolean (true);
+											packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"),
+																				"needs-attention",
+																				attention_val);
 										}
-									}
-									populate_packages_list ((owned) pkgs);
-								});
-							} else {
-								populate_packages_list ((owned) pkgs);
+									});
+								}
 							}
 						});
+						aur_list.clear ();
 						break;
-					case 1:
-						search_in_aur.begin (search_string, (obj, res) => {
-							populate_aur_list (aur_search_results.lookup (search_string));
+					case "aur":
+						transaction.search_in_aur.begin (search_string, (obj, res) => {
+							populate_aur_list (transaction.search_in_aur.end (res));
 						});
+						packages_list.clear ();
 						break;
 					default:
 						break;
@@ -1548,96 +1271,106 @@ namespace Pamac {
 
 		[GtkCallback]
 		void on_groups_treeview_selection_changed () {
-			Gtk.TreeModel model;
-			Gtk.TreeIter? iter;
+			Gtk.TreeIter iter;
 			Gtk.TreeSelection selection = groups_treeview.get_selection ();
-			if (selection.get_selected (out model, out iter)) {
+			if (selection.get_selected (null, out iter)) {
 				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-				GLib.Value grp_name;
-				model.get_value (iter, 0, out grp_name);
-				get_group_pkgs.begin ((string) grp_name, (obj, res) => {
-					var pkgs = get_group_pkgs.end (res);
-					populate_packages_list ((owned) pkgs);
+				string group_name;
+				groups_list.get (iter, 0, out group_name);
+				transaction.get_group_pkgs.begin (group_name, (obj, res) => {
+					populate_packages_list (transaction.get_group_pkgs.end (res));
 				});
 			}
 		}
 
 		[GtkCallback]
 		void on_states_treeview_selection_changed () {
-			Gtk.TreeModel model;
-			Gtk.TreeIter? treeiter;
+			Gtk.TreeIter iter;
 			Gtk.TreeSelection selection = states_treeview.get_selection ();
-			if (selection.get_selected (out model, out treeiter)) {
+			if (selection.get_selected (null, out iter)) {
 				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-				GLib.Value val;
-				model.get_value (treeiter, 0, out val);
-				unowned string state = val.get_string ();
-				if (state == dgettext (null, "To install")) {
-					var pkgs = new Alpm.List<unowned Alpm.Package?> ();
-					foreach (unowned string pkgname in transaction.to_add) {
-						unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkgname);
-						if (pkg == null) {
-							pkg = transaction.alpm_utils.get_sync_pkg (pkgname);
+				packages_stackswitcher.visible = false;
+				string state;
+				states_list.get (iter, 0, out state);
+				if (state == dgettext (null, "Installed")) {
+					transaction.get_installed_pkgs.begin ((obj, res) => {
+						populate_packages_list (transaction.get_installed_pkgs.end (res));
+					});
+				} else if (state == dgettext (null, "Orphans")) {
+					transaction.get_orphans.begin ((obj, res) => {
+						populate_packages_list (transaction.get_orphans.end (res));
+					});
+				} else if (state == dgettext (null, "Foreign")) {
+					transaction.get_foreign_pkgs.begin ((obj, res) => {
+						populate_packages_list (transaction.get_foreign_pkgs.end (res));
+					});
+				} else if (state == dgettext (null, "Pending")) {
+					AlpmPackage[] pkgs = {};
+					foreach (unowned string pkgname in transaction.to_install) {
+						AlpmPackage pkg = transaction.get_installed_pkg (pkgname);
+						if (pkg.name == "") {
+							pkg = transaction.get_sync_pkg (pkgname);
 						}
-						if (pkg != null) {
-							pkgs.add (pkg);
+						if (pkg.name != "") {
+							pkgs += pkg;
 						}
 					}
-					populate_packages_list ((owned) pkgs);
-				} else if (state == dgettext (null, "To remove")) {
-					var pkgs = new Alpm.List<unowned Alpm.Package?> ();
 					foreach (unowned string pkgname in transaction.to_remove) {
-						unowned Alpm.Package? pkg = transaction.alpm_utils.get_installed_pkg (pkgname);
-						if (pkg != null) {
-							pkgs.add (pkg);
+						AlpmPackage pkg = transaction.get_installed_pkg (pkgname);
+						if (pkg.name != "") {
+							pkgs += pkg;
+						}
+					}
+					populate_packages_list (pkgs);
+					if (transaction.to_build.length != 0) {
+						packages_stackswitcher.visible = true;
+						AURPackage[] aur_pkgs = {};
+						foreach (unowned string pkgname in transaction.to_build) {
+							transaction.get_aur_details.begin (pkgname, (obj, res) => {
+								AURPackageDetails details_pkg = transaction.get_aur_details.end (res);
+								if (details_pkg.name != "") {
+									var aur_pkg = AURPackage () {
+										name = details_pkg.name,
+										version = details_pkg.version,
+										desc = details_pkg.desc,
+										popularity = details_pkg.popularity
+									};
+									aur_pkgs += aur_pkg;
+									populate_aur_list (aur_pkgs);
+									if (aur_pkgs.length > 0 ) {
+										if (pkgs.length == 0) {
+											packages_stack.visible_child_name = "aur";
+										} else {
+											var attention_val = GLib.Value (typeof (bool));
+											attention_val.set_boolean (true);
+											packages_stack.child_set_property (packages_stack.get_child_by_name ("aur"),
+																				"needs-attention",
+																				attention_val);
+										}
+									}
+								}
+							});
 						}
 					}
-					populate_packages_list ((owned) pkgs);
-				} else if (state == dgettext (null, "Installed")) {
-					get_installed_pkgs.begin ((obj, res) => {
-						var pkgs = get_installed_pkgs.end (res);
-						populate_packages_list ((owned) pkgs);
-					});
-				} else if (state == dgettext (null, "Uninstalled")) {
-					//get_sync_pkgs.begin ((obj, res) => {
-						//var pkgs = get_sync_pkgs.end (res);
-						//populate_packages_list ((owned) pkgs);
-					//});
-				} else if (state == dgettext (null, "Orphans")) {
-					get_orphans.begin ((obj, res) => {
-						var pkgs = get_orphans.end (res);
-						populate_packages_list ((owned) pkgs);
-					});
 				}
 			}
 		}
 
 		[GtkCallback]
 		void on_repos_treeview_selection_changed () {
-			Gtk.TreeModel model;
-			Gtk.TreeIter? iter;
+			Gtk.TreeIter iter;
 			Gtk.TreeSelection selection = repos_treeview.get_selection ();
-			if (selection.get_selected (out model, out iter)) {
+			if (selection.get_selected (null, out iter)) {
 				this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
-				GLib.Value val;
-				model.get_value (iter, 0, out val);
-				unowned string repo = val.get_string ();
-				if (repo == dgettext (null, "local")) {
-					get_local_pkgs.begin ((obj, res) => {
-						var pkgs = get_local_pkgs.end (res);
-						populate_packages_list ((owned) pkgs);
-					});
-				} else {
-					get_repo_pkgs.begin (repo, (obj, res) => {
-						var pkgs = get_repo_pkgs.end (res);
-						populate_packages_list ((owned) pkgs);
-					});
-				}
+				string repo;
+				repos_list.get (iter, 0, out repo);
+				transaction.get_repo_pkgs.begin (repo, (obj, res) => {
+					populate_packages_list (transaction.get_repo_pkgs.end (res));
+				});
 			}
 		}
 
-		[GtkCallback]
-		void on_filters_notebook_switch_page (Gtk.Widget page, uint page_num) {
+		void on_filters_stack_visible_child_changed () {
 			refresh_packages_list ();
 		}
 
@@ -1700,6 +1433,7 @@ namespace Pamac {
 					while (Gtk.events_pending ()) {
 						Gtk.main_iteration ();
 					}
+					transaction_running = true;
 					transaction.run ();
 				}
 			} else {
@@ -1729,18 +1463,38 @@ namespace Pamac {
 		}
 
 		[GtkCallback]
-		void on_valid_button_clicked () {
-			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+		void on_transaction_infos_details_button_clicked () {
+			if (transaction_running) {
+				transaction.show_progress ();
+			} else {
+				Gtk.TreeIter iter;
+				// show "Pending" in states_list
+				// "Pending" is at indice 3
+				states_list.get_iter (out iter, new Gtk.TreePath.from_indices (3));
+				Gtk.TreeSelection selection = states_treeview.get_selection ();
+				selection.changed.disconnect (on_states_treeview_selection_changed);
+				selection.select_iter (iter);
+				selection.changed.connect_after (on_states_treeview_selection_changed);
+				filters_stack.visible_child_name = "states";
+			}
+		}
+
+		[GtkCallback]
+		void on_transaction_infos_apply_button_clicked () {
+			//this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+			transaction_running = true;
 			transaction.run ();
 		}
 
 		[GtkCallback]
-		void on_cancel_button_clicked () {
-			transaction.clear_lists ();
-			set_buttons_sensitive (false);
-			// force a display refresh
-			packages_treeview.queue_draw ();
-			aur_treeview.queue_draw ();
+		void on_transaction_infos_cancel_button_clicked () {
+			if (transaction_running) {
+				transaction.cancel ();
+			} else {
+				transaction.clear_lists ();
+				set_pendings_operations ();
+				refresh_packages_list ();
+			}
 		}
 
 		[GtkCallback]
@@ -1748,23 +1502,34 @@ namespace Pamac {
 			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
 			refreshing = true;
 			transaction.start_refresh (false);
+			transaction_infos_apply_button.visible = false;
+			transaction_infobox.visible = true;
+		}
+
+		void on_start_transaction () {
+			transaction_infos_cancel_button.visible = false;
+			transaction_infos_apply_button.visible = false;
+		}
+
+		void on_emit_action (string action) {
+			transaction_infos_label.label = action;
 		}
 
 		void on_transaction_finished (bool success) {
-			if (transaction.to_add.length == 0
-					&& transaction.to_remove.length == 0
-					&& transaction.to_load.length == 0
-					&& transaction.to_build.length == 0) {
-				set_buttons_sensitive (false);
-			}
 			refresh_packages_list ();
 			transaction.to_load.remove_all ();
 			if (refreshing) {
 				if (success) {
+					transaction_running = true;
 					transaction.sysupgrade (false);
 				}
 				refreshing = false;
+			} else {
+				transaction_running = false;
+				transaction_infos_cancel_button.visible = true;
+				transaction_infos_apply_button.visible = true;
 			}
+			set_pendings_operations ();
 		}
 	}
 }
diff --git a/src/mirrors_config.vala b/src/mirrors_config.vala
index 3414562767088b21402945eb2e8fc3fcdcc6da7f..5c3130344ad3f08acd0dba64dbbe147af4f59d03 100644
--- a/src/mirrors_config.vala
+++ b/src/mirrors_config.vala
@@ -18,13 +18,32 @@
  */
 
 namespace Pamac {
-	[Compact]
-	public class MirrorsConfig {
-		public string conf_path;
-		public string mirrorlists_dir;
-		public string choosen_generation_method;
-		public string choosen_country;
-		public GLib.List<string> countrys;
+	class MirrorsConfig {
+		string conf_path;
+		GLib.List<string> _countrys ;
+
+
+		public string mirrorlists_dir { get; private set; }
+		public string choosen_generation_method { get; private set; }
+		public string choosen_country { get; private set; }
+		public unowned GLib.List<string> countrys {
+			get {
+				try {
+					var directory = GLib.File.new_for_path (mirrorlists_dir);
+					var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0);
+					FileInfo file_info;
+					_countrys = new GLib.List<string> ();
+					while ((file_info = enumerator.next_file ()) != null) {
+						_countrys.append(file_info.get_name ());
+					}
+					_countrys.sort (strcmp);
+				} catch (Error e) {
+					stderr.printf ("%s\n", e.message);
+				}
+				return _countrys;
+			}
+		}
+
 
 		public MirrorsConfig (string path) {
 			conf_path = path;
@@ -39,22 +58,7 @@ namespace Pamac {
 			parse_file (conf_path);
 		}
 
-		public void get_countrys () {
-			try {
-				var directory = GLib.File.new_for_path (mirrorlists_dir);
-				var enumerator = directory.enumerate_children (FileAttribute.STANDARD_NAME, 0);
-				FileInfo file_info;
-				countrys = new GLib.List<string> ();
-				while ((file_info = enumerator.next_file ()) != null) {
-					countrys.append(file_info.get_name ());
-				}
-				countrys.sort (strcmp);
-			} catch (Error e) {
-				stderr.printf ("%s\n", e.message);
-			}
-		}
-
-		public void parse_file (string path) {
+		void parse_file (string path) {
 			var file = GLib.File.new_for_path (path);
 			if (file.query_exists ()) {
 				try {
diff --git a/src/package.vala b/src/package.vala
new file mode 100644
index 0000000000000000000000000000000000000000..681078d4d2431f8d94075f2b721400d04fe8ee20
--- /dev/null
+++ b/src/package.vala
@@ -0,0 +1,82 @@
+/*
+ *  pamac-vala
+ *
+ *  Copyright (C) 2014-2016 Guillaume Benoit <guillaume@manjaro.org>
+ *
+ *  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 get of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Pamac {
+	public struct AlpmPackage {
+		public string name;
+		public string version;
+		public string desc;
+		public string repo;
+		public uint64 size;
+		public uint origin;
+	}
+
+	public struct AlpmPackageDetails {
+		public string name;
+		public string version;
+		public string desc;
+		public string repo;
+		public string url;
+		public string packager;
+		public string builddate;
+		public string installdate;
+		public string reason;
+		public string has_signature;
+		public string[] licenses;
+		public string[] depends;
+		public string[] optdepends;
+		public string[] requiredby;
+		public string[] optionalfor;
+		public string[] provides;
+		public string[] replaces;
+		public string[] conflicts;
+		public string[] groups;
+		public string[] backups;
+		public string[] files;
+	}
+
+	public struct AURPackage {
+		public string name;
+		public string version;
+		public string desc;
+		public double popularity;
+	}
+
+	public struct AURPackageDetails {
+		public string name;
+		public string version;
+		public string desc;
+		public double popularity;
+		public string packagebase;
+		public string url;
+		public string maintainer;
+		public int64 firstsubmitted;
+		public int64 lastmodified;
+		public int64 outofdate;
+		public int64 numvotes;
+		public string[] licenses;
+		public string[] depends;
+		public string[] makedepends;
+		public string[] checkdepends;
+		public string[] optdepends;
+		public string[] provides;
+		public string[] replaces;
+		public string[] conflicts;
+	}
+}
diff --git a/src/pamac_config.vala b/src/pamac_config.vala
index c263ba9dfe7fc97d3af9afb0462834c541033f64..f56466c465e2e51b1836a4fdf4bd544a13f42bcb 100644
--- a/src/pamac_config.vala
+++ b/src/pamac_config.vala
@@ -18,43 +18,48 @@
  */
 
 namespace Pamac {
-	[Compact]
-	public class Config {
-		public string conf_path;
-		public bool recurse;
-		public uint64 refresh_period;
-		public bool no_update_hide_icon;
-		public bool enable_aur;
-		public bool search_aur;
-		public bool check_aur_updates;
-		public bool no_confirm_build;
-		public HashTable<string,string> environment_variables;
+	class Config {
+		string conf_path;
+		HashTable<string,string> _environment_variables;
+
+		public bool recurse { get; private set; }
+		public uint64 refresh_period { get; private set; }
+		public bool no_update_hide_icon { get; private set; }
+		public bool enable_aur { get; private set; }
+		public bool search_aur { get; private set; }
+		public bool check_aur_updates { get; private set; }
+		public bool no_confirm_build { get; private set; }
+		public unowned HashTable<string,string> environment_variables {
+			get {
+				return _environment_variables;
+			}
+		}
 
 		public Config (string path) {
 			conf_path = path;
 			//get environment variables
-			environment_variables = new HashTable<string,string> (str_hash, str_equal);
+			_environment_variables = new HashTable<string,string> (str_hash, str_equal);
 			var utsname = Posix.utsname();
-			environment_variables.insert ("HTTP_USER_AGENT", "pamac (%s %s)".printf (utsname.sysname, utsname.machine));
+			_environment_variables.insert ("HTTP_USER_AGENT", "pamac (%s %s)".printf (utsname.sysname, utsname.machine));
 			unowned string? variable = Environment.get_variable ("http_proxy");
 			if (variable != null) {
-				environment_variables.insert ("http_proxy", variable);
+				_environment_variables.insert ("http_proxy", variable);
 			}
 			variable = Environment.get_variable ("https_proxy");
 			if (variable != null) {
-				environment_variables.insert ("https_proxy", variable);
+				_environment_variables.insert ("https_proxy", variable);
 			}
 			variable = Environment.get_variable ("ftp_proxy");
 			if (variable != null) {
-				environment_variables.insert ("ftp_proxy", variable);
+				_environment_variables.insert ("ftp_proxy", variable);
 			}
 			variable = Environment.get_variable ("socks_proxy");
 			if (variable != null) {
-				environment_variables.insert ("socks_proxy", variable);
+				_environment_variables.insert ("socks_proxy", variable);
 			}
 			variable = Environment.get_variable ("no_proxy");
 			if (variable != null) {
-				environment_variables.insert ("no_proxy", variable);
+				_environment_variables.insert ("no_proxy", variable);
 			}
 			// set default option
 			refresh_period = 6;
@@ -72,7 +77,7 @@ namespace Pamac {
 			parse_file (conf_path);
 		}
 
-		public void parse_file (string path) {
+		void parse_file (string path) {
 			var file = GLib.File.new_for_path (path);
 			if (file.query_exists ()) {
 				try {
diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala
index 9f34882ea4c576d69f2db3831b077775a97842d7..7beb3c31089e53745ca12753512611218559a949 100644
--- a/src/preferences_dialog.vala
+++ b/src/preferences_dialog.vala
@@ -37,8 +37,6 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.Box ignorepkgs_box;
 		[GtkChild]
-		Gtk.ListStore ignorepkgs_liststore;
-		[GtkChild]
 		Gtk.TreeView ignorepkgs_treeview;
 		[GtkChild]
 		Gtk.Box mirrors_config_box;
@@ -59,6 +57,7 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.CheckButton no_confirm_build_checkbutton;
 
+		Gtk.ListStore ignorepkgs_liststore;
 		Transaction transaction;
 		uint64 previous_refresh_period;
 
@@ -67,9 +66,9 @@ namespace Pamac {
 
 			this.transaction = transaction;
 			refresh_period_label.set_markup (dgettext (null, "How often to check for updates, value in hours") +":");
-			remove_unrequired_deps_button.active = transaction.pamac_config.recurse;
-			check_space_button.active = (transaction.alpm_utils.get_checkspace () == 1);
-			if (transaction.pamac_config.refresh_period == 0) {
+			remove_unrequired_deps_button.active = transaction.recurse;
+			check_space_button.active = transaction.get_checkspace ();
+			if (transaction.refresh_period == 0) {
 				check_updates_button.active = false;
 				refresh_period_label.sensitive = false;
 				// set default value
@@ -80,15 +79,16 @@ namespace Pamac {
 				ignorepkgs_box.sensitive = false;
 			} else {
 				check_updates_button.active = true;
-				refresh_period_spin_button.value = transaction.pamac_config.refresh_period;
-				previous_refresh_period = transaction.pamac_config.refresh_period;
+				refresh_period_spin_button.value = transaction.refresh_period;
+				previous_refresh_period = transaction.refresh_period;
 			}
-			no_update_hide_icon_checkbutton.active = transaction.pamac_config.no_update_hide_icon;
+			no_update_hide_icon_checkbutton.active = transaction.no_update_hide_icon;
 
 			// populate ignorepkgs_liststore
-			Gtk.TreeIter iter;
-			foreach (unowned string ignorepkg in transaction.alpm_utils.get_ignorepkgs ()) {
-				ignorepkgs_liststore.insert_with_values (out iter, -1, 0, ignorepkg);
+			ignorepkgs_liststore = new Gtk.ListStore (1, typeof (string));
+			ignorepkgs_treeview.set_model (ignorepkgs_liststore);
+			foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) {
+				ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg);
 			}
 			remove_unrequired_deps_button.state_set.connect (on_remove_unrequired_deps_button_state_set);
 			check_space_button.state_set.connect (on_check_space_button_state_set);
@@ -98,15 +98,14 @@ namespace Pamac {
 			no_update_hide_icon_checkbutton.toggled.connect (on_no_update_hide_icon_checkbutton_toggled);
 			transaction.write_pamac_config_finished.connect (on_write_pamac_config_finished);
 
-			unowned Alpm.Package? pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "pacman-mirrorlist");
-			if (pkg == null) {
+			AlpmPackage pkg = transaction.find_installed_satisfier ("pacman-mirrorlist");
+			if (pkg.name == "") {
 				mirrors_config_box.visible = false;
 			} else {
 				var mirrors_config = new MirrorsConfig ("/etc/pacman-mirrors.conf");
 				mirrors_country_comboboxtext.append_text (dgettext (null, "Worldwide"));
 				mirrors_country_comboboxtext.active = 0;
 				int index = 1;
-				mirrors_config.get_countrys ();
 				foreach (unowned string country in mirrors_config.countrys) {
 					mirrors_country_comboboxtext.append_text (country);
 					if (country == mirrors_config.choosen_country) {
@@ -126,17 +125,17 @@ namespace Pamac {
 				transaction.write_mirrors_config_finished.connect (on_write_mirrors_config_finished);
 			}
 
-			pkg = Alpm.find_satisfier (transaction.alpm_utils.get_installed_pkgs (), "yaourt");
-			if (pkg == null) {
+			pkg = transaction.find_installed_satisfier ("yaourt");
+			if (pkg.name == "") {
 				aur_config_box.visible = false;
 			} else {
-				enable_aur_button.active = transaction.pamac_config.enable_aur;
-				search_aur_checkbutton.active = transaction.pamac_config.search_aur;
-				search_aur_checkbutton.sensitive = transaction.pamac_config.enable_aur;
-				check_aur_updates_checkbutton.active = transaction.pamac_config.check_aur_updates;
-				check_aur_updates_checkbutton.sensitive = transaction.pamac_config.enable_aur;
-				no_confirm_build_checkbutton.active = transaction.pamac_config.no_confirm_build;
-				no_confirm_build_checkbutton.sensitive = transaction.pamac_config.enable_aur;
+				enable_aur_button.active = transaction.enable_aur;
+				search_aur_checkbutton.active = transaction.search_aur;
+				search_aur_checkbutton.sensitive = transaction.enable_aur;
+				check_aur_updates_checkbutton.active = transaction.check_aur_updates;
+				check_aur_updates_checkbutton.sensitive = transaction.enable_aur;
+				no_confirm_build_checkbutton.active = transaction.no_confirm_build;
+				no_confirm_build_checkbutton.sensitive = transaction.enable_aur;
 				enable_aur_button.state_set.connect (on_enable_aur_button_state_set);
 				search_aur_checkbutton.toggled.connect (on_search_aur_checkbutton_toggled);
 				check_aur_updates_checkbutton.toggled.connect (on_check_aur_updates_checkbutton_toggled);
@@ -248,40 +247,45 @@ namespace Pamac {
 		[GtkCallback]
 		void on_add_ignorepkgs_button_clicked () {
 			var choose_ignorepkgs_dialog = new ChooseIgnorepkgsDialog (this);
-			foreach (var pkg in transaction.alpm_utils.get_installed_pkgs ()) {
-				Gtk.TreeIter iter;
-				if (transaction.alpm_utils.get_ignorepkgs ().find_str (pkg.name) == null) {
-					choose_ignorepkgs_dialog.pkgs_list.insert_with_values (out iter, -1, 0, false, 1, pkg.name);
-				} else {
-					choose_ignorepkgs_dialog.pkgs_list.insert_with_values (out iter, -1, 0, true, 1, pkg.name);
-				}
+			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+			while (Gtk.events_pending ()) {
+				Gtk.main_iteration ();
 			}
-			if (choose_ignorepkgs_dialog.run () == Gtk.ResponseType.OK) {
-				var ignorepkg_string = new StringBuilder ();
-				choose_ignorepkgs_dialog.pkgs_list.foreach ((model, path, iter) => {
-					GLib.Value val;
-					// get value at column 0 to know if it is selected
-					choose_ignorepkgs_dialog.pkgs_list.get_value (iter, 0, out val);
-					if ((bool) val) {
-						// get value at column 1 to get the pkg name
-						choose_ignorepkgs_dialog.pkgs_list.get_value (iter, 1, out val);
-						if (ignorepkg_string.len != 0) {
-							ignorepkg_string.append (" ");
-						}
-						ignorepkg_string.append ((string) val);
+			transaction.get_installed_pkgs.begin ((obj, res) => {
+				var pkgs = transaction.get_installed_pkgs.end (res);
+				foreach (unowned AlpmPackage pkg in pkgs) {
+					if (pkg.name in transaction.get_ignorepkgs ()) {
+						choose_ignorepkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, true, 1, pkg.name);
+					} else {
+						choose_ignorepkgs_dialog.pkgs_list.insert_with_values (null, -1, 0, false, 1, pkg.name);
 					}
-					return false;
-				});
-				if (ignorepkg_string.len != 0) {
+				}
+				this.get_window ().set_cursor (null);
+				if (choose_ignorepkgs_dialog.run () == Gtk.ResponseType.OK) {
+					var ignorepkg_string = new StringBuilder ();
+					choose_ignorepkgs_dialog.pkgs_list.foreach ((model, path, iter) => {
+						GLib.Value val;
+						// get value at column 0 to know if it is selected
+						model.get_value (iter, 0, out val);
+						if ((bool) val) {
+							// get value at column 1 to get the pkg name
+							model.get_value (iter, 1, out val);
+							if (ignorepkg_string.len != 0) {
+								ignorepkg_string.append (" ");
+							}
+							ignorepkg_string.append ((string) val);
+						}
+						return false;
+					});
 					var new_alpm_conf = new HashTable<string,Variant> (str_hash, str_equal);
 					new_alpm_conf.insert ("IgnorePkg", new Variant.string (ignorepkg_string.str));
 					transaction.start_write_alpm_config (new_alpm_conf);
 				}
-			}
-			choose_ignorepkgs_dialog.destroy ();
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
-			}
+				choose_ignorepkgs_dialog.destroy ();
+				while (Gtk.events_pending ()) {
+					Gtk.main_iteration ();
+				}
+			});
 		}
 
 		[GtkCallback]
@@ -293,7 +297,7 @@ namespace Pamac {
 				var ignorepkg_string = new StringBuilder ();
 				ignorepkgs_liststore.foreach ((model, path, iter) => {
 					GLib.Value name;
-					ignorepkgs_liststore.get_value (iter, 0, out name);
+					model.get_value (iter, 0, out name);
 					if (ignorepkg_string.len != 0) {
 						ignorepkg_string.append (" ");
 					}
@@ -303,16 +307,15 @@ namespace Pamac {
 				var new_alpm_conf = new HashTable<string,Variant> (str_hash, str_equal);
 				new_alpm_conf.insert ("IgnorePkg", new Variant.string (ignorepkg_string.str));
 				transaction.start_write_alpm_config (new_alpm_conf);
+
 			}
 		}
 
 		void on_write_alpm_config_finished (bool checkspace) {
 			check_space_button.state = checkspace;
-			// re-populate ignorepkgs_liststore
-			Gtk.TreeIter iter;
 			ignorepkgs_liststore.clear ();
-			foreach (unowned string ignorepkg in transaction.alpm_utils.get_ignorepkgs ()) {
-				ignorepkgs_liststore.insert_with_values (out iter, -1, 0, ignorepkg);
+			foreach (unowned string ignorepkg in transaction.get_ignorepkgs ()) {
+				ignorepkgs_liststore.insert_with_values (null, -1, 0, ignorepkg);
 			}
 		}
 
diff --git a/src/transaction.vala b/src/transaction.vala
index fcec28f9e66ec8d70b455dfc80a40c56ddbfe9d2..3c0e66da7722566e6645aabad89f59078164ac37 100644
--- a/src/transaction.vala
+++ b/src/transaction.vala
@@ -28,20 +28,40 @@ namespace Pamac {
 		public abstract void start_write_mirrors_config (HashTable<string,Variant> new_mirrors_conf) throws IOError;
 		public abstract void start_generate_mirrors_list () throws IOError;
 		public abstract void start_set_pkgreason (string pkgname, uint reason) throws IOError;
-		public abstract PackageInfos get_installed_pkg (string pkgname) throws IOError;
+		public abstract AlpmPackage get_installed_pkg (string pkgname) throws IOError;
 		public abstract void start_refresh (bool force) throws IOError;
+		public abstract bool get_checkspace () throws IOError;
+		public abstract string[] get_ignorepkgs () throws IOError;
+		public abstract bool should_hold (string pkgname) throws IOError;
+		public abstract uint get_pkg_reason (string pkgname) throws IOError;
+		public abstract uint get_pkg_origin (string pkgname) throws IOError;
+		public abstract async AlpmPackage[] get_installed_pkgs () throws IOError;
+		public abstract async AlpmPackage[] get_foreign_pkgs () throws IOError;
+		public abstract async AlpmPackage[] get_orphans () throws IOError;
+		public abstract AlpmPackage find_installed_satisfier (string depstring) throws IOError;
+		public abstract AlpmPackage get_sync_pkg (string pkgname) throws IOError;
+		public abstract AlpmPackage find_sync_satisfier (string depstring) throws IOError;
+		public abstract async AlpmPackage[] search_pkgs (string search_string) throws IOError;
+		public abstract async AURPackage[] search_in_aur (string search_string) throws IOError;
+		public abstract async string[] get_aur_build_list (string pkgname) throws IOError;
+		public abstract string[] get_repos_names () throws IOError;
+		public abstract async AlpmPackage[] get_repo_pkgs (string repo) throws IOError;
+		public abstract string[] get_groups_names () throws IOError;
+		public abstract async AlpmPackage[] get_group_pkgs (string groupname) throws IOError;
+		public abstract AlpmPackageDetails get_pkg_details (string pkgname) throws IOError;
+		public abstract async AURPackageDetails get_aur_details (string pkgname) throws IOError;
+		public abstract string[] get_pkg_uninstalled_optdeps (string pkgname) throws IOError;
 		public abstract void add_ignorepkg (string pkgname) throws IOError;
 		public abstract void remove_ignorepkg (string pkgname) throws IOError;
 		public abstract void start_get_updates (bool check_aur_updates) throws IOError;
-		public abstract bool trans_init (Alpm.TransFlag transflags) throws IOError;
+		public abstract bool trans_init (int transflags) throws IOError;
 		public abstract bool trans_sysupgrade (bool enable_downgrade) throws IOError;
 		public abstract bool trans_add_pkg (string pkgname) throws IOError;
 		public abstract bool trans_remove_pkg (string pkgname) throws IOError;
 		public abstract bool trans_load_pkg (string pkgpath) throws IOError;
 		public abstract void start_trans_prepare () throws IOError;
 		public abstract void choose_provider (int provider) throws IOError;
-		public abstract PackageInfos[] trans_to_add () throws IOError;
-		public abstract PackageInfos[] trans_to_remove () throws IOError;
+		public abstract TransactionSummary get_transaction_summary () throws IOError;
 		public abstract void start_trans_commit () throws IOError;
 		public abstract void trans_release () throws IOError;
 		[DBus (no_reply = true)]
@@ -84,24 +104,32 @@ namespace Pamac {
 
 		Daemon daemon;
 
-		public AlpmUtils alpm_utils;
-		public Pamac.Config pamac_config;
+		Pamac.Config pamac_config;
+		public bool check_aur_updates { get { return pamac_config.check_aur_updates; } }
+		public bool enable_aur { get { return pamac_config.enable_aur; }  }
+		public unowned GLib.HashTable<string,string> environment_variables { get {return pamac_config.environment_variables; } }
+		public bool no_confirm_build { get { return pamac_config.no_confirm_build; } }
+		public bool no_update_hide_icon { get { return pamac_config.no_update_hide_icon; } }
+		public bool recurse { get { return pamac_config.no_confirm_build; } }
+		public uint64 refresh_period { get { return pamac_config.refresh_period; } }
+		public bool search_aur { get { return pamac_config.search_aur; } }
 
-		public Alpm.TransFlag flags;
+		//Alpm.TransFlag
+		int flags;
 
-		public GenericSet<string?> to_add;
+		public GenericSet<string?> to_install;
 		public GenericSet<string?> to_remove;
 		public GenericSet<string?> to_load;
 		public GenericSet<string?> to_build;
+		GenericSet<string?> previous_to_install;
+		GenericSet<string?> previous_to_remove;
+		public GenericSet<string?> transaction_summary;
 		public GenericSet<string?> temporary_ignorepkgs;
 
-		HashTable<string,Json.Object> aur_infos;
-
-		public Mode mode;
+		public Mode mode { get; set; }
 
 		uint64 total_download;
 		uint64 already_downloaded;
-		string previous_label;
 		string previous_textbar;
 		float previous_percent;
 		string previous_filename;
@@ -112,7 +140,6 @@ namespace Pamac {
 		uint64 download_rate;
 		uint64 rates_nb;
 		Timer timer;
-		bool database_modified;
 		bool success;
 
 		//dialogs
@@ -120,8 +147,11 @@ namespace Pamac {
 		TransactionInfoDialog transaction_info_dialog;
 		ProgressDialog progress_dialog;
 		//parent window
-		public Gtk.ApplicationWindow? application_window;
+		public Gtk.ApplicationWindow? application_window { get; private set; }
 
+		public signal void start_transaction ();
+		public signal void emit_action (string action);
+		public signal void alpm_handle_refreshed ();
 		public signal void finished (bool success);
 		public signal void set_pkgreason_finished ();
 		public signal void get_updates_finished (Updates updates);
@@ -132,36 +162,36 @@ namespace Pamac {
 		public signal void write_mirrors_config_finished (string choosen_country, string choosen_generation_method);
 
 		public Transaction (Gtk.ApplicationWindow? application_window) {
-			alpm_utils = new AlpmUtils ("/etc/pacman.conf");
 			pamac_config = new Pamac.Config ("/etc/pamac.conf");
-			flags = Alpm.TransFlag.CASCADE;
+			flags = (1 << 4); //Alpm.TransFlag.CASCADE
 			if (pamac_config.recurse) {
-				flags |= Alpm.TransFlag.RECURSE;
+				flags |= (1 << 5); //Alpm.TransFlag.RECURSE
 			}
 			
-			to_add = new GenericSet<string?> (str_hash, str_equal);
+			to_install = new GenericSet<string?> (str_hash, str_equal);
 			to_remove = new GenericSet<string?> (str_hash, str_equal);
 			to_load = new GenericSet<string?> (str_hash, str_equal);
 			to_build = new GenericSet<string?> (str_hash, str_equal);
+			previous_to_install = new GenericSet<string?> (str_hash, str_equal);
+			previous_to_remove = new GenericSet<string?> (str_hash, str_equal);
+			transaction_summary = new GenericSet<string?> (str_hash, str_equal);
 			temporary_ignorepkgs = new GenericSet<string?> (str_hash, str_equal);
-			aur_infos = new HashTable<string,Json.Object> (str_hash, str_equal);
 			connecting_dbus_signals ();
 			//creating dialogs
 			this.application_window = application_window;
 			transaction_sum_dialog = new TransactionSumDialog (application_window);
 			transaction_info_dialog = new TransactionInfoDialog (application_window);
 			progress_dialog = new ProgressDialog (application_window);
-			progress_dialog.close_button.clicked.connect (on_progress_dialog_close_button_clicked);
+			progress_dialog.close_button.clicked.connect (hide_progress);
+			progress_dialog.delete_event.connect (progress_dialog.hide_on_delete);
 			progress_dialog.cancel_button.clicked.connect (on_progress_dialog_cancel_button_clicked);
 			// connect to child_exited signal which will only be emit after a call to watch_child
 			progress_dialog.term.child_exited.connect (on_term_child_exited);
 			// progress data
-			previous_label = "";
 			previous_textbar = "";
 			previous_filename = "";
 			sysupgrade_after_trans = false;
 			timer = new Timer ();
-			database_modified = false;
 			success = false;
 		}
 
@@ -224,16 +254,31 @@ namespace Pamac {
 			}
 		}
 
+		public void show_progress () {
+			progress_dialog.show ();
+		}
+
+		public void hide_progress () {
+			progress_dialog.hide ();
+		}
+
+		void reset_progress_dialog (string action,
+									bool cancel_button_visible = true,
+									bool expander_expanded = false) {
+			progress_dialog.spawn_in_term ({"echo", action});
+			progress_dialog.action_label.label = action;
+			progress_dialog.progressbar.fraction = 0;
+			progress_dialog.progressbar.text = "";
+			progress_dialog.cancel_button.visible = cancel_button_visible;
+			progress_dialog.expander.expanded = expander_expanded;
+			if (expander_expanded) {
+				progress_dialog.width_request = 700;
+			}
+		}
+
 		public void start_generate_mirrors_list () {
 			string action = dgettext (null, "Refreshing mirrors list") + "...";
-			progress_dialog.spawn_in_term ({"echo", action});
-			progress_dialog.action_label.set_text (action);
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.progressbar.set_text ("");
-			progress_dialog.cancel_button.set_visible (false);
-			progress_dialog.close_button.set_visible (false);
-			progress_dialog.expander.set_expanded (true);
-			progress_dialog.width_request = 700;
+			reset_progress_dialog (action, false, true);
 			pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_dialog.progressbar.pulse);
 			progress_dialog.show ();
 			while (Gtk.events_pending ()) {
@@ -247,9 +292,9 @@ namespace Pamac {
 			}
 		}
 
-		public void start_set_pkgreason (string pkgname, Alpm.Package.Reason reason) {
+		public void start_set_pkgreason (string pkgname, uint reason) {
 			try {
-				daemon.start_set_pkgreason (pkgname, (uint) reason);
+				daemon.start_set_pkgreason (pkgname, reason);
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
 			}
@@ -257,15 +302,13 @@ namespace Pamac {
 
 		public void start_refresh (bool force) {
 			string action = dgettext (null, "Synchronizing package databases") + "...";
-			progress_dialog.spawn_in_term ({"echo", action});
-			progress_dialog.action_label.set_text (action);
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.progressbar.set_text ("");
-			progress_dialog.cancel_button.set_visible (true);
-			progress_dialog.close_button.set_visible (false);
-			progress_dialog.show ();
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
+			reset_progress_dialog (action);
+			emit_action (action);
+			if (mode != Mode.MANAGER) {
+				progress_dialog.show ();
+				while (Gtk.events_pending ()) {
+					Gtk.main_iteration ();
+				}
 			}
 			try {
 				daemon.refresh_finished.connect (on_refresh_finished);
@@ -273,12 +316,264 @@ namespace Pamac {
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
 				daemon.refresh_finished.disconnect (on_refresh_finished);
-				database_modified = true;
 				success = false;
 				finish_transaction ();
 			}
 		}
 
+		public bool get_checkspace () {
+			bool checkspace = false;
+			try {
+				checkspace = daemon.get_checkspace ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return checkspace;
+		}
+
+		public string[] get_ignorepkgs () {
+			string[] ignorepkgs = {};
+			try {
+				ignorepkgs = daemon.get_ignorepkgs ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return ignorepkgs;
+		}
+
+		public AlpmPackage get_installed_pkg (string pkgname) {
+			try {
+				return daemon.get_installed_pkg (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				return AlpmPackage () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = ""
+				};
+			}
+		}
+
+		public AlpmPackage find_installed_satisfier (string depstring) {
+			try {
+				return daemon.find_installed_satisfier (depstring);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				return AlpmPackage () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = ""
+				};
+			}
+		}
+
+		public bool should_hold (string pkgname) {
+			bool should_hold = false;
+			try {
+				should_hold = daemon.should_hold (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return should_hold;
+		}
+
+		public uint get_pkg_reason (string pkgname) {
+			uint reason = 0;
+			try {
+				reason = daemon.get_pkg_reason (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return reason;
+		}
+
+		public uint get_pkg_origin (string pkgname) {
+			uint origin = 0;
+			try {
+				origin = daemon.get_pkg_origin (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return origin;
+		}
+
+		public async AlpmPackage[] get_installed_pkgs () {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.get_installed_pkgs ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public async AlpmPackage[] get_foreign_pkgs () {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.get_foreign_pkgs ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public async AlpmPackage[] get_orphans () {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.get_orphans ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public AlpmPackage get_sync_pkg (string pkgname) {
+			try {
+				return daemon.get_sync_pkg (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				return AlpmPackage () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = ""
+				};
+			}
+		}
+
+		public AlpmPackage find_sync_satisfier (string depstring) {
+			try {
+				return daemon.find_sync_satisfier (depstring);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				return AlpmPackage () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = ""
+				};
+			}
+		}
+
+		public async AlpmPackage[] search_pkgs (string search_string) {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.search_pkgs (search_string);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public async AURPackage[] search_in_aur (string search_string) {
+			AURPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.search_in_aur (search_string);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public async string[] get_aur_build_list (string pkgname) {
+			string[] names = {};
+			try {
+				names = yield daemon.get_aur_build_list (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return names;
+		}
+
+		public string[] get_repos_names () {
+			string[] repos_names = {};
+			try {
+				repos_names = daemon.get_repos_names ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return repos_names;
+		}
+
+		public async AlpmPackage[] get_repo_pkgs (string repo) {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.get_repo_pkgs (repo);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public string[] get_groups_names () {
+			string[] groups_names = {};
+			try {
+				groups_names = daemon.get_groups_names ();
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return groups_names;
+		}
+
+		public async AlpmPackage[] get_group_pkgs (string group_name) {
+			AlpmPackage[] pkgs = {};
+			try {
+				pkgs = yield daemon.get_group_pkgs (group_name);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return pkgs;
+		}
+
+		public string[] get_pkg_uninstalled_optdeps (string pkgname) {
+			string[] optdeps = {};
+			try {
+				optdeps = daemon.get_pkg_uninstalled_optdeps (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+			}
+			return optdeps;
+		}
+
+		public AlpmPackageDetails get_pkg_details (string pkgname) {
+			try {
+				return daemon.get_pkg_details (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				return AlpmPackageDetails () {
+					name = "",
+					version = "",
+					desc = "",
+					repo = "",
+					url = "",
+					packager = "",
+					builddate = "",
+					installdate = "",
+					reason = "",
+					has_signature = ""
+				};
+			}
+		}
+
+		public async AURPackageDetails get_aur_details (string pkgname) {
+			var pkg = AURPackageDetails () {
+				name = "",
+				version = "",
+				desc = "",
+				packagebase = "",
+				url = "",
+				maintainer = ""
+			};
+			try {
+				pkg = yield daemon.get_aur_details (pkgname);
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message); 
+			}
+			return pkg;
+		}
+
 		public void start_get_updates () {
 			daemon.get_updates_finished.connect (on_get_updates_finished);
 			try {
@@ -318,7 +613,7 @@ namespace Pamac {
 			}
 		}
 
-		public bool init (Alpm.TransFlag flags) {
+		public bool init (int flags) {
 			foreach (unowned string pkgname in temporary_ignorepkgs) {
 				add_ignorepkg (pkgname);
 			}
@@ -331,8 +626,8 @@ namespace Pamac {
 		}
 
 		void sysupgrade_simple (bool enable_downgrade) {
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.cancel_button.set_visible (true);
+			progress_dialog.progressbar.fraction = 0;
+			progress_dialog.cancel_button.visible = true;
 			success = init (0);
 			if (success) {
 				try {
@@ -342,9 +637,11 @@ namespace Pamac {
 					success = false;
 				}
 				if (success) {
-					progress_dialog.show ();
-					while (Gtk.events_pending ()) {
-						Gtk.main_iteration ();
+					if (mode != Mode.MANAGER) {
+						progress_dialog.show ();
+						while (Gtk.events_pending ()) {
+							Gtk.main_iteration ();
+						}
 					}
 					try {
 						daemon.start_trans_prepare ();
@@ -366,15 +663,8 @@ namespace Pamac {
 		public void sysupgrade (bool enable_downgrade) {
 			this.enable_downgrade = enable_downgrade;
 			string action = dgettext (null, "Starting full system upgrade") + "...";
-			progress_dialog.spawn_in_term ({"echo", action});
-			progress_dialog.action_label.set_text (action);
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.progressbar.set_text ("");
-			progress_dialog.cancel_button.set_visible (true);
-			progress_dialog.close_button.set_visible (false);
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
-			}
+			reset_progress_dialog (action);
+			emit_action (action);
 			start_get_updates_for_sysupgrade ();
 		}
 
@@ -391,15 +681,15 @@ namespace Pamac {
 				if (mode == Mode.MANAGER) {
 					sysupgrade_after_trans = true;
 				}
-				foreach (unowned PackageInfos infos in updates.repos_updates) {
-					to_add.add (infos.name);
+				foreach (unowned UpdateInfos infos in updates.repos_updates) {
+					to_install.add (infos.name);
 				}
 				// run as a standard transaction
 				run ();
 			} else {
 				if (updates.aur_updates.length != 0) {
 					clear_lists ();
-					foreach (unowned PackageInfos infos in updates.aur_updates) {
+					foreach (unowned UpdateInfos infos in updates.aur_updates) {
 						if (!(infos.name in temporary_ignorepkgs)) {
 							to_build.add (infos.name);
 						}
@@ -408,35 +698,34 @@ namespace Pamac {
 				if (updates.repos_updates.length != 0) {
 					sysupgrade_simple (enable_downgrade);
 				} else {
-					progress_dialog.show ();
-					while (Gtk.events_pending ()) {
-						Gtk.main_iteration ();
-					}
 					on_trans_prepare_finished (true);
 				}
 			}
 		}
 
 		public void clear_lists () {
-			to_add.remove_all ();
+			to_install.remove_all ();
 			to_remove.remove_all ();
 			to_build.remove_all ();
 		}
 
+		void clear_previous_lists () {
+			previous_to_install.remove_all ();
+			previous_to_remove.remove_all ();
+		}
+
 		public void run () {
 			string action = dgettext (null, "Preparing") + "...";
-			progress_dialog.spawn_in_term ({"echo", action});
-			progress_dialog.action_label.set_text (action);
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.progressbar.set_text ("");
-			progress_dialog.cancel_button.set_visible (true);
-			progress_dialog.close_button.set_visible (false);
-			progress_dialog.show ();
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
+			reset_progress_dialog (action);
+			emit_action (action);
+			if (mode != Mode.MANAGER) {
+				progress_dialog.show ();
+				while (Gtk.events_pending ()) {
+					Gtk.main_iteration ();
+				}
 			}
 			// run
-			if (to_add.length == 0
+			if (to_install.length == 0
 					&& to_remove.length == 0
 					&& to_load.length == 0
 					&& to_build.length != 0) {
@@ -451,7 +740,7 @@ namespace Pamac {
 				}
 				if (success) {
 					success = false;
-					foreach (unowned string name in to_add) {
+					foreach (unowned string name in to_install) {
 						try {
 							success = daemon.trans_add_pkg (name);
 						} catch (IOError e) {
@@ -523,142 +812,116 @@ namespace Pamac {
 			// return 0 if transaction_sum is empty, 2, if there are only aur updates, 1 otherwise
 			Type type = 0;
 			uint64 dsize = 0;
-			PackageInfos[] prepared_to_add = {};
-			PackageInfos[] prepared_to_remove = {};
-			string[] to_downgrade = {};
-			string[] to_install = {};
-			string[] to_reinstall = {};
-			string[] to_update = {};
-			string[] _to_build = {};
-			Gtk.TreeIter iter;
+			transaction_summary.remove_all ();
+			var summary = TransactionSummary ();
 			transaction_sum_dialog.top_label.set_markup ("<big><b>%s</b></big>".printf (dgettext (null, "Transaction Summary")));
 			transaction_sum_dialog.sum_list.clear ();
 			try {
-				prepared_to_add = daemon.trans_to_add ();
-				prepared_to_remove = daemon.trans_to_remove ();
+				summary = daemon.get_transaction_summary ();
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
 			}
-			foreach (unowned PackageInfos pkg_info in prepared_to_add) {
-				dsize += pkg_info.download_size;
-				try {
-					PackageInfos local_pkg_info = daemon.get_installed_pkg (pkg_info.name);
-					if (local_pkg_info.name == "") {
-						to_install += "%s %s".printf (pkg_info.name, pkg_info.version);
-					} else {
-						int cmp = Alpm.pkg_vercmp (pkg_info.version, local_pkg_info.version);
-						if (cmp == 1) {
-							to_update += "%s %s".printf (pkg_info.name, pkg_info.version);
-						} else if (cmp == 0) {
-							to_reinstall += "%s %s".printf (pkg_info.name, pkg_info.version);
-						} else {
-							to_downgrade += "%s %s".printf (pkg_info.name, pkg_info.version);
-						}
-					}
-				} catch (IOError e) {
-					stderr.printf ("IOError: %s\n", e.message);
-				}
-			}
-			foreach (unowned string name in to_build) {
-				_to_build += name;
-			}
-			int len = prepared_to_remove.length;
-			int i;
-			if (len != 0) {
+			var iter = Gtk.TreeIter ();
+			if (summary.to_remove.length > 0) {
 				type |= Type.STANDARD;
-				transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "To remove") + ":",
-												1, "%s %s".printf (prepared_to_remove[0].name, prepared_to_remove[0].version));
-				i = 1;
-				while (i < len) {
+				foreach (unowned UpdateInfos infos in summary.to_remove) {
+					transaction_summary.add (infos.name);
 					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												1, "%s %s".printf (prepared_to_remove[i].name, prepared_to_remove[i].version));
-					i++;
+												1, infos.name,
+												2, infos.old_version);
 				}
+				Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (summary.to_remove.length - 1);
+				transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To remove") + ":"));
 			}
-			len = to_downgrade.length;
-			if (len != 0) {
+			if (summary.to_downgrade.length > 0) {
 				type |= Type.STANDARD;
-				transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "To downgrade") + ":",
-												1, to_downgrade[0]);
-				i = 1;
-				while (i < len) {
+				foreach (unowned UpdateInfos infos in summary.to_downgrade) {
+					dsize += infos.download_size;
+					transaction_summary.add (infos.name);
 					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												1, to_downgrade[i]);
-					i++;
+												1, infos.name,
+												2, infos.new_version,
+												3, "(%s)".printf (infos.old_version));
 				}
+				Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (summary.to_downgrade.length - 1);
+				transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To downgrade") + ":"));
 			}
-			len = _to_build.length;
-			if (len != 0) {
+			if (to_build.length > 0) {
 				type |= Type.BUILD;
-				transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "To build") + ":",
-												1, _to_build[0]);
-				i = 1;
-				while (i < len) {
+				foreach (unowned string name in to_build) {
+					transaction_summary.add (name);
 					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												1, _to_build[i]);
-					i++;
+												1, name);
 				}
+				Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - ((int) to_build.length - 1);
+				transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To build") + ":"));
 			}
-			len = to_install.length;
-			if (len != 0) {
+			if (summary.to_install.length > 0) {
 				type |= Type.STANDARD;
-				transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "To install") + ":",
-												1, to_install[0]);
-				i = 1;
-				while (i < len) {
+				foreach (unowned UpdateInfos infos in summary.to_install) {
+					dsize += infos.download_size;
+					transaction_summary.add (infos.name);
 					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												1, to_install[i]);
-					i++;
+												1, infos.name,
+												2, infos.new_version);
 				}
+				Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (summary.to_install.length - 1);
+				transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To install") + ":"));
 			}
-			len = to_reinstall.length;
-			if (len != 0) {
+			if (summary.to_reinstall.length > 0) {
 				type |= Type.STANDARD;
-				transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												0, dgettext (null, "To reinstall") + ":",
-												1, to_reinstall[0]);
-				i = 1;
-				while (i < len) {
+				foreach (unowned UpdateInfos infos in summary.to_reinstall) {
+					dsize += infos.download_size;
+					transaction_summary.add (infos.name);
 					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-												1, to_reinstall[i]);
-					i++;
+												1, infos.name,
+												2, infos.old_version);
 				}
+				Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+				int pos = (path.get_indices ()[0]) - (summary.to_reinstall.length - 1);
+				transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+				transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To reinstall") + ":"));
 			}
-			len = to_update.length;
-			if (len != 0) {
+			if (summary.to_upgrade.length > 0) {
 				type |= Type.UPDATE;
 				if (mode != Mode.UPDATER) {
-					transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-													0, dgettext (null, "To update") + ":",
-													1, to_update[0]);
-					i = 1;
-					while (i < len) {
+					foreach (unowned UpdateInfos infos in summary.to_upgrade) {
+						dsize += infos.download_size;
+						transaction_summary.add (infos.name);
 						transaction_sum_dialog.sum_list.insert_with_values (out iter, -1,
-													1, to_update[i]);
-						i++;
+												1, infos.name,
+												2, infos.new_version,
+												3, "(%s)".printf (infos.old_version));
 					}
+					Gtk.TreePath path = transaction_sum_dialog.sum_list.get_path (iter);
+					int pos = (path.get_indices ()[0]) - (summary.to_upgrade.length - 1);
+					transaction_sum_dialog.sum_list.get_iter (out iter, new Gtk.TreePath.from_indices (pos));
+					transaction_sum_dialog.sum_list.set (iter, 0, "<b>%s</b>".printf (dgettext (null, "To update") + ":"));
 				}
 			}
 			if (dsize == 0) {
-				transaction_sum_dialog.bottom_label.set_visible (false);
+				transaction_sum_dialog.bottom_label.visible = false;
 			} else {
 				transaction_sum_dialog.bottom_label.set_markup ("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size (dsize)));
-				transaction_sum_dialog.bottom_label.set_visible (true);
+				transaction_sum_dialog.bottom_label.visible = true;
 			}
 			return type;
 		}
 
 		public void start_commit () {
-			progress_dialog.cancel_button.set_visible (false);
+			progress_dialog.cancel_button.visible = false;
 			try {
 				daemon.start_trans_commit ();
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
-				database_modified = true;
 				success = false;
 				finish_transaction ();
 			}
@@ -666,16 +929,15 @@ namespace Pamac {
 
 		public void build_aur_packages () {
 			string action = dgettext (null, "Building packages") + "...";
-			progress_dialog.spawn_in_term ({"echo", action});
-			progress_dialog.action_label.set_text (action);
-			progress_dialog.progressbar.set_fraction (0);
-			progress_dialog.progressbar.set_text ("");
-			progress_dialog.cancel_button.set_visible (false);
-			progress_dialog.close_button.set_visible (false);
-			progress_dialog.expander.set_expanded (true);
-			progress_dialog.width_request = 700;
+			reset_progress_dialog (action, false, true);
+			emit_action (action);
 			progress_dialog.term.grab_focus ();
 			pulse_timeout_id = Timeout.add (500, (GLib.SourceFunc) progress_dialog.progressbar.pulse);
+			progress_dialog.close_button.visible = false;
+			progress_dialog.show ();
+			while (Gtk.events_pending ()) {
+				Gtk.main_iteration ();
+			}
 			string[] cmds = {"yaourt", "-S"};
 			if (pamac_config.no_confirm_build) {
 				cmds += "--noconfirm";
@@ -687,14 +949,15 @@ namespace Pamac {
 			progress_dialog.spawn_in_term (cmds, out child_pid);
 			// watch_child is needed in order to have the child_exited signal emitted
 			progress_dialog.term.watch_child (child_pid);
-		}
-
-		public async Json.Object get_aur_infos (string aur_name) {
-			if (!aur_infos.contains (aur_name)) {
-				Json.Array results = AUR.multiinfo ({aur_name});
-				aur_infos.insert (aur_name, results.get_object_element (0));
-			}
-			return aur_infos.lookup (aur_name);
+//~ 			foreach (unowned string pkgname in to_build) {
+//~ 				stdout.printf("aur deps for %s:\n", pkgname);
+//~ 				get_aur_build_list.begin (pkgname, (obj, res) => {
+//~ 					string[] names = get_aur_build_list.end (res);
+//~ 					foreach (unowned string name in names) {
+//~ 						stdout.printf("\t%s\n", name);
+//~ 					}
+//~ 				});
+//~ 			}
 		}
 
 		public void cancel () {
@@ -703,7 +966,9 @@ namespace Pamac {
 			} catch (IOError e) {
 				stderr.printf ("IOError: %s\n", e.message);
 			}
-			progress_dialog.expander.set_expanded (false);
+			progress_dialog.hide ();
+			progress_dialog.spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"});
+			progress_dialog.expander.expanded = false;
 			Gtk.TextIter start_iter;
 			Gtk.TextIter end_iter;
 			transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
@@ -731,188 +996,167 @@ namespace Pamac {
 		}
 
 		void on_emit_event (uint primary_event, uint secondary_event, string[] details) {
-			string msg;
+			string? action = null;
+			string? detailed_action = null;
 			switch (primary_event) {
-				case Alpm.Event.Type.HOOK_START:
-					switch (secondary_event) {
-						case Alpm.HookWhen.PRE_TRANSACTION:
-							msg = dgettext (null, "Running pre-transaction hooks") + "...";
-							progress_dialog.action_label.set_text (msg);
-							progress_dialog.spawn_in_term ({"echo", msg});
-							break;
-						case Alpm.HookWhen.POST_TRANSACTION:
-							msg = dgettext (null, "Running post-transaction hooks") + "...";
-							progress_dialog.action_label.set_text (msg);
-							progress_dialog.spawn_in_term ({"echo", msg});
-							break;
-						default:
-							break;
-					}
-					break;
-				case Alpm.Event.Type.HOOK_RUN_START:
-					string textbar = "%s/%s".printf (details[2], details[3]);
-					if (textbar != previous_textbar) {
-						previous_textbar = textbar;
-						progress_dialog.progressbar.set_text (textbar);
-					}
-					float fraction = (float) int.parse (details[2]) / int.parse (details[3]);
-					if (fraction != previous_percent) {
-						previous_percent = fraction;
-						progress_dialog.progressbar.set_fraction (fraction);
-					}
-					if (details[1] != "") {
-						msg = details[1] + ":";
-					} else {
-						msg = details[0] + ":";
-					}
-					progress_dialog.spawn_in_term ({"echo", msg});
-					break;
-				case Alpm.Event.Type.CHECKDEPS_START:
-					msg = dgettext (null, "Checking dependencies") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 1: //Alpm.Event.Type.CHECKDEPS_START
+					action = dgettext (null, "Checking dependencies") + "...";
 					break;
-				case Alpm.Event.Type.FILECONFLICTS_START:
-					msg = dgettext (null, "Checking file conflicts") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 3: //Alpm.Event.Type.FILECONFLICTS_START
+					action = dgettext (null, "Checking file conflicts") + "...";
 					break;
-				case Alpm.Event.Type.RESOLVEDEPS_START:
-					msg = dgettext (null, "Resolving dependencies") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 5: //Alpm.Event.Type.RESOLVEDEPS_START
+					action = dgettext (null, "Resolving dependencies") + "...";
 					break;
-				case Alpm.Event.Type.INTERCONFLICTS_START:
-					msg = dgettext (null, "Checking inter-conflicts") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 7: //Alpm.Event.Type.INTERCONFLICTS_START
+					action = dgettext (null, "Checking inter-conflicts") + "...";
 					break;
-				case Alpm.Event.Type.TRANSACTION_START:
-					progress_dialog.cancel_button.set_visible (false);
+				case 9: //Alpm.Event.Type.TRANSACTION_START
+					progress_dialog.cancel_button.visible = false;
+					start_transaction ();
 					break;
-				case Alpm.Event.Type.PACKAGE_OPERATION_START:
+				case 11: //Alpm.Event.Type.PACKAGE_OPERATION_START
 					switch (secondary_event) {
-						case Alpm.Package.Operation.INSTALL:
+						// special cases handle differently
+						case 1: //Alpm.Package.Operation.INSTALL
 							previous_filename = details[0];
-							msg = dgettext (null, "Installing %s").printf (details[0]) + "...";
-							progress_dialog.action_label.set_text (msg);
-							msg = dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
-							progress_dialog.spawn_in_term ({"echo", msg});
+							string msg = dgettext (null, "Installing %s").printf (details[0]) + "...";
+							progress_dialog.action_label.label = msg;
+							emit_action (msg);
+							progress_dialog.spawn_in_term ({"echo", dgettext (null, "Installing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."});
 							break;
-						case Alpm.Package.Operation.REINSTALL:
+						case 2: //Alpm.Package.Operation.UPGRADE
 							previous_filename = details[0];
-							msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "...";
-							progress_dialog.action_label.set_text (msg);
-							msg = dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
-							progress_dialog.spawn_in_term ({"echo", msg});
+							string msg = dgettext (null, "Upgrading %s").printf (details[0]) + "...";
+							progress_dialog.action_label.label = msg;
+							emit_action (msg);
+							progress_dialog.spawn_in_term ({"echo", dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."});
 							break;
-						case Alpm.Package.Operation.REMOVE:
+						case 3: //Alpm.Package.Operation.REINSTALL
 							previous_filename = details[0];
-							msg = dgettext (null, "Removing %s").printf (details[0]) + "...";
-							progress_dialog.action_label.set_text (msg);
-							msg = dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "...";
-							progress_dialog.spawn_in_term ({"echo", msg});
+							string msg = dgettext (null, "Reinstalling %s").printf (details[0]) + "...";
+							progress_dialog.action_label.label = msg;
+							emit_action (msg);
+							progress_dialog.spawn_in_term ({"echo", dgettext (null, "Reinstalling %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."});
 							break;
-						case Alpm.Package.Operation.UPGRADE:
+						case 4: //Alpm.Package.Operation.DOWNGRADE
 							previous_filename = details[0];
-							msg = dgettext (null, "Upgrading %s").printf (details[0]) + "...";
-							progress_dialog.action_label.set_text (msg);
-							msg = dgettext (null, "Upgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "...";
-							progress_dialog.spawn_in_term ({"echo", msg});
+							string msg = dgettext (null, "Downgrading %s").printf (details[0]) + "...";
+							progress_dialog.action_label.label = msg;
+							emit_action (msg);
+							progress_dialog.spawn_in_term ({"echo", dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "..."});
 							break;
-						case Alpm.Package.Operation.DOWNGRADE:
+						case 5: //Alpm.Package.Operation.REMOVE
 							previous_filename = details[0];
-							msg = dgettext (null, "Downgrading %s").printf (details[0]) + "...";
-							progress_dialog.action_label.set_text (msg);
-							msg = dgettext (null, "Downgrading %s").printf ("%s (%s -> %s)".printf (details[0], details[1], details[2]))+ "...";
-							progress_dialog.spawn_in_term ({"echo", msg});
+							string msg = dgettext (null, "Removing %s").printf (details[0]) + "...";
+							progress_dialog.action_label.label = msg;
+							emit_action (msg);
+							progress_dialog.spawn_in_term ({"echo", dgettext (null, "Removing %s").printf ("%s (%s)".printf (details[0], details[1]))+ "..."});
 							break;
 					}
 					break;
-				case Alpm.Event.Type.INTEGRITY_START:
-					msg = dgettext (null, "Checking integrity") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 13: //Alpm.Event.Type.INTEGRITY_START
+					action = dgettext (null, "Checking integrity") + "...";
 					break;
-				case Alpm.Event.Type.KEYRING_START:
-					progress_dialog.cancel_button.set_visible (true);
-					msg = dgettext (null, "Checking keyring") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 15: //Alpm.Event.Type.LOAD_START
+					action = dgettext (null, "Loading packages files") + "...";
 					break;
-				case Alpm.Event.Type.KEY_DOWNLOAD_START:
-					msg = dgettext (null, "Downloading required keys") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 17: //Alpm.Event.Type.DELTA_INTEGRITY_START
+					action = dgettext (null, "Checking delta integrity") + "...";
 					break;
-				case Alpm.Event.Type.LOAD_START:
-					msg = dgettext (null, "Loading packages files") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 19: //Alpm.Event.Type.DELTA_PATCHES_START
+					action = dgettext (null, "Applying deltas") + "...";
 					break;
-				case Alpm.Event.Type.DELTA_INTEGRITY_START:
-					msg = dgettext (null, "Checking delta integrity") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 21: //Alpm.Event.Type.DELTA_PATCH_START
+					detailed_action = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "...";
 					break;
-				case Alpm.Event.Type.DELTA_PATCHES_START:
-					msg = dgettext (null, "Applying deltas") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 22: //Alpm.Event.Type.DELTA_PATCH_DONE
+					detailed_action = dgettext (null, "Generation succeeded") + "...";
 					break;
-				case Alpm.Event.Type.DELTA_PATCH_START:
-					msg = dgettext (null, "Generating %s with %s").printf (details[0], details[1]) + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 23: //Alpm.Event.Type.DELTA_PATCH_FAILED
+					detailed_action = dgettext (null, "Generation failed") + "...";
 					break;
-				case Alpm.Event.Type.DELTA_PATCH_DONE:
-					msg = dgettext (null, "Generation succeeded") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 24: //Alpm.Event.Type.SCRIPTLET_INFO
+					progress_dialog.expander.expanded = true;
+					action = dgettext (null, "Configuring %s").printf (previous_filename) + "...";
+					detailed_action = details[0].replace ("\n", "");
 					break;
-				case Alpm.Event.Type.DELTA_PATCH_FAILED:
-					msg = dgettext (null, "Generation failed") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 25: //Alpm.Event.Type.RETRIEVE_START
+					progress_dialog.cancel_button.visible = true;
+					action = dgettext (null, "Downloading") + "...";
 					break;
-				case Alpm.Event.Type.SCRIPTLET_INFO:
-					progress_dialog.action_label.set_text (dgettext (null, "Configuring %s").printf (previous_filename) + "...");
-					progress_dialog.expander.set_expanded (true);
-					progress_dialog.spawn_in_term ({"echo", "-n", details[0]});
+				case 28: //Alpm.Event.Type.PKGDOWNLOAD_START
+					string name_version_release = details[0].slice (0, details[0].last_index_of_char ('-'));
+					string name_version = name_version_release.slice (0, name_version_release.last_index_of_char ('-'));
+					string name = name_version.slice (0, name_version.last_index_of_char ('-'));
+					action = dgettext (null, "Downloading %s").printf (name) + "...";
 					break;
-				case Alpm.Event.Type.RETRIEVE_START:
-					progress_dialog.cancel_button.set_visible (true);
-					msg = dgettext (null, "Downloading") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 31: //Alpm.Event.Type.DISKSPACE_START
+					action = dgettext (null, "Checking available disk space") + "...";
 					break;
-				case Alpm.Event.Type.DISKSPACE_START:
-					msg = dgettext (null, "Checking available disk space") + "...";
-					progress_dialog.action_label.set_text (msg);
-					progress_dialog.spawn_in_term ({"echo", msg});
-					break;
-				case Alpm.Event.Type.OPTDEP_REMOVAL:
-					msg = dgettext (null, "%s optionally requires %s").printf (details[0], details[1]);
-					progress_dialog.spawn_in_term ({"echo", msg});
+				case 33: //Alpm.Event.Type.OPTDEP_REMOVAL
+					detailed_action = dgettext (null, "%s optionally requires %s").printf (details[0], details[1]);
 					Gtk.TextIter end_iter;
-					msg += "\n";
+					string msg = detailed_action + "\n";
 					transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
 					transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length);
 					break;
-				case Alpm.Event.Type.DATABASE_MISSING:
-					progress_dialog.spawn_in_term ({"echo", dgettext (null, "Database file for %s does not exist").printf (details[0])});
+				case 34: //Alpm.Event.Type.DATABASE_MISSING
+					detailed_action = dgettext (null, "Database file for %s does not exist").printf (details[0]);
+					break;
+				case 35: //Alpm.Event.Type.KEYRING_START
+					progress_dialog.cancel_button.visible = true;
+					action = dgettext (null, "Checking keyring") + "...";
 					break;
-				case Alpm.Event.Type.PACNEW_CREATED:
-					progress_dialog.spawn_in_term ({"echo", dgettext (null, "%s installed as %s.pacnew").printf (details[0])});
+				case 37: //Alpm.Event.Type.KEY_DOWNLOAD_START
+					action = dgettext (null, "Downloading required keys") + "...";
 					break;
-				case Alpm.Event.Type.PACSAVE_CREATED:
-					progress_dialog.spawn_in_term ({"echo", dgettext (null, "%s installed as %s.pacsave").printf (details[0])});
+				case 39: //Alpm.Event.Type.PACNEW_CREATED
+					detailed_action = dgettext (null, "%s installed as %s.pacnew").printf (details[0]);
+					break;
+				case 40: //Alpm.Event.Type.PACSAVE_CREATED
+					detailed_action = dgettext (null, "%s installed as %s.pacsave").printf (details[0]);
+					break;
+				case 41: //Alpm.Event.Type.HOOK_START
+					switch (secondary_event) {
+						case 1: //Alpm.HookWhen.PRE_TRANSACTION
+							action = dgettext (null, "Running pre-transaction hooks") + "...";
+							break;
+						case 2: //Alpm.HookWhen.POST_TRANSACTION
+							action = dgettext (null, "Running post-transaction hooks") + "...";
+							break;
+						default:
+							break;
+					}
+					break;
+				case 43: // Alpm.Event.Type.HOOK_RUN_START
+					string textbar = "%s/%s".printf (details[2], details[3]);
+					if (textbar != previous_textbar) {
+						previous_textbar = textbar;
+						progress_dialog.progressbar.text = textbar;
+					}
+					float fraction = (float) int.parse (details[2]) / int.parse (details[3]);
+					if (fraction != previous_percent) {
+						previous_percent = fraction;
+						progress_dialog.progressbar.fraction = fraction;
+					}
+					if (details[1] != "") {
+						detailed_action = details[1] + ":";
+					} else {
+						detailed_action = details[0] + ":";
+					}
+					
 					break;
 				default:
 					break;
 			}
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
+			if (action != null) {
+				progress_dialog.action_label.label = action;
+				progress_dialog.spawn_in_term ({"echo", action});
+				emit_action (action);
+			}
+			if (detailed_action != null) {
+				progress_dialog.spawn_in_term ({"echo", detailed_action});
 			}
 		}
 
@@ -923,18 +1167,18 @@ namespace Pamac {
 		void on_emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target) {
 			float fraction;
 			switch (progress) {
-				case Alpm.Progress.ADD_START:
-				case Alpm.Progress.UPGRADE_START:
-				case Alpm.Progress.DOWNGRADE_START:
-				case Alpm.Progress.REINSTALL_START:
-				case Alpm.Progress.REMOVE_START:
+				case 0: //Alpm.Progress.ADD_START
+				case 1: //Alpm.Progress.UPGRADE_START
+				case 2: //Alpm.Progress.DOWNGRADE_START
+				case 3: //Alpm.Progress.REINSTALL_START
+				case 4: //Alpm.Progress.REMOVE_START
 					fraction = ((float) (current_target - 1) / n_targets) + ((float) percent / (100 * n_targets));
 					break;
-				case Alpm.Progress.CONFLICTS_START:
-				case Alpm.Progress.DISKSPACE_START:
-				case Alpm.Progress.INTEGRITY_START:
-				case Alpm.Progress.KEYRING_START:
-				case Alpm.Progress.LOAD_START:
+				case 5: //Alpm.Progress.CONFLICTS_START
+				case 6: //Alpm.Progress.DISKSPACE_START
+				case 7: //Alpm.Progress.INTEGRITY_START
+				case 8: //Alpm.Progress.LOAD_START
+				case 9: //Alpm.Progress.KEYRING_START
 				default:
 					fraction = (float) percent / 100;
 					break;
@@ -942,34 +1186,17 @@ namespace Pamac {
 			string textbar = "%lu/%lu".printf (current_target, n_targets);
 			if (textbar != previous_textbar) {
 				previous_textbar = textbar;
-				progress_dialog.progressbar.set_text (textbar);
+				progress_dialog.progressbar.text = textbar;
 			}
 			if (fraction != previous_percent) {
 				previous_percent = fraction;
-				progress_dialog.progressbar.set_fraction (fraction);
+				progress_dialog.progressbar.fraction = fraction;
 			}
-//~ 			while (Gtk.events_pending ()) {
-//~ 				Gtk.main_iteration ();
-//~ 			}
 		}
 
 		void on_emit_download (string filename, uint64 xfered, uint64 total) {
-			string label;
 			var text = new StringBuilder ();
 			float fraction;
-			if (filename != previous_filename) {
-				previous_filename = filename;
-				if (filename.has_suffix (".db")) {
-					label = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "...";
-				} else {
-					label = dgettext (null, "Downloading %s").printf (filename.replace (".pkg.tar.xz", "")) + "...";
-				}
-				if (label != previous_label) {
-					previous_label = label;
-					progress_dialog.action_label.set_text (label);
-					progress_dialog.spawn_in_term ({"echo", label});
-				}
-			}
 			if (total_download > 0) {
 				if (xfered == 0) {
 					previous_xfered = 0;
@@ -1017,6 +1244,13 @@ namespace Pamac {
 					rates_nb = 0;
 					fraction = 0;
 					timer.start ();
+					// start download pkg is handled by Alpm.Event.Type.PKGDOWNLOAD_START
+					if (filename.has_suffix (".db")) {
+						string action = dgettext (null, "Refreshing %s").printf (filename.replace (".db", "")) + "...";
+						progress_dialog.action_label.label = action;
+						progress_dialog.spawn_in_term ({"echo", action});
+						emit_action (action);
+					}
 				} else if (xfered == total) {
 					timer.stop ();
 					fraction = 1;
@@ -1053,11 +1287,11 @@ namespace Pamac {
 			}
 			if (fraction != previous_percent) {
 				previous_percent = fraction;
-				progress_dialog.progressbar.set_fraction (fraction);
+				progress_dialog.progressbar.fraction = fraction;
 			}
 			if (text.str != previous_textbar) {
 				previous_textbar = text.str;
-				progress_dialog.progressbar.set_text (text.str);
+				progress_dialog.progressbar.text = text.str;
 			}
 		}
 
@@ -1078,7 +1312,13 @@ namespace Pamac {
 			// msg ends with \n
 			string? line = null;
 			Gtk.TextIter end_iter;
-			if ((Alpm.LogLevel) level == Alpm.LogLevel.WARNING) {
+			if (level == 1) { //Alpm.LogLevel.ERROR
+				if (previous_filename != "") {
+					line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg;
+				} else {
+					line = dgettext (null, "Error") + ": " + msg;
+				}
+			} else if (level == (1 << 1)) { //Alpm.LogLevel.WARNING
 				// do not show warning when manjaro-system remove db.lck
 				if (previous_filename != "manjaro-system") {
 					if (previous_filename != "") {
@@ -1089,25 +1329,18 @@ namespace Pamac {
 					transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
 					transaction_info_dialog.textbuffer.insert (ref end_iter, msg, msg.length);
 				}
-			} else if ((Alpm.LogLevel) level == Alpm.LogLevel.ERROR) {
-				if (previous_filename != "") {
-					line = dgettext (null, "Error") + ": " + previous_filename + ": " + msg;
-				} else {
-					line = dgettext (null, "Error") + ": " + msg;
-				}
 			}
 			if (line != null) {
-				progress_dialog.expander.set_expanded (true);
-				progress_dialog.spawn_in_term ({"echo", "-n", line});
+				display_error (line, {});
 			}
 		}
 
 		void show_warnings () {
 			if (transaction_info_dialog.textbuffer.text != "") {
-				transaction_info_dialog.set_title (dgettext (null, "Warning"));
-				transaction_info_dialog.label.set_visible (false);
-				transaction_info_dialog.expander.set_visible (true);
-				transaction_info_dialog.expander.set_expanded (true);
+				transaction_info_dialog.title = dgettext (null, "Warning");
+				transaction_info_dialog.label.visible = false;
+				transaction_info_dialog.expander.visible = true;
+				transaction_info_dialog.expander.expanded = true;
 				transaction_info_dialog.run ();
 				transaction_info_dialog.hide ();
 				while (Gtk.events_pending ()) {
@@ -1121,57 +1354,58 @@ namespace Pamac {
 			}
 		}
 
-		void handle_error (ErrorInfos error) {
-			if (error.message != "") {
-				progress_dialog.action_label.set_text ("");
-				progress_dialog.progressbar.set_fraction (0);
-				progress_dialog.expander.set_expanded (true);
-				progress_dialog.spawn_in_term ({"echo", "-n", error.message});
-				Gtk.TextIter start_iter;
-				Gtk.TextIter end_iter;
-				transaction_info_dialog.set_title (dgettext (null, "Error"));
-				transaction_info_dialog.label.set_visible (true);
-				transaction_info_dialog.label.set_markup (error.message);
-				if (error.details.length != 0) {
-					transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
-					transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
-					transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
-					transaction_info_dialog.expander.set_visible (true);
-					transaction_info_dialog.expander.set_expanded (true);
-					progress_dialog.spawn_in_term ({"echo", ":"});
-					foreach (unowned string detail in error.details) {
-						progress_dialog.spawn_in_term ({"echo", detail});
-						string str = detail + "\n";
-						transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
-						transaction_info_dialog.textbuffer.insert (ref end_iter, str, str.length);
-					}
-				} else {
-					transaction_info_dialog.expander.set_visible (false);
-				}
-				progress_dialog.spawn_in_term ({"echo"});
-				transaction_info_dialog.run ();
-				transaction_info_dialog.hide ();
+		void display_error (string message, string[] details) {
+			progress_dialog.spawn_in_term ({"echo", "-n", message});
+			Gtk.TextIter start_iter;
+			Gtk.TextIter end_iter;
+			transaction_info_dialog.title = dgettext (null, "Error");
+			transaction_info_dialog.label.visible = true;
+			transaction_info_dialog.label.label = message;
+			if (details.length != 0) {
 				transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
 				transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
 				transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
-				progress_dialog.spawn_in_term ({"echo"});
-				while (Gtk.events_pending ()) {
-					Gtk.main_iteration ();
+				transaction_info_dialog.expander.visible = true;
+				transaction_info_dialog.expander.expanded = true;
+				progress_dialog.spawn_in_term ({"echo", ":"});
+				foreach (unowned string detail in details) {
+					progress_dialog.spawn_in_term ({"echo", detail});
+					string str = detail + "\n";
+					transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
+					transaction_info_dialog.textbuffer.insert (ref end_iter, str, str.length);
 				}
+			} else {
+				transaction_info_dialog.expander.visible = false;
+			}
+			transaction_info_dialog.run ();
+			transaction_info_dialog.hide ();
+			transaction_info_dialog.textbuffer.get_start_iter (out start_iter);
+			transaction_info_dialog.textbuffer.get_end_iter (out end_iter);
+			transaction_info_dialog.textbuffer.delete (ref start_iter, ref end_iter);
+			while (Gtk.events_pending ()) {
+				Gtk.main_iteration ();
+			}
+		}
+
+		void handle_error (ErrorInfos error) {
+			if (error.message != "") {
+				progress_dialog.action_label.label = "";
+				progress_dialog.progressbar.fraction = 0;
+				display_error (error.message, error.details);
+				progress_dialog.spawn_in_term ({"echo"});
+				progress_dialog.spawn_in_term ({"echo"});
 			}
 			finish_transaction ();
 		}
 
 		void finish_transaction () {
-			if (database_modified) {
-				alpm_utils.reload ();
-				database_modified = false;
-			}
-			if (progress_dialog.expander.get_expanded ()) {
-				progress_dialog.cancel_button.set_visible (false);
-				progress_dialog.close_button.set_visible (true);
+			transaction_summary.remove_all ();
+			if (progress_dialog.expander.expanded) {
+				progress_dialog.show ();
+				progress_dialog.cancel_button.visible = false;
+				progress_dialog.close_button.clicked.connect (hide_progress_and_finish);
 			} else {
-				on_progress_dialog_close_button_clicked ();
+				hide_progress_and_finish ();
 			}
 		}
 
@@ -1179,38 +1413,26 @@ namespace Pamac {
 			this.success = success;
 			clear_lists ();
 			if (success) {
-				// database is modified
-				alpm_utils.reload ();
 				finished (success);
-				if (mode == Mode.UPDATER) {
-					progress_dialog.hide ();
-				}
+				progress_dialog.hide ();
 				success = false;
 			} else {
-				database_modified = true;
 				handle_error (get_current_error ());
 			}
 			previous_filename = "";
 			daemon.refresh_finished.disconnect (on_refresh_finished);
 		}
 
-		void on_progress_dialog_close_button_clicked () {
+		void hide_progress_and_finish () {
 			finished (success);
 			progress_dialog.hide ();
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
-			}
+			progress_dialog.expander.expanded = false;
 			success = false;
+			progress_dialog.close_button.clicked.connect (hide_progress);
 		}
 
 		void on_progress_dialog_cancel_button_clicked () {
 			cancel ();
-			clear_lists ();
-			progress_dialog.spawn_in_term ({"/usr/bin/echo", dgettext (null, "Transaction cancelled") + ".\n"});
-			progress_dialog.hide ();
-			while (Gtk.events_pending ()) {
-				Gtk.main_iteration ();
-			}
 		}
 
 		void on_trans_prepare_finished (bool success) {
@@ -1232,15 +1454,24 @@ namespace Pamac {
 							release ();
 							on_trans_commit_finished (true);
 						} else {
+							// backup to_install and to_remove
+							foreach (unowned string name in to_install) {
+								previous_to_install.add (name);
+							}
+							foreach (unowned string name in to_remove) {
+								previous_to_remove.add (name);
+							}
+							to_install.remove_all ();
+							to_remove.remove_all ();
 							start_commit ();
 						}
 					} else {
 						transaction_sum_dialog.hide ();
 						unowned string action = dgettext (null, "Transaction cancelled");
 						progress_dialog.spawn_in_term ({"echo", action + ".\n"});
-						progress_dialog.action_label.set_text (action);
+						progress_dialog.action_label.label = action;
 						release ();
-						//to_build.remove_all ();
+						transaction_summary.remove_all ();
 						sysupgrade_after_trans = false;
 						success = false;
 						finish_transaction ();
@@ -1263,14 +1494,14 @@ namespace Pamac {
 			this.success = success;
 			if (success) {
 				if (to_build.length != 0) {
-					if (to_add.length != 0
-							|| to_remove.length != 0
+					if (previous_to_install.length != 0
+							|| previous_to_remove.length != 0
 							|| to_load.length != 0) {
 						progress_dialog.spawn_in_term ({"echo", dgettext (null, "Transaction successfully finished") + ".\n"});
 					}
 					build_aur_packages ();
 				} else {
-					clear_lists ();
+					clear_previous_lists ();
 					show_warnings ();
 					if (sysupgrade_after_trans) {
 						sysupgrade_after_trans = false;
@@ -1278,19 +1509,24 @@ namespace Pamac {
 					} else {
 						unowned string action = dgettext (null, "Transaction successfully finished");
 						progress_dialog.spawn_in_term ({"echo", action + ".\n"});
-						progress_dialog.action_label.set_text (action);
-						database_modified = true;
+						progress_dialog.action_label.label = action;
 						finish_transaction ();
 					}
 				}
 			} else {
 				// if it is an authentication or a download error, database was not modified
 				var err = get_current_error ();
-				if (err.message != dgettext (null, "Authentication failed")
-					&& err.errno != Alpm.Errno.EXTERNAL_DOWNLOAD) {
-					clear_lists ();
-					database_modified = true;
+				if (err.message == dgettext (null, "Authentication failed")
+					|| err.errno == 54) { //Alpm.Errno.EXTERNAL_DOWNLOAD
+					// recover old pkgnames
+					foreach (unowned string name in previous_to_install) {
+						to_install.add (name);
+					}
+					foreach (unowned string name in previous_to_remove) {
+						to_remove.add (name);
+					}
 				}
+				clear_previous_lists ();
 				handle_error (err);
 			}
 			total_download = 0;
@@ -1300,29 +1536,28 @@ namespace Pamac {
 
 		void on_term_child_exited (int status) {
 			Source.remove (pulse_timeout_id);
-			clear_lists ();
+			clear_previous_lists ();
+			to_build.remove_all ();
 			// let the time to the daemon to update databases
 			Timeout.add (1000, () => {
 				if (status == 0) {
 					success = true;
 					unowned string action = dgettext (null, "Transaction successfully finished");
 					progress_dialog.spawn_in_term ({"echo", action + ".\n"});
-					progress_dialog.action_label.set_text (action);
+					progress_dialog.action_label.label = action;
 				} else {
 					success = false;
 					progress_dialog.spawn_in_term ({"echo"});
 				}
-				progress_dialog.progressbar.set_fraction (1);
-				alpm_utils.reload ();
-				database_modified = false;
-				progress_dialog.cancel_button.set_visible (false);
-				progress_dialog.close_button.set_visible (true);
+				transaction_summary.remove_all ();
+				progress_dialog.progressbar.fraction = 1;
+				progress_dialog.close_button.clicked.connect (hide_progress_and_finish);
+				progress_dialog.close_button.visible = true;
 				return false;
 			});
 		}
 
 		void on_set_pkgreason_finished () {
-			alpm_utils.reload ();
 			set_pkgreason_finished ();
 		}
 
@@ -1330,13 +1565,15 @@ namespace Pamac {
 												bool enable_aur, bool search_aur, bool check_aur_updates,
 												bool no_confirm_build) {
 			pamac_config.reload ();
+			if (recurse) {
+				flags |= (1 << 5); //Alpm.TransFlag.RECURSE
+			}
 			write_pamac_config_finished (recurse, refresh_period, no_update_hide_icon,
 											enable_aur, search_aur, check_aur_updates,
 											no_confirm_build);
 		}
 
 		void on_write_alpm_config_finished (bool checkspace) {
-			alpm_utils.reload ();
 			write_alpm_config_finished (checkspace);
 		}
 
diff --git a/src/transaction_sum_dialog.vala b/src/transaction_sum_dialog.vala
index 43f792fb73edbba89b1fce8f5179f012fbc9b022..cef47976c8ca10a357adcf3a023532eadb4d2ccc 100644
--- a/src/transaction_sum_dialog.vala
+++ b/src/transaction_sum_dialog.vala
@@ -34,7 +34,7 @@ namespace Pamac {
 		public TransactionSumDialog (Gtk.ApplicationWindow? window) {
 			Object (transient_for: window, use_header_bar: 0);
 
-			sum_list = new Gtk.ListStore (2, typeof (string), typeof (string));
+			sum_list = new Gtk.ListStore (4, typeof (string), typeof (string), typeof (string), typeof (string));
 			treeview.set_model (sum_list);
 		}
 	}
diff --git a/src/tray.vala b/src/tray.vala
index bb7cf47dd057279592d84acaea9d6c4a824fa444..7aaee090887d6ab003110bd828a820f99ab4ca9b 100644
--- a/src/tray.vala
+++ b/src/tray.vala
@@ -27,6 +27,7 @@ const string noupdate_info = _("Your system is up-to-date");
 namespace Pamac {
 	[DBus (name = "org.manjaro.pamac")]
 	interface Daemon : Object {
+		public abstract string get_lockfile () throws IOError;
 		public abstract void start_refresh (bool force) throws IOError;
 		public abstract void start_get_updates (bool check_aur_updates) throws IOError;
 		[DBus (no_reply = true)]
@@ -320,10 +321,14 @@ namespace Pamac {
 
 			Notify.init (_("Update Manager"));
 
-			var alpm_config = new AlpmConfig ("/etc/pacman.conf");
-			alpm_config.set_handle ();
-			lockfile = GLib.File.new_for_path (alpm_config.handle.lockfile);
 			start_daemon ();
+			try {
+				lockfile = GLib.File.new_for_path (daemon.get_lockfile ());
+			} catch (IOError e) {
+				stderr.printf ("IOError: %s\n", e.message);
+				//try standard lock file
+				lockfile = GLib.File.new_for_path ("var/lib/pacman/db.lck");
+			}
 			Timeout.add (200, check_pacman_running);
 			start_refresh ();
 			launch_refresh_timeout (pamac_config.refresh_period);
diff --git a/src/updater_window.vala b/src/updater_window.vala
index e69db2bc62fa6d2c82cf443c986990aa3b03df10..685fc1bd3cfc15bb2b2f6cc2bcec95b9407ca583 100644
--- a/src/updater_window.vala
+++ b/src/updater_window.vala
@@ -25,7 +25,7 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.Label top_label;
 		[GtkChild]
-		Gtk.Notebook notebook;
+		Gtk.StackSwitcher stackswitcher;
 		[GtkChild]
 		Gtk.ScrolledWindow repos_scrolledwindow;
 		[GtkChild]
@@ -51,10 +51,10 @@ namespace Pamac {
 		public UpdaterWindow (Gtk.Application application) {
 			Object (application: application);
 
-			bottom_label.set_visible (false);
-			apply_button.set_sensitive (false);
-			notebook.set_show_tabs (false);
-			aur_scrolledwindow.set_visible (false);
+			bottom_label.visible  = false;
+			apply_button.sensitive = false;
+			stackswitcher.visible = false;
+			aur_scrolledwindow.visible = false;
 
 			Timeout.add (100, populate_window);
 		}
@@ -62,9 +62,9 @@ namespace Pamac {
 		bool populate_window () {
 			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
 
-			repos_updates_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string));
+			repos_updates_list = new Gtk.ListStore (6, typeof (bool), typeof (string), typeof (string), typeof (string),typeof (string), typeof (string));
 			repos_updates_treeview.set_model (repos_updates_list);
-			aur_updates_list = new Gtk.ListStore (2, typeof (bool), typeof (string));
+			aur_updates_list = new Gtk.ListStore (3, typeof (bool), typeof (string), typeof (string));
 			aur_updates_treeview.set_model (aur_updates_list);
 
 			transaction = new Transaction (this as Gtk.ApplicationWindow);
@@ -80,31 +80,29 @@ namespace Pamac {
 		void set_apply_button_sensitive () {
 			bool sensitive = false;
 			repos_updates_list.foreach ((model, path, iter) => {
-				GLib.Value selected;
-				repos_updates_list.get_value (iter, 0, out selected);
-				sensitive = (bool) selected;
+				bool selected;
+				repos_updates_list.get (iter, 0, out selected);
+				sensitive = selected;
 				return sensitive;
 			});
 			if (!sensitive) {
 				aur_updates_list.foreach ((model, path, iter) => {
-					GLib.Value selected;
-					aur_updates_list.get_value (iter, 0, out selected);
-					sensitive = (bool) selected;
+					bool selected;
+					aur_updates_list.get (iter, 0, out selected);
+					sensitive = selected;
 					return sensitive;
 				});
 			}
-			apply_button.set_sensitive (sensitive);
+			apply_button.sensitive = sensitive;
 		}
 
 		[GtkCallback]
 		void on_repos_select_update_toggled (string path) {
 			Gtk.TreePath treepath = new Gtk.TreePath.from_string (path);
 			Gtk.TreeIter iter;
-			GLib.Value name_string;
+			string pkgname;
 			repos_updates_list.get_iter (out iter, treepath);
-			repos_updates_list.get_value (iter, 1, out name_string);
-			// string has the form "pkgname pkgversion"
-			string pkgname = name_string.get_string ().split (" ", 2)[0];
+			repos_updates_list.get (iter, 1, out pkgname);
 			if (repos_select_update.active) {
 				repos_updates_list.set (iter, 0, false);
 				transaction.temporary_ignorepkgs.add (pkgname);
@@ -119,11 +117,9 @@ namespace Pamac {
 		void on_aur_select_update_toggled  (string path) {
 			Gtk.TreePath treepath = new Gtk.TreePath.from_string (path);
 			Gtk.TreeIter iter;
-			GLib.Value name_string;
+			string pkgname;
 			aur_updates_list.get_iter (out iter, treepath);
-			aur_updates_list.get_value (iter, 1, out name_string);
-			// string has the form "pkgname pkgversion"
-			string pkgname = name_string.get_string ().split (" ", 2)[0];
+			aur_updates_list.get (iter, 1, out pkgname);
 			if (aur_select_update.active) {
 				aur_updates_list.set (iter, 0, false);
 				transaction.temporary_ignorepkgs.add (pkgname);
@@ -166,34 +162,32 @@ namespace Pamac {
 		void on_get_updates_finished (Updates updates) {
 			top_label.set_markup ("");
 			repos_updates_list.clear ();
-			notebook.set_show_tabs (false);
-			repos_scrolledwindow.set_visible (true);
+			stackswitcher.visible = false;
+			repos_scrolledwindow.visible = true;
 			aur_updates_list.clear ();
-			aur_scrolledwindow.set_visible (false);
-			bottom_label.set_visible (false);
-			Gtk.TreeIter iter;
+			aur_scrolledwindow.visible = false;
+			bottom_label.visible = false;
 			uint64 dsize = 0;
 			uint repos_updates_nb = 0;
 			uint aur_updates_nb = 0;
-			foreach (unowned PackageInfos infos in updates.repos_updates) {
-				string name = infos.name + " " + infos.version;
+			foreach (unowned UpdateInfos infos in updates.repos_updates) {
 				string size = infos.download_size != 0 ? format_size (infos.download_size) : "";
 				dsize += infos.download_size;
 				repos_updates_nb++;
-				if (infos.name in transaction.temporary_ignorepkgs) {
-					repos_updates_list.insert_with_values (out iter, -1, 0, false, 1, name, 2, size);
-				} else {
-					repos_updates_list.insert_with_values (out iter, -1, 0, true, 1, name, 2, size);
-				}
+				repos_updates_list.insert_with_values (null, -1,
+														0, !transaction.temporary_ignorepkgs.contains (infos.name),
+														1, infos.name,
+														2, infos.new_version,
+														3, "(%s)".printf (infos.old_version),
+														4, infos.repo,
+														5, size);
 			}
-			foreach (unowned PackageInfos infos in updates.aur_updates) {
-				string name = infos.name + " " + infos.version;
+			foreach (unowned UpdateInfos infos in updates.aur_updates) {
 				aur_updates_nb++;
-				if (infos.name in transaction.temporary_ignorepkgs) {
-					aur_updates_list.insert_with_values (out iter, -1, 0, false, 1, name);
-				} else {
-					aur_updates_list.insert_with_values (out iter, -1, 0, true, 1, name);
-				}
+				aur_updates_list.insert_with_values (null, -1,
+														0, !transaction.temporary_ignorepkgs.contains (infos.name),
+														1, infos.name,
+														2, "%s\t (%s)".printf (infos.new_version, infos.old_version));
 			}
 			uint updates_nb = repos_updates_nb + aur_updates_nb;
 			if (updates_nb == 0) {
@@ -204,16 +198,16 @@ namespace Pamac {
 			set_apply_button_sensitive ();
 			if (dsize != 0) {
 				bottom_label.set_markup("<b>%s: %s</b>".printf (dgettext (null, "Total download size"), format_size(dsize)));
-				bottom_label.set_visible (true);
+				bottom_label.visible = true;
 			} else {
-				bottom_label.set_visible (false);
+				bottom_label.visible = false;
 			}
 			if (aur_updates_nb != 0) {
-				aur_scrolledwindow.set_visible (true);
+				aur_scrolledwindow.visible = true;
 				if (repos_updates_nb == 0) {
-					repos_scrolledwindow.set_visible (false);
+					repos_scrolledwindow.visible = false;
 				}
-				notebook.set_show_tabs (true);
+				stackswitcher.visible = true;
 			}
 			this.get_window ().set_cursor (null);
 		}
diff --git a/vapi/libalpm.vapi b/vapi/libalpm.vapi
index 12ce4c4b0c2d43c10c0d549207f6a86647d7e04c..83e82c624f384129a1501063968a0fb5ca8d3d89 100644
--- a/vapi/libalpm.vapi
+++ b/vapi/libalpm.vapi
@@ -1,8 +1,7 @@
 /*
- *  libalpm-vala
  *  Vala bindings for libalpm
  *
- *  Copyright (C) 2014-2015 Guillaume Benoit <guillaume@manjaro.org>
+ *  Copyright (C) 2014-2016 Guillaume Benoit <guillaume@manjaro.org>
  *  Copyright (c) 2011 Rémy Oudompheng <remy@archlinux.org>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -45,7 +44,11 @@ namespace Alpm {
 
 	public int pkg_vercmp(string a, string b);
 
-	public unowned Alpm.List<unowned Package?> find_group_pkgs(Alpm.List<DB> dbs, string name);
+	/** Find group members across a list of databases.
+	 * If a member exists in several databases, only the first database is used.
+	 * IgnorePkg is also handled.
+	 */
+	public Alpm.List<unowned Package?> find_group_pkgs(Alpm.List<DB> dbs, string name);
 
 	/** Returns the string corresponding to an error number. */
 	public unowned string strerror(Errno err);
@@ -57,7 +60,7 @@ namespace Alpm {
 	[Compact]
 	public class Handle {
 		[CCode (cname = "alpm_initialize")]
-		public static Handle? @new(string root, string dbpath, out Alpm.Errno error);
+		public Handle (string root, string dbpath, out Alpm.Errno error);
 
 		public unowned string root {
 			[CCode (cname = "alpm_option_get_root")] get;
@@ -69,7 +72,7 @@ namespace Alpm {
 			[CCode (cname = "alpm_option_get_arch")] get;
 			[CCode (cname = "alpm_option_set_arch")] set;
 		}
-		public unowned Alpm.List<unowned string?> cachedirs {
+		public unowned Alpm.List<unowned string> cachedirs {
 			[CCode (cname = "alpm_option_get_cachedirs")] get;
 			[CCode (cname = "alpm_option_set_cachedirs")] set;
 		}
@@ -78,7 +81,7 @@ namespace Alpm {
 		[CCode (cname = "alpm_option_remove_cachedir")]
 		public int remove_cachedir(string cachedir);
 
-		public unowned Alpm.List<unowned string?> hookdirs {
+		public unowned Alpm.List<unowned string> hookdirs {
 			[CCode (cname = "alpm_option_get_hookdirs")] get;
 			[CCode (cname = "alpm_option_set_hookdirs")] set;
 		}
@@ -103,7 +106,7 @@ namespace Alpm {
 			/** Sets whether to use syslog (0 is FALSE, TRUE otherwise). */
 			[CCode (cname = "alpm_option_set_usesyslog")] set;
 		}
-		public unowned Alpm.List<unowned string?> noupgrades {
+		public unowned Alpm.List<unowned string> noupgrades {
 			[CCode (cname = "alpm_option_get_noupgrades")] get;
 			[CCode (cname = "alpm_option_set_noupgrades")] set;
 		}
@@ -112,7 +115,7 @@ namespace Alpm {
 		[CCode (cname = "alpm_option_remove_noupgrade")]
 		public int remove_noupgrade(string path);
 
-		public unowned Alpm.List<unowned string?> noextracts {
+		public unowned Alpm.List<unowned string> noextracts {
 			[CCode (cname = "alpm_option_get_noextracts")] get;
 			[CCode (cname = "alpm_option_set_noextracts")] set;
 		}
@@ -123,7 +126,7 @@ namespace Alpm {
 		[CCode (cname = "alpm_option_match_noextract")]
 		public int match_noextract(string path);
 
-		public unowned Alpm.List<unowned string?> ignorepkgs {
+		public unowned Alpm.List<unowned string> ignorepkgs {
 			[CCode (cname = "alpm_option_get_ignorepkgs")] get;
 			[CCode (cname = "alpm_option_set_ignorepkgs")] set;
 		}
@@ -132,7 +135,7 @@ namespace Alpm {
 		[CCode (cname = "alpm_option_remove_ignorepkg")]
 		public int remove_ignorepkg(string pkg);
 
-		public unowned Alpm.List<unowned string?> ignoregroups {
+		public unowned Alpm.List<unowned string> ignoregroups {
 			[CCode (cname = "alpm_option_get_ignoregroups")] get;
 			[CCode (cname = "alpm_option_set_ignoregroups")] set;
 		}
@@ -141,7 +144,7 @@ namespace Alpm {
 		[CCode (cname = "alpm_option_remove_ignorepkg")]
 		public int remove_ignoregroup(string grp);
 
-		public unowned Alpm.List<unowned Depend?> assumeinstalled {
+		public unowned Alpm.List<unowned Depend> assumeinstalled {
 			[CCode (cname = "alpm_option_get_assumeinstalled")] get;
 			[CCode (cname = "alpm_option_set_assumeinstalled")] set;
 		}
@@ -178,10 +181,10 @@ namespace Alpm {
 			[CCode (cname = "alpm_option_set_remote_file_siglevel")] set;
 		}
 
-		public unowned DB? localdb {
+		public unowned DB localdb {
 				[CCode (cname = "alpm_get_localdb")] get;
 		}
-		public unowned Alpm.List<unowned DB?> syncdbs {
+		public unowned Alpm.List<unowned DB> syncdbs {
 				[CCode (cname = "alpm_get_syncdbs")] get;
 		}
 
@@ -218,14 +221,14 @@ namespace Alpm {
 		public int unlock();
 
 		[CCode (cname = "alpm_register_syncdb")]
-		public unowned DB? register_syncdb(string treename, Signature.Level level);
+		public unowned DB register_syncdb(string treename, Signature.Level level);
 		[CCode (cname = "alpm_unregister_all_syncdbs")]
 		public int unregister_all_syncdbs();
 
 		// the return package can be freed except if it is added to a transaction,
 		// it will be freed upon Handle.trans_release() invocation.
-		[CCode (cname = "alpm_pkg_load_file")]
-		public Package? load_file(string filename, int full, Signature.Level level);
+		[CCode (cname = "alpm_pkg_load")]
+		public int load_tarball(string filename, int full, Signature.Level level, out Package pkg);
 
 		/** Test if a package should be ignored.
 		 * Checks if the package is ignored via IgnorePkg, or if the package is
@@ -252,11 +255,11 @@ namespace Alpm {
 
 		/** Returns a list of packages added by the transaction.*/
 		[CCode (cname = "alpm_trans_get_add")]
-		public unowned Alpm.List<unowned Package?> trans_to_add();
+		public unowned Alpm.List<unowned Package> trans_to_add();
 
 		/** Returns the list of packages removed by the transaction.*/
 		[CCode (cname = "alpm_trans_get_remove")]
-		public unowned Alpm.List<unowned Package?> trans_to_remove();
+		public unowned Alpm.List<unowned Package> trans_to_remove();
 
 		/** Initialize the transaction.
 		* @param flags flags of the transaction (like nodeps, etc)
@@ -333,16 +336,16 @@ namespace Alpm {
 			[CCode (cname = "alpm_db_get_siglevel")] get;
 		}
 
-		public unowned Alpm.List<unowned string?> servers {
+		public unowned Alpm.List<unowned string> servers {
 			[CCode (cname = "alpm_db_get_servers")] get;
 			[CCode (cname = "alpm_db_set_servers")] set;
 		}
 
-		public unowned Alpm.List<unowned Package?> pkgcache {
+		public unowned Alpm.List<unowned Package> pkgcache {
 			[CCode (cname = "alpm_db_get_pkgcache")] get;
 		}
 
-		public unowned Alpm.List<unowned Group?> groupcache {
+		public unowned Alpm.List<unowned Group> groupcache {
 			[CCode (cname = "alpm_db_get_groupcache")] get;
 		}
 
@@ -368,7 +371,7 @@ namespace Alpm {
 
 		public unowned Package? get_pkg(string name);
 		public unowned Group? get_group(string name);
-		public Alpm.List<unowned Package?> search(Alpm.List<string> needles);
+		public Alpm.List<unowned Package> search(Alpm.List<string> needles);
 
 		public int check_pgp_signature(out SigList siglist);
 	}
@@ -440,37 +443,37 @@ namespace Alpm {
 			 */
 			[CCode (cname = "alpm_pkg_set_reason")] set;
 		}
-		public unowned Alpm.List<unowned string?> licenses {
+		public unowned Alpm.List<unowned string> licenses {
 			[CCode (cname = "alpm_pkg_get_licenses")] get;
 		}
-		public unowned Alpm.List<unowned string?> groups {
+		public unowned Alpm.List<unowned string> groups {
 			[CCode (cname = "alpm_pkg_get_groups")] get;
 		}
-		public unowned Alpm.List<unowned Depend?> depends {
+		public unowned Alpm.List<unowned Depend> depends {
 			[CCode (cname = "alpm_pkg_get_depends")] get;
 		}
-		public unowned Alpm.List<unowned Depend?> optdepends {
+		public unowned Alpm.List<unowned Depend> optdepends {
 			[CCode (cname = "alpm_pkg_get_optdepends")] get;
 		}
-		public unowned Alpm.List<unowned Depend?> conflicts {
+		public unowned Alpm.List<unowned Depend> conflicts {
 			[CCode (cname = "alpm_pkg_get_conflicts")] get;
 		}
-		public unowned Alpm.List<unowned Depend?> provides {
+		public unowned Alpm.List<unowned Depend> provides {
 			[CCode (cname = "alpm_pkg_get_provides")] get;
 		}
-		public unowned Alpm.List<unowned string?> deltas {
+		public unowned Alpm.List<unowned string> deltas {
 			[CCode (cname = "alpm_pkg_get_deltas")] get;
 		}
-		public unowned Alpm.List<unowned Depend?> replaces {
+		public unowned Alpm.List<unowned Depend> replaces {
 			[CCode (cname = "alpm_pkg_get_replaces")] get;
 		}
-		public unowned Alpm.List<unowned File?> files {
-			[CCode (cname = "alpm_pkg_get_files_list")] get;
+		public unowned FileList files {
+			[CCode (cname = "alpm_pkg_get_files")] get;
 		}
-		public unowned Alpm.List<unowned string?> unused_deltas {
+		public unowned Alpm.List<unowned string> unused_deltas {
 			[CCode (cname = "alpm_pkg_unused_deltas")] get;
 		}
-		public unowned Alpm.List<unowned Backup?> backups {
+		public unowned Alpm.List<unowned Backup> backups {
 			[CCode (cname = "alpm_pkg_get_backup")] get;
 		}
 		public unowned DB? db {
@@ -528,8 +531,8 @@ namespace Alpm {
 		public int checkmd5sum();
 		public int has_scriptlet();
 
-		public Alpm.List<string?> compute_requiredby();
-		public Alpm.List<string?> compute_optionalfor();
+		public Alpm.List<string> compute_requiredby();
+		public Alpm.List<string> compute_optionalfor();
 
 		[CCode (cname = "alpm_sync_newversion")]
 		public unowned Package? sync_newversion(Alpm.List<DB> dbs);
@@ -613,13 +616,15 @@ namespace Alpm {
 
 	/** Package group */
 	[CCode (cname = "alpm_group_t", has_type_id = false)]
+	[Compact]
 	public class Group {
 		public string name;
-		public unowned Alpm.List<unowned Package?> packages;
+		public unowned Alpm.List<unowned Package> packages;
 	}
 
 	/** Package upgrade delta */
 	[CCode (cname = "alpm_delta_t", has_type_id = false)]
+	[Compact]
 	public class Delta {
 		/** filename of the delta patch */
 		public string delta;
@@ -637,6 +642,7 @@ namespace Alpm {
 
 	/** File in a package */
 	[CCode (cname = "alpm_file_t", has_type_id = false)]
+	[Compact]
 	public class File {
 		public string name;
 		public uint64 size;
@@ -645,10 +651,15 @@ namespace Alpm {
 
 	/** Package filelist container */
 	[CCode (cname = "alpm_filelist_t", has_type_id = false)]
+	[Compact]
 	public class FileList {
+		// Usage:
+		// Alpm.File* files = filelist.files;
+		// for (size_t i = 0; i < filelist.count; i++, files++) {
+		// 	stdout.printf("%s\n", files->name);
+		// }
 		public size_t count;
-		[CCode (array_length_cname = "count", array_length_type = "size_t")]
-		public unowned Alpm.File[] files;
+		public Alpm.File* files;
 		/** Determines whether a package filelist contains a given path.
 		 * The provided path should be relative to the install root with no leading
 		 * slashes, e.g. "etc/localtime". When searching for directories, the path must
@@ -662,6 +673,7 @@ namespace Alpm {
 
 	/** Local package or package file backup entry */
 	[CCode (cname = "alpm_backup_t", has_type_id = false)]
+	[Compact]
 	public class Backup {
 		public string name;
 		public string hash;
@@ -669,6 +681,7 @@ namespace Alpm {
 
 	namespace Signature {
 		[CCode (cname = "alpm_pgpkey_t", has_type_id = false)]
+		[Compact]
 		public class PGPKey {
 			public void *data;
 			public string fingerprint;
@@ -687,6 +700,7 @@ namespace Alpm {
 		* signature.
 		*/
 		[CCode (cname = "alpm_sigresult_t", has_type_id = false)]
+		[Compact]
 		public class Result {
 			public PGPKey key;
 			public Status status;
@@ -865,12 +879,14 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_any_t", has_type_id = false)]
+		[Compact]
 		public class Any {
 			/** Type of event. */
 			public Type type;
 		}
 
 		[CCode (cname = "alpm_event_package_operation_t", has_type_id = false)]
+		[Compact]
 		public class PackageOperation {
 			/** Type of event. */
 			public Type type;
@@ -883,6 +899,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_optdep_removal_t", has_type_id = false)]
+		[Compact]
 		public class OptDepRemoval {
 			/** Type of event. */
 			public Type type;
@@ -893,6 +910,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_delta_patch_t", has_type_id = false)]
+		[Compact]
 		public class DeltaPatch {
 			/** Type of event. */
 			public Type type;
@@ -901,6 +919,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_scriptlet_info_t", has_type_id = false)]
+		[Compact]
 		public class ScriptletInfo {
 			/** Type of event. */
 			public Type type;
@@ -909,6 +928,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_database_missing_t", has_type_id = false)]
+		[Compact]
 		public class DatabaseMissing {
 			/** Type of event. */
 			public Type type;
@@ -917,6 +937,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_pkgdownload_t", has_type_id = false)]
+		[Compact]
 		public class PkgDownload {
 			/** Type of event. */
 			public Type type;
@@ -925,6 +946,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_pacnew_created_t", has_type_id = false)]
+		[Compact]
 		public class PacnewCreated {
 			/** Type of event. */
 			public Type type;
@@ -939,6 +961,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_pacsave_created_t", has_type_id = false)]
+		[Compact]
 		public class PacsaveCreated {
 			/** Type of event. */
 			public Type type;
@@ -949,6 +972,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_hook_t", has_type_id = false)]
+		[Compact]
 		public class Hook {
 			/** Type of event.*/
 			public Type type;
@@ -957,6 +981,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_event_hook_run_t", has_type_id = false)]
+		[Compact]
 		public class HookRun {
 			/** Type of event.*/
 			public Type type;
@@ -975,6 +1000,7 @@ namespace Alpm {
 		 * typecast the pointer to the right structure, or use the union field, in order
 		 * to access event-specific data. */
 		[CCode (cname = "alpm_event_t", has_type_id = false)]
+		[Compact]
 		public class Data {
 			/** Type of event. */
 			public Type type;
@@ -1054,6 +1080,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_any_t", has_type_id = false)]
+		[Compact]
 		public class Any {
 			/** Type of question. */
 			public Type type;
@@ -1062,6 +1089,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_install_ignorepkg_t", has_type_id = false)]
+		[Compact]
 		public class InstallIgnorePkg {
 			/** Type of question. */
 			public Type type;
@@ -1072,6 +1100,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_replace_t", has_type_id = false)]
+		[Compact]
 		public class Replace {
 			/** Type of question. */
 			public Type type;
@@ -1086,6 +1115,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_conflict_t", has_type_id = false)]
+		[Compact]
 		public class Conflict {
 			/** Type of question. */
 			public Type type;
@@ -1096,6 +1126,7 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_corrupted_t", has_type_id = false)]
+		[Compact]
 		public class Corrupted {
 			/** Type of question. */
 			public Type type;
@@ -1108,28 +1139,31 @@ namespace Alpm {
 		}
 
 		[CCode (cname = "alpm_question_remove_pkgs_t", has_type_id = false)]
+		[Compact]
 		public class RemovePkgs {
 			/** Type of question. */
 			public Type type;
 			/** Answer: whether or not to skip packages. */
 			public int skip;
 			/** List of alpm_pkg_t* with unresolved dependencies. */
-			public unowned Alpm.List<unowned Package?> packages;
+			public unowned Alpm.List<unowned Package> packages;
 		}
 
 		[CCode (cname = "alpm_question_select_provider_t", has_type_id = false)]
+		[Compact]
 		public class SelectProvider {
 			/** Type of question. */
 			public Type type;
 			/** Answer: which provider to use (index from providers). */
 			public int use_index;
 			/** List of alpm_pkg_t* as possible providers. */
-			public unowned Alpm.List<unowned Package?> providers;
+			public unowned Alpm.List<unowned Package> providers;
 			/** What providers provide for. */
 			public unowned Depend depend;
 		}
 
 		[CCode (cname = "alpm_question_import_key_t", has_type_id = false)]
+		[Compact]
 		public class ImportKey {
 			/** Type of question. */
 			public Type type;
@@ -1144,6 +1178,7 @@ namespace Alpm {
 		 * typecast the pointer to the right structure, or use the union field, in order
 		 * to access question-specific data. */
 		[CCode (cname = "alpm_question_t", has_type_id = false)]
+		[Compact]
 		public class Data {
 			public Type type;
 			// Any any;
@@ -1179,12 +1214,12 @@ namespace Alpm {
 			[CCode (cname = "remove_pkgs.skip")]
 			public int remove_pkgs_skip;
 			[CCode (cname = "remove_pkgs.packages")]
-			public unowned Alpm.List<unowned Package?> remove_pkgs_packages;
+			public unowned Alpm.List<unowned Package> remove_pkgs_packages;
 			// SelectProvider select_provider;
 			[CCode (cname = "select_provider.use_index")]
 			public int select_provider_use_index;
 			[CCode (cname = "select_provider.providers")]
-			public unowned Alpm.List<unowned Package?> select_provider_providers;
+			public unowned Alpm.List<unowned Package> select_provider_providers;
 			[CCode (cname = "select_provider.depend")]
 			public unowned Depend select_provider_depend;
 			// ImportKey import_key;
@@ -1348,24 +1383,25 @@ namespace Alpm {
 		GPGME
 	}
 
-	[CCode (cname = "alpm_list_t", cprefix = "alpm_list_", cheader_filename = "alpm_list.h,alpm-util.h",
+	[CCode (cname = "alpm_list_t", cprefix = "alpm_list_", cheader_filename = "alpm_list.h",
 			dup_function = "alpm_list_copy", free_function = "alpm_list_free")]
 	[Compact]
 	public class List<G> {
 
-		public List ();
-
 		/* comparator */
 		[CCode (cname = "alpm_list_fn_cmp", has_target = false)]
 		public delegate int CompareFunc<G>(G a, G b);
+		/* deallocator */
+		[CCode (cname = "alpm_list_fn_free", has_target = false)]
+		public delegate void FreeFunc<G>(G a);
 
 		/* properties */
 		public size_t length {
 		[CCode (cname = "alpm_list_count")] get;
 		}
-		public unowned G? data {
-		[CCode (cname = "alpm_list_get_data")] get;
-		}
+
+		/* field */
+		public G data;
 
 		/* item mutators */
 		[ReturnsModifiedPointer ()]
@@ -1374,42 +1410,32 @@ namespace Alpm {
 		[ReturnsModifiedPointer ()]
 		public void join(owned List<G> list);
 
+		[CCode (cname = "alpm_list_msort", has_target = false)]
 		[ReturnsModifiedPointer ()]
-		public void sort(CompareFunc fn);
+		public void sort(size_t n, CompareFunc fn);
 
 		[ReturnsModifiedPointer ()]
 		public void remove(G data, CompareFunc fn, out G removed_data );
 
 		/* free the internal data of this */
-		public void free_data();
+		public void free_inner(FreeFunc fn);
 
 		public List<unowned G> copy();
-		public List<G> copy_data();
 
 		[ReturnsModifiedPointer ()]
 		public void reverse ();
 
 		/* item accessors */
-		public unowned List<G>? first();
-		public unowned List<G>? last();
-		public unowned List<G>? nth(size_t index);
-		public unowned List<G>? next();
-		public unowned List<G>? previous();
+		public unowned List<G> nth(size_t index);
+		[ReturnsModifiedPointer ()]
+		public void next();
 
 		/* misc */
-		public unowned G? find(G needle, CompareFunc fn);
+		public unowned G find(G needle, CompareFunc fn);
 		public unowned string? find_str(string needle);
 
 		/** @return a list containing all items in `this` not present in `list` */
-		public List<unowned G>? diff(List<G>? list, CompareFunc fn);
-
-		/* iterator */
-		public Iterator<G> iterator();
-
-		[CCode (cname = "alpm_list_iterator_t", cprefix = "alpm_list_iterator_")]
-		public struct Iterator<G> {
-			public unowned G? next_value();
-		}
+		public List<unowned G> diff(List<G> list, CompareFunc fn); 
 
 	}
 }