diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java
index c3cf9b00e..914d62832 100644
--- a/src/org/fdroid/fdroid/DB.java
+++ b/src/org/fdroid/fdroid/DB.java
@@ -35,571 +35,575 @@ import android.util.Log;
 
 public class DB {
 
-    private static final String DATABASE_NAME = "fdroid";
+	private static final String DATABASE_NAME = "fdroid";
 
-    private SQLiteDatabase db;
+	private SQLiteDatabase db;
 
-    // The TABLE_APP table stores details of all the applications we know about.
-    // This information is retrieved from the repositories.
-    private static final String TABLE_APP = "fdroid_app";
-    private static final String CREATE_TABLE_APP = "create table " + TABLE_APP
-            + " ( " + "id text not null, " + "name text not null, "
-            + "summary text not null, " + "icon text, "
-            + "description text not null, " + "license text not null, "
-            + "webURL text, " + "trackerURL text, " + "sourceURL text, "
-            + "installedVersion text," + "hasUpdates int not null,"
-            + "primary key(id));";
+	// The TABLE_APP table stores details of all the applications we know about.
+	// This information is retrieved from the repositories.
+	private static final String TABLE_APP = "fdroid_app";
+	private static final String CREATE_TABLE_APP = "create table " + TABLE_APP
+			+ " ( " + "id text not null, " + "name text not null, "
+			+ "summary text not null, " + "icon text, "
+			+ "description text not null, " + "license text not null, "
+			+ "webURL text, " + "trackerURL text, " + "sourceURL text, "
+			+ "installedVersion text," + "hasUpdates int not null,"
+			+ "primary key(id));";
 
-    public static class App {
+	public static class App {
 
-        public App() {
-            name = "Unknown";
-            summary = "Unknown application";
-            icon = "noicon.png";
-            id = "unknown";
-            license = "Unknown";
-            trackerURL = "";
-            sourceURL = "";
-            webURL = "";
-            hasUpdates = false;
-            updated = false;
-            apks = new Vector<Apk>();
-        }
+		public App() {
+			name = "Unknown";
+			summary = "Unknown application";
+			icon = "noicon.png";
+			id = "unknown";
+			license = "Unknown";
+			trackerURL = "";
+			sourceURL = "";
+			webURL = "";
+			hasUpdates = false;
+			updated = false;
+			apks = new Vector<Apk>();
+		}
 
-        public String id;
-        public String name;
-        public String summary;
-        public String icon;
-        public String description;
-        public String license;
-        public String webURL;
-        public String trackerURL;
-        public String sourceURL;
-        public String installedVersion;
-        public int installedVerCode;
-        public String marketVersion;
-        public int marketVercode;
+		public String id;
+		public String name;
+		public String summary;
+		public String icon;
+		public String description;
+		public String license;
+		public String webURL;
+		public String trackerURL;
+		public String sourceURL;
+		public String installedVersion;
+		public int installedVerCode;
+		public String marketVersion;
+		public int marketVercode;
 
-        // True if there are new versions (apks) that the user hasn't
-        // explicitly ignored. (We're currently not using the database
-        // field for this - we make the decision on the fly in getApps().
-        public boolean hasUpdates;
+		// True if there are new versions (apks) that the user hasn't
+		// explicitly ignored. (We're currently not using the database
+		// field for this - we make the decision on the fly in getApps().
+		public boolean hasUpdates;
 
-        // Used internally for tracking during repo updates.
-        public boolean updated;
+		// Used internally for tracking during repo updates.
+		public boolean updated;
 
-        public Vector<Apk> apks;
+		public Vector<Apk> apks;
 
-        // Get the current version - this will be one of the Apks from 'apks'.
-        // Can return null if there are no available versions.
-        // This should be the 'current' version, as in the most recent stable
-        // one, that most users would want by default. It might not be the
-        // most recent, if for example there are betas etc.
-        public Apk getCurrentVersion() {
+		// Get the current version - this will be one of the Apks from 'apks'.
+		// Can return null if there are no available versions.
+		// This should be the 'current' version, as in the most recent stable
+		// one, that most users would want by default. It might not be the
+		// most recent, if for example there are betas etc.
+		public Apk getCurrentVersion() {
 
-            // Try and return the version that's in Google's market first...
-            if (marketVersion != null && marketVercode > 0) {
-                for (Apk apk : apks) {
-                    if (apk.vercode == marketVercode)
-                        return apk;
-                }
-            }
+			// Try and return the version that's in Google's market first...
+			if (marketVersion != null && marketVercode > 0) {
+				for (Apk apk : apks) {
+					if (apk.vercode == marketVercode)
+						return apk;
+				}
+			}
 
-            // If we don't know the market version, or we don't have it, we
-            // return the most recent version we have...
-            int latestcode = -1;
-            Apk latestapk = null;
-            for (Apk apk : apks) {
-                if (apk.vercode > latestcode) {
-                    latestapk = apk;
-                    latestcode = apk.vercode;
-                }
-            }
-            return latestapk;
-        }
+			// If we don't know the market version, or we don't have it, we
+			// return the most recent version we have...
+			int latestcode = -1;
+			Apk latestapk = null;
+			for (Apk apk : apks) {
+				if (apk.vercode > latestcode) {
+					latestapk = apk;
+					latestcode = apk.vercode;
+				}
+			}
+			return latestapk;
+		}
 
-    }
+	}
 
-    // The TABLE_APK table stores details of all the application versions we
-    // know about. Each relates directly back to an entry in TABLE_APP.
-    // This information is retrieved from the repositories.
-    private static final String TABLE_APK = "fdroid_apk";
-    private static final String CREATE_TABLE_APK = "create table " + TABLE_APK
-            + " ( " + "id text not null, " + "version text not null, "
-            + "server text not null, " + "hash text not null, "
-            + "vercode int not null," + "apkName text not null, "
-            + "size int not null," + "primary key(id,version));";
+	// The TABLE_APK table stores details of all the application versions we
+	// know about. Each relates directly back to an entry in TABLE_APP.
+	// This information is retrieved from the repositories.
+	private static final String TABLE_APK = "fdroid_apk";
+	private static final String CREATE_TABLE_APK = "create table " + TABLE_APK
+			+ " ( " + "id text not null, " + "version text not null, "
+			+ "server text not null, " + "hash text not null, "
+			+ "vercode int not null," + "apkName text not null, "
+			+ "size int not null," + "primary key(id,version));";
 
-    public static class Apk {
+	public static class Apk {
 
-        public Apk() {
-            updated = false;
-            size = 0;
-            apkSource = null;
-        }
+		public Apk() {
+			updated = false;
+			size = 0;
+			apkSource = null;
+		}
 
-        public String id;
-        public String version;
-        public int vercode;
-        public int size; // Size in bytes - 0 means we don't know!
-        public String server;
-        public String hash;
-        public String apkName;
+		public String id;
+		public String version;
+		public int vercode;
+		public int size; // Size in bytes - 0 means we don't know!
+		public String server;
+		public String hash;
+		public String apkName;
 
-        // If null, the apk comes from the same server as the repo index.
-        // Otherwise
-        // this is the complete URL to download the apk from.
-        public String apkSource;
+		// If null, the apk comes from the same server as the repo index.
+		// Otherwise
+		// this is the complete URL to download the apk from.
+		public String apkSource;
 
-        // Used internally for tracking during repo updates.
-        public boolean updated;
+		// Used internally for tracking during repo updates.
+		public boolean updated;
 
-        public String getURL() {
-            String path = apkName.replace(" ", "%20");
-            return server + "/" + path;
-        }
-    }
+		public String getURL() {
+			String path = apkName.replace(" ", "%20");
+			return server + "/" + path;
+		}
+	}
 
-    // The TABLE_REPO table stores the details of the repositories in use.
-    private static final String TABLE_REPO = "fdroid_repo";
-    private static final String CREATE_TABLE_REPO = "create table "
-            + TABLE_REPO + " (" + "address text primary key, "
-            + "inuse integer not null, " + "priority integer not null);";
+	// The TABLE_REPO table stores the details of the repositories in use.
+	private static final String TABLE_REPO = "fdroid_repo";
+	private static final String CREATE_TABLE_REPO = "create table "
+			+ TABLE_REPO + " (" + "address text primary key, "
+			+ "inuse integer not null, " + "priority integer not null);";
 
-    public static class Repo {
-        public String address;
-        public boolean inuse;
-        public int priority;
-    }
+	public static class Repo {
+		public String address;
+		public boolean inuse;
+		public int priority;
+	}
 
-    // SQL to update the database to versions beyond the first. Here is
-    // how the database works:
-    //
-    // * The SQL to create the database tables always creates version
-    // 1. This SQL will never be altered.
-    // * In the array below there is SQL for each subsequent version
-    // from 2 onwards.
-    // * For a new install, the database is always initialised to version
-    // 1.
-    // * Then, whether it's a new install or not, all the upgrade SQL in
-    // the array below is executed in order to bring the database up to
-    // the latest version.
-    // * The current version is tracked by an entry in the TABLE_VERSION
-    // table.
-    //
-    private static final String[][] DB_UPGRADES = {
+	// SQL to update the database to versions beyond the first. Here is
+	// how the database works:
+	//
+	// * The SQL to create the database tables always creates version
+	// 1. This SQL will never be altered.
+	// * In the array below there is SQL for each subsequent version
+	// from 2 onwards.
+	// * For a new install, the database is always initialised to version
+	// 1.
+	// * Then, whether it's a new install or not, all the upgrade SQL in
+	// the array below is executed in order to bring the database up to
+	// the latest version.
+	// * The current version is tracked by an entry in the TABLE_VERSION
+	// table.
+	//
+	private static final String[][] DB_UPGRADES = {
 
-    // Version 2...
-            { "alter table " + TABLE_APP + " add marketVersion text",
-                    "alter table " + TABLE_APP + " add marketVercode integer" },
+	// Version 2...
+			{ "alter table " + TABLE_APP + " add marketVersion text",
+					"alter table " + TABLE_APP + " add marketVercode integer" },
 
-            // Version 3...
-            { "alter table " + TABLE_APK + " add apkSource text" },
+			// Version 3...
+			{ "alter table " + TABLE_APK + " add apkSource text" },
 
-            // Version 4...
-            { "alter table " + TABLE_APP + " add installedVerCode integer" }
+			// Version 4...
+			{ "alter table " + TABLE_APP + " add installedVerCode integer" }
 
-    };
+	};
 
-    private class DBHelper extends SQLiteOpenHelper {
+	private class DBHelper extends SQLiteOpenHelper {
 
-        public DBHelper(Context context) {
-            super(context, DATABASE_NAME, null, DB_UPGRADES.length + 1);
-        }
+		public DBHelper(Context context) {
+			super(context, DATABASE_NAME, null, DB_UPGRADES.length + 1);
+		}
 
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL(CREATE_TABLE_REPO);
-            db.execSQL(CREATE_TABLE_APP);
-            db.execSQL(CREATE_TABLE_APK);
-            ContentValues values = new ContentValues();
-            values.put("address", "http://f-droid.org/repo");
-            values.put("inuse", 1);
-            values.put("priority", 10);
-            db.insert(TABLE_REPO, null, values);
-            onUpgrade(db, 1, DB_UPGRADES.length + 1);
-        }
+		@Override
+		public void onCreate(SQLiteDatabase db) {
+			db.execSQL(CREATE_TABLE_REPO);
+			db.execSQL(CREATE_TABLE_APP);
+			db.execSQL(CREATE_TABLE_APK);
+			ContentValues values = new ContentValues();
+			values.put("address", "http://f-droid.org/repo");
+			values.put("inuse", 1);
+			values.put("priority", 10);
+			db.insert(TABLE_REPO, null, values);
+			onUpgrade(db, 1, DB_UPGRADES.length + 1);
+		}
 
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            for (int v = oldVersion + 1; v <= newVersion; v++)
-                for (int i = 0; i < DB_UPGRADES[v - 2].length; i++)
-                    db.execSQL(DB_UPGRADES[v - 2][i]);
-        }
+		@Override
+		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+			for (int v = oldVersion + 1; v <= newVersion; v++)
+				for (int i = 0; i < DB_UPGRADES[v - 2].length; i++)
+					db.execSQL(DB_UPGRADES[v - 2][i]);
+		}
 
-    }
+	}
 
-    public static String getIconsPath() {
-        return "/sdcard/.fdroid/icons/";
-    }
+	public static String getIconsPath() {
+		return "/sdcard/.fdroid/icons/";
+	}
 
-    private PackageManager mPm;
+	private PackageManager mPm;
 
-    public DB(Context ctx) {
+	public DB(Context ctx) {
 
-        DBHelper h = new DBHelper(ctx);
-        db = h.getWritableDatabase();
-        mPm = ctx.getPackageManager();
-    }
+		DBHelper h = new DBHelper(ctx);
+		db = h.getWritableDatabase();
+		mPm = ctx.getPackageManager();
+	}
 
-    public void close() {
-        db.close();
-        db = null;
-    }
+	public void close() {
+		db.close();
+		db = null;
+	}
 
-    // Delete the database, which should cause it to be re-created next time
-    // it's used.
-    public static void delete(Context ctx) {
-        try {
-            ctx.deleteDatabase(DATABASE_NAME);
-            // Also try and delete the old one, from versions 0.13 and earlier.
-            ctx.deleteDatabase("fdroid_db");
-        } catch (Exception ex) {
-            Log.d("FDroid", "Exception in DB.delete: " + ex.getMessage());
-        }
-    }
+	// Delete the database, which should cause it to be re-created next time
+	// it's used.
+	public static void delete(Context ctx) {
+		try {
+			ctx.deleteDatabase(DATABASE_NAME);
+			// Also try and delete the old one, from versions 0.13 and earlier.
+			ctx.deleteDatabase("fdroid_db");
+		} catch (Exception ex) {
+			Log.d("FDroid", "Exception in DB.delete: " + ex.getMessage());
+		}
+	}
 
-    // Return a list of apps matching the given criteria.
-    // 'appid' - specific app id to retrieve, or null
-    // 'filter' - search text to filter on.
-    // 'update' - update installed version information from device, rather than
-    // simply using values cached in the database. Slower.
-    public Vector<App> getApps(String appid, String filter, boolean update) {
-        Vector<App> result = new Vector<App>();
-        Cursor c = null;
-        Cursor c2 = null;
-        try {
+	// Get the number of apps that have updates available.
+	public int getNumUpdates() {
+		Vector<App> apps = getApps(null, null, false);
+		int count = 0;
+		for (App app : apps) {
+			if (app.hasUpdates)
+				count++;
+		}
+		return count;
+	}
 
-            String query = "select * from " + TABLE_APP;
-            if (appid != null) {
-                query += " where id = '" + appid + "'";
-            } else if (filter != null) {
-                query += " where name like '%" + filter + "%'"
-                        + " or description like '%" + filter + "%'";
-            }
-            query += " order by name collate nocase";
+	// Return a list of apps matching the given criteria.
+	// 'appid' - specific app id to retrieve, or null
+	// 'filter' - search text to filter on, or null
+	// 'update' - update installed version information from device, rather than
+	// simply using values cached in the database. Slower.
+	public Vector<App> getApps(String appid, String filter, boolean update) {
+		Vector<App> result = new Vector<App>();
+		Cursor c = null;
+		Cursor c2 = null;
+		try {
 
-            c = db.rawQuery(query, null);
-            c.moveToFirst();
-            while (!c.isAfterLast()) {
+			String query = "select * from " + TABLE_APP;
+			if (appid != null) {
+				query += " where id = '" + appid + "'";
+			} else if (filter != null) {
+				query += " where name like '%" + filter + "%'"
+						+ " or description like '%" + filter + "%'";
+			}
+			query += " order by name collate nocase";
 
-                App app = new App();
-                app.id = c.getString(c.getColumnIndex("id"));
-                app.name = c.getString(c.getColumnIndex("name"));
-                app.summary = c.getString(c.getColumnIndex("summary"));
-                app.icon = c.getString(c.getColumnIndex("icon"));
-                app.description = c.getString(c.getColumnIndex("description"));
-                app.license = c.getString(c.getColumnIndex("license"));
-                app.webURL = c.getString(c.getColumnIndex("webURL"));
-                app.trackerURL = c.getString(c.getColumnIndex("trackerURL"));
-                app.sourceURL = c.getString(c.getColumnIndex("sourceURL"));
-                app.installedVersion = c.getString(c
-                        .getColumnIndex("installedVersion"));
-                app.installedVerCode = c.getInt(c
-                        .getColumnIndex("installedVerCode"));
-                app.marketVersion = c.getString(c
-                        .getColumnIndex("marketVersion"));
-                app.marketVercode = c.getInt(c.getColumnIndex("marketVercode"));
-                app.hasUpdates = false;
+			c = db.rawQuery(query, null);
+			c.moveToFirst();
+			while (!c.isAfterLast()) {
 
-                c2 = db.rawQuery("select * from " + TABLE_APK
-                        + " where id = ? order by vercode desc",
-                        new String[] { app.id });
-                c2.moveToFirst();
-                while (!c2.isAfterLast()) {
-                    Apk apk = new Apk();
-                    apk.id = app.id;
-                    apk.version = c2.getString(c2.getColumnIndex("version"));
-                    apk.vercode = c2.getInt(c2.getColumnIndex("vercode"));
-                    apk.server = c2.getString(c2.getColumnIndex("server"));
-                    apk.hash = c2.getString(c2.getColumnIndex("hash"));
-                    apk.size = c2.getInt(c2.getColumnIndex("size"));
-                    apk.apkName = c2.getString(c2.getColumnIndex("apkName"));
-                    apk.apkSource = c2
-                            .getString(c2.getColumnIndex("apkSource"));
-                    app.apks.add(apk);
-                    c2.moveToNext();
-                }
-                c2.close();
+				App app = new App();
+				app.id = c.getString(c.getColumnIndex("id"));
+				app.name = c.getString(c.getColumnIndex("name"));
+				app.summary = c.getString(c.getColumnIndex("summary"));
+				app.icon = c.getString(c.getColumnIndex("icon"));
+				app.description = c.getString(c.getColumnIndex("description"));
+				app.license = c.getString(c.getColumnIndex("license"));
+				app.webURL = c.getString(c.getColumnIndex("webURL"));
+				app.trackerURL = c.getString(c.getColumnIndex("trackerURL"));
+				app.sourceURL = c.getString(c.getColumnIndex("sourceURL"));
+				app.installedVersion = c.getString(c
+						.getColumnIndex("installedVersion"));
+				app.installedVerCode = c.getInt(c
+						.getColumnIndex("installedVerCode"));
+				app.marketVersion = c.getString(c
+						.getColumnIndex("marketVersion"));
+				app.marketVercode = c.getInt(c.getColumnIndex("marketVercode"));
+				app.hasUpdates = false;
 
-                result.add(app);
-                c.moveToNext();
-            }
+				c2 = db.rawQuery("select * from " + TABLE_APK
+						+ " where id = ? order by vercode desc",
+						new String[] { app.id });
+				c2.moveToFirst();
+				while (!c2.isAfterLast()) {
+					Apk apk = new Apk();
+					apk.id = app.id;
+					apk.version = c2.getString(c2.getColumnIndex("version"));
+					apk.vercode = c2.getInt(c2.getColumnIndex("vercode"));
+					apk.server = c2.getString(c2.getColumnIndex("server"));
+					apk.hash = c2.getString(c2.getColumnIndex("hash"));
+					apk.size = c2.getInt(c2.getColumnIndex("size"));
+					apk.apkName = c2.getString(c2.getColumnIndex("apkName"));
+					apk.apkSource = c2
+							.getString(c2.getColumnIndex("apkSource"));
+					app.apks.add(apk);
+					c2.moveToNext();
+				}
+				c2.close();
 
-        } catch (Exception e) {
-            Log.d("FDroid", "Exception during database reading - "
-                    + e.getMessage() + " ... " + e.toString());
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-            if (c2 != null) {
-                c2.close();
-            }
-        }
+				result.add(app);
+				c.moveToNext();
+			}
 
-        if (update) {
-            getUpdates(result);
-        }
+		} catch (Exception e) {
+			Log.d("FDroid", "Exception during database reading - "
+					+ e.getMessage() + " ... " + e.toString());
+		} finally {
+			if (c != null) {
+				c.close();
+			}
+			if (c2 != null) {
+				c2.close();
+			}
+		}
 
-        // We'll say an application has updates if it's installed AND the
-        // installed version is not the 'current' one AND the installed
-        // version is older than the current one.
-        for (App app : result) {
-            Apk curver = app.getCurrentVersion();
-            if (curver != null && app.installedVersion != null
-                    && !app.installedVersion.equals(curver.version)) {
-                if (app.installedVerCode < curver.vercode)
-                    app.hasUpdates = true;
-            }
-        }
+		if (update) {
+			getUpdates(result);
+		}
 
-        return result;
-    }
+		// We'll say an application has updates if it's installed AND the
+		// installed version is not the 'current' one AND the installed
+		// version is older than the current one.
+		for (App app : result) {
+			Apk curver = app.getCurrentVersion();
+			if (curver != null && app.installedVersion != null
+					&& !app.installedVersion.equals(curver.version)) {
+				if (app.installedVerCode < curver.vercode)
+					app.hasUpdates = true;
+			}
+		}
 
-    // Verify installed status against the system's package list.
-    private void getUpdates(Vector<DB.App> apps) {
-        List<PackageInfo> installedPackages = mPm.getInstalledPackages(0);
-        Map<String, PackageInfo> systemApks = new HashMap<String, PackageInfo>();
-        Log.d("FDroid", "Reading installed packages");
-        for (PackageInfo appInfo : installedPackages) {
-            systemApks.put(appInfo.packageName, appInfo);
-        }
+		return result;
+	}
 
-        for (DB.App app : apps) {
-            if (systemApks.containsKey(app.id)) {
-                PackageInfo sysapk = systemApks.get(app.id);
-                String version = sysapk.versionName;
-                int vercode = sysapk.versionCode;
-                if (app.installedVersion == null
-                        || !app.installedVersion.equals(version)) {
-                    setInstalledVersion(app.id, version, vercode);
-                    app.installedVersion = version;
-                }
-            } else {
-                if (app.installedVersion != null) {
-                    setInstalledVersion(app.id, null, 0);
-                    app.installedVersion = null;
-                }
-            }
-        }
-    }
+	// Verify installed status against the system's package list.
+	private void getUpdates(Vector<DB.App> apps) {
+		List<PackageInfo> installedPackages = mPm.getInstalledPackages(0);
+		Map<String, PackageInfo> systemApks = new HashMap<String, PackageInfo>();
+		Log.d("FDroid", "Reading installed packages");
+		for (PackageInfo appInfo : installedPackages) {
+			systemApks.put(appInfo.packageName, appInfo);
+		}
 
-    private Vector<App> updateApps = null;
-    private int updateNewUpdates;
+		for (DB.App app : apps) {
+			if (systemApks.containsKey(app.id)) {
+				PackageInfo sysapk = systemApks.get(app.id);
+				String version = sysapk.versionName;
+				int vercode = sysapk.versionCode;
+				if (app.installedVersion == null
+						|| !app.installedVersion.equals(version)) {
+					setInstalledVersion(app.id, version, vercode);
+					app.installedVersion = version;
+				}
+			} else {
+				if (app.installedVersion != null) {
+					setInstalledVersion(app.id, null, 0);
+					app.installedVersion = null;
+				}
+			}
+		}
+	}
 
-    // Called before a repo update starts.
-    public void beginUpdate() {
-        // Get a list of all apps. All the apps and apks in this list will
-        // have 'updated' set to false at this point, and we will only set
-        // it to true when we see the app/apk in a repository. Thus, at the
-        // end, any that are still false can be removed.
-        // TODO: Need to ensure that UI and UpdateService can't both be doing
-        // an update at the same time.
-        updateApps = getApps(null, null, true);
-        updateNewUpdates = 0;
-        Log.d("FDroid", "AppUpdate: " + updateApps.size()
-                + " apps before starting.");
-    }
+	private Vector<App> updateApps = null;
 
-    // Called when a repo update ends. Any applications that have not been
-    // updated (by a call to updateApplication) are assumed to be no longer
-    // in the repos.
-    // Returns the number of new updates (installed applications for which
-    // there is a new version available)
-    public int endUpdate() {
-        if (updateApps == null)
-            return 0;
-        for (App app : updateApps) {
-            if (!app.updated) {
-                // The application hasn't been updated, so it's no longer
-                // in the repos.
-                Log.d("FDroid", "AppUpdate: " + app.name
-                        + " is no longer in any repository - removing");
-                db.delete(TABLE_APP, "id = ?", new String[] { app.id });
-                db.delete(TABLE_APK, "id = ?", new String[] { app.id });
-            } else {
-                for (Apk apk : app.apks) {
-                    if (!apk.updated) {
-                        // The package hasn't been updated, so this is a
-                        // version that's no longer available.
-                        Log.d("FDroid", "AppUpdate: Package " + apk.id + "/"
-                                + apk.version
-                                + " is no longer in any repository - removing");
-                        db.delete(TABLE_APK, "id = ? and version = ?",
-                                new String[] { app.id, apk.version });
-                    }
-                }
-            }
-        }
-        Log.d("FDroid", "AppUpdate: " + updateApps.size()
-                + " apps on completion.");
-        updateApps = null;
-        return updateNewUpdates;
-    }
+	// Called before a repo update starts.
+	public void beginUpdate() {
+		// Get a list of all apps. All the apps and apks in this list will
+		// have 'updated' set to false at this point, and we will only set
+		// it to true when we see the app/apk in a repository. Thus, at the
+		// end, any that are still false can be removed.
+		// TODO: Need to ensure that UI and UpdateService can't both be doing
+		// an update at the same time.
+		updateApps = getApps(null, null, true);
+		Log.d("FDroid", "AppUpdate: " + updateApps.size()
+				+ " apps before starting.");
+	}
 
-    // Called during update to supply new details for an application (or
-    // details of a completely new one). Calls to this must be wrapped by
-    // a call to beginUpdate and a call to endUpdate.
-    public void updateApplication(App upapp) {
+	// Called when a repo update ends. Any applications that have not been
+	// updated (by a call to updateApplication) are assumed to be no longer
+	// in the repos.
+	public void endUpdate() {
+		if (updateApps == null)
+			return;
+		for (App app : updateApps) {
+			if (!app.updated) {
+				// The application hasn't been updated, so it's no longer
+				// in the repos.
+				Log.d("FDroid", "AppUpdate: " + app.name
+						+ " is no longer in any repository - removing");
+				db.delete(TABLE_APP, "id = ?", new String[] { app.id });
+				db.delete(TABLE_APK, "id = ?", new String[] { app.id });
+			} else {
+				for (Apk apk : app.apks) {
+					if (!apk.updated) {
+						// The package hasn't been updated, so this is a
+						// version that's no longer available.
+						Log.d("FDroid", "AppUpdate: Package " + apk.id + "/"
+								+ apk.version
+								+ " is no longer in any repository - removing");
+						db.delete(TABLE_APK, "id = ? and version = ?",
+								new String[] { app.id, apk.version });
+					}
+				}
+			}
+		}
+		Log.d("FDroid", "AppUpdate: " + updateApps.size()
+				+ " apps on completion.");
+		updateApps = null;
+		return;
+	}
 
-        if (updateApps == null) {
-            return;
-        }
+	// Called during update to supply new details for an application (or
+	// details of a completely new one). Calls to this must be wrapped by
+	// a call to beginUpdate and a call to endUpdate.
+	public void updateApplication(App upapp) {
 
-        boolean found = false;
-        for (App app : updateApps) {
-            if (app.id.equals(upapp.id)) {
-                Log.d("FDroid", "AppUpdate: " + app.id
-                        + " is already in the database.");
-                updateAppIfDifferent(app, upapp);
-                app.updated = true;
-                found = true;
-                for (Apk upapk : upapp.apks) {
-                    boolean afound = false;
-                    for (Apk apk : app.apks) {
-                        if (apk.version.equals(upapk.version)) {
-                            Log.d("FDroid", "AppUpdate: " + apk.version
-                                    + " is a known version.");
-                            updateApkIfDifferent(apk, upapk);
-                            apk.updated = true;
-                            afound = true;
-                            break;
-                        }
-                    }
-                    if (!afound) {
-                        // A new version of this application.
-                        Log.d("FDroid", "AppUpdate: " + upapk.version
-                                + " is a new version.");
-                        updateApkIfDifferent(null, upapk);
-                        upapk.updated = true;
-                        app.apks.add(upapk);
-                        if (!app.hasUpdates && app.installedVersion != null)
-                            updateNewUpdates++;
-                        app.hasUpdates = true;
-                    }
-                }
-                break;
-            }
-        }
-        if (!found) {
-            // It's a brand new application...
-            Log
-                    .d("FDroid", "AppUpdate: " + upapp.id
-                            + " is a new application.");
-            updateAppIfDifferent(null, upapp);
-            for (Apk upapk : upapp.apks) {
-                updateApkIfDifferent(null, upapk);
-                upapk.updated = true;
-            }
-            upapp.updated = true;
-            updateApps.add(upapp);
-        }
+		if (updateApps == null) {
+			return;
+		}
 
-    }
+		boolean found = false;
+		for (App app : updateApps) {
+			if (app.id.equals(upapp.id)) {
+				Log.d("FDroid", "AppUpdate: " + app.id
+						+ " is already in the database.");
+				updateAppIfDifferent(app, upapp);
+				app.updated = true;
+				found = true;
+				for (Apk upapk : upapp.apks) {
+					boolean afound = false;
+					for (Apk apk : app.apks) {
+						if (apk.version.equals(upapk.version)) {
+							Log.d("FDroid", "AppUpdate: " + apk.version
+									+ " is a known version.");
+							updateApkIfDifferent(apk, upapk);
+							apk.updated = true;
+							afound = true;
+							break;
+						}
+					}
+					if (!afound) {
+						// A new version of this application.
+						Log.d("FDroid", "AppUpdate: " + upapk.version
+								+ " is a new version.");
+						updateApkIfDifferent(null, upapk);
+						upapk.updated = true;
+						app.apks.add(upapk);
+					}
+				}
+				break;
+			}
+		}
+		if (!found) {
+			// It's a brand new application...
+			Log
+					.d("FDroid", "AppUpdate: " + upapp.id
+							+ " is a new application.");
+			updateAppIfDifferent(null, upapp);
+			for (Apk upapk : upapp.apks) {
+				updateApkIfDifferent(null, upapk);
+				upapk.updated = true;
+			}
+			upapp.updated = true;
+			updateApps.add(upapp);
+		}
 
-    // Update application details in the database, if different to the
-    // previous ones.
-    // 'oldapp' - previous details - i.e. what's in the database.
-    // If null, this app is not in the database at all and
-    // should be added.
-    // 'upapp' - updated details
-    private void updateAppIfDifferent(App oldapp, App upapp) {
-        ContentValues values = new ContentValues();
-        values.put("id", upapp.id);
-        values.put("name", upapp.name);
-        values.put("summary", upapp.summary);
-        values.put("icon", upapp.icon);
-        values.put("description", upapp.description);
-        values.put("license", upapp.license);
-        values.put("webURL", upapp.webURL);
-        values.put("trackerURL", upapp.trackerURL);
-        values.put("sourceURL", upapp.sourceURL);
-        values.put("installedVersion", upapp.installedVersion);
-        values.put("installedVerCode", upapp.installedVerCode);
-        values.put("marketVersion", upapp.marketVersion);
-        values.put("marketVercode", upapp.marketVercode);
-        values.put("hasUpdates", upapp.hasUpdates ? 1 : 0);
-        if (oldapp != null) {
-            db.update(TABLE_APP, values, "id = ?", new String[] { oldapp.id });
-        } else {
-            db.insert(TABLE_APP, null, values);
-        }
-    }
+	}
 
-    // Update apk details in the database, if different to the
-    // previous ones.
-    // 'oldapk' - previous details - i.e. what's in the database.
-    // If null, this apk is not in the database at all and
-    // should be added.
-    // 'upapk' - updated details
-    private void updateApkIfDifferent(Apk oldapk, Apk upapk) {
-        ContentValues values = new ContentValues();
-        values.put("id", upapk.id);
-        values.put("version", upapk.version);
-        values.put("vercode", upapk.vercode);
-        values.put("server", upapk.server);
-        values.put("hash", upapk.hash);
-        values.put("size", upapk.size);
-        values.put("apkName", upapk.apkName);
-        values.put("apkSource", upapk.apkSource);
-        if (oldapk != null) {
-            db.update(TABLE_APK, values, "id = ? and version =?", new String[] {
-                    oldapk.id, oldapk.version });
-        } else {
-            db.insert(TABLE_APK, null, values);
-        }
-    }
+	// Update application details in the database, if different to the
+	// previous ones.
+	// 'oldapp' - previous details - i.e. what's in the database.
+	// If null, this app is not in the database at all and
+	// should be added.
+	// 'upapp' - updated details
+	private void updateAppIfDifferent(App oldapp, App upapp) {
+		ContentValues values = new ContentValues();
+		values.put("id", upapp.id);
+		values.put("name", upapp.name);
+		values.put("summary", upapp.summary);
+		values.put("icon", upapp.icon);
+		values.put("description", upapp.description);
+		values.put("license", upapp.license);
+		values.put("webURL", upapp.webURL);
+		values.put("trackerURL", upapp.trackerURL);
+		values.put("sourceURL", upapp.sourceURL);
+		values.put("installedVersion", upapp.installedVersion);
+		values.put("installedVerCode", upapp.installedVerCode);
+		values.put("marketVersion", upapp.marketVersion);
+		values.put("marketVercode", upapp.marketVercode);
+		values.put("hasUpdates", upapp.hasUpdates ? 1 : 0);
+		if (oldapp != null) {
+			db.update(TABLE_APP, values, "id = ?", new String[] { oldapp.id });
+		} else {
+			db.insert(TABLE_APP, null, values);
+		}
+	}
 
-    public void setInstalledVersion(String id, String version, int vercode) {
-        ContentValues values = new ContentValues();
-        values.put("installedVersion", version);
-        values.put("installedVerCode", vercode);
-        db.update(TABLE_APP, values, "id = ?", new String[] { id });
-    }
+	// Update apk details in the database, if different to the
+	// previous ones.
+	// 'oldapk' - previous details - i.e. what's in the database.
+	// If null, this apk is not in the database at all and
+	// should be added.
+	// 'upapk' - updated details
+	private void updateApkIfDifferent(Apk oldapk, Apk upapk) {
+		ContentValues values = new ContentValues();
+		values.put("id", upapk.id);
+		values.put("version", upapk.version);
+		values.put("vercode", upapk.vercode);
+		values.put("server", upapk.server);
+		values.put("hash", upapk.hash);
+		values.put("size", upapk.size);
+		values.put("apkName", upapk.apkName);
+		values.put("apkSource", upapk.apkSource);
+		if (oldapk != null) {
+			db.update(TABLE_APK, values, "id = ? and version =?", new String[] {
+					oldapk.id, oldapk.version });
+		} else {
+			db.insert(TABLE_APK, null, values);
+		}
+	}
 
-    // Get a list of the configured repositories.
-    public Vector<Repo> getRepos() {
-        Vector<Repo> repos = new Vector<Repo>();
-        Cursor c = null;
-        try {
-            c = db.rawQuery("select address, inuse, priority from "
-                    + TABLE_REPO + " order by priority", null);
-            c.moveToFirst();
-            while (!c.isAfterLast()) {
-                Repo repo = new Repo();
-                repo.address = c.getString(0);
-                repo.inuse = (c.getInt(1) == 1);
-                repo.priority = c.getInt(2);
-                repos.add(repo);
-                c.moveToNext();
-            }
-        } catch (Exception e) {
-        } finally {
-            if (c != null) {
-                c.close();
-            }
-        }
-        return repos;
-    }
+	public void setInstalledVersion(String id, String version, int vercode) {
+		ContentValues values = new ContentValues();
+		values.put("installedVersion", version);
+		values.put("installedVerCode", vercode);
+		db.update(TABLE_APP, values, "id = ?", new String[] { id });
+	}
 
-    public void changeServerStatus(String address) {
-        db.rawQuery("update " + TABLE_REPO
-                + " set inuse=1-inuse where address= ?",
-                new String[] { address });
-    }
+	// Get a list of the configured repositories.
+	public Vector<Repo> getRepos() {
+		Vector<Repo> repos = new Vector<Repo>();
+		Cursor c = null;
+		try {
+			c = db.rawQuery("select address, inuse, priority from "
+					+ TABLE_REPO + " order by priority", null);
+			c.moveToFirst();
+			while (!c.isAfterLast()) {
+				Repo repo = new Repo();
+				repo.address = c.getString(0);
+				repo.inuse = (c.getInt(1) == 1);
+				repo.priority = c.getInt(2);
+				repos.add(repo);
+				c.moveToNext();
+			}
+		} catch (Exception e) {
+		} finally {
+			if (c != null) {
+				c.close();
+			}
+		}
+		return repos;
+	}
 
-    public void addServer(String address, int priority) {
-        ContentValues values = new ContentValues();
-        values.put("address", address);
-        values.put("inuse", 1);
-        values.put("priority", priority);
-        db.insert(TABLE_REPO, null, values);
-    }
+	public void changeServerStatus(String address) {
+		db.rawQuery("update " + TABLE_REPO
+				+ " set inuse=1-inuse where address= ?",
+				new String[] { address });
+	}
 
-    public void removeServers(Vector<String> addresses) {
-        for (String address : addresses) {
-            db.delete(TABLE_REPO, "address = ?", new String[] { address });
-        }
-    }
+	public void addServer(String address, int priority) {
+		ContentValues values = new ContentValues();
+		values.put("address", address);
+		values.put("inuse", 1);
+		values.put("priority", priority);
+		db.insert(TABLE_REPO, null, values);
+	}
+
+	public void removeServers(Vector<String> addresses) {
+		for (String address : addresses) {
+			db.delete(TABLE_REPO, "address = ?", new String[] { address });
+		}
+	}
 }
diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java
index d012a7687..46023ed44 100644
--- a/src/org/fdroid/fdroid/RepoXMLHandler.java
+++ b/src/org/fdroid/fdroid/RepoXMLHandler.java
@@ -184,8 +184,7 @@ public class RepoXMLHandler extends DefaultHandler {
         }
     }
 
-    // Returns the number of applications with updates.
-    public static int doUpdates(Context ctx, DB db) {
+    public static void doUpdates(Context ctx, DB db) {
         db.beginUpdate();
         Vector<DB.Repo> repos = db.getRepos();
         for (DB.Repo repo : repos) {
@@ -236,7 +235,7 @@ public class RepoXMLHandler extends DefaultHandler {
 
             }
         }
-        return db.endUpdate();
+        db.endUpdate();
 
     }
 
diff --git a/src/org/fdroid/fdroid/UpdateService.java b/src/org/fdroid/fdroid/UpdateService.java
index a7ce2024c..29e785c2f 100644
--- a/src/org/fdroid/fdroid/UpdateService.java
+++ b/src/org/fdroid/fdroid/UpdateService.java
@@ -35,121 +35,129 @@ import android.util.Log;
 
 public class UpdateService extends Service {
 
-    // Schedule (or cancel schedule for) this service, according to the
-    // current preferences. Should be called a) at boot, or b) if the preference
-    // is changed.
-    // TODO: What if we get upgraded?
-    public static void schedule(Context ctx) {
+	// Schedule (or cancel schedule for) this service, according to the
+	// current preferences. Should be called a) at boot, or b) if the preference
+	// is changed.
+	// TODO: What if we get upgraded?
+	public static void schedule(Context ctx) {
 
-        SharedPreferences prefs = PreferenceManager
-                .getDefaultSharedPreferences(ctx);
-        String sint = prefs.getString("updateInterval", "0");
-        int interval = Integer.parseInt(sint);
+		SharedPreferences prefs = PreferenceManager
+				.getDefaultSharedPreferences(ctx);
+		String sint = prefs.getString("updateInterval", "0");
+		int interval = Integer.parseInt(sint);
 
-        Intent intent = new Intent(ctx, UpdateService.class);
-        PendingIntent pending = PendingIntent.getService(ctx, 0, intent, 0);
+		Intent intent = new Intent(ctx, UpdateService.class);
+		PendingIntent pending = PendingIntent.getService(ctx, 0, intent, 0);
 
-        AlarmManager alarm = (AlarmManager) ctx
-                .getSystemService(Context.ALARM_SERVICE);
-        alarm.cancel(pending);
-        if (interval > 0) {
-            alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
-                    SystemClock.elapsedRealtime() + 5000,
-                    AlarmManager.INTERVAL_HOUR, pending);
-        }
+		AlarmManager alarm = (AlarmManager) ctx
+				.getSystemService(Context.ALARM_SERVICE);
+		alarm.cancel(pending);
+		if (interval > 0) {
+			alarm.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,
+					SystemClock.elapsedRealtime() + 5000,
+					AlarmManager.INTERVAL_HOUR, pending);
+		}
 
-    }
+	}
 
-    // For API levels <5
-    @Override
-    public void onStart(Intent intent, int startId) {
-        handleCommand();
-    }
+	// For API levels <5
+	@Override
+	public void onStart(Intent intent, int startId) {
+		handleCommand();
+	}
 
-    // For API levels >=5
-    @Override
-    public int onStartCommand(Intent intent, int flags, int startId) {
-        handleCommand();
-        return START_REDELIVER_INTENT;
-    }
+	// For API levels >=5
+	@Override
+	public int onStartCommand(Intent intent, int flags, int startId) {
+		handleCommand();
+		return START_REDELIVER_INTENT;
+	}
 
-    private void handleCommand() {
+	private void handleCommand() {
 
-        new Thread() {
-            public void run() {
+		new Thread() {
+			public void run() {
 
-                // If we're in one of our list activities, we don't want
-                // to run an update because the database will be out of
-                // sync with the display.
-                if (((FDroidApp) getApplication()).inActivity != 0)
-                    return;
+				// If we're in one of our list activities, we don't want
+				// to run an update because the database will be out of
+				// sync with the display.
+				if (((FDroidApp) getApplication()).inActivity != 0)
+					return;
 
-                // See if it's time to actually do anything yet...
-                SharedPreferences prefs = PreferenceManager
-                        .getDefaultSharedPreferences(getBaseContext());
-                long lastUpdate = prefs.getLong("lastUpdateCheck", 0);
-                String sint = prefs.getString("updateInterval", "0");
-                int interval = Integer.parseInt(sint);
-                if (interval == 0)
-                    return;
-                if (lastUpdate + (interval * 60 * 60) > System
-                        .currentTimeMillis())
-                    return;
+				// See if it's time to actually do anything yet...
+				SharedPreferences prefs = PreferenceManager
+						.getDefaultSharedPreferences(getBaseContext());
+				long lastUpdate = prefs.getLong("lastUpdateCheck", 0);
+				String sint = prefs.getString("updateInterval", "0");
+				int interval = Integer.parseInt(sint);
+				if (interval == 0)
+					return;
+				if (lastUpdate + (interval * 60 * 60) > System
+						.currentTimeMillis())
+					return;
 
-                // Make sure we have a connection...
-                ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
-                if (netstate.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED
-                        && netstate.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED)
-                    return;
+				// Make sure we have a connection...
+				ConnectivityManager netstate = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+				if (netstate.getNetworkInfo(1).getState() != NetworkInfo.State.CONNECTED
+						&& netstate.getNetworkInfo(0).getState() != NetworkInfo.State.CONNECTED)
+					return;
 
-                // Do the update...
-                DB db = null;
-                try {
-                    db = new DB(getBaseContext());
-                    int updateNum = RepoXMLHandler.doUpdates(getBaseContext(),
-                            db);
+				// Do the update...
+				DB db = null;
+				try {
+					db = new DB(getBaseContext());
+					boolean notify = prefs.getBoolean("updateNotify", false);
 
-                    if (updateNum != 0) {
-                        // We have updates.
-                        if (prefs.getBoolean("updateNotify", false)) {
-                            // And the user wants to know.
-                            NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
-                            Notification notification = new Notification(
-                                    R.drawable.icon,
-                                    "FDroid Updates Available", System
-                                            .currentTimeMillis());
-                            Context context = getApplicationContext();
-                            CharSequence contentTitle = "FDroid";
-                            CharSequence contentText = "Updates are available.";
-                            Intent notificationIntent = new Intent(
-                                    UpdateService.this, FDroid.class);
-                            PendingIntent contentIntent = PendingIntent
-                                    .getActivity(UpdateService.this, 0,
-                                            notificationIntent, 0);
-                            notification.setLatestEventInfo(context,
-                                    contentTitle, contentText, contentIntent);
-                            notification.flags |= Notification.FLAG_AUTO_CANCEL;
-                            n.notify(1, notification);
-                        }
-                    }
+					// Get the number of updates available before we
+					// start, so we can notify if there are new ones.
+					// (But avoid doing it if the user doesn't want
+					// notifications, since it may be time consuming)
+					int prevUpdates = 0;
+					if (notify)
+						prevUpdates = db.getNumUpdates();
 
-                } catch (Exception e) {
-                    Log.d("FDroid", "Exception during handleCommand() - "
-                            + e.getMessage());
-                } finally {
-                    if (db != null)
-                        db.close();
-                    stopSelf();
-                }
+					RepoXMLHandler.doUpdates(getBaseContext(), db);
 
-            }
-        }.start();
+					if (notify) {
+						if (db.getNumUpdates() > prevUpdates) {
+							// And the user wants to know.
+							NotificationManager n = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+							Notification notification = new Notification(
+									R.drawable.icon,
+									"FDroid Updates Available", System
+											.currentTimeMillis());
+							Context context = getApplicationContext();
+							CharSequence contentTitle = "FDroid";
+							CharSequence contentText = "Updates are available.";
+							Intent notificationIntent = new Intent(
+									UpdateService.this, FDroid.class);
+							PendingIntent contentIntent = PendingIntent
+									.getActivity(UpdateService.this, 0,
+											notificationIntent, 0);
+							notification.setLatestEventInfo(context,
+									contentTitle, contentText, contentIntent);
+							notification.flags |= Notification.FLAG_AUTO_CANCEL;
+							n.notify(1, notification);
+						}
+					}
 
-    }
+				} catch (Exception e) {
+					Log.d("FDroid", "Exception during handleCommand() - "
+							+ e.getMessage());
+				} finally {
+					if (db != null)
+						db.close();
+					stopSelf();
+				}
 
-    @Override
-    public IBinder onBind(Intent intent) {
-        return null;
-    }
+			}
+		}.start();
+
+	}
+
+	@Override
+	public IBinder onBind(Intent intent) {
+		return null;
+	}
 
 }