diff --git a/README.md b/README.md
index 627c590c91275a22d3b3bb219c7b2f4a00eaa039..f79a77a84b981c1b420e6c84c032279d2cd39f6a 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,13 @@
-Pamac is a GUI for libalpm (pacman) with AUR and Appstream support
+Pamac is a Package Manager based on libalpm with AUR and Appstream support
 
 #### Features
 
- - Library to access package infos and run transactions
- - Python bindings
- - CLI
- - GTK3 frontend with Dbus daemon
- - Tray icon with Updates notifications
+ - libpamac: Library to access package infos and run transactions
+ - Python bindings for libpamac
+ - pamac: a CLI
+ - pamac_manager/pamac-updater: a Gtk3 GUI
+ - pamac-tray: a Gtk3 tray icon with updates notifications
+ - ppamac-tray-appindicator: a AppIndicator tray icon with updates notifications
 
 #### Installing from source
 
diff --git a/data/config/pamac.conf b/data/config/pamac.conf
index 7351dd4c4f97e79a080248975ffa6f63320af935..78b652b52d98f759ce3bf0360b752e39eac7f3e3 100644
--- a/data/config/pamac.conf
+++ b/data/config/pamac.conf
@@ -11,13 +11,13 @@ RefreshPeriod = 6
 #NoUpdateHideIcon
 
 ## Allow Pamac to search and install packages from AUR:
-#EnableAUR
+EnableAUR
 
 ## When AUR support is enabled check for updates from AUR:
-#CheckAURUpdates
+CheckAURUpdates
 
 ## AUR build directory:
-BuildDirectory = /tmp
+BuildDirectory = /var/tmp
 
 ## Number of versions of each package to keep in the cache:
 KeepNumPackages = 3
diff --git a/resources/manager_window.ui b/resources/manager_window.ui
index 644eff721815f979c2bf6ddacfa24e9848333500..7ebf5b32ecdf496f92b0e1199c76e7867c79dcd1 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.22.0 -->
+<!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <object class="GtkPopoverMenu" id="popovermenu">
@@ -97,6 +97,127 @@
     <property name="gravity">center</property>
     <property name="show_menubar">False</property>
     <signal name="delete-event" handler="on_ManagerWindow_delete_event" swapped="no"/>
+    <child type="titlebar">
+      <object class="GtkHeaderBar" id="headerbar">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="show_close_button">True</property>
+        <child>
+          <object class="GtkBox" id="header_left_buttonbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">32</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="icon_name">go-previous-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>
+            <child>
+              <object class="GtkLabel" id="header_filter_label">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkButton" id="select_all_button">
+                <property name="label" translatable="yes">Select All</property>
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="margin_left">18</property>
+                <signal name="clicked" handler="on_select_all_button_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">3</property>
+              </packing>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkBox" id="header_right_buttonbox">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="spacing">3</property>
+            <child>
+              <object class="GtkToggleButton" id="search_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <signal name="toggled" handler="on_search_button_toggled" swapped="no"/>
+                <child>
+                  <object class="GtkImage" id="search_image">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">edit-find-symbolic</property>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkMenuButton" id="menu_button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">False</property>
+                <property name="popover">popovermenu</property>
+                <signal name="toggled" handler="on_menu_button_toggled" swapped="no"/>
+                <child>
+                  <object class="GtkImage" id="menu_icon">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="icon_name">open-menu-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>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
     <child>
       <object class="GtkBox" id="main_box">
         <property name="visible">True</property>
@@ -651,24 +772,10 @@
                             <property name="orientation">vertical</property>
                             <property name="spacing">12</property>
                             <property name="homogeneous">True</property>
-                            <child>
-                              <object class="GtkSpinner" id="checking_spinner">
-                                <property name="height_request">40</property>
-                                <property name="visible">True</property>
-                                <property name="can_focus">False</property>
-                                <property name="valign">end</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="checking_label">
                                 <property name="visible">True</property>
                                 <property name="can_focus">False</property>
-                                <property name="valign">start</property>
                               </object>
                               <packing>
                                 <property name="expand">False</property>
@@ -849,6 +956,34 @@
                                 <property name="position">2</property>
                               </packing>
                             </child>
+                            <child>
+                              <object class="GtkToggleButton" id="build_togglebutton">
+                                <property name="label" translatable="yes">Build</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <signal name="toggled" handler="on_build_togglebutton_toggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">3</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkButton" id="reset_files_button">
+                                <property name="label" translatable="yes">Reset build files</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">True</property>
+                                <signal name="clicked" handler="on_reset_files_button_clicked" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="expand">True</property>
+                                <property name="fill">True</property>
+                                <property name="position">4</property>
+                              </packing>
+                            </child>
                           </object>
                           <packing>
                             <property name="expand">False</property>
@@ -1203,126 +1338,5 @@
         </child>
       </object>
     </child>
-    <child type="titlebar">
-      <object class="GtkHeaderBar" id="headerbar">
-        <property name="visible">True</property>
-        <property name="can_focus">False</property>
-        <property name="show_close_button">True</property>
-        <child>
-          <object class="GtkBox" id="header_left_buttonbox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="spacing">32</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="icon_name">go-previous-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>
-            <child>
-              <object class="GtkLabel" id="header_filter_label">
-                <property name="visible">True</property>
-                <property name="can_focus">False</property>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">1</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkButton" id="select_all_button">
-                <property name="label" translatable="yes">Select All</property>
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">True</property>
-                <property name="margin_left">18</property>
-                <signal name="clicked" handler="on_select_all_button_clicked" swapped="no"/>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">3</property>
-              </packing>
-            </child>
-          </object>
-        </child>
-        <child>
-          <object class="GtkBox" id="header_right_buttonbox">
-            <property name="visible">True</property>
-            <property name="can_focus">False</property>
-            <property name="spacing">3</property>
-            <child>
-              <object class="GtkToggleButton" id="search_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <signal name="toggled" handler="on_search_button_toggled" swapped="no"/>
-                <child>
-                  <object class="GtkImage" id="search_image">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">edit-find-symbolic</property>
-                  </object>
-                </child>
-              </object>
-              <packing>
-                <property name="expand">False</property>
-                <property name="fill">True</property>
-                <property name="position">0</property>
-              </packing>
-            </child>
-            <child>
-              <object class="GtkMenuButton" id="menu_button">
-                <property name="visible">True</property>
-                <property name="can_focus">True</property>
-                <property name="receives_default">False</property>
-                <property name="popover">popovermenu</property>
-                <signal name="toggled" handler="on_menu_button_toggled" swapped="no"/>
-                <child>
-                  <object class="GtkImage" id="menu_icon">
-                    <property name="visible">True</property>
-                    <property name="can_focus">False</property>
-                    <property name="icon_name">open-menu-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>
-          </object>
-          <packing>
-            <property name="pack_type">end</property>
-            <property name="position">1</property>
-          </packing>
-        </child>
-      </object>
-    </child>
   </template>
 </interface>
diff --git a/resources/transaction_sum_dialog.ui b/resources/transaction_sum_dialog.ui
index 9a94f0ad54b7874da4cae7d0bf58670348c71ccb..d8e3cb535f7db16d2f887f8e8d5b7756fdecf73b 100644
--- a/resources/transaction_sum_dialog.ui
+++ b/resources/transaction_sum_dialog.ui
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.20.0 -->
+<!-- Generated with glade 3.22.1 -->
 <interface>
   <requires lib="gtk+" version="3.20"/>
   <template class="PamacTransactionSumDialog" parent="GtkDialog">
@@ -11,6 +11,9 @@
     <property name="icon_name">system-software-install</property>
     <property name="type_hint">dialog</property>
     <property name="deletable">False</property>
+    <child>
+      <placeholder/>
+    </child>
     <child internal-child="vbox">
       <object class="GtkBox" id="dialog-vbox6">
         <property name="can_focus">False</property>
@@ -25,6 +28,9 @@
                 <property name="label" translatable="yes">_Cancel</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="can_default">True</property>
+                <property name="has_default">True</property>
                 <property name="receives_default">False</property>
                 <property name="use_underline">True</property>
               </object>
@@ -39,9 +45,6 @@
                 <property name="label" translatable="yes">Commit</property>
                 <property name="visible">True</property>
                 <property name="can_focus">True</property>
-                <property name="has_focus">True</property>
-                <property name="can_default">True</property>
-                <property name="has_default">True</property>
                 <property name="receives_default">False</property>
               </object>
               <packing>
diff --git a/src/alpm_utils.vala b/src/alpm_utils.vala
index 20a725b2da6e591a3ca88d2dd4f850a91424f05b..fbcc55b9494b559862d61c7c4bdbf11ad663657a 100644
--- a/src/alpm_utils.vala
+++ b/src/alpm_utils.vala
@@ -76,6 +76,7 @@ private int alpm_pkg_sort_search_by_relevance (Alpm.Package pkg_a, Alpm.Package
 
 namespace Pamac {
 	internal class AlpmUtils: Object {
+		Config config;
 		internal AlpmConfig alpm_config;
 		internal Alpm.Handle? alpm_handle;
 		internal Alpm.Handle? files_handle;
@@ -87,6 +88,7 @@ namespace Pamac {
 		internal bool enable_downgrade;
 		internal bool check_aur_updates;
 		internal int flags;
+		string[] to_syncfirst;
 		internal string[] to_install;
 		internal string[] to_remove;
 		internal string[] to_load;
@@ -119,12 +121,12 @@ namespace Pamac {
 		public signal void emit_log (uint level, string msg);
 		public signal void refresh_finished (bool success);
 		public signal void emit_get_updates_progress (uint percent);
-		public signal void get_updates_finished (UpdatesStruct updates);
 		public signal void downloading_updates_finished ();
 		public signal void trans_prepare_finished (bool success);
 		public signal void trans_commit_finished (bool success);
 
-		public AlpmUtils () {
+		public AlpmUtils (Config config) {
+			this.config = config;
 			alpm_config = new AlpmConfig ("/etc/pacman.conf");
 			aur_pkgbases_to_build = new GLib.List<string> ();
 			aur_desc_list = new GenericSet<string?> (str_hash, str_equal);
@@ -401,12 +403,7 @@ namespace Pamac {
 					}
 				}
 			});
-			// keep a ref pkg is needed
-			var pkgs = new List<Package> ();
-			foreach (unowned Package pkg in result) {
-				pkgs.append (pkg);
-			}
-			return pkgs;
+			return (owned) result;
 		}
 
 		internal List<Package> get_explicitly_installed_pkgs () {
@@ -587,7 +584,8 @@ namespace Pamac {
 					name = "",
 					version = "",
 					installed_version = "",
-					desc = ""
+					desc = "",
+					packagebase = ""
 				};
 			}
 			string installed_version = "";
@@ -601,13 +599,14 @@ namespace Pamac {
 				installed_version = (owned) installed_version,
 				// desc can be null
 				desc = json_object.get_null_member ("Description") ? "" : json_object.get_string_member ("Description"),
-				popularity = json_object.get_double_member ("Popularity")
+				popularity = json_object.get_double_member ("Popularity"),
+				packagebase = json_object.get_string_member ("PackageBase")
 			};
 		}
 
-		internal List<AURPackage> search_in_aur (string search_string) {
+		internal async List<AURPackage> search_in_aur (string search_string) {
 			if (!aur_search_results.contains (search_string)) {
-				Json.Array pkgs = aur_search (search_string.split (" "));
+				Json.Array pkgs = yield aur_search (search_string.split (" "));
 				aur_search_results.insert (search_string, pkgs);
 			}
 			var result = new List<AURPackage> ();
@@ -619,17 +618,12 @@ namespace Pamac {
 					result.append (new AURPackage.from_struct (initialise_aur_struct (aur_pkg)));
 				}
 			});
-			// keep a ref pkg is needed
-			var pkgs = new List<AURPackage> ();
-			foreach (unowned AURPackage pkg in result) {
-				pkgs.append (pkg);
-			}
-			return pkgs;
+			return (owned) result;
 		}
 
-		internal AURPackage get_aur_pkg (string pkgname) {
+		internal async AURPackage get_aur_pkg (string pkgname) {
 			if (!aur_infos.contains (pkgname)) {
-				Json.Array results = aur_multiinfo ({pkgname});
+				Json.Array results = yield aur_multiinfo ({pkgname});
 				if (results.get_length () > 0) {
 					aur_infos.insert (pkgname, results.get_object_element (0));
 				}
@@ -638,7 +632,7 @@ namespace Pamac {
 			return new AURPackage.from_struct (initialise_aur_struct (json_object));
 		}
 
-		internal AURPackageDetails get_aur_pkg_details (string pkgname) {
+		internal async AURPackageDetails get_aur_pkg_details (string pkgname) {
 			string name = "";
 			string version = "";
 			string desc = "";
@@ -660,7 +654,7 @@ namespace Pamac {
 			string[] conflicts = {};
 			var details = AURPackageDetailsStruct ();
 			if (!aur_infos.contains (pkgname)) {
-				Json.Array results = aur_multiinfo ({pkgname});
+				Json.Array results = yield aur_multiinfo ({pkgname});
 				if (results.get_length () > 0) {
 					aur_infos.insert (pkgname, results.get_object_element (0));
 				}
@@ -783,6 +777,29 @@ namespace Pamac {
 			return new AURPackageDetails.from_struct (details);
 		}
 
+		internal string get_srcinfo_version (string pkgdir_name) {
+			StringBuilder version = new StringBuilder ();
+			// assume file exists
+			var srcinfo = File.new_for_path (pkgdir_name + "/.SRCINFO");
+			try {
+				var dis = new DataInputStream (srcinfo.read ());
+				string line;
+				while ((line = dis.read_line ()) != null) {
+					if ("pkgver = " in line) {
+						version.append (line.split ("pkgver = ", 2)[1]);
+					} else if ("pkgrel = " in line) {
+						version.append ("-");
+						version.append (line.split ("pkgrel = ", 2)[1]);
+						// we have all we want
+						break;
+					}
+				}
+			} catch (GLib.Error e) {
+				stderr.printf ("%s\n", e.message);
+			}
+			return version.str;
+		}
+
 		internal List<string> get_repos_names () {
 			var repos_names = new List<string> ();
 			unowned Alpm.List<unowned Alpm.DB> syncdbs = alpm_handle.syncdbs;
@@ -924,12 +941,7 @@ namespace Pamac {
 					}
 				});
 			});
-			// keep a ref pkg is needed
-			var pkgs = new List<Package> ();
-			foreach (unowned Package pkg in result) {
-				pkgs.append (pkg);
-			}
-			return pkgs;
+			return (owned) result;
 		}
 
 		internal List<string> get_pkg_uninstalled_optdeps (string pkgname) {
@@ -1163,7 +1175,10 @@ namespace Pamac {
 				Alpm.File* file_ptr = filelist.files;
 				for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
 					if (!file_ptr->name.has_suffix ("/")) {
-						files.append (alpm_handle.root + file_ptr->name);
+						var filename = new StringBuilder ();
+						filename.append (alpm_handle.root);
+						filename.append (file_ptr->name);
+						files.append (filename.str);
 					}
 				}
 			} else {
@@ -1176,7 +1191,10 @@ namespace Pamac {
 						Alpm.File* file_ptr = filelist.files;
 						for (size_t i = 0; i < filelist.count; i++, file_ptr++) {
 							if (!file_ptr->name.has_suffix ("/")) {
-								files.append (alpm_handle.root + file_ptr->name);
+								var filename = new StringBuilder ();
+								filename.append (alpm_handle.root);
+								filename.append (file_ptr->name);
+								files.append (filename.str);
 							}
 						}
 						break;
@@ -1201,9 +1219,11 @@ namespace Pamac {
 						// exclude directory name
 						if (!file_ptr->name.has_suffix ("/")) {
 							// adding / to compare
-							string real_file_name = alpm_handle.root + file_ptr->name;
-							if (file in real_file_name) {
-								found_files += real_file_name;
+							var real_file_name = new StringBuilder ();
+							real_file_name.append (alpm_handle.root);
+							real_file_name.append (file_ptr->name);
+							if (file in real_file_name.str) {
+								found_files += real_file_name.str;
 							}
 						}
 					}
@@ -1226,9 +1246,11 @@ namespace Pamac {
 							// exclude directory name
 							if (!file_ptr->name.has_suffix ("/")) {
 								// adding / to compare
-								string real_file_name = alpm_handle.root + file_ptr->name;
-								if (file in real_file_name) {
-									found_files += real_file_name;
+								var real_file_name = new StringBuilder ();
+								real_file_name.append (alpm_handle.root);
+								real_file_name.append (file_ptr->name);
+								if (file in real_file_name.str) {
+									found_files += real_file_name.str;
 								}
 							}
 						}
@@ -1401,7 +1423,7 @@ namespace Pamac {
 			}
 		}
 
-		internal void compute_aur_build_list () {
+		internal async void compute_aur_build_list () {
 			try {
 				Process.spawn_command_line_sync ("mkdir -p %s".printf (aurdb_path));
 			} catch (SpawnError e) {
@@ -1409,146 +1431,207 @@ namespace Pamac {
 			}
 			aur_desc_list.remove_all ();
 			already_checked_aur_dep.remove_all ();
-			check_aur_dep_list (to_build);
+			yield check_aur_dep_list (to_build);
+		}
+
+		internal async string clone_build_files (string pkgname, bool overwrite_files) {
+			int status = 1;
+			string builddir_name = Path.build_path ("/", config.aur_build_dir, "pamac-build");
+			string[] cmds;
+			var builddir = File.new_for_path (builddir_name);
+			if (!builddir.query_exists ()) {
+				try {
+					builddir.make_directory_with_parents ();
+					Process.spawn_command_line_sync ("chmod --quiet -R ugo+w %s".printf (builddir_name));
+				} catch (Error e) {
+					stderr.printf ("Error: %s\n", e.message);
+				}
+			}
+			string pkgdir_name = builddir_name + "/" + pkgname;
+			var pkgdir = File.new_for_path (pkgdir_name);
+			var launcher = new SubprocessLauncher (SubprocessFlags.NONE);
+			if (overwrite_files) {
+				try {
+					Process.spawn_command_line_sync ("rm -rf %s".printf (pkgdir_name));
+				} catch (Error e) {
+					stderr.printf ("Error: %s\n", e.message);
+				}
+			}
+			if (pkgdir.query_exists ()) {
+				var aur_pkg = yield get_aur_pkg (pkgname);
+				if (aur_pkg.version == alpm_utils.get_srcinfo_version (pkgdir_name)) {
+					// up to date
+					return pkgdir_name;
+				} else {
+					launcher.set_cwd (pkgdir_name);
+					cmds = {"git", "pull", "-q"};
+					try {
+						Subprocess process = launcher.spawnv (cmds);
+						yield process.wait_async ();
+						if (process.get_if_exited ()) {
+							status = process.get_exit_status ();
+						}
+						if (status == 0) {
+							return pkgdir_name;
+						} else {
+							launcher.set_cwd (builddir_name);
+							cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)};
+						}
+					} catch (Error e) {
+						stderr.printf ("Error: %s\n", e.message);
+					}
+				}
+			} else {
+				launcher.set_cwd (builddir_name);
+				cmds = {"git", "clone", "-q", "--depth=1", "https://aur.archlinux.org/%s.git".printf (pkgname)};
+			}
+			try {
+				Subprocess process = launcher.spawnv (cmds);
+				yield process.wait_async ();
+				if (process.get_if_exited ()) {
+					status = process.get_exit_status ();
+				}
+			} catch (Error e) {
+				stderr.printf ("Error: %s\n", e.message);
+			}
+			if (status == 0) {
+				return pkgdir_name;
+			}
+			return "";
 		}
 
-		void check_aur_dep_list (string[] pkgnames) {
-			string[] dep_types = {"Depends", "MakeDepends", "CheckDepends"};
+		async void check_aur_dep_list (string[] pkgnames) {
 			string[] dep_to_check = {};
-			Json.Array results = aur_multiinfo (pkgnames);
-			results.foreach_element ((array, index, node) => {
-				unowned Json.Object? pkg_info = node.get_object ();
-				// create fake db desc file
-				if (pkg_info != null) {
-					string name = pkg_info.get_string_member ("Name");
-					string version = pkg_info.get_string_member ("Version");
+			foreach (unowned string name in pkgnames) {
+				string version = "";
+				string pkgbase = "";
+				string desc = "";
+				string[] depends = {};
+				string[] conflicts = {};
+				string[] provides = {};
+				string[] replaces = {};
+				// clone build files
+				string pkgdir_name = yield clone_build_files (name, false);
+				if (pkgdir_name == "") {
+					// error
+					continue;
+				}
+				// read .SRCINFO
+				var srcinfo = File.new_for_path (pkgdir_name + "/.SRCINFO");
+				try {
+					var dis = new DataInputStream (srcinfo.read ());
+					string line;
+					while ((line = dis.read_line ()) != null) {
+						if ("pkgbase = " in line) {
+							pkgbase = line.split ("pkgbase = ", 2)[1];
+						} else if ("pkgdesc = " in line) {
+							desc = line.split ("pkgdesc = ", 2)[1];
+						} else if ("pkgver = " in line) {
+							version = line.split ("pkgver = ", 2)[1];
+						} else if ("pkgrel = " in line) {
+							version += "-";
+							version += line.split ("pkgrel = ", 2)[1];
+						// compute depends, makedepends and checkdepends in depends
+						} else if ("checkdepends = " in line) {
+							depends += line.split ("checkdepends = ", 2)[1];
+						} else if ("makedepends = " in line) {
+							depends += line.split ("makedepends = ", 2)[1];
+						} else if ("depends = " in line) {
+							depends += line.split ("depends = ", 2)[1];
+						} else if ("provides = " in line) {
+							provides += line.split ("provides = ", 2)[1];
+						} else if ("conflicts = " in line) {
+							conflicts += line.split ("conflicts = ", 2)[1];
+						} else if ("replaces = " in line) {
+							replaces += line.split ("replaces = ", 2)[1];
+						}
+					}
+					// check deps
+					foreach (unowned string dep_string in depends) {
+						string dep_name = Alpm.Depend.from_string (dep_string).name;
+						unowned Alpm.Package? pkg = null;
+						// search for the name first to avoid provides trouble
+						pkg = alpm_handle.localdb.get_pkg (dep_name);
+						if (pkg == null) {
+							pkg = get_syncpkg (dep_name);
+						}
+						if (pkg == null) {
+							if (!(dep_name in already_checked_aur_dep)) {
+								dep_to_check += (owned) dep_name;
+							}
+						}
+					}
+					// write desc file
 					string pkgdir = "%s-%s".printf (name, version);
 					string pkgdir_path = "%s/%s".printf (aurdb_path, pkgdir);
 					aur_desc_list.add (pkgdir);
 					already_checked_aur_dep.add (name);
-					try {
-						var file = GLib.File.new_for_path (pkgdir_path);
-						bool write_desc_file = false;
-						if (!file.query_exists ()) {
-							file.make_directory ();
-							write_desc_file = true;
+					var file = GLib.File.new_for_path (pkgdir_path);
+					// always recreate desc in case of .SRCINFO modifications
+					if (file.query_exists ()) {
+						Process.spawn_command_line_sync ("rm -rf %s".printf (pkgdir_path));
+					}
+					file.make_directory ();
+					file = GLib.File.new_for_path ("%s/desc".printf (pkgdir_path));
+					// creating a DataOutputStream to the file
+					var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION));
+					// fake filename
+					dos.put_string ("%FILENAME%\n" + "%s-%s-any.pkg.tar.xz\n\n".printf (name, version));
+					// name
+					dos.put_string ("%NAME%\n%s\n\n".printf (name));
+					// version
+					dos.put_string ("%VERSION%\n%s\n\n".printf (version));
+					// base
+					dos.put_string ("%BASE%\n%s\n\n".printf (pkgbase));
+					// desc
+					dos.put_string ("%DESC%\n%s\n\n".printf (desc));
+					// version
+					dos.put_string ("%VERSION%\n%s\n\n".printf (version));
+					// fake arch
+					dos.put_string ("%ARCH%\nany\n\n");
+					// depends
+					if (depends.length > 0) {
+						dos.put_string ("%DEPENDS%\n");
+						foreach (unowned string depend in depends) {
+							dos.put_string ("%s\n".printf (depend));
 						}
-						// compute depends, makedepends and checkdepends in DEPENDS
-						var depends = new StringBuilder ();
-						foreach (unowned string dep_type in dep_types) {
-							unowned Json.Node? dep_node = pkg_info.get_member (dep_type);
-							if (dep_node != null) {
-								dep_node.get_array ().foreach_element ((array, index, node) => {
-									if (write_desc_file) {
-										depends.append (node.get_string ());
-										depends.append ("\n");
-									}
-									// check deps
-									unowned string dep_string = node.get_string ();
-									string dep_name = Alpm.Depend.from_string (dep_string).name;
-									unowned Alpm.Package? pkg = null;
-									// search for the name first to avoid provides trouble
-									pkg = alpm_handle.localdb.get_pkg (dep_name);
-									if (pkg == null) {
-										pkg = get_syncpkg (dep_name);
-									}
-									if (pkg == null) {
-										if (!(dep_name in already_checked_aur_dep)) {
-											dep_to_check += (owned) dep_name;
-										}
-									}
-								});
-							}
+						dos.put_string ("\n");
+					}
+					// conflicts
+					if (conflicts.length > 0) {
+						dos.put_string ("%CONFLICTS%\n");
+						foreach (unowned string conflict in conflicts) {
+							dos.put_string ("%s\n".printf (conflict));
 						}
-						if (write_desc_file) {
-							file = GLib.File.new_for_path ("%s/desc".printf (pkgdir_path));
-							// creating a DataOutputStream to the file
-							var dos = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION));
-							// fake filename
-							dos.put_string ("%FILENAME%\n" + "%s-%s-any.pkg.tar.xz\n\n".printf (name, version));
-							// name
-							dos.put_string ("%NAME%\n%s\n\n".printf (name));
-							// version
-							dos.put_string ("%VERSION%\n%s\n\n".printf (version));
-							//base
-							dos.put_string ("%BASE%\n%s\n\n".printf (pkg_info.get_string_member ("PackageBase")));
-							// desc can be null
-							if (!pkg_info.get_null_member ("Description")) {
-								dos.put_string ("%DESC%\n%s\n\n".printf (pkg_info.get_string_member ("Description")));
-							}
-							// version
-							dos.put_string ("%VERSION%\n%s\n\n".printf (pkg_info.get_string_member ("Version")));
-							// fake arch
-							dos.put_string ("%ARCH%\nany\n\n");
-							// depends
-							if (depends.len > 0) {
-								dos.put_string ("%DEPENDS%\n%s\n".printf (depends.str));
-							}
-							// conflicts
-							unowned Json.Node? info_node = pkg_info.get_member ("Conflicts");
-							if (info_node != null) {
-								try {
-									dos.put_string ("%CONFLICTS%\n");
-									info_node.get_array ().foreach_element ((array, index, _node) => {
-										try {
-											dos.put_string ("%s\n".printf (_node.get_string ()));
-										} catch (GLib.Error e) {
-											GLib.stderr.printf("%s\n", e.message);
-										}
-									});
-									dos.put_string ("\n");
-								} catch (GLib.Error e) {
-									GLib.stderr.printf("%s\n", e.message);
-								}
-							}
-							// provides
-							info_node = pkg_info.get_member ("Provides");
-							if (info_node != null) {
-								try {
-									dos.put_string ("%PROVIDES%\n");
-									info_node.get_array ().foreach_element ((array, index, _node) => {
-										try {
-											dos.put_string ("%s\n".printf (_node.get_string ()));
-										} catch (GLib.Error e) {
-											GLib.stderr.printf("%s\n", e.message);
-										}
-									});
-									dos.put_string ("\n");
-								} catch (GLib.Error e) {
-									GLib.stderr.printf("%s\n", e.message);
-								}
-							}
-							// replaces
-							info_node = pkg_info.get_member ("Replaces");
-							if (info_node != null) {
-								try {
-									dos.put_string ("%REPLACES%\n");
-									info_node.get_array ().foreach_element ((array, index, _node) => {
-										try {
-											dos.put_string ("%s\n".printf (_node.get_string ()));
-										} catch (GLib.Error e) {
-											GLib.stderr.printf("%s\n", e.message);
-										}
-									});
-									dos.put_string ("\n");
-								} catch (GLib.Error e) {
-									GLib.stderr.printf("%s\n", e.message);
-								}
-							}
+						dos.put_string ("\n");
+					}
+					// provides
+					if (provides.length > 0) {
+						dos.put_string ("%PROVIDES%\n");
+						foreach (unowned string provide in provides) {
+							dos.put_string ("%s\n".printf (provide));
 						}
-					} catch (GLib.Error e) {
-						GLib.stderr.printf("%s\n", e.message);
+						dos.put_string ("\n");
+					}
+					// replaces
+					if (replaces.length > 0) {
+						dos.put_string ("%REPLACES%\n");
+						foreach (unowned string replace in replaces) {
+							dos.put_string ("%s\n".printf (replace));
+						}
+						dos.put_string ("\n");
 					}
+				} catch (GLib.Error e) {
+					GLib.stderr.printf("%s\n", e.message);
 				}
-			});
+			}
 			if (dep_to_check.length > 0) {
-				check_aur_dep_list (dep_to_check);
+				yield check_aur_dep_list (dep_to_check);
 			}
 		}
 
-		internal Updates get_updates (bool refresh_files_dbs) {
+		internal async Updates get_updates (bool refresh_files_dbs) {
 			var repos_updates = new List<Package> ();
-			var aur_updates = new List<AURPackage> ();
 			unowned Alpm.Package? pkg = null;
 			unowned Alpm.Package? candidate = null;
 			// use a tmp handle
@@ -1606,58 +1689,35 @@ namespace Pamac {
 			emit_get_updates_progress (95);
 			if (check_aur_updates) {
 				// count this step as 5% of the total
-				var aur_updates_structs = get_aur_updates (aur_multiinfo (local_pkgs));
-				foreach (unowned AURPackageStruct aur_struct in aur_updates_structs) {
-					aur_updates.append (new AURPackage.from_struct (aur_struct));
-				}
+				emit_get_updates_progress (100);
+				return new Updates.from_lists ((owned) repos_updates, get_aur_updates_real (yield aur_multiinfo (local_pkgs)));
+			} else {
+				emit_get_updates_progress (100);
+				return new Updates.from_lists ((owned) repos_updates, new List<AURPackage> ());
 			}
-			emit_get_updates_progress (100);
-			return new Updates.from_lists ((owned) repos_updates, (owned) aur_updates);
 		}
 
-		internal void get_updates_for_sysupgrade () {
-			// only get syncfirst repos updates and aur updates
-			PackageStruct[] syncfirst_updates = {};
-			AURPackageStruct[] aur_updates = {};
-			unowned Alpm.Package? pkg = null;
-			unowned Alpm.Package? candidate = null;
-			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_handle.syncdbs);
-					if (candidate != null) {
-						var infos = initialise_pkg_struct (candidate);
-						syncfirst_updates += (owned) infos;
-					}
-				}
-			}
-			if (check_aur_updates) {
-				// get local pkgs
-				string[] local_pkgs = {};
-				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_handle.should_ignore (installed_pkg) == 0) {
-						// check if installed_pkg is a local pkg
-						pkg = get_syncpkg (installed_pkg.name);
-						if (pkg == null) {
-							local_pkgs += installed_pkg.name;
-						}
+		internal async List<AURPackage> get_aur_updates () {
+			// get local pkgs
+			string[] local_pkgs = {};
+			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_handle.should_ignore (installed_pkg) == 0) {
+					// check if installed_pkg is a local pkg
+					unowned Alpm.Package? pkg = get_syncpkg (installed_pkg.name);
+					if (pkg == null) {
+						local_pkgs += installed_pkg.name;
 					}
-					pkgcache.next ();
 				}
-				aur_updates = get_aur_updates (aur_multiinfo (local_pkgs));
+				pkgcache.next ();
 			}
-			var updates = UpdatesStruct () {
-				syncfirst_repos_updates = (owned) syncfirst_updates,
-				aur_updates = (owned) aur_updates
-			};
-			get_updates_finished (updates);
+			return get_aur_updates_real (yield aur_multiinfo (local_pkgs));
 		}
 
-		AURPackageStruct[] get_aur_updates (Json.Array aur_updates_json) {
-			AURPackageStruct[] aur_updates = {};
+		List<AURPackage> get_aur_updates_real (Json.Array aur_updates_json) {
+			var aur_updates = new List<AURPackage> ();
 			aur_updates_json.foreach_element ((array, index, node) => {
 				unowned Json.Object pkg_info = node.get_object ();
 				unowned string name = pkg_info.get_string_member ("Name");
@@ -1666,10 +1726,10 @@ namespace Pamac {
 				if (Alpm.pkg_vercmp (new_version, old_version) == 1) {
 					var infos = initialise_aur_struct (pkg_info);
 					infos.installed_version = old_version;
-					aur_updates += (owned) infos;
+					aur_updates.append (new AURPackage.from_struct ((owned) infos));
 				}
 			});
-			return aur_updates;
+			return (owned) aur_updates;
 		}
 
 		internal int download_updates () {
@@ -1714,7 +1774,6 @@ namespace Pamac {
 		bool trans_sysupgrade () {
 			current_error = ErrorInfos ();
 			add_ignorepkgs ();
-			add_overwrite_files ();
 			if (alpm_handle.trans_sysupgrade ((enable_downgrade) ? 1 : 0) == -1) {
 				Alpm.Errno errno = alpm_handle.errno ();
 				current_error.message = _("Failed to prepare transaction");
@@ -1723,6 +1782,17 @@ namespace Pamac {
 				}
 				return false;
 			}
+			// check syncfirsts
+			to_syncfirst = {};
+			foreach (unowned string name in alpm_config.get_syncfirsts ()) {
+				unowned Alpm.Package? pkg = Alpm.find_satisfier (alpm_handle.localdb.pkgcache, name);
+				if (pkg != null) {
+					unowned Alpm.Package? candidate = pkg.sync_newversion (alpm_handle.syncdbs);
+					if (candidate != null) {
+						to_syncfirst += candidate.name;
+					}
+				}
+			}
 			return true;
 		}
 
@@ -1982,9 +2052,28 @@ namespace Pamac {
 
 		void launch_trans_prepare_real () {
 			bool success = trans_init (flags);
-			if (success && sysupgrade) {
-				// add upgrades to transaction
-				success = trans_sysupgrade ();
+			// check if you add upgrades to transaction
+			if (success) {
+				if (!sysupgrade && to_install.length > 0) {
+					foreach (unowned string name in to_install) {
+						unowned Alpm.Package? local_pkg = alpm_handle.localdb.get_pkg (name);
+						if (local_pkg == null) {
+							sysupgrade = true;
+							break;
+						} else {
+							unowned Alpm.Package? sync_pkg = get_syncpkg (name);
+							if (sync_pkg != null) {
+								if (local_pkg.version != sync_pkg.version) {
+									sysupgrade = true;
+									break;
+								}
+							}
+						}
+					}
+				}
+				if (sysupgrade) {
+					success = trans_sysupgrade ();
+				}
 			}
 			if (success) {
 				foreach (unowned string name in to_install) {
@@ -2139,13 +2228,13 @@ namespace Pamac {
 										if (aur_pkgbases_to_build.find_custom (trans_pkg.pkgbase, strcmp) == null) {
 											aur_pkgbases_to_build.append (trans_pkg.pkgbase);
 										}
-										var pkg = AURPackageStruct () {
+										to_build_pkgs += AURPackageStruct () {
 											name = trans_pkg.name,
 											version = trans_pkg.version,
 											installed_version = "",
-											desc = ""
+											desc = "",
+											packagebase = ""
 										};
-										to_build_pkgs += (owned) pkg;
 										if (!(trans_pkg.name in to_build)) {
 											to_install_as_dep.insert (trans_pkg.name, trans_pkg.name);
 										}
@@ -2165,8 +2254,7 @@ namespace Pamac {
 								unowned Alpm.Package trans_pkg = pkgs_to_remove.data;
 								// it is a pkg to remove
 								if (!(trans_pkg.name in to_remove)) {
-									var pkg = initialise_pkg_struct (trans_pkg);
-									aur_conflicts_to_remove += (owned) pkg;
+									aur_conflicts_to_remove += initialise_pkg_struct (trans_pkg);
 								}
 								pkgs_to_remove.next ();
 							}
@@ -2231,8 +2319,7 @@ namespace Pamac {
 			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 = initialise_pkg_struct (trans_pkg);
-				to_remove += (owned) infos;
+				to_remove += initialise_pkg_struct (trans_pkg);
 				pkgs_to_remove.next ();
 			}
 			PackageStruct[] conflicts_to_remove = {};
@@ -2258,9 +2345,83 @@ namespace Pamac {
 		}
 
 		internal void trans_commit () {
+			add_overwrite_files ();
+			bool success = false;
+			if (to_syncfirst.length > 0) {
+				trans_release ();
+				success = trans_init (flags);
+				if (success) {
+					foreach (unowned string name in to_syncfirst) {
+						success = trans_add_pkg (name);
+						if (!success) {
+							break;
+						}
+					}
+					if (success) {
+						success = trans_prepare_real ();
+					}
+					if (success) {
+						success = trans_commit_real ();
+					}
+					trans_release ();
+					if (success) {
+						success = trans_init (flags);
+						if (success && sysupgrade) {
+							success = trans_sysupgrade ();
+						}
+						if (success) {
+							foreach (unowned string name in to_install) {
+								success = trans_add_pkg (name);
+								if (!success) {
+									break;
+								}
+							}
+						}
+						if (success) {
+							foreach (unowned string name in to_remove) {
+								success = trans_remove_pkg (name);
+								if (!success) {
+									break;
+								}
+							}
+						}
+						if (success) {
+							foreach (unowned string path in to_load) {
+								success = trans_load_pkg (path);
+								if (!success) {
+									break;
+								}
+							}
+						}
+						if (success) {
+							success = trans_prepare_real ();
+						} else {
+							trans_release ();
+						}
+					}
+				}
+				if (!success) {
+					trans_commit_finished (success);
+					return;
+				}
+			}
+			success = trans_commit_real ();
+			if (success) {
+				to_install_as_dep.foreach_remove ((pkgname, val) => {
+					unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
+					if (pkg != null) {
+						pkg.reason = Alpm.Package.Reason.DEPEND;
+						return true; // remove current pkgname
+					}
+					return false;
+				});
+			}
+			trans_commit_finished (success);
+		}
+
+		bool trans_commit_real () {
 			current_error = ErrorInfos ();
 			bool success = true;
-			add_overwrite_files ();
 			Alpm.List err_data;
 			if (alpm_handle.trans_commit (out err_data) == -1) {
 				Alpm.Errno errno = alpm_handle.errno ();
@@ -2268,7 +2429,7 @@ namespace Pamac {
 				if (errno == Alpm.Errno.EXTERNAL_DOWNLOAD && cancellable.is_cancelled ()) {
 					trans_release ();
 					trans_commit_finished (false);
-					return;
+					return false;
 				}
 				current_error.message = _("Failed to commit transaction");
 				switch (errno) {
@@ -2322,15 +2483,7 @@ namespace Pamac {
 				success = false;
 			}
 			trans_release ();
-			to_install_as_dep.foreach_remove ((pkgname, val) => {
-				unowned Alpm.Package? pkg = alpm_handle.localdb.get_pkg (pkgname);
-				if (pkg != null) {
-					pkg.reason = Alpm.Package.Reason.DEPEND;
-					return true; // remove current pkgname
-				}
-				return false;
-			});
-			trans_commit_finished (success);
+			return success;
 		}
 
 		internal void trans_release () {
diff --git a/src/aur.vala b/src/aur.vala
index 65ad5935461108425fd8a1ac527064996e721258..bb3830bc00380f3a63f605795946fd16333ef172 100644
--- a/src/aur.vala
+++ b/src/aur.vala
@@ -25,37 +25,41 @@ namespace Pamac {
 	const string rpc_multiinfo = "&type=info";
 	const string rpc_multiinfo_arg = "&arg[]=";
 
-	Json.Array rpc_query (string uri) {
+	async Json.Array rpc_query (string uri) {
+		SourceFunc callback = rpc_query.callback;
 		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) {
-			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 query %s from AUR\n", uri);
-			} else {
-				results = root.get_object ().get_array_member ("results");
+		session.queue_message (message, (sess, mess) => {
+			try {
+				parser.load_from_data ((string) mess.response_body.flatten ().data, -1);
+				unowned Json.Node? root = parser.get_root ();
+				if (root != null) {
+					if (root.get_object ().get_string_member ("type") == "error") {
+						stderr.printf ("Failed to query %s from AUR\n", uri);
+					} else {
+						results = root.get_object ().get_array_member ("results");
+					}
+				}
+			} catch (Error e) {
+				critical (e.message);
 			}
-		}
+			Idle.add ((owned) callback);
+		});
+		yield;
 		return results;
 	}
 
-	internal Json.Array aur_search (string[] needles) {
+	internal async Json.Array aur_search (string[] needles) {
 		if (needles.length == 0) {
 			return new Json.Array ();
 		} else {
 			Json.Array[] found_array = {};
 			foreach (unowned string needle in needles) {
-				found_array += rpc_query (rpc_url + rpc_search + Uri.escape_string (needle));
+				found_array += yield rpc_query (rpc_url + rpc_search + Uri.escape_string (needle));
 			}
 			var result = new Json.Array ();
 			foreach (unowned Json.Array found in found_array) {
@@ -81,17 +85,44 @@ namespace Pamac {
 		}
 	}
 
-	internal Json.Array aur_multiinfo (string[] pkgnames) {
+	internal async Json.Array aur_multiinfo (string[] pkgnames) {
 		if (pkgnames.length == 0) {
 			return new Json.Array ();
 		}
-		var builder = new StringBuilder ();
-		builder.append (rpc_url);
-		builder.append (rpc_multiinfo);
-		foreach (unowned string pkgname in pkgnames) {
-			builder.append (rpc_multiinfo_arg);
-			builder.append (Uri.escape_string (pkgname));
+		// query pkgnames hundred by hundred to avoid too long uri error
+		// example: ros-lunar-desktop
+		if (pkgnames.length <= 100) {
+			var builder = new StringBuilder ();
+			builder.append (rpc_url);
+			builder.append (rpc_multiinfo);
+			foreach (unowned string pkgname in pkgnames) {
+				builder.append (rpc_multiinfo_arg);
+				builder.append (Uri.escape_string (pkgname));
+			}
+			return yield rpc_query (builder.str);
+		} else {
+			var result = new Json.Array ();
+			int index_max = pkgnames.length - 1;
+			int index = 0;
+			while (index < index_max) {
+				var builder = new StringBuilder ();
+				builder.append (rpc_url);
+				builder.append (rpc_multiinfo);
+				for (int i = 0; i < 100; i++) {
+					unowned string pkgname = pkgnames[index];
+					builder.append (rpc_multiinfo_arg);
+					builder.append (Uri.escape_string (pkgname));
+					index++;
+					if (index == index_max) {
+						break;
+					}
+				}
+				var array = yield rpc_query (builder.str);
+				array.foreach_element ((array, index, node) => {
+					result.add_element (node);
+				});
+			}
+			return result;
 		}
-		return rpc_query (builder.str);
 	}
 }
diff --git a/src/cli.vala b/src/cli.vala
index 74fadd0b717a235c07a3f6a5c47c0c0e49047498..1cb3b5ac6db25ecca769dc9bc15114264690a503 100644
--- a/src/cli.vala
+++ b/src/cli.vala
@@ -99,7 +99,10 @@ namespace Pamac {
 					} else if (args[2] == "--aur" || args[2] == "-a") {
 						init_database ();
 						database.config.enable_aur = true;
-						search_in_aur (concatenate_strings (args[3:args.length]));
+						search_in_aur.begin (concatenate_strings (args[3:args.length]), () => {
+							loop.quit ();
+						});
+						loop.run ();
 					} else if (args[2] == "--files" || args[2] == "-f") {
 						init_database ();
 						search_files (args[3:args.length]);
@@ -117,7 +120,10 @@ namespace Pamac {
 					} else if (args[2] == "--aur" || args[2] == "-a") {
 						init_database ();
 						database.config.enable_aur = true;
-						display_aur_infos (args[3:args.length]);
+						display_aur_infos.begin (args[3:args.length], () => {
+							loop.quit ();
+						});
+						loop.run ();
 					} else {
 						init_database ();
 						display_pkg_infos (args[2:args.length]);
@@ -245,7 +251,10 @@ namespace Pamac {
 			} else if (args[1] == "checkupdates") {
 				if (args.length == 2) {
 					init_database ();
-					checkupdates ();
+					checkupdates.begin (() => {
+						loop.quit ();
+					});
+					loop.run ();
 				} else if (args.length == 3) {
 					if (args[2] == "--help" || args[2] == "-h") {
 						display_checkupdates_help ();
@@ -253,7 +262,10 @@ namespace Pamac {
 						init_database ();
 						database.config.enable_aur = true;
 						database.config.check_aur_updates = true;
-						checkupdates ();
+						checkupdates.begin ((obj, res) => {
+							loop.quit ();
+						});
+						loop.run ();
 					} else {
 						display_checkupdates_help ();
 					}
@@ -742,8 +754,8 @@ namespace Pamac {
 			}
 		}
 
-		void search_in_aur (string search_string) {
-			var pkgs = database.search_in_aur (search_string);
+		async void search_in_aur (string search_string) {
+			var pkgs = yield database.search_in_aur (search_string);
 			if (pkgs.length () == 0) {
 				exit_status = 1;
 				return;
@@ -997,7 +1009,7 @@ namespace Pamac {
 			}
 		}
 
-		void display_aur_infos (string[] pkgnames) {
+		async void display_aur_infos (string[] pkgnames) {
 			string[] properties = {};
 			properties += dgettext (null, "Name");
 			properties += dgettext (null, "Package Base");
@@ -1025,7 +1037,7 @@ namespace Pamac {
 				}
 			}
 			foreach (string pkgname in pkgnames) {
-				var details = database.get_aur_pkg_details (pkgname);
+				var details = yield database.get_aur_pkg_details (pkgname);
 				if (details.name == "") {
 					print_error (dgettext (null, "target not found: %s").printf (pkgname) + "\n");
 					return;
@@ -1306,8 +1318,8 @@ namespace Pamac {
 			}
 		}
 
-		void checkupdates () {
-			var updates = database.get_updates ();
+		async void checkupdates () {
+			var updates = yield database.get_updates ();
 			uint updates_nb = updates.repos_updates.length () + updates.aur_updates.length ();
 			if (updates_nb == 0) {
 				stdout.printf ("%s.\n", dgettext (null, "Your system is up-to-date"));
@@ -1362,7 +1374,6 @@ namespace Pamac {
 													dgettext (null, "AUR"));
 				}
 			}
-			loop.quit ();
 		}
 
 		void install_pkgs (string[] targets) {
diff --git a/src/common.vala b/src/common.vala
index 64dc73e198d0b68bdd4bd030040bb0fbf9d6721e..8d659ed7976748eb4a1d7cbb15a61617a5e53070 100644
--- a/src/common.vala
+++ b/src/common.vala
@@ -65,6 +65,7 @@ namespace Pamac {
 		public string installed_version;
 		public string desc;
 		public double popularity;
+		public string packagebase;
 	}
 
 	struct AURPackageDetailsStruct {
@@ -99,9 +100,4 @@ namespace Pamac {
 		public PackageStruct[] aur_conflicts_to_remove;
 		public string[] aur_pkgbases_to_build;
 	}
-
-	struct UpdatesStruct {
-		public PackageStruct[] syncfirst_repos_updates;
-		public AURPackageStruct[] aur_updates;
-	}
 }
diff --git a/src/common_daemon.vala b/src/common_daemon.vala
index 35d367f1237725523f7478d7b1a0f1e2dae979d7..d146e71ca6e53198e6411ed6488919107477e92b 100644
--- a/src/common_daemon.vala
+++ b/src/common_daemon.vala
@@ -65,6 +65,7 @@ namespace Pamac {
 		public string installed_version;
 		public string desc;
 		public double popularity;
+		public string packagebase;
 	}
 
 	public struct AURPackageDetailsStruct {
@@ -100,11 +101,6 @@ namespace Pamac {
 		public string[] aur_pkgbases_to_build;
 	}
 
-	public struct UpdatesStruct {
-		public PackageStruct[] syncfirst_repos_updates;
-		public AURPackageStruct[] aur_updates;
-	}
-
 	public struct ErrorInfos {
 		public string message;
 		public string[] details;
diff --git a/src/database.vala b/src/database.vala
index 0218047729c9ca75b428edd4386623fea52c4982..ed0769eff7398457041d2934a88641eda9311885 100644
--- a/src/database.vala
+++ b/src/database.vala
@@ -31,7 +31,7 @@ namespace Pamac {
 
 		construct {
 			// alpm_utils global variable declared in alpm_utils.vala
-			alpm_utils = new AlpmUtils ();
+			alpm_utils = new AlpmUtils (config);
 			refresh_files_dbs_on_get_updates = false;
 		}
 
@@ -168,18 +168,14 @@ namespace Pamac {
 			return alpm_utils.search_pkgs (search_string);
 		}
 
-		public List<AURPackage> search_in_aur (string search_string) {
+		public async List<AURPackage> search_in_aur (string search_string) {
 			var pkgs = new List<AURPackage> ();
 			if (config.enable_aur) {
-				pkgs = alpm_utils.search_in_aur (search_string);
+				pkgs = yield alpm_utils.search_in_aur (search_string);
 			}
 			return pkgs;
 		}
 
-		public async List<AURPackage> search_in_aur_async (string search_string) {
-			return search_in_aur (search_string);
-		}
-
 		public HashTable<string, Variant> search_files (string[] files) {
 			return alpm_utils.search_files (files);
 		}
@@ -232,40 +228,36 @@ namespace Pamac {
 			return alpm_utils.get_pkg_files (pkgname);
 		}
 
-		public AURPackage get_aur_pkg (string pkgname) {
+		public async string clone_build_files (string pkgname, bool overwrite_files) {
+			return yield alpm_utils.clone_build_files (pkgname, overwrite_files);
+		}
+
+		public async AURPackage get_aur_pkg (string pkgname) {
 			if (config.enable_aur) {
-				return alpm_utils.get_aur_pkg (pkgname);
+				return yield alpm_utils.get_aur_pkg (pkgname);
 			} else {
 				return new AURPackage ();
 			}
 		}
 
-		public async AURPackage get_aur_pkg_async (string pkgname) {
-			return get_aur_pkg (pkgname);
-		}
-
-		public AURPackageDetails get_aur_pkg_details (string pkgname) {
+		public async AURPackageDetails get_aur_pkg_details (string pkgname) {
 			if (config.enable_aur) {
-				return alpm_utils.get_aur_pkg_details (pkgname);
+				return yield alpm_utils.get_aur_pkg_details (pkgname);
 			} else {
 				return new AURPackageDetails ();
 			}
 		}
 
-		public async AURPackageDetails get_aur_pkg_details_async (string pkgname) {
-			return get_aur_pkg_details (pkgname);
+		public async List<AURPackage> get_aur_updates () {
+			return yield alpm_utils.get_aur_updates ();
 		}
 
-		public Updates get_updates () {
+		public async Updates get_updates () {
 			alpm_utils.emit_get_updates_progress.connect (on_emit_get_updates_progress);
 			alpm_utils.check_aur_updates = config.check_aur_updates;
 			// be sure we have the good updates
 			alpm_utils.refresh_handle ();
-			return alpm_utils.get_updates (refresh_files_dbs_on_get_updates);
-		}
-
-		public async Updates get_updates_async () {
-			return get_updates ();
+			return yield alpm_utils.get_updates (refresh_files_dbs_on_get_updates);
 		}
 
 		void on_emit_get_updates_progress (uint percent) {
diff --git a/src/manager_window.vala b/src/manager_window.vala
index 6117586a7c24b89261a7e3adb2bf9492a0959add..97ead189064ee6bd2e6c994d6ff1c5d5ec3c8ffb 100644
--- a/src/manager_window.vala
+++ b/src/manager_window.vala
@@ -109,8 +109,6 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.Label checking_label;
 		[GtkChild]
-		Gtk.Spinner checking_spinner;
-		[GtkChild]
 		Gtk.Stack properties_stack;
 		[GtkChild]
 		Gtk.ListBox properties_listbox;
@@ -139,6 +137,10 @@ namespace Pamac {
 		[GtkChild]
 		Gtk.ToggleButton install_togglebutton;
 		[GtkChild]
+		Gtk.ToggleButton build_togglebutton;
+		[GtkChild]
+		Gtk.Button reset_files_button;
+		[GtkChild]
 		Gtk.TextView files_textview;
 		[GtkChild]
 		Gtk.Box transaction_infobox;
@@ -202,6 +204,7 @@ namespace Pamac {
 		Gtk.Label pending_label;
 		Gtk.ListBoxRow pending_row;
 		Gtk.ListBoxRow files_row;
+		Gtk.ListBoxRow build_files_row;
 		bool scroll_to_top;
 
 		public ManagerWindow (Gtk.Application application) {
@@ -374,8 +377,10 @@ namespace Pamac {
 			intern_lock = false;
 			Timeout.add (200, check_extern_lock);
 
-			transaction = new TransactionGtk (database, this as Gtk.ApplicationWindow);
+			transaction = new TransactionGtk (database, this);
 			transaction.no_confirm_upgrade = true;
+			transaction.start_preparing.connect (on_start_preparing);
+			transaction.stop_preparing.connect (on_stop_preparing);
 			transaction.start_downloading.connect (on_start_downloading);
 			transaction.stop_downloading.connect (on_stop_downloading);
 			transaction.start_building.connect (on_start_building);
@@ -392,6 +397,8 @@ namespace Pamac {
 			// integrate progress box and term widget
 			main_stack.add_named (transaction.term_window, "term");
 			transaction_infobox.pack_start (transaction.progress_box);
+			// integrate build files notebook
+			properties_stack.add_named (transaction.build_files_notebook, "build_files");
 
 			display_package_queue = new Queue<string> ();
 			to_install = new GenericSet<string?> (str_hash, str_equal);
@@ -707,6 +714,11 @@ namespace Pamac {
 			files_row.visible = true;
 			files_row.add (label);
 			properties_listbox.add (files_row);
+			label = create_list_label (dgettext (null, "Build files"));
+			build_files_row = new Gtk.ListBoxRow ();
+			build_files_row.visible = false;
+			build_files_row.add (label);
+			properties_listbox.add (build_files_row);
 			properties_listbox.select_row (properties_listbox.get_row_at_index (0));
 		}
 
@@ -824,10 +836,6 @@ namespace Pamac {
 			return label as Gtk.Widget;
 		}
 
-		void destroy_widget (Gtk.Widget widget) {
-			widget.destroy ();
-		}
-
 		async Gdk.Pixbuf get_screenshot_pixbuf (string url) {
 			var uri = File.new_for_uri (url);
 			var cached_screenshot = File.new_for_path ("/tmp/pamac-app-screenshots/%s".printf (uri.get_basename ()));
@@ -868,7 +876,7 @@ namespace Pamac {
 			return pixbuf;
 		}
 
-		void set_package_details (string pkgname, string app_name) {
+		async void set_package_details (string pkgname, string app_name) {
 			PackageDetails details = database.get_pkg_details (pkgname, app_name);
 			// download screenshot
 			app_screenshot.pixbuf = null;
@@ -927,6 +935,8 @@ namespace Pamac {
 			licenses_label.set_text (licenses.str);
 			if (details.installed_version != "") {
 				install_togglebutton.visible = false;
+				build_togglebutton.visible = false;
+				reset_files_button.visible = false;
 				remove_togglebutton.visible = true;
 				remove_togglebutton.active = to_remove.contains (details.name);
 				reinstall_togglebutton.visible = false;
@@ -937,29 +947,32 @@ namespace Pamac {
 						reinstall_togglebutton.active = to_install.contains (details.name);
 					}
 				} else {
-					database.get_aur_pkg_details_async.begin (details.name, (obj, res) => {
-						AURPackageDetails aur_details = database.get_aur_pkg_details_async.end (res);
-						if (aur_details.name != "") {
-							// always show reinstall button for VCS package
-							if (aur_details.name.has_suffix ("-git") ||
-								aur_details.name.has_suffix ("-svn") ||
-								aur_details.name.has_suffix ("-bzr") ||
-								aur_details.name.has_suffix ("-hg") ||
-								aur_details.version == details.version) {
-								reinstall_togglebutton.visible = true;
-								reinstall_togglebutton.active = to_build.contains (details.name);
-							}
+					AURPackage aur_pkg = yield database.get_aur_pkg (details.name);
+					if (aur_pkg.name != "") {
+						// always show reinstall button for VCS package
+						if (aur_pkg.name.has_suffix ("-git") ||
+							aur_pkg.name.has_suffix ("-svn") ||
+							aur_pkg.name.has_suffix ("-bzr") ||
+							aur_pkg.name.has_suffix ("-hg") ||
+							aur_pkg.version == details.version) {
+							build_togglebutton.visible = true;
+							build_togglebutton.active = to_build.contains (details.name);
 						}
-					});
+						build_files_row.visible = true;
+						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 (escaped_url, escaped_url, aur_url, aur_url));
+					}
 				}
 			} else {
 				remove_togglebutton.visible = false;
 				reinstall_togglebutton.visible = false;
+				build_togglebutton.visible = false;
+				reset_files_button.visible = false;
 				install_togglebutton.visible = true;
 				install_togglebutton.active = to_install.contains (details.name);
 			}
 			// details
-			details_grid.foreach (destroy_widget);
+			details_grid.foreach (transaction.destroy_widget);
 			Gtk.Widget? previous_widget = null;
 			if (details.repo != "") {
 				previous_widget = populate_details_grid (dgettext (null, "Repository"), details.repo, previous_widget);
@@ -1015,7 +1028,7 @@ namespace Pamac {
 			}
 			details_grid.show_all ();
 			// deps
-			deps_grid.foreach (destroy_widget);
+			deps_grid.foreach (transaction.destroy_widget);
 			previous_widget = null;
 			if (details.depends.length () > 0) {
 				previous_widget = populate_dep_grid (dgettext (null, "Depends On"), details.depends, previous_widget);
@@ -1061,7 +1074,7 @@ namespace Pamac {
 			}
 		}
 
-		void set_aur_details (string pkgname) {
+		async void set_aur_details (string pkgname) {
 			app_image.pixbuf = null;
 			app_screenshot.pixbuf = null;
 			name_label.set_text ("");
@@ -1072,95 +1085,100 @@ namespace Pamac {
 			remove_togglebutton.visible = false;
 			reinstall_togglebutton.visible = false;
 			install_togglebutton.visible = false;
+			build_togglebutton.visible = false;
+			reset_files_button.visible = false;
 			properties_listbox.visible = false;
-			details_grid.foreach (destroy_widget);
-			deps_grid.foreach (destroy_widget);
+			details_grid.foreach (transaction.destroy_widget);
+			deps_grid.foreach (transaction.destroy_widget);
 			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
 			while (Gtk.events_pending ()) {
 				Gtk.main_iteration ();
 			}
-			database.get_aur_pkg_details_async.begin (pkgname, (obj, res) => {
-				AURPackageDetails details = database.get_aur_pkg_details_async.end (res);
-				// infos
-				name_label.set_markup ("<big><b>%s  %s</b></big>".printf (details.name, details.version));
-				app_image.pixbuf = package_icon;
-				desc_label.set_text (details.desc);
-				string aur_url = "http://aur.archlinux.org/packages/" + details.name;
-				string escaped_url = Markup.escape_text (details.url);
-				link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (escaped_url, escaped_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);
-				install_togglebutton.visible = true;
-				install_togglebutton.active = to_build.contains (details.name);
-				Package pkg = database.get_installed_pkg (details.name);
-				if (pkg.name != "") {
-					remove_togglebutton.visible = true;
-					remove_togglebutton.active = to_remove.contains (pkg.name);
-				}
-				// details
-				properties_listbox.visible = true;
-				details_grid.foreach (destroy_widget);
-				Gtk.Widget? previous_widget = null;
-				if (details.packagebase != details.name) {
-					previous_widget = populate_details_grid (dgettext (null, "Package Base"), details.packagebase, previous_widget);
-				}
-				if (details.maintainer != "") {
-					previous_widget = populate_details_grid (dgettext (null, "Maintainer"), details.maintainer, previous_widget);
-				}
-				previous_widget = populate_details_grid (dgettext (null, "First Submitted"), details.firstsubmitted, previous_widget);
-				previous_widget = populate_details_grid (dgettext (null, "Last Modified"), details.lastmodified, previous_widget);
-				previous_widget = populate_details_grid (dgettext (null, "Votes"), details.numvotes.to_string (), previous_widget);
-				if (details.outofdate != "") {
-					previous_widget = populate_details_grid (dgettext (null, "Out of Date"), details.outofdate, previous_widget);
-				}
-				details_grid.show_all ();
-				// deps
-				previous_widget = null;
-				if (details.depends.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Depends On"), details.depends, previous_widget);
-				}
-				if (details.makedepends.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Make Dependencies"), details.makedepends, previous_widget);
-				}
-				if (details.checkdepends.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Check Dependencies"), details.checkdepends, previous_widget);
-				}
-				if (details.optdepends.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Optional Dependencies"), details.optdepends, previous_widget);
-				}
-				if (details.provides.length () > 0) {
-					var label = new Gtk.Label ("<b>%s</b>".printf (dgettext (null, "Provides") + ":"));
-					label.use_markup = true;
-					label.halign = Gtk.Align.START;
-					label.valign = Gtk.Align.START;
-					label.margin_top = 6;
-					deps_grid.attach_next_to (label, previous_widget, Gtk.PositionType.BOTTOM);
-					var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12);
-					box.margin = 3;
-					foreach (unowned string name in details.provides) {
-						var label2 = new Gtk.Label (name);
-						label2.halign = Gtk.Align.START;
-						label2.margin_start = 12;
-						box.pack_start (label2);
-					}
-					deps_grid.attach_next_to (box, label, Gtk.PositionType.RIGHT);
-					previous_widget = label as Gtk.Widget;
-				}
-				if (details.replaces.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Replaces"), details.replaces, previous_widget);
-				}
-				if (details.conflicts.length () > 0) {
-					previous_widget = populate_dep_grid (dgettext (null, "Conflicts With"), details.conflicts, previous_widget);
+			AURPackageDetails details = yield database.get_aur_pkg_details (pkgname);
+			// infos
+			name_label.set_markup ("<big><b>%s  %s</b></big>".printf (details.name, details.version));
+			app_image.pixbuf = package_icon;
+			desc_label.set_text (details.desc);
+			string aur_url = "http://aur.archlinux.org/packages/" + details.name;
+			string escaped_url = Markup.escape_text (details.url);
+			link_label.set_markup ("<a href=\"%s\">%s</a>\n\n<a href=\"%s\">%s</a>".printf (escaped_url, escaped_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);
+			build_togglebutton.visible = true;
+			build_togglebutton.active = to_build.contains (details.name);
+			Package pkg = database.get_installed_pkg (details.name);
+			if (pkg.name != "") {
+				remove_togglebutton.visible = true;
+				remove_togglebutton.active = to_remove.contains (pkg.name);
+			}
+			// details
+			properties_listbox.visible = true;
+			details_grid.foreach (transaction.destroy_widget);
+			Gtk.Widget? previous_widget = null;
+			if (details.packagebase != details.name) {
+				previous_widget = populate_details_grid (dgettext (null, "Package Base"), details.packagebase, previous_widget);
+			}
+			if (details.maintainer != "") {
+				previous_widget = populate_details_grid (dgettext (null, "Maintainer"), details.maintainer, previous_widget);
+			}
+			previous_widget = populate_details_grid (dgettext (null, "First Submitted"), details.firstsubmitted, previous_widget);
+			previous_widget = populate_details_grid (dgettext (null, "Last Modified"), details.lastmodified, previous_widget);
+			previous_widget = populate_details_grid (dgettext (null, "Votes"), details.numvotes.to_string (), previous_widget);
+			if (details.outofdate != "") {
+				previous_widget = populate_details_grid (dgettext (null, "Out of Date"), details.outofdate, previous_widget);
+			}
+			details_grid.show_all ();
+			// deps
+			previous_widget = null;
+			if (details.depends.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Depends On"), details.depends, previous_widget);
+			}
+			if (details.makedepends.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Make Dependencies"), details.makedepends, previous_widget);
+			}
+			if (details.checkdepends.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Check Dependencies"), details.checkdepends, previous_widget);
+			}
+			if (details.optdepends.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Optional Dependencies"), details.optdepends, previous_widget);
+			}
+			if (details.provides.length () > 0) {
+				var label = new Gtk.Label ("<b>%s</b>".printf (dgettext (null, "Provides") + ":"));
+				label.use_markup = true;
+				label.halign = Gtk.Align.START;
+				label.valign = Gtk.Align.START;
+				label.margin_top = 6;
+				deps_grid.attach_next_to (label, previous_widget, Gtk.PositionType.BOTTOM);
+				var box = new Gtk.Box (Gtk.Orientation.VERTICAL, 12);
+				box.margin = 3;
+				foreach (unowned string name in details.provides) {
+					var label2 = new Gtk.Label (name);
+					label2.halign = Gtk.Align.START;
+					label2.margin_start = 12;
+					box.pack_start (label2);
 				}
-				deps_grid.show_all ();
-				this.get_window ().set_cursor (null);
-			});
+				deps_grid.attach_next_to (box, label, Gtk.PositionType.RIGHT);
+				previous_widget = label as Gtk.Widget;
+			}
+			if (details.replaces.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Replaces"), details.replaces, previous_widget);
+			}
+			if (details.conflicts.length () > 0) {
+				previous_widget = populate_dep_grid (dgettext (null, "Conflicts With"), details.conflicts, previous_widget);
+			}
+			deps_grid.show_all ();
+			this.get_window ().set_cursor (null);
+			// build files
+			// will be populated on properties_stack switch
+			if (properties_stack.visible_child_name == "build_files") {
+				on_properties_stack_visible_child_changed ();
+			}
 		}
 
 		[GtkCallback]
@@ -1168,14 +1186,21 @@ namespace Pamac {
 			int index = row.get_index ();
 			switch (index) {
 				case 0: // details
+					reset_files_button.visible = false;
 					properties_stack.visible_child_name = "details";
 					break;
 				case 1: // deps
+					reset_files_button.visible = false;
 					properties_stack.visible_child_name = "deps";
 					break;
 				case 2: // files
+					reset_files_button.visible = false;
 					properties_stack.visible_child_name = "files";
 					break;
+				case 3: // build files
+					reset_files_button.visible = true;
+					properties_stack.visible_child_name = "build_files";
+					break;
 				default:
 					break;
 			}
@@ -1185,22 +1210,43 @@ namespace Pamac {
 		void on_install_togglebutton_toggled () {
 			if (install_togglebutton.active) {
 				install_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-				Package find_pkg = database.get_sync_pkg (current_package_displayed);
-				if (find_pkg.name != "") {
-					to_install.add (current_package_displayed);
-				} else {
-					to_build.add (current_package_displayed);
-				}
+				to_install.add (current_package_displayed);
 			} else {
 				install_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
-				if (to_install.remove (current_package_displayed)) {
-				} else {
-					to_build.remove (current_package_displayed);
+				to_install.remove (current_package_displayed);
+			}
+			set_pendings_operations ();
+		}
+
+		[GtkCallback]
+		void on_build_togglebutton_toggled () {
+			if (build_togglebutton.active) {
+				build_togglebutton.get_style_context ().add_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+				to_build.add (current_package_displayed);
+				if (properties_stack.visible_child_name == "build_files") {
+					transaction.save_build_files.begin (current_package_displayed);
 				}
+			} else {
+				build_togglebutton.get_style_context ().remove_class (Gtk.STYLE_CLASS_SUGGESTED_ACTION);
+				to_build.remove (current_package_displayed);
 			}
 			set_pendings_operations ();
 		}
 
+		[GtkCallback]
+		void on_reset_files_button_clicked () {
+			transaction.build_files_notebook.foreach (transaction.destroy_widget);
+			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+			while (Gtk.events_pending ()) {
+				Gtk.main_iteration ();
+			}
+			database.get_aur_pkg.begin (current_package_displayed, (obj, res) => {
+				AURPackage pkg = database.get_aur_pkg.end (res);
+				transaction.populate_build_files.begin (pkg.packagebase, true);
+				this.get_window ().set_cursor (null);
+			});
+		}
+
 		[GtkCallback]
 		void on_remove_togglebutton_toggled () {
 			if (remove_togglebutton.active) {
@@ -1240,16 +1286,7 @@ namespace Pamac {
 
 		void populate_packages_list (List<Package> pkgs) {
 			// populate liststore
-			packages_treeview.freeze_notify ();
-			packages_treeview.freeze_child_notify ();
 			packages_list.clear ();
-			// scroll to top
-			if (scroll_to_top) {
-				packages_scrolledwindow.vadjustment.value = 0;
-			} else {
-				// don't scroll to top just once
-				scroll_to_top = true;
-			}
 			if (pkgs.length () == 0) {
 				origin_stack.visible_child_name = "no_item";
 				packages_treeview.thaw_child_notify ();
@@ -1263,78 +1300,78 @@ namespace Pamac {
 				}
 			}
 			foreach (unowned Package pkg in pkgs) {
-				uint origin = 0;
-				string version;
-				uint64 size;
-				string size_str;
-				string summary;
-				Gdk.Pixbuf pixbuf = null;
-				if (pkg.app_name == "") {
-					summary = "<b>%s</b>\n%s".printf (pkg.name, Markup.escape_text (pkg.desc));
-				} else {
-					summary = "<b>%s  (%s)</b>\n%s".printf (Markup.escape_text (pkg.app_name), pkg.name, Markup.escape_text (pkg.desc));
-				}
-				if (filters_stack.visible_child_name == "updates") {
-					version = "<b>%s</b>\n(%s)".printf (pkg.version, pkg.installed_version);
-					size = pkg.download_size;
-					size_str = pkg.download_size == 0 ? "" : GLib.format_size (pkg.download_size);
-				} else {
-					version = pkg.version;
-					size = pkg.size;
-					size_str = GLib.format_size (pkg.size);
-				}
-				if (pkg.icon != "") {
+				create_packagelist_row (pkg);
+			}
+			// scroll to top
+			if (scroll_to_top) {
+				packages_scrolledwindow.vadjustment.value = 0;
+			} else {
+				// don't scroll to top just once
+				scroll_to_top = true;
+			}
+			this.get_window ().set_cursor (null);
+		}
+
+		void create_packagelist_row (Package pkg) {
+			uint origin = 0;
+			string version;
+			uint64 size;
+			string size_str;
+			string summary;
+			Gdk.Pixbuf pixbuf = null;
+			if (pkg.app_name == "") {
+				summary = "<b>%s</b>\n%s".printf (pkg.name, Markup.escape_text (pkg.desc));
+			} else {
+				summary = "<b>%s  (%s)</b>\n%s".printf (Markup.escape_text (pkg.app_name), pkg.name, Markup.escape_text (pkg.desc));
+			}
+			if (filters_stack.visible_child_name == "updates") {
+				version = "<b>%s</b>\n(%s)".printf (pkg.version, pkg.installed_version);
+				size = pkg.download_size;
+				size_str = pkg.download_size == 0 ? "" : GLib.format_size (pkg.download_size);
+			} else {
+				version = pkg.version;
+				size = pkg.size;
+				size_str = GLib.format_size (pkg.size);
+			}
+			if (pkg.icon != "") {
+				try {
+					pixbuf = new Gdk.Pixbuf.from_file_at_scale (pkg.icon, 32, 32, true);
+				} catch (GLib.Error e) {
+					// some icons are not in the right repo
+					string icon = pkg.icon;
+					if ("extra" in pkg.icon) {
+						icon = pkg.icon.replace ("extra", "community");
+					} else if ("community" in pkg.icon) {
+						icon = pkg.icon.replace ("community", "extra");
+					}
 					try {
-						pixbuf = new Gdk.Pixbuf.from_file_at_scale (pkg.icon, 32, 32, true);
+						pixbuf = new Gdk.Pixbuf.from_file_at_scale (icon, 32, 32, true);
 					} catch (GLib.Error e) {
-						// some icons are not in the right repo
-						string icon = pkg.icon;
-						if ("extra" in pkg.icon) {
-							icon = pkg.icon.replace ("extra", "community");
-						} else if ("community" in pkg.icon) {
-							icon = pkg.icon.replace ("community", "extra");
-						}
-						try {
-							pixbuf = new Gdk.Pixbuf.from_file_at_scale (icon, 32, 32, true);
-						} catch (GLib.Error e) {
-							pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR);
-							stderr.printf ("%s: %s\n", pkg.icon, e.message);
-						}
+						pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR);
+						stderr.printf ("%s: %s\n", pkg.icon, e.message);
 					}
-				} else {
-					pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR);
-				}
-				if (pkg.installed_version == "") {
-					origin = 1;
 				}
-				packages_list.insert_with_values (null, -1,
-												0, origin,
-												1, pkg.name,
-												2, summary,
-												3, version,
-												4, pkg.repo,
-												5, size,
-												6, size_str,
-												7, pkg.app_name,
-												8, pixbuf);
-			}
-			packages_treeview.thaw_child_notify ();
-			packages_treeview.thaw_notify ();
-			this.get_window ().set_cursor (null);
+			} else {
+				pixbuf = package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR);
+			}
+			if (pkg.installed_version == "") {
+				origin = 1;
+			}
+			packages_list.insert_with_values (null, -1,
+											0, origin,
+											1, pkg.name,
+											2, summary,
+											3, version,
+											4, pkg.repo,
+											5, size,
+											6, size_str,
+											7, pkg.app_name,
+											8, pixbuf);
 		}
 
 		void populate_aur_list (List<AURPackage> pkgs) {
 			// populate liststore
-			aur_treeview.freeze_notify ();
-			aur_treeview.freeze_child_notify ();
 			aur_list.clear ();
-			// scroll to top
-			if (scroll_to_top) {
-				aur_scrolledwindow.vadjustment.value = 0;
-			} else {
-				// don't scroll to top just once
-				scroll_to_top = true;
-			}
 			if (pkgs.length () == 0) {
 				origin_stack.visible_child_name = "no_item";
 				aur_treeview.thaw_child_notify ();
@@ -1348,28 +1385,37 @@ namespace Pamac {
 				}
 			}
 			foreach (unowned AURPackage aur_pkg in pkgs) {
-				string version;
-				if (filters_stack.visible_child_name == "updates") {
-					version = "<b>%s</b>\n(%s)".printf (aur_pkg.version, aur_pkg.installed_version);
-				} else if (aur_pkg.installed_version == "") {
-					version = aur_pkg.version;
-				} else {
-					version = aur_pkg.installed_version;
-				}
-				aur_list.insert_with_values (null, -1,
-											0, aur_pkg.installed_version == "" ? 1 : 0, // installed
-											1, aur_pkg.name,
-											2, "<b>%s</b>\n%s".printf (aur_pkg.name, Markup.escape_text (aur_pkg.desc)),
-											3, version,
-											4, aur_pkg.popularity,
-											5, "%.2f".printf (aur_pkg.popularity),
-											6, package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR));
+				create_aurlist_row (aur_pkg);
+			}
+			// scroll to top
+			if (scroll_to_top) {
+				aur_scrolledwindow.vadjustment.value = 0;
+			} else {
+				// don't scroll to top just once
+				scroll_to_top = true;
 			}
-			aur_treeview.thaw_child_notify ();
-			aur_treeview.thaw_notify ();
 			this.get_window ().set_cursor (null);
 		}
 
+		void create_aurlist_row (AURPackage aur_pkg) {
+			string version;
+			if (filters_stack.visible_child_name == "updates") {
+				version = "<b>%s</b>\n(%s)".printf (aur_pkg.version, aur_pkg.installed_version);
+			} else if (aur_pkg.installed_version == "") {
+				version = aur_pkg.version;
+			} else {
+				version = aur_pkg.installed_version;
+			}
+			aur_list.insert_with_values (null, -1,
+										0, aur_pkg.installed_version == "" ? 1 : 0, // installed
+										1, aur_pkg.name,
+										2, "<b>%s</b>\n%s".printf (aur_pkg.name, Markup.escape_text (aur_pkg.desc)),
+										3, version,
+										4, aur_pkg.popularity,
+										5, "%.2f".printf (aur_pkg.popularity),
+										6, package_icon.scale_simple (32, 32, Gdk.InterpType.BILINEAR));
+		}
+
 		void save_packages_sort_order () {
 			if (restore_sort_order == false) {
 				packages_list.get_sort_column_id (out sort_column_id, out sort_order);
@@ -1491,7 +1537,6 @@ namespace Pamac {
 					packages_list.set_sort_column_id (2, Gtk.SortType.ASCENDING);
 					hide_sidebar ();
 					origin_stack.visible_child_name = "checking";
-					checking_spinner.active = true;
 					packages_list.clear ();
 					aur_list.clear ();
 					select_all_button.visible = false;
@@ -1499,7 +1544,7 @@ namespace Pamac {
 					this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
 					// let time to hide_sidebar
 					Timeout.add (200, () => {
-						database.get_updates_async.begin (on_get_updates_finished);
+						database.get_updates.begin (on_get_updates_finished);
 						return false;
 					});
 					break;
@@ -1528,8 +1573,13 @@ namespace Pamac {
 
 		void display_package_properties (string pkgname, string app_name = "") {
 			current_package_displayed = pkgname;
+			// select details if build files was selected
+			if (properties_listbox.get_selected_row ().get_index () == 3) {
+				properties_listbox.get_row_at_index (0).activate ();
+			}
 			files_row.visible = true;
-			set_package_details (current_package_displayed, app_name);
+			build_files_row.visible = false;
+			set_package_details.begin (current_package_displayed, app_name);
 		}
 
 		void display_aur_properties (string pkgname) {
@@ -1539,7 +1589,8 @@ namespace Pamac {
 				properties_listbox.get_row_at_index (0).activate ();
 			}
 			files_row.visible = false;
-			set_aur_details (current_package_displayed);
+			build_files_row.visible = true;
+			set_aur_details.begin (current_package_displayed);
 		}
 
 		[GtkCallback]
@@ -1587,9 +1638,9 @@ namespace Pamac {
 						while (Gtk.events_pending ()) {
 							Gtk.main_iteration ();
 						}
-						database.get_aur_pkg_details_async.begin (depstring, (obj, res) => {
+						database.get_aur_pkg.begin (depstring, (obj, res) => {
 							this.get_window ().set_cursor (null);
-							if (database.get_aur_pkg_details_async.end (res).name != "") {
+							if (database.get_aur_pkg.end (res).name != "") {
 								display_aur_properties (depstring);
 							} else {
 								var pkg = database.find_installed_satisfier (depstring);
@@ -1628,6 +1679,18 @@ namespace Pamac {
 						this.get_window ().set_cursor (null);
 					});
 					break;
+				case "build_files":
+					transaction.build_files_notebook.foreach (transaction.destroy_widget);
+					this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+					while (Gtk.events_pending ()) {
+						Gtk.main_iteration ();
+					}
+					database.get_aur_pkg.begin (current_package_displayed, (obj, res) => {
+						AURPackage pkg = database.get_aur_pkg.end (res);
+						transaction.populate_build_files.begin (pkg.packagebase, false);
+						this.get_window ().set_cursor (null);
+					});
+					break;
 				default:
 					break;
 			}
@@ -1720,8 +1783,8 @@ namespace Pamac {
 							pkg = database.get_sync_pkg (pkgname);
 						}
 						if (pkg.name == "") {
-							database.get_aur_pkg_details_async.begin (pkgname, (obj, res) => {
-								if (database.get_aur_pkg_details_async.end (res).name != "") {
+							database.get_aur_pkg.begin (pkgname, (obj, res) => {
+								if (database.get_aur_pkg.end (res).name != "") {
 									display_aur_properties (pkgname);
 								} else {
 									pkg = database.find_installed_satisfier (pkgname);
@@ -1924,7 +1987,7 @@ namespace Pamac {
 		async void populate_pendings_aur_pkgs () {
 			var aur_pkgs = new List<AURPackage> ();
 			foreach (unowned string pkgname in to_build) {
-				var aur_pkg = yield database.get_aur_pkg_async (pkgname);
+				var aur_pkg = yield database.get_aur_pkg (pkgname);
 				if (aur_pkg.name != "") {
 					aur_pkgs.append (aur_pkg);
 				}
@@ -1958,9 +2021,9 @@ namespace Pamac {
 						}
 						var pkgs = database.search_pkgs_async.end (res);
 						if (pkgs.length () == 0 && database.config.enable_aur) {
-							database.search_in_aur_async.begin (search_string, (obj, res) => {
+							database.search_in_aur.begin (search_string, (obj, res) => {
 								unowned Gtk.ListBoxRow aur_row = search_listbox.get_row_at_index (1);
-								if (database.search_in_aur_async.end (res).length () > 0) {
+								if (database.search_in_aur.end (res).length () > 0) {
 									row.activatable = false;
 									row.selectable = false;
 									row.has_focus = false;
@@ -1992,8 +2055,8 @@ namespace Pamac {
 					while (Gtk.events_pending ()) {
 						Gtk.main_iteration ();
 					}
-					database.search_in_aur_async.begin (search_string, (obj, res) => {
-						populate_aur_list (database.search_in_aur_async.end (res));
+					database.search_in_aur.begin (search_string, (obj, res) => {
+						populate_aur_list (database.search_in_aur.end (res));
 					});
 					database.search_pkgs_async.begin (search_string, (obj, res) => {
 						unowned Gtk.ListBoxRow repo_row = search_listbox.get_row_at_index (0);
@@ -2566,8 +2629,7 @@ namespace Pamac {
 			transaction.unlock ();
 			if (filters_stack.visible_child_name == "updates") {
 				origin_stack.visible_child_name = "checking";
-				checking_spinner.active = true;
-				database.get_updates_async.begin (on_get_updates_finished);
+				database.get_updates.begin (on_get_updates_finished);
 			} else {
 				this.get_window ().set_cursor (null);
 			}
@@ -2723,7 +2785,7 @@ namespace Pamac {
 		}
 
 		void on_get_updates_finished (Object? source_object, AsyncResult res) {
-			var updates = database.get_updates_async.end (res);
+			var updates = database.get_updates.end (res);
 			// copy updates in lists (keep a ref of them)
 			repos_updates = new List<Package> ();
 			foreach (unowned Package pkg in updates.repos_updates) {
@@ -2734,7 +2796,6 @@ namespace Pamac {
 				aur_updates.append (pkg);
 			}
 			origin_stack.visible_child_name = "repos";
-			checking_spinner.active = false;
 			if (filters_stack.visible_child_name == "updates") {
 				populate_updates ();
 			} else {
@@ -2780,6 +2841,18 @@ namespace Pamac {
 			}
 		}
 
+		void on_start_preparing () {
+			this.get_window ().set_cursor (new Gdk.Cursor.for_display (Gdk.Display.get_default (), Gdk.CursorType.WATCH));
+		}
+
+		void on_stop_preparing () {
+			this.get_window ().set_cursor (null);
+			// restore build_files_notebook
+			if (properties_listbox.get_selected_row ().get_index () == 3) {
+				properties_stack.visible_child_name = "build_files";
+			}
+		}
+
 		void on_start_downloading () {
 			cancel_button.sensitive = true;
 		}
diff --git a/src/package.vala b/src/package.vala
index 29e8b964ef20f524ba32966e77742cd852cccf84..30b2d8e5e6a6d4c643a4bd63d99e8048638db217 100644
--- a/src/package.vala
+++ b/src/package.vala
@@ -163,12 +163,14 @@ namespace Pamac {
 		public string installed_version { get {return pkg_struct.installed_version;} }
 		public string desc { get {return pkg_struct.desc;} }
 		public double popularity { get {return pkg_struct.popularity;} }
+		public string packagebase { get {return pkg_struct.packagebase;} }
 		internal AURPackage () {
 			pkg_struct = AURPackageStruct () {
 				name = "",
 				version = "",
 				installed_version = "",
-				desc = ""
+				desc = "",
+				packagebase = ""
 			};
 		}
 		internal AURPackage.from_struct (owned AURPackageStruct pkg_struct) {
diff --git a/src/pamac_config.vala b/src/pamac_config.vala
index cccc3731773d268562210473db328433bf133342..93af9ff96773e9cc1b57459d135f3b28db9bb7e6 100644
--- a/src/pamac_config.vala
+++ b/src/pamac_config.vala
@@ -76,7 +76,7 @@ namespace Pamac {
 			recurse = false;
 			no_update_hide_icon = false;
 			enable_aur = false;
-			aur_build_dir = "/tmp";
+			aur_build_dir = "/var/tmp";
 			check_aur_updates = false;
 			download_updates = false;
 			clean_keep_num_pkgs = 3;
diff --git a/src/preferences_dialog.vala b/src/preferences_dialog.vala
index b5dfd2acd0316d76f53a7ec63519201c26bb13d3..1dfd4c34dca1a96a2ab37b3d9df0f693314cf276 100644
--- a/src/preferences_dialog.vala
+++ b/src/preferences_dialog.vala
@@ -136,9 +136,9 @@ namespace Pamac {
 			aur_build_dir_label.sensitive = transaction.database.config.enable_aur;
 			aur_build_dir_file_chooser.sensitive = transaction.database.config.enable_aur;
 			aur_build_dir_file_chooser.set_filename (transaction.database.config.aur_build_dir);
-			// add /tmp choice always visible
+			// add /var/tmp choice always visible
 			try {
-				aur_build_dir_file_chooser.add_shortcut_folder ("/tmp");
+				aur_build_dir_file_chooser.add_shortcut_folder ("/var/tmp");
 			} catch (GLib.Error e) {
 				stderr.printf ("%s\n", e.message);
 			}
diff --git a/src/system_daemon.vala b/src/system_daemon.vala
index 84efd392939c8257e50cb6bd128ab9192ecefa0c..d9bcb472720e1e1e17e44b472ddb457476bd4145 100644
--- a/src/system_daemon.vala
+++ b/src/system_daemon.vala
@@ -39,6 +39,7 @@ public class AlpmAction {
 namespace Pamac {
 	[DBus (name = "org.manjaro.pamac.system")]
 	public class SystemDaemon: Object {
+		private Config config;
 		private bool refreshed;
 		private HashTable<string,Variant> new_alpm_conf;
 		private string mirrorlist_country;
@@ -55,7 +56,6 @@ namespace Pamac {
 		public signal void emit_log (uint level, string msg);
 		public signal void set_pkgreason_finished ();
 		public signal void refresh_finished (bool success);
-		public signal void get_updates_finished (UpdatesStruct updates);
 		public signal void downloading_updates_finished ();
 		public signal void trans_prepare_finished (bool success);
 		public signal void trans_commit_finished (bool success);
@@ -68,10 +68,11 @@ namespace Pamac {
 		public signal void generate_mirrors_list_finished ();
 
 		public SystemDaemon () {
+			config = new Config ("/etc/pamac.conf");
 			lock_id = new BusName ("");
 			authorized = false;
 			// alpm_utils global variable declared in alpm_utils.vala
-			alpm_utils = new AlpmUtils ();
+			alpm_utils = new AlpmUtils (config);
 			lockfile = GLib.File.new_for_path (alpm_utils.alpm_handle.lockfile);
 			check_old_lock ();
 			check_extern_lock ();
@@ -99,9 +100,6 @@ namespace Pamac {
 			alpm_utils.refresh_finished.connect ((success) => {
 				refresh_finished (success);
 			});
-			alpm_utils.get_updates_finished.connect ((updates) => {
-				get_updates_finished (updates);
-			});
 			alpm_utils.downloading_updates_finished.connect (() => {
 				downloading_updates_finished ();
 			});
@@ -279,15 +277,14 @@ namespace Pamac {
 
 		public void start_write_pamac_config (HashTable<string,Variant> new_pamac_conf, GLib.BusName sender) throws Error {
 			check_authorization.begin (sender, (obj, res) => {
-				var pamac_config = new Config ("/etc/pamac.conf");
 				bool authorized = check_authorization.end (res);
 				if (authorized) {
-					pamac_config.write (new_pamac_conf);
-					pamac_config.reload ();
+					config.write (new_pamac_conf);
+					config.reload ();
 				}
-				write_pamac_config_finished (pamac_config.recurse, pamac_config.refresh_period, pamac_config.no_update_hide_icon,
-											pamac_config.enable_aur, pamac_config.aur_build_dir, pamac_config.check_aur_updates,
-											pamac_config.download_updates);
+				write_pamac_config_finished (config.recurse, config.refresh_period, config.no_update_hide_icon,
+											config.enable_aur, config.aur_build_dir, config.check_aur_updates,
+											config.download_updates);
 			});
 		}
 
@@ -423,15 +420,6 @@ namespace Pamac {
 			}
 		}
 
-		public void start_get_updates_for_sysupgrade (bool check_aur_updates) throws Error {
-			alpm_utils.check_aur_updates = check_aur_updates;
-			try {
-				thread_pool.add (new AlpmAction (alpm_utils.get_updates_for_sysupgrade));
-			} catch (ThreadError e) {
-				stderr.printf ("Thread Error %s\n", e.message);
-			}
-		}
-
 		public void start_downloading_updates () throws Error {
 			// do not add this thread to the threadpool so it won't be queued
 			new Thread<int> ("download updates thread", alpm_utils.download_updates);
@@ -484,9 +472,7 @@ namespace Pamac {
 			alpm_utils.to_load = to_load;
 			alpm_utils.to_build = to_build;
 			alpm_utils.overwrite_files = overwrite_files;
-			if (alpm_utils.to_install.length > 0) {
-				alpm_utils.sysupgrade = true;
-			}
+			alpm_utils.sysupgrade = false;
 			if (alpm_utils.downloading_updates) {
 				alpm_utils.cancellable.cancel ();
 				// let time to cancel download updates
@@ -501,12 +487,13 @@ namespace Pamac {
 
 		private void launch_prepare_thread () {
 			if (alpm_utils.to_build.length != 0) {
-				try {
-					thread_pool.add (new AlpmAction (alpm_utils.compute_aur_build_list));
-					thread_pool.add (new AlpmAction (alpm_utils.build_prepare));
-				} catch (ThreadError e) {
-					stderr.printf ("Thread Error %s\n", e.message);
-				}
+				alpm_utils.compute_aur_build_list.begin (() => {
+					try {
+						thread_pool.add (new AlpmAction (alpm_utils.build_prepare));
+					} catch (ThreadError e) {
+						stderr.printf ("Thread Error %s\n", e.message);
+					}
+				});
 			} else {
 				try {
 					thread_pool.add (new AlpmAction (alpm_utils.trans_prepare));
diff --git a/src/transaction-cli.vala b/src/transaction-cli.vala
index fb6422d89cf1c205b9c0104b4ddc8dd2a9457737..5162941106665b30343235ea7351343f68591ac9 100644
--- a/src/transaction-cli.vala
+++ b/src/transaction-cli.vala
@@ -454,5 +454,29 @@ namespace Pamac {
 			}
 			return false;
 		}
+
+		protected override async void review_build_files (string pkgname) {
+			string builddir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname);
+			string[] cmds = {"nano", "-S", "-w", "-i"};
+			// PKGBUILD
+			cmds += Path.build_path ("/", builddir_name, "PKGBUILD");
+			// other file
+			var build_dir = File.new_for_path (builddir_name);
+			try {
+				FileEnumerator enumerator = yield build_dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE);
+				FileInfo info;
+				while ((info = enumerator.next_file (null)) != null) {
+					unowned string filename = info.get_name ();
+					if (".install" in filename || ".patch" in filename) {
+						cmds += Path.build_path ("/", builddir_name, filename);
+					}
+				}
+				var process = new Subprocess.newv (cmds, SubprocessFlags.STDIN_INHERIT);
+				yield process.wait_async ();
+			} catch (Error e) {
+				print ("Error: %s\n", e.message);
+			}
+			yield regenerate_srcinfo (pkgname);
+		}
 	}
 }
diff --git a/src/transaction-gtk.vala b/src/transaction-gtk.vala
index 6d17dc1e72c6bd0932911f44b917748651f30c32..3458ebdce4a425ff3cef02070a16e8685c6f2ce1 100644
--- a/src/transaction-gtk.vala
+++ b/src/transaction-gtk.vala
@@ -29,6 +29,7 @@ namespace Pamac {
 		Vte.Terminal term;
 		Vte.Pty pty;
 		public Gtk.ScrolledWindow term_window;
+		public Gtk.Notebook build_files_notebook;
 		//parent window
 		public Gtk.ApplicationWindow? application_window { get; construct; }
 		// ask_confirmation option
@@ -69,6 +70,10 @@ namespace Pamac {
 			term_window.visible = true;
 			term_window.propagate_natural_height = true;
 			term_window.add (term);
+			// create build files notebook
+			build_files_notebook = new Gtk.Notebook ();
+			build_files_notebook.visible = true;
+			build_files_notebook.expand = true;
 			// connect to signal
 			emit_action.connect (display_action);
 			emit_action_progress.connect (display_action_progress);
@@ -84,6 +89,8 @@ namespace Pamac {
 			sysupgrade_finished.connect (on_finished);
 			start_generating_mirrors_list.connect (start_progressbar_pulse);
 			generate_mirrors_list_finished.connect (reset_progress_box);
+			start_preparing.connect (start_progressbar_pulse);
+			stop_preparing.connect (stop_progressbar_pulse);
 			start_building.connect (start_progressbar_pulse);
 			stop_building.connect (stop_progressbar_pulse);
 			write_pamac_config_finished.connect (set_trans_flags);
@@ -345,6 +352,138 @@ namespace Pamac {
 			return false;
 		}
 
+		public void destroy_widget (Gtk.Widget widget) {
+			widget.destroy ();
+		}
+
+		protected override async void review_build_files (string pkgname) {
+			// remove noteboook from manager_window properties stack
+			unowned Gtk.Stack? stack = build_files_notebook.get_parent () as Gtk.Stack;
+			if (stack != null) {
+				stack.remove (build_files_notebook);
+			}
+			// create dialog
+			var flags = Gtk.DialogFlags.MODAL;
+			int use_header_bar;
+			Gtk.Settings.get_default ().get ("gtk-dialogs-use-header", out use_header_bar);
+			if (use_header_bar == 1) {
+				flags |= Gtk.DialogFlags.USE_HEADER_BAR;
+			}
+			var dialog = new Gtk.Dialog.with_buttons (dgettext (null, "Review %s build files".printf (pkgname)),
+													application_window,
+													flags);
+			dialog.border_width = 6;
+			dialog.icon_name = "system-software-install";
+			unowned Gtk.Widget widget = dialog.add_button (dgettext (null, "_Close"), Gtk.ResponseType.CLOSE);
+			widget.can_focus = true;
+			widget.has_focus = true;
+			widget.can_default = true;
+			widget.has_default = true;
+			unowned Gtk.Box box = dialog.get_content_area ();
+			box.add (build_files_notebook);
+			dialog.default_width = 700;
+			dialog.default_height = 500;
+			// populate notebook
+			yield populate_build_files (pkgname, false);
+			// run
+			dialog.run ();
+			// re-add noteboook to manager_window properties stack
+			box.remove (build_files_notebook);
+			if (stack != null) {
+				stack.add_named (build_files_notebook, "build_files");
+			}
+			dialog.destroy ();
+			// save modifications
+			yield save_build_files (pkgname);
+		}
+
+		async void create_build_files_tab (File parent, string filename) {
+			var file = parent.get_child (filename);
+			if (file.query_exists ()) {
+				try {
+					StringBuilder text = new StringBuilder ();
+					var fis = yield file.read_async ();
+					var dis = new DataInputStream (fis);
+					string line;
+					while ((line = yield dis.read_line_async ()) != null) {
+						text.append (line);
+						text.append ("\n");
+					}
+					var scrolled_window = new Gtk.ScrolledWindow (null, null);
+					scrolled_window.visible = true;
+					var textview = new Gtk.TextView ();
+					textview.wrap_mode = Gtk.WrapMode.NONE;
+					textview.top_margin = 8;
+					textview.bottom_margin = 8;
+					textview.left_margin = 8;
+					textview.right_margin = 8;
+					textview.buffer.set_text (text.str, (int) text.len);
+					Gtk.TextIter iter;
+					textview.buffer.get_start_iter (out iter);
+					textview.buffer.place_cursor (iter);
+					textview.visible = true;
+					scrolled_window.add (textview);
+					var label =  new Gtk.Label (filename);
+					label.visible = true;
+					build_files_notebook.append_page (scrolled_window, label);
+				} catch (GLib.Error e) {
+					stderr.printf ("%s\n", e.message);
+				}
+			}
+		}
+
+		public async void populate_build_files (string pkgname, bool overwrite) {
+			build_files_notebook.foreach (destroy_widget);
+			string clone_dir_name = yield database.clone_build_files (pkgname, overwrite);
+			if (clone_dir_name != "") {
+				var clone_dir = File.new_for_path (clone_dir_name);
+				// PKGBUILD
+				yield create_build_files_tab (clone_dir, "PKGBUILD");
+				// other file
+				try {
+					FileEnumerator enumerator = yield clone_dir.enumerate_children_async ("standard::*", FileQueryInfoFlags.NONE);
+					FileInfo info;
+					while ((info = enumerator.next_file (null)) != null) {
+						string filename = info.get_name ();
+						if (".install" in filename || ".patch" in filename) {
+							yield create_build_files_tab (clone_dir, filename);
+						}
+					}
+				} catch (Error e) {
+					print ("Error: %s\n", e.message);
+				}
+			}
+		}
+
+		public async void save_build_files (string pkgname) {
+			string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname);
+			int num_pages = build_files_notebook.get_n_pages ();
+			int index = 0;
+			while (index < num_pages) {
+				Gtk.Widget child = build_files_notebook.get_nth_page (index);
+				string file_name = Path.build_path ("/", pkgdir_name, build_files_notebook.get_tab_label_text (child));
+				var scrolled_window = child as Gtk.ScrolledWindow;
+				var textview = scrolled_window.get_child () as Gtk.TextView;
+				var file = File.new_for_path (file_name);
+				Gtk.TextIter start_iter;
+				Gtk.TextIter end_iter;
+				textview.buffer.get_start_iter (out start_iter);
+				textview.buffer.get_end_iter (out end_iter);
+				try {
+					// delete the file before rewrite it
+					yield file.delete_async ();
+					// creating a DataOutputStream to the file
+					var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION));
+					// writing a string to the stream
+					dos.put_string (textview.buffer.get_text (start_iter, end_iter, false));
+				} catch (GLib.Error e) {
+					stderr.printf("%s\n", e.message);
+				}
+				index++;
+			}
+			yield regenerate_srcinfo (pkgname);
+		}
+
 		void show_warnings (bool block) {
 			if (warning_textbuffer.len > 0) {
 				var flags = Gtk.DialogFlags.MODAL;
diff --git a/src/transaction.vala b/src/transaction.vala
index 21a8d81c09ba2b2b5305a227eaaa7c3c731bb848..984149824372b8c875b13915adaec5fda3956fce 100644
--- a/src/transaction.vala
+++ b/src/transaction.vala
@@ -31,17 +31,20 @@ namespace Pamac {
 		string current_status;
 		double current_progress;
 		string current_filename;
-		bool sysupgrade_after_trans;
 		bool no_confirm_commit;
 		bool enable_downgrade;
 		bool sysupgrading;
 		bool force_refresh;
-		string[] to_install_first;
+		string[] to_install;
+		string[] to_remove;
+		string[] to_load;
+		string[] to_build;
 		string[] temporary_ignorepkgs;
 		string[] overwrite_files;
 		// building data
 		Queue<string> to_build_queue;
 		string[] aur_pkgs_to_install;
+		GenericSet<string?> build_files_reviewed;
 		bool building;
 		Cancellable build_cancellable;
 		// download data
@@ -62,6 +65,8 @@ namespace Pamac {
 		public signal void emit_script_output (string message);
 		public signal void emit_warning (string message);
 		public signal void emit_error (string message, string[] details);
+		public signal void start_preparing ();
+		public signal void stop_preparing ();
 		public signal void start_downloading ();
 		public signal void stop_downloading ();
 		public signal void start_building ();
@@ -100,14 +105,13 @@ namespace Pamac {
 			current_action = "";
 			current_status = "";
 			current_filename = "";
-			sysupgrade_after_trans = false;
 			no_confirm_commit = false;
 			sysupgrading = false;
-			to_install_first = {};
 			temporary_ignorepkgs = {};
 			overwrite_files = {};
 			// building data
 			to_build_queue = new Queue<string> ();
+			build_files_reviewed = new GenericSet<string?> (str_hash, str_equal);
 			build_cancellable = new Cancellable ();
 			building = false;
 			// download data
@@ -123,6 +127,35 @@ namespace Pamac {
 			return true;
 		}
 
+		protected virtual async void review_build_files (string pkgname) {
+			// nothing
+		}
+
+		protected async void regenerate_srcinfo (string pkgname) {
+			string pkgdir_name = Path.build_path ("/", database.config.aur_build_dir, "pamac-build", pkgname);
+			// generate .SRCINFO
+			var launcher = new SubprocessLauncher (SubprocessFlags.STDOUT_PIPE);
+			launcher.set_cwd (pkgdir_name);
+			try {
+				Subprocess process = launcher.spawnv ({"makepkg", "--printsrcinfo"});
+				yield process.wait_async ();
+				var dis = new DataInputStream (process.get_stdout_pipe ());
+				var file = File.new_for_path (Path.build_path ("/", pkgdir_name, ".SRCINFO"));
+				try {
+					// delete the file before rewrite it
+					yield file.delete_async ();
+					// creating a DataOutputStream to the file
+					var dos = new DataOutputStream (yield file.create_async (FileCreateFlags.REPLACE_DESTINATION));
+					// writing makepkg output to .SRCINFO
+					yield dos.splice_async (dis, 0);
+				} catch (GLib.Error e) {
+					stderr.printf("%s\n", e.message);
+				}
+			} catch (Error e) {
+				stderr.printf ("Error: %s\n", e.message);
+			}
+		}
+
 		protected virtual int choose_provider (string depend, string[] providers) {
 			// choose first provider
 			return 0;
@@ -206,13 +239,7 @@ namespace Pamac {
 			downloading_updates_finished ();
 		}
 
-		void start_get_updates_for_sysupgrade () {
-			transaction_interface.get_updates_finished.connect (on_get_updates_for_sysupgrade_finished);
-			transaction_interface.start_get_updates_for_sysupgrade (database.config.check_aur_updates);
-		}
-
-		void sysupgrade_real (string[] to_build) {
-			connecting_signals ();
+		void sysupgrade_real () {
 			// this will respond with trans_prepare_finished signal
 			transaction_interface.start_sysupgrade_prepare (enable_downgrade, temporary_ignorepkgs, to_build, overwrite_files);
 		}
@@ -223,49 +250,41 @@ namespace Pamac {
 			this.overwrite_files = overwrite_files;
 			sysupgrading = true;
 			emit_action (dgettext (null, "Starting full system upgrade") + "...");
-			start_get_updates_for_sysupgrade ();
-		}
-
-		void on_get_updates_for_sysupgrade_finished (UpdatesStruct updates_struct) {
-			transaction_interface.get_updates_finished.disconnect (on_get_updates_for_sysupgrade_finished);
-			if (updates_struct.syncfirst_repos_updates.length != 0) {
-				to_install_first = {};
-				foreach (unowned PackageStruct infos in updates_struct.syncfirst_repos_updates) {
-					to_install_first += infos.name;
-				}
-			}
-			string[] to_build = {};
-			foreach (unowned AURPackageStruct infos in updates_struct.aur_updates) {
-				if (!(infos.name in temporary_ignorepkgs)) {
-					to_build += infos.name;
-				}
+			connecting_signals ();
+			if (database.config.check_aur_updates) {
+				database.get_aur_updates.begin ((obj, res) => {
+					var aur_updates = database.get_aur_updates.end (res);
+					to_build = {};
+					foreach (unowned AURPackage aur_update in aur_updates) {
+						if (!(aur_update.name in temporary_ignorepkgs)) {
+							to_build += aur_update.name;
+						}
+					}
+					sysupgrade_real ();
+				});
+			} else {
+				sysupgrade_real ();
 			}
-			// to_install_first will be read by start_commit
-			sysupgrade_real (to_build);
 		}
 
-		void start_trans_prepare (string[] to_install, string[] to_remove, string[] to_load, string[] to_build) {
+		void trans_prepare_real () {
 			transaction_interface.start_trans_prepare (flags, to_install, to_remove, to_load, to_build, overwrite_files);
 		}
 
 		public void start (string[] to_install, string[] to_remove, string[] to_load, string[] to_build, string[] overwrite_files) {
+			this.to_install = to_install;
+			this.to_remove = to_remove;
+			this.to_load = to_load;
+			this.to_build = to_build;
 			this.overwrite_files = overwrite_files;
 			emit_action (dgettext (null, "Preparing") + "...");
+			start_preparing ();
 			connecting_signals ();
-			start_trans_prepare (to_install, to_remove, to_load, to_build);
+			trans_prepare_real ();
 		}
 
 		void start_commit () {
-			if (to_install_first.length > 0) {
-				release ();
-				to_build_queue.clear ();
-				no_confirm_commit = true;
-				sysupgrade_after_trans = true;
-				start_trans_prepare (to_install_first, {}, {}, {});
-				to_install_first = {};
-			} else {
-				transaction_interface.start_trans_commit ();
-			}
+			transaction_interface.start_trans_commit ();
 		}
 
 		public virtual async int run_cmd_line (string[] args, string working_directory, Cancellable cancellable) {
@@ -303,12 +322,7 @@ namespace Pamac {
 			important_details_outpout (false);
 			string [] built_pkgs = {};
 			int status = 1;
-			string builddir;
-			if (database.config.aur_build_dir == "/tmp") {
-				builddir = "/tmp/pamac-build-%s".printf (Environment.get_user_name ());
-			} else {
-				builddir = database.config.aur_build_dir;
-			}
+			string builddir = Path.build_path ("/", database.config.aur_build_dir, "pamac-build");
 			status = yield run_cmd_line ({"mkdir", "-p", builddir}, "/", build_cancellable);
 			if (status == 0) {
 				status = yield run_cmd_line ({"rm", "-rf", pkgname}, builddir, build_cancellable);
@@ -368,7 +382,12 @@ namespace Pamac {
 			if (status == 0 && built_pkgs.length > 0) {
 				no_confirm_commit = true;
 				emit_script_output ("");
-				start_trans_prepare ({}, {}, built_pkgs, {});
+				to_install = {};
+				to_remove = {};
+				to_load = built_pkgs;
+				to_build = {};
+				overwrite_files = {};
+				trans_prepare_real ();
 			} else {
 				important_details_outpout (true);
 				to_build_queue.clear ();
@@ -764,14 +783,6 @@ namespace Pamac {
 				}
 				if (summary_struct.to_build.length > 0) {
 					type |= Type.BUILD;
-					// populate build queue
-					foreach (unowned string name in summary_struct.aur_pkgbases_to_build) {
-						to_build_queue.push_tail (name);
-					}
-					aur_pkgs_to_install = {};
-					foreach (unowned AURPackageStruct infos in summary_struct.to_build) {
-						aur_pkgs_to_install += infos.name;
-					}
 				}
 				if (no_confirm_commit) {
 					no_confirm_commit = false;
@@ -779,33 +790,77 @@ namespace Pamac {
 				} else if (type != 0) {
 					var summary = new TransactionSummary (summary_struct);
 					if (ask_confirmation (summary)) {
-						if (type == Type.BUILD) {
-							// there only AUR packages to build
-							release ();
-							on_trans_commit_finished (true);
+						if ((type & Type.BUILD) != 0) {
+							// ask to review build files
+							string[] build_files_to_review = {};
+							foreach (unowned string name in summary_struct.aur_pkgbases_to_build) {
+								if (!build_files_reviewed.contains (name)) {
+									build_files_to_review += name;
+								}
+							}
+							if (build_files_to_review.length > 0) {
+								release ();
+								review_build_files_and_reprepare.begin (build_files_to_review);
+								return;
+							}
+							// populate build queue
+							foreach (unowned string name in summary_struct.aur_pkgbases_to_build) {
+								to_build_queue.push_tail (name);
+							}
+							aur_pkgs_to_install = {};
+							foreach (unowned AURPackageStruct infos in summary_struct.to_build) {
+								aur_pkgs_to_install += infos.name;
+							}
+							stop_preparing ();
+							if (type == Type.BUILD) {
+								// there only AUR packages to build
+								release ();
+								on_trans_commit_finished (true);
+							} else {
+								start_commit ();
+							}
 						} else {
+							stop_preparing ();
 							start_commit ();
 						}
 					} else {
+						stop_preparing ();
 						emit_action (dgettext (null, "Transaction cancelled") + ".");
 						release ();
 						to_build_queue.clear ();
-						sysupgrade_after_trans = false;
 						finish_transaction (false);
 					}
 				} else {
 					//var err = ErrorInfos ();
 					//err.message = dgettext (null, "Nothing to do") + "\n";
+					stop_preparing ();
 					emit_action (dgettext (null, "Nothing to do") + ".");
 					release ();
 					finish_transaction (true);
 					//handle_error (err);
 				}
 			} else {
+				stop_preparing ();
 				handle_error (get_current_error ());
 			}
 		}
 
+		async void review_build_files_and_reprepare (string[] build_files_to_review) {
+			foreach (string name in build_files_to_review) {
+				yield review_build_files (name);
+				build_files_reviewed.add (name);
+			}
+			emit_script_output ("");
+			// prepare again
+			if (sysupgrading) {
+				emit_action (dgettext (null, "Starting full system upgrade") + "...");
+				sysupgrade_real ();
+			} else {
+				emit_action (dgettext (null, "Preparing") + "...");
+				trans_prepare_real ();
+			}
+		}
+
 		void launch_build_next_aur_package (bool authorized) {
 			get_authorization_finished.disconnect (launch_build_next_aur_package);
 			if (authorized) {
@@ -819,19 +874,13 @@ namespace Pamac {
 		void on_trans_commit_finished (bool success) {
 			if (success) {
 				if (to_build_queue.get_length () != 0) {
+					build_files_reviewed.remove_all ();
 					emit_script_output ("");
 					get_authorization_finished.connect (launch_build_next_aur_package);
 					start_get_authorization ();
 				} else {
-					if (sysupgrade_after_trans) {
-						sysupgrade_after_trans = false;
-						no_confirm_commit = true;
-						disconnecting_signals ();
-						start_sysupgrade (enable_downgrade, temporary_ignorepkgs, {});
-					} else {
-						emit_action (dgettext (null, "Transaction successfully finished") + ".");
-						finish_transaction (true);
-					}
+					emit_action (dgettext (null, "Transaction successfully finished") + ".");
+					finish_transaction (true);
 				}
 			} else {
 				to_build_queue.clear ();
diff --git a/src/transaction_interface.vala b/src/transaction_interface.vala
index a589c829f294fc913257e42226d0cdf0d68beae7..428d3a4e04b49d0b30722a7d9445f5eeeed8c08d 100644
--- a/src/transaction_interface.vala
+++ b/src/transaction_interface.vala
@@ -37,9 +37,7 @@ namespace Pamac {
 		public abstract void start_trans_commit ();
 		public abstract void trans_release ();
 		public abstract void trans_cancel ();
-		public abstract void start_get_updates_for_sysupgrade (bool check_aur_updates);
 		public abstract void quit_daemon ();
-		public signal void get_updates_finished (UpdatesStruct updates_struct);
 		public signal void emit_event (uint primary_event, uint secondary_event, string[] details);
 		public signal void emit_providers (string depend, string[] providers);
 		public signal void emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target);
diff --git a/src/transaction_interface_daemon.vala b/src/transaction_interface_daemon.vala
index cfbce6f5c3a534a9e34f79517ad23545367ae0e6..ee5537ca109062310ae90c3753dd27ef5724e4fe 100644
--- a/src/transaction_interface_daemon.vala
+++ b/src/transaction_interface_daemon.vala
@@ -39,10 +39,8 @@ namespace Pamac {
 		public abstract void start_trans_commit () throws Error;
 		public abstract void trans_release () throws Error;
 		public abstract void trans_cancel () throws Error;
-		public abstract void start_get_updates_for_sysupgrade (bool check_aur_updates) throws Error;
 		[DBus (no_reply = true)]
 		public abstract void quit () throws Error;
-		public signal void get_updates_finished (UpdatesStruct updates_struct);
 		public signal void emit_event (uint primary_event, uint secondary_event, string[] details);
 		public signal void emit_providers (string depend, string[] providers);
 		public signal void emit_progress (uint progress, string pkgname, uint percent, uint n_targets, uint current_target);
@@ -216,20 +214,6 @@ namespace Pamac {
 			downloading_updates_finished ();
 		}
 
-		public void start_get_updates_for_sysupgrade (bool check_aur_updates) {
-			try {
-				system_daemon.start_get_updates_for_sysupgrade (check_aur_updates);
-				system_daemon.get_updates_finished.connect (on_get_updates_finished);
-			} catch (Error e) {
-				stderr.printf ("start_get_updates: %s\n", e.message);
-			}
-		}
-
-		void on_get_updates_finished (UpdatesStruct updates) {
-			system_daemon.get_updates_finished.disconnect (on_get_updates_finished);
-			get_updates_finished (updates);
-		}
-
 		void start_sysupgrade_prepare (bool enable_downgrade,
 										string[] temporary_ignorepkgs,
 										string[] to_build,
diff --git a/src/transaction_interface_root.vala b/src/transaction_interface_root.vala
index 8e8dd298925bf3332cf0e810a893b6eb48d0c68a..6de6257af56fa583195ebd47a5119f173ee0788d 100644
--- a/src/transaction_interface_root.vala
+++ b/src/transaction_interface_root.vala
@@ -44,9 +44,6 @@ namespace Pamac {
 			alpm_utils.refresh_finished.connect ((success) => {
 				refresh_finished (success);
 			});
-			alpm_utils.get_updates_finished.connect ((updates) => {
-				get_updates_finished (updates);
-			});
 			alpm_utils.downloading_updates_finished.connect (() => {
 				downloading_updates_finished ();
 			});
@@ -173,16 +170,6 @@ namespace Pamac {
 			}
 		}
 
-		int get_updates_for_sysupgrade () {
-			alpm_utils.get_updates_for_sysupgrade ();
-			return 0;
-		}
-
-		public void start_get_updates_for_sysupgrade (bool check_aur_updates) {
-			alpm_utils.check_aur_updates = check_aur_updates;
-			new Thread<int> ("get_updates_for_sysupgrade", get_updates_for_sysupgrade);
-		}
-
 		int download_updates () {
 			alpm_utils.download_updates ();
 			return 0;
@@ -229,9 +216,7 @@ namespace Pamac {
 			alpm_utils.to_load = to_load;
 			alpm_utils.to_build = to_build;
 			alpm_utils.overwrite_files = overwrite_files;
-			if (alpm_utils.to_install.length > 0) {
-				alpm_utils.sysupgrade = true;
-			}
+			alpm_utils.sysupgrade = false;
 			if (alpm_utils.downloading_updates) {
 				alpm_utils.cancellable.cancel ();
 				// let time to cancel download updates
@@ -249,15 +234,11 @@ namespace Pamac {
 			return 0;
 		}
 
-		int build_prepare () {
-			alpm_utils.build_prepare ();
-			return 0;
-		}
-
 		private void launch_prepare () {
 			if (alpm_utils.to_build.length != 0) {
-				alpm_utils.compute_aur_build_list ();
-				new Thread<int> ("build_prepare", build_prepare);
+				alpm_utils.compute_aur_build_list.begin (() => {
+					alpm_utils.build_prepare ();
+				});
 			} else {
 				new Thread<int> ("trans_prepare", trans_prepare);
 			}
diff --git a/src/tray.vala b/src/tray.vala
index d15c117538f9db60a18f265341ad8375f0b43700..2587b4790467f30b611a7260950b2b8b1e42f711 100644
--- a/src/tray.vala
+++ b/src/tray.vala
@@ -139,25 +139,27 @@ namespace Pamac {
 
 		bool check_updates () {
 			if (database.config.refresh_period != 0) {
-				var updates = database.get_updates ();
-				updates_nb = updates.repos_updates.length () + updates.aur_updates.length ();
-				if (updates_nb == 0) {
-					set_icon (noupdate_icon_name);
-					set_tooltip (noupdate_info);
-					set_icon_visible (!database.config.no_update_hide_icon);
-					close_notification ();
-				} else {
-					if (!check_pamac_running () && database.config.download_updates) {
-						start_system_daemon ();
-						try {
-							system_daemon.start_download_updates ();
-						} catch (Error e) {
-							stderr.printf ("Error: %s\n", e.message);
-						}
+				database.get_updates.begin ((obj, res) => {
+					var updates = database.get_updates.end (res);
+					updates_nb = updates.repos_updates.length () + updates.aur_updates.length ();
+					if (updates_nb == 0) {
+						set_icon (noupdate_icon_name);
+						set_tooltip (noupdate_info);
+						set_icon_visible (!database.config.no_update_hide_icon);
+						close_notification ();
 					} else {
-						show_or_update_notification ();
+						if (!check_pamac_running () && database.config.download_updates) {
+							start_system_daemon ();
+							try {
+								system_daemon.start_download_updates ();
+							} catch (Error e) {
+								stderr.printf ("Error: %s\n", e.message);
+							}
+						} else {
+							show_or_update_notification ();
+						}
 					}
-				}
+				});
 			}
 			return true;
 		}