Index: java/HTTPFileDownloader/.classpath
===================================================================
--- java/HTTPFileDownloader/.classpath	(revision 741)
+++ java/HTTPFileDownloader/.classpath	(revision 741)
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
Index: java/HTTPFileDownloader/.project
===================================================================
--- java/HTTPFileDownloader/.project	(revision 741)
+++ java/HTTPFileDownloader/.project	(revision 741)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>HTTPFileDownloader</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
Index: java/HTTPFileDownloader/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- java/HTTPFileDownloader/.settings/org.eclipse.jdt.core.prefs	(revision 741)
+++ java/HTTPFileDownloader/.settings/org.eclipse.jdt.core.prefs	(revision 741)
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
Index: java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloadListener.java
===================================================================
--- java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloadListener.java	(revision 741)
+++ java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloadListener.java	(revision 741)
@@ -0,0 +1,24 @@
+package net.oni2.httpfiledownloader;
+
+/**
+ * Interface for listeners to status updates during file download
+ * 
+ * @author Christian Illy
+ */
+public interface FileDownloadListener {
+
+	/**
+	 * Called after checking out / updating a single file
+	 * 
+	 * @param source
+	 *            Source of event
+	 * @param state
+	 *            Current state of downloader
+	 * @param done
+	 *            Bytes done
+	 * @param total
+	 *            Total bytes for the download
+	 */
+	public void statusUpdate(FileDownloader source,
+			FileDownloader.EState state, int done, int total);
+}
Index: java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloader.java
===================================================================
--- java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloader.java	(revision 741)
+++ java/HTTPFileDownloader/src/net/oni2/httpfiledownloader/FileDownloader.java	(revision 741)
@@ -0,0 +1,260 @@
+package net.oni2.httpfiledownloader;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.HashSet;
+
+/**
+ * @author Christian Illy
+ */
+public class FileDownloader implements Runnable {
+	/**
+	 * @author Christian Illy
+	 */
+	public enum EState {
+		/**
+		 * Downloader initialized but not started
+		 */
+		INIT,
+		/**
+		 * Download running
+		 */
+		RUNNING,
+		/**
+		 * Download suspended
+		 */
+		PAUSED,
+		/**
+		 * Download interrupted
+		 */
+		INTERRUPTED,
+		/**
+		 * Download finished successfully
+		 */
+		FINISHED,
+		/**
+		 * Aborted because of an error
+		 */
+		ERROR
+	};
+
+	private HashSet<FileDownloadListener> listeners = new HashSet<FileDownloadListener>();
+	private Thread t = null;
+	private URL url = null;
+	private File target = null;
+	private int fileLength = Integer.MAX_VALUE;
+	private int downloaded = 0;
+
+	private EState state = EState.INIT;
+
+	/**
+	 * @param url
+	 *            URL of file to download
+	 * @param target
+	 *            Path of target file to save to
+	 * @throws IOException
+	 *             If url could not be opened
+	 */
+	public FileDownloader(String url, File target) throws IOException {
+		this.url = new URL(url);
+		this.target = target;
+	}
+
+	/**
+	 * @param listener
+	 *            Listener to add
+	 */
+	public void addListener(FileDownloadListener listener) {
+		listeners.add(listener);
+	}
+
+	/**
+	 * @param listener
+	 *            Listener to remove
+	 */
+	public void removeListener(FileDownloadListener listener) {
+		listeners.remove(listener);
+	}
+
+	/**
+	 * Start the download process
+	 */
+	public synchronized void start() {
+		if (t == null) {
+			t = new Thread(this);
+			t.start();
+			state = EState.RUNNING;
+		}
+	}
+
+	/**
+	 * @param suspend
+	 *            Suspend or resume
+	 */
+	public synchronized void suspend(boolean suspend) {
+		if ((state == EState.RUNNING) || (state == EState.PAUSED)) {
+			if (suspend)
+				state = EState.PAUSED;
+			else
+				state = EState.RUNNING;
+			updateStatus(downloaded, fileLength);
+		}
+	}
+
+	/**
+	 * Stop (abort) download
+	 */
+	public synchronized void stop() {
+		if (state != EState.FINISHED) {
+			state = EState.INTERRUPTED;
+			if (t != null) {
+				try {
+					t.join();
+				} catch (InterruptedException e) {
+					e.printStackTrace();
+				}
+				t = null;
+			}
+			updateStatus(0, 1);
+			if (target.exists())
+				target.delete();
+		}
+	}
+
+	/**
+	 * @return current state
+	 */
+	public EState getState() {
+		return state;
+	}
+
+	private synchronized void updateStatus(int current, int total) {
+		downloaded = current;
+		for (FileDownloadListener l : listeners) {
+			l.statusUpdate(this, state, current, total);
+		}
+	}
+
+	@Override
+	public void run() {
+		int downloaded = 0;
+		String strLastModified = null;
+		String strEtag = null;
+		RandomAccessFile outFile = null;
+		try {
+			outFile = new RandomAccessFile(target, "rw");
+		} catch (FileNotFoundException e1) {
+			e1.printStackTrace();
+			state = EState.ERROR;
+			updateStatus(downloaded, fileLength);
+			return;
+		}
+
+		try {
+			while (downloaded < fileLength) {
+				switch (state) {
+					case ERROR:
+						updateStatus(downloaded, fileLength);
+						return;
+					case PAUSED:
+						try {
+							Thread.sleep(100);
+						} catch (InterruptedException e) {
+							e.printStackTrace();
+						}
+						break;
+					case INTERRUPTED:
+						return;
+					case RUNNING:
+						BufferedInputStream input = null;
+						try {
+							URLConnection connection = url.openConnection();
+							connection.setRequestProperty("Cache-Control", "no-cache");
+							if (downloaded == 0) {
+								connection.connect();
+								strLastModified = connection
+										.getHeaderField("Last-Modified");
+								strEtag = connection.getHeaderField("ETag");
+								fileLength = connection.getContentLength();
+							} else {
+								connection.setRequestProperty("Range", "bytes="
+										+ downloaded + "-");
+								if (strEtag != null)
+									connection.setRequestProperty("If-Range",
+											strEtag);
+								else
+									connection.setRequestProperty("If-Range",
+											strLastModified);
+								connection.connect();
+							}
+
+							// Setup streams and buffers.
+							input = new BufferedInputStream(
+									connection.getInputStream(), 8192);
+							if (downloaded > 0)
+								outFile.seek(downloaded);
+							byte data[] = new byte[1024];
+
+							// Download file.
+							int dataRead = 0;
+							int i = 0;
+							while (((dataRead = input.read(data, 0, 1024)) != -1)
+									&& (state == EState.RUNNING)) {
+								outFile.write(data, 0, dataRead);
+								downloaded += dataRead;
+								if (downloaded >= fileLength)
+									break;
+
+								i++;
+								if ((i % 50) == 0)
+									updateStatus(downloaded, fileLength);
+							}
+							input.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+							try {
+								if (input != null)
+									input.close();
+							} catch (IOException e2) {
+								e2.printStackTrace();
+							}
+						}
+						break;
+					default:
+						break;
+				}
+			}
+		} finally {
+			try {
+				// Close streams.
+				outFile.close();
+			} catch (IOException e) {
+				e.printStackTrace();
+			}
+		}
+
+		state = EState.FINISHED;
+		updateStatus(downloaded, fileLength);
+	}
+
+	/**
+	 * @return the target
+	 */
+	public File getTarget() {
+		return target;
+	}
+
+	/**
+	 * @return the downloaded size
+	 */
+	public int getDownloaded() {
+		return downloaded;
+	}
+
+}
Index: java/installer2/.classpath
===================================================================
--- java/installer2/.classpath	(revision 740)
+++ java/installer2/.classpath	(revision 741)
@@ -25,4 +25,5 @@
 	<classpathentry combineaccessrules="false" kind="src" path="/SVNAccess"/>
 	<classpathentry kind="lib" path="/_ThirdPartyLibs/NaturalOrderComparator.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/HTTPFileDownloader"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
Index: java/installer2/src/net/oni2/aeinstaller/DepotPackageCheck.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/DepotPackageCheck.java	(revision 740)
+++ java/installer2/src/net/oni2/aeinstaller/DepotPackageCheck.java	(revision 741)
@@ -23,5 +23,4 @@
 		System.out.println("\nReading done");
 		System.out.println();
-		DepotManager.getInstance().printStats();
 
 		System.out.println();
Index: java/installer2/src/net/oni2/aeinstaller/backend/WinRegistry.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/WinRegistry.java	(revision 740)
+++ 	(revision )
@@ -1,502 +1,0 @@
-package net.oni2.aeinstaller.backend;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.prefs.Preferences;
-
-/**
- * @author Unknown
- */
-public class WinRegistry {
-	/**
-	 * Constant for accessing HKCU
-	 */
-	public static final int HKEY_CURRENT_USER = 0x80000001;
-	/**
-	 * Constant for accessing HKLM
-	 */
-	public static final int HKEY_LOCAL_MACHINE = 0x80000002;
-	/**
-	 * Constant for successful accesses
-	 */
-	public static final int REG_SUCCESS = 0;
-	/**
-	 * Constant for not found
-	 */
-	public static final int REG_NOTFOUND = 2;
-	/**
-	 * Constant for access denied
-	 */
-	public static final int REG_ACCESSDENIED = 5;
-
-	/**
-	 * Access 32bit registry view when running as 64bit application
-	 */
-	public static final int KEY_WOW64_32KEY = 0x0200;
-	/**
-	 * Access 64bit registry view when running as 32bit application
-	 */
-	public static final int KEY_WOW64_64KEY = 0x0100;
-
-	private static final int KEY_ALL_ACCESS = 0xf003f;
-	private static final int KEY_READ = 0x20019;
-	private static Preferences userRoot = Preferences.userRoot();
-	private static Preferences systemRoot = Preferences.systemRoot();
-	private static Class<? extends Preferences> userClass = userRoot.getClass();
-	private static Method regOpenKey = null;
-	private static Method regCloseKey = null;
-	private static Method regQueryValueEx = null;
-	private static Method regEnumValue = null;
-	private static Method regQueryInfoKey = null;
-	private static Method regEnumKeyEx = null;
-	private static Method regCreateKeyEx = null;
-	private static Method regSetValueEx = null;
-	private static Method regDeleteKey = null;
-	private static Method regDeleteValue = null;
-
-	private static boolean usable = false;
-
-	static {
-		try {
-			regOpenKey = userClass.getDeclaredMethod("WindowsRegOpenKey",
-					new Class[] { int.class, byte[].class, int.class });
-			regOpenKey.setAccessible(true);
-			regCloseKey = userClass.getDeclaredMethod("WindowsRegCloseKey",
-					new Class[] { int.class });
-			regCloseKey.setAccessible(true);
-			regQueryValueEx = userClass.getDeclaredMethod(
-					"WindowsRegQueryValueEx", new Class[] { int.class,
-							byte[].class });
-			regQueryValueEx.setAccessible(true);
-			regEnumValue = userClass.getDeclaredMethod("WindowsRegEnumValue",
-					new Class[] { int.class, int.class, int.class });
-			regEnumValue.setAccessible(true);
-			regQueryInfoKey = userClass.getDeclaredMethod(
-					"WindowsRegQueryInfoKey1", new Class[] { int.class });
-			regQueryInfoKey.setAccessible(true);
-			regEnumKeyEx = userClass.getDeclaredMethod("WindowsRegEnumKeyEx",
-					new Class[] { int.class, int.class, int.class });
-			regEnumKeyEx.setAccessible(true);
-			regCreateKeyEx = userClass.getDeclaredMethod(
-					"WindowsRegCreateKeyEx", new Class[] { int.class,
-							byte[].class });
-			regCreateKeyEx.setAccessible(true);
-			regSetValueEx = userClass.getDeclaredMethod("WindowsRegSetValueEx",
-					new Class[] { int.class, byte[].class, byte[].class });
-			regSetValueEx.setAccessible(true);
-			regDeleteValue = userClass.getDeclaredMethod(
-					"WindowsRegDeleteValue", new Class[] { int.class,
-							byte[].class });
-			regDeleteValue.setAccessible(true);
-			regDeleteKey = userClass.getDeclaredMethod("WindowsRegDeleteKey",
-					new Class[] { int.class, byte[].class });
-			regDeleteKey.setAccessible(true);
-			usable = true;
-		} catch (Exception e) {
-			// e.printStackTrace();
-		}
-	}
-
-	private WinRegistry() {
-	}
-
-	/**
-	 * Read a value from key and value name
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @param valueName
-	 *            Name of value to read
-	 * @param wow64
-	 *            0 for standard registry access (32-bits for 32-bit app,
-	 *            64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
-	 *            32-bit registry view, or KEY_WOW64_64KEY to force access to
-	 *            64-bit registry view
-	 * @return the value
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static String readString(int hkey, String key, String valueName,
-			int wow64) throws Exception, IllegalArgumentException,
-			IllegalAccessException, InvocationTargetException {
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			return readString(systemRoot, hkey, key, valueName, wow64);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			return readString(userRoot, hkey, key, valueName, wow64);
-		} else {
-			throw new IllegalArgumentException("hkey=" + hkey);
-		}
-	}
-
-	/**
-	 * Read value(s) and value name(s) form given key
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @param wow64
-	 *            0 for standard registry access (32-bits for 32-bit app,
-	 *            64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
-	 *            32-bit registry view, or KEY_WOW64_64KEY to force access to
-	 *            64-bit registry view
-	 * @return the value name(s) plus the value(s)
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static Map<String, String> readStringValues(int hkey, String key,
-			int wow64) throws Exception, IllegalArgumentException,
-			IllegalAccessException, InvocationTargetException {
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			return readStringValues(systemRoot, hkey, key, wow64);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			return readStringValues(userRoot, hkey, key, wow64);
-		} else {
-			throw new IllegalArgumentException("hkey=" + hkey);
-		}
-	}
-
-	/**
-	 * Read the value name(s) from a given key
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @param wow64
-	 *            0 for standard registry access (32-bits for 32-bit app,
-	 *            64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
-	 *            32-bit registry view, or KEY_WOW64_64KEY to force access to
-	 *            64-bit registry view
-	 * @return the value name(s)
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static List<String> readStringSubKeys(int hkey, String key, int wow64)
-			throws Exception, IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			return readStringSubKeys(systemRoot, hkey, key, wow64);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			return readStringSubKeys(userRoot, hkey, key, wow64);
-		} else {
-			throw new IllegalArgumentException("hkey=" + hkey);
-		}
-	}
-
-	/**
-	 * Create a key
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static void createKey(int hkey, String key) throws Exception,
-			IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		int[] ret;
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			ret = createKey(systemRoot, hkey, key);
-			regCloseKey
-					.invoke(systemRoot, new Object[] { new Integer(ret[0]) });
-		} else if (hkey == HKEY_CURRENT_USER) {
-			ret = createKey(userRoot, hkey, key);
-			regCloseKey.invoke(userRoot, new Object[] { new Integer(ret[0]) });
-		} else {
-			throw new IllegalArgumentException("hkey=" + hkey);
-		}
-		if (ret[1] != REG_SUCCESS) {
-			throw new IllegalArgumentException("rc=" + ret[1] + "  key=" + key);
-		}
-	}
-
-	/**
-	 * Write a value in a given key/value name
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @param valueName
-	 *            Name of value to write to
-	 * @param value
-	 *            String to write
-	 * @param wow64
-	 *            0 for standard registry access (32-bits for 32-bit app,
-	 *            64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
-	 *            32-bit registry view, or KEY_WOW64_64KEY to force access to
-	 *            64-bit registry view
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static void writeStringValue(int hkey, String key, String valueName,
-			String value, int wow64) throws Exception,
-			IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			writeStringValue(systemRoot, hkey, key, valueName, value, wow64);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			writeStringValue(userRoot, hkey, key, valueName, value, wow64);
-		} else {
-			throw new IllegalArgumentException("hkey=" + hkey);
-		}
-	}
-
-	/**
-	 * Delete a given key
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to delete
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static void deleteKey(int hkey, String key) throws Exception,
-			IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		int rc = -1;
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			rc = deleteKey(systemRoot, hkey, key);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			rc = deleteKey(userRoot, hkey, key);
-		}
-		if (rc != REG_SUCCESS) {
-			throw new IllegalArgumentException("rc=" + rc + "  key=" + key);
-		}
-	}
-
-	/**
-	 * delete a value from a given key/value name
-	 * 
-	 * @param hkey
-	 *            HKEY_CURRENT_USER/HKEY_LOCAL_MACHINE
-	 * @param key
-	 *            Key to access
-	 * @param value
-	 *            Name of value to delete
-	 * @param wow64
-	 *            0 for standard registry access (32-bits for 32-bit app,
-	 *            64-bits for 64-bits app) or KEY_WOW64_32KEY to force access to
-	 *            32-bit registry view, or KEY_WOW64_64KEY to force access to
-	 *            64-bit registry view
-	 * @throws Exception
-	 *             If registry access impossible
-	 * @throws IllegalArgumentException
-	 *             On illegal arguments
-	 * @throws IllegalAccessException
-	 *             On illegal access
-	 * @throws InvocationTargetException
-	 *             On reflection problems
-	 */
-	public static void deleteValue(int hkey, String key, String value, int wow64)
-			throws Exception, IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		if (!usable)
-			throw new Exception(
-					"Registry access not supported (not a Windows OS?).");
-		int rc = -1;
-		if (hkey == HKEY_LOCAL_MACHINE) {
-			rc = deleteValue(systemRoot, hkey, key, value, wow64);
-		} else if (hkey == HKEY_CURRENT_USER) {
-			rc = deleteValue(userRoot, hkey, key, value, wow64);
-		}
-		if (rc != REG_SUCCESS) {
-			throw new IllegalArgumentException("rc=" + rc + "  key=" + key
-					+ "  value=" + value);
-		}
-	}
-
-	// ========================================================================
-	private static int deleteValue(Preferences root, int hkey, String key,
-			String value, int wow64) throws IllegalArgumentException,
-			IllegalAccessException, InvocationTargetException {
-		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
-				new Integer(hkey), toCstr(key),
-				new Integer(KEY_ALL_ACCESS | wow64) });
-		if (handles[1] != REG_SUCCESS) {
-			return handles[1]; // can be REG_NOTFOUND, REG_ACCESSDENIED
-		}
-		int rc = ((Integer) regDeleteValue.invoke(root, new Object[] {
-				new Integer(handles[0]), toCstr(value) })).intValue();
-		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
-		return rc;
-	}
-
-	// ========================================================================
-	private static int deleteKey(Preferences root, int hkey, String key)
-			throws IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		int rc = ((Integer) regDeleteKey.invoke(root, new Object[] {
-				new Integer(hkey), toCstr(key) })).intValue();
-		return rc; // can REG_NOTFOUND, REG_ACCESSDENIED, REG_SUCCESS
-	}
-
-	// ========================================================================
-	private static String readString(Preferences root, int hkey, String key,
-			String value, int wow64) throws IllegalArgumentException,
-			IllegalAccessException, InvocationTargetException {
-		int[] handles = (int[]) regOpenKey
-				.invoke(root, new Object[] { new Integer(hkey), toCstr(key),
-						new Integer(KEY_READ | wow64) });
-		if (handles[1] != REG_SUCCESS) {
-			return null;
-		}
-		byte[] valb = (byte[]) regQueryValueEx.invoke(root, new Object[] {
-				new Integer(handles[0]), toCstr(value) });
-		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
-		return (valb != null ? new String(valb).trim() : null);
-	}
-
-	// ========================================================================
-	private static Map<String, String> readStringValues(Preferences root,
-			int hkey, String key, int wow64) throws Exception,
-			IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		HashMap<String, String> results = new HashMap<String, String>();
-		int[] handles = (int[]) regOpenKey
-				.invoke(root, new Object[] { new Integer(hkey), toCstr(key),
-						new Integer(KEY_READ | wow64) });
-		if (handles[1] != REG_SUCCESS) {
-			return null;
-		}
-		int[] info = (int[]) regQueryInfoKey.invoke(root,
-				new Object[] { new Integer(handles[0]) });
-
-		int count = info[2]; // count
-		int maxlen = info[4]; // value length max
-		for (int index = 0; index < count; index++) {
-			byte[] name = (byte[]) regEnumValue.invoke(root, new Object[] {
-					new Integer(handles[0]), new Integer(index),
-					new Integer(maxlen + 1) });
-			String value = readString(hkey, key, new String(name), wow64);
-			results.put(new String(name).trim(), value);
-		}
-		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
-		return results;
-	}
-
-	// ========================================================================
-	private static List<String> readStringSubKeys(Preferences root, int hkey,
-			String key, int wow64) throws IllegalArgumentException,
-			IllegalAccessException, InvocationTargetException {
-		List<String> results = new ArrayList<String>();
-		int[] handles = (int[]) regOpenKey
-				.invoke(root, new Object[] { new Integer(hkey), toCstr(key),
-						new Integer(KEY_READ | wow64) });
-		if (handles[1] != REG_SUCCESS) {
-			return null;
-		}
-		int[] info = (int[]) regQueryInfoKey.invoke(root,
-				new Object[] { new Integer(handles[0]) });
-
-		int count = info[0]; // Fix: info[2] was being used here with wrong
-								// results. Suggested by davenpcj, confirmed by
-								// Petrucio
-		int maxlen = info[3]; // value length max
-		for (int index = 0; index < count; index++) {
-			byte[] name = (byte[]) regEnumKeyEx.invoke(root, new Object[] {
-					new Integer(handles[0]), new Integer(index),
-					new Integer(maxlen + 1) });
-			results.add(new String(name).trim());
-		}
-		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
-		return results;
-	}
-
-	// ========================================================================
-	private static int[] createKey(Preferences root, int hkey, String key)
-			throws IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		return (int[]) regCreateKeyEx.invoke(root, new Object[] {
-				new Integer(hkey), toCstr(key) });
-	}
-
-	// ========================================================================
-	private static void writeStringValue(Preferences root, int hkey,
-			String key, String valueName, String value, int wow64)
-			throws IllegalArgumentException, IllegalAccessException,
-			InvocationTargetException {
-		int[] handles = (int[]) regOpenKey.invoke(root, new Object[] {
-				new Integer(hkey), toCstr(key),
-				new Integer(KEY_ALL_ACCESS | wow64) });
-		regSetValueEx.invoke(root, new Object[] { new Integer(handles[0]),
-				toCstr(valueName), toCstr(value) });
-		regCloseKey.invoke(root, new Object[] { new Integer(handles[0]) });
-	}
-
-	// ========================================================================
-	// utility
-	private static byte[] toCstr(String str) {
-		byte[] result = new byte[str.length() + 1];
-
-		for (int i = 0; i < str.length(); i++) {
-			result[i] = (byte) str.charAt(i);
-		}
-		result[str.length()] = 0;
-		return result;
-	}
-}
Index: java/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java	(revision 740)
+++ java/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java	(revision 741)
@@ -24,5 +24,5 @@
 import net.oni2.aeinstaller.backend.depot.model.TaxonomyTerm;
 import net.oni2.aeinstaller.backend.depot.model.TaxonomyVocabulary;
-import net.oni2.aeinstaller.backend.network.FileDownloader;
+import net.oni2.httpfiledownloader.FileDownloader;
 
 import org.apache.http.HttpResponse;
@@ -73,5 +73,5 @@
 					+ (new Date().getTime() / 1000), zipName);
 			fd.start();
-			while (fd.getState() != net.oni2.aeinstaller.backend.network.FileDownloader.EState.FINISHED) {
+			while (fd.getState() != FileDownloader.EState.FINISHED) {
 				Thread.sleep(50);
 			}
@@ -318,16 +318,4 @@
 	}
 
-	/**
-	 * Print stats about nodes and files
-	 */
-	public void printStats() {
-		System.out.println("Nodes by type:");
-		for (String t : nodesByType.keySet()) {
-			System.out.println("  " + t + ": " + nodesByType.get(t).size());
-		}
-
-		System.out.println("Files: " + files.size());
-	}
-
 	private static XStream getXStream() {
 		XStream xs = new XStream(new StaxDriver());
Index: java/installer2/src/net/oni2/aeinstaller/backend/packages/download/ModDownload.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/packages/download/ModDownload.java	(revision 740)
+++ java/installer2/src/net/oni2/aeinstaller/backend/packages/download/ModDownload.java	(revision 741)
@@ -8,7 +8,7 @@
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.packages.Package;
-import net.oni2.aeinstaller.backend.network.FileDownloadListener;
-import net.oni2.aeinstaller.backend.network.FileDownloader;
-import net.oni2.aeinstaller.backend.network.FileDownloader.EState;
+import net.oni2.httpfiledownloader.FileDownloadListener;
+import net.oni2.httpfiledownloader.FileDownloader;
+import net.oni2.httpfiledownloader.FileDownloader.EState;
 import net.oni2.aeinstaller.backend.packages.unpack.UnpackListener;
 import net.oni2.aeinstaller.backend.packages.unpack.Unpacker;
Index: java/installer2/src/net/oni2/aeinstaller/gui/about/AboutDialog.properties
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/gui/about/AboutDialog.properties	(revision 740)
+++ java/installer2/src/net/oni2/aeinstaller/gui/about/AboutDialog.properties	(revision 741)
@@ -5,6 +5,6 @@
 
 panAE=AE Credits:
-AENames=<html>Alloc:<br>Geyser:<br>Gumby:<br>Iritscen:<br>Loser:<br>Neo:<br>Paradox:<br>RossyMiles:<br>s10k:<br>Sfeli:<br>SSG:</html>
-AEWork=<html>AE Installer 2<br>Original creator of the Edition<br>Modular AE framework, AE Installer 1<br>Project management, Mac support<br>Documenting Oni's game data<br>OniSplit, documenting Oni<br>Documenting Oni's game data<br>Daodan DLL port to C<br>xmlTools<br>Original Daodan DLL<br>Documenting Oni's game data</html>
+AENames=<html>Alloc:<br>Geyser:<br>Gumby:<br>Iritscen:<br>Loser:<br>Neo:<br>Paradox:<br>RossyMiles:<br>s10k:<br>Samer:<br>Sfeli:<br>SSG:</html>
+AEWork=<html>AE Installer 2<br>Original creator of the Edition<br>Modular AE framework, AE Installer 1<br>Project management, Mac support<br>Documenting Oni's game data<br>OniSplit, documenting Oni<br>Documenting Oni's game data<br>Daodan DLL port to C<br>xmlTools<br>Testing and package support<br>Original Daodan DLL<br>Documenting Oni's game data</html>
 
 panLinks=Links:
