Index: AE/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties
===================================================================
--- AE/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties	(revision 671)
+++ AE/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties	(revision 672)
@@ -82,2 +82,8 @@
 
 doUpdate.title=Aktualisiere Pakete
+
+jreNotFound.text=Dieses Tool benötigt eine JRE aber es wurde keine gefunden.
+jreNotFound.title=JRE nicht gefunden
+
+dotNetNotFound.text=Dieses Tool benötigt eine .NET Runtime aber es wurde keine gefunden.
+dotNetNotFound.title=.NET Runtime nicht gefunden
Index: AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 672)
@@ -1,2 +1,2 @@
 appname=AE Installer 2
-appversion=0.99p
+appversion=0.99q
Index: AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java	(revision 672)
@@ -21,4 +21,5 @@
 import javax.swing.UIManager.LookAndFeelInfo;
 
+import net.oni2.aeinstaller.backend.DotNet;
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.Settings;
@@ -171,5 +172,5 @@
 		System.out.println("Platform:  " + Settings.getPlatform());
 		System.out.println("Architect: " + Settings.getArchitecture());
-		System.out.println(".NET:      " + OniSplit.isDotNETInstalled());
+		System.out.println(".NET:      " + DotNet.isInstalled());
 		System.out.println("OniSplit:  " + OniSplit.isOniSplitInstalled());
 		System.out.println("Globalized:" + Installer.isEditionInitialized());
@@ -185,5 +186,5 @@
 		System.out.println();
 
-		if (!OniSplit.isDotNETInstalled()) {
+		if (!DotNet.isInstalled()) {
 			HTMLLinkLabel hll = new HTMLLinkLabel();
 			String dlUrl = "";
Index: AE/installer2/src/net/oni2/aeinstaller/backend/DotNet.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/DotNet.java	(revision 672)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/DotNet.java	(revision 672)
@@ -0,0 +1,77 @@
+package net.oni2.aeinstaller.backend;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Map;
+import java.util.Vector;
+
+import net.oni2.aeinstaller.backend.Settings.Architecture;
+import net.oni2.aeinstaller.backend.Settings.Platform;
+
+/**
+ * @author Christian Illy
+ */
+public class DotNet {
+
+	/**
+	 * @return is a .NET implementation installed?
+	 */
+	public static boolean isInstalled() {
+		switch (Settings.getPlatform()) {
+			case WIN:
+				try {
+					int view = WinRegistry.KEY_WOW64_32KEY;
+					if (Settings.getArchitecture() == Architecture.AMD64)
+						view = WinRegistry.KEY_WOW64_64KEY;
+
+					Map<String, String> m = WinRegistry
+							.readStringValues(
+									WinRegistry.HKEY_LOCAL_MACHINE,
+									"Software\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727",
+									view);
+					return m != null;
+				} catch (IllegalArgumentException e) {
+					e.printStackTrace();
+				} catch (IllegalAccessException e) {
+					e.printStackTrace();
+				} catch (InvocationTargetException e) {
+					e.printStackTrace();
+				} catch (Exception e) {
+					if (!e.getMessage()
+							.equals("Registry access not supported (not a Windows OS?)."))
+						e.printStackTrace();
+				}
+				return false;
+			case MACOS:
+			case LINUX:
+				Vector<String> cmd = new Vector<String>();
+				cmd.add("which");
+				cmd.add("mono");
+				Vector<String> res = null;
+				try {
+					res = AppExecution.executeAndWait(cmd);
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+				if (res != null) {
+					if (res.get(0).startsWith("/")
+							&& res.get(0).endsWith("mono")) {
+						return true;
+					}
+				}
+				return false;
+			default:
+				return false;
+		}
+	}
+
+	/**
+	 * @return Get the .Net runtime executable name
+	 */
+	public static String getRuntimeExe() {
+		if (Settings.getPlatform() != Platform.WIN)
+			return "mono";
+		return "";
+	}
+
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/ToolLauncher.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/ToolLauncher.java	(revision 672)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/ToolLauncher.java	(revision 672)
@@ -0,0 +1,53 @@
+package net.oni2.aeinstaller.backend;
+
+import java.io.File;
+import java.util.Vector;
+
+import net.oni2.aeinstaller.backend.Settings.Platform;
+import net.oni2.aeinstaller.backend.packages.Package;
+
+/**
+ * @author Christian Illy
+ */
+public class ToolLauncher {
+	/**
+	 * @param p
+	 *            Package of tool to launch
+	 * @throws Exception
+	 *             If a required runtime is not found
+	 */
+	public static void launch(Package p) throws Exception {
+		File exe = p.getExeFile();
+
+		Vector<String> params = new Vector<String>();
+		switch (p.getExeType()) {
+			case OSBINARY:
+				break;
+			case DOTNET:
+				if (!DotNet.isInstalled())
+					throw new Exception(".NET not found");
+				if (Settings.getPlatform() != Platform.WIN) {
+					params.add(DotNet.getRuntimeExe());
+				}
+				break;
+			case JAR:
+				File jre = null;
+				if (Settings.getPlatform() == Platform.WIN)
+					jre = new File(System.getProperties().getProperty(
+							"java.home"), "bin/javaw.exe");
+				else
+					jre = new File(System.getProperties().getProperty(
+							"java.home"), "bin/java");
+				if (!jre.exists())
+					throw new Exception("JRE not found");
+				params.add(jre.getPath());
+				params.add("-jar");
+				break;
+		}
+		params.add(exe.getPath());
+
+		File wd = p.getWorkingDir();
+
+		AppExecution.execute(params, wd);
+	}
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/depot/DepotManager.java	(revision 672)
@@ -275,6 +275,12 @@
 				NodeMod nm = (NodeMod) n;
 				if (nm.getInstallMethod().getName()
-						.equalsIgnoreCase(instMethName))
-					result.add(nm);
+						.equalsIgnoreCase(instMethName)) {
+					try {
+						nm.getPackageNumber();
+						result.add(nm);
+					} catch (NumberFormatException e) {
+						System.err.println("Node " + nm.getNid() + " does not have a package number!!!");
+					}
+				}
 			}
 		}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java	(revision 672)
@@ -3,14 +3,11 @@
 import java.io.File;
 import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Map;
 import java.util.Vector;
 
+import net.oni2.aeinstaller.backend.DotNet;
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.AppExecution;
 import net.oni2.aeinstaller.backend.Settings;
-import net.oni2.aeinstaller.backend.Settings.Architecture;
 import net.oni2.aeinstaller.backend.Settings.Platform;
-import net.oni2.aeinstaller.backend.WinRegistry;
 
 /**
@@ -18,56 +15,4 @@
  */
 public class OniSplit {
-
-	/**
-	 * @return is a .NET implementation installed?
-	 */
-	public static boolean isDotNETInstalled() {
-		switch (Settings.getPlatform()) {
-			case WIN:
-				try {
-					int view = WinRegistry.KEY_WOW64_32KEY;
-					if (Settings.getArchitecture() == Architecture.AMD64)
-						view = WinRegistry.KEY_WOW64_64KEY;
-
-					Map<String, String> m = WinRegistry
-							.readStringValues(
-									WinRegistry.HKEY_LOCAL_MACHINE,
-									"Software\\Microsoft\\NET Framework Setup\\NDP\\v2.0.50727",
-									view);
-					return m != null;
-				} catch (IllegalArgumentException e) {
-					e.printStackTrace();
-				} catch (IllegalAccessException e) {
-					e.printStackTrace();
-				} catch (InvocationTargetException e) {
-					e.printStackTrace();
-				} catch (Exception e) {
-					if (!e.getMessage()
-							.equals("Registry access not supported (not a Windows OS?)."))
-						e.printStackTrace();
-				}
-				return false;
-			case MACOS:
-			case LINUX:
-				Vector<String> cmd = new Vector<String>();
-				cmd.add("which");
-				cmd.add("mono");
-				Vector<String> res = null;
-				try {
-					res = AppExecution.executeAndWait(cmd);
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-				if (res != null) {
-					if (res.get(0).startsWith("/")
-							&& res.get(0).endsWith("mono")) {
-						return true;
-					}
-				}
-				return false;
-			default:
-				return false;
-		}
-	}
 
 	/**
@@ -209,6 +154,6 @@
 	private static Vector<String> getProgramInvocation() {
 		Vector<String> res = new Vector<String>();
-		if (Settings.getPlatform() != Platform.WIN)
-			res.add("mono");
+		if (DotNet.getRuntimeExe().length() > 0)
+			res.add(DotNet.getRuntimeExe());
 		res.add(getProgramFile().getPath());
 		return res;
Index: AE/installer2/src/net/oni2/aeinstaller/backend/packages/EExeType.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/packages/EExeType.java	(revision 672)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/packages/EExeType.java	(revision 672)
@@ -0,0 +1,19 @@
+package net.oni2.aeinstaller.backend.packages;
+
+/**
+ * @author Christian Illy
+ */
+public enum EExeType {
+	/**
+	 * Exe is an executable for the target platform
+	 */
+	OSBINARY,
+	/**
+	 * Exe is a .Net executable
+	 */
+	DOTNET,
+	/**
+	 * Exe is a Java .jar archive
+	 */
+	JAR
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java	(revision 672)
@@ -27,4 +27,5 @@
 
 	private File exeFile = null;
+	private EExeType exeType = EExeType.OSBINARY;
 	private File iconFile = null;
 	private String workingDir = "Base";
@@ -111,4 +112,11 @@
 				} else if (sName.equalsIgnoreCase("ExeName")) {
 					exeFile = new File(Paths.getEditionBasePath(), sVal);
+				} else if (sName.equalsIgnoreCase("ExeType")) {
+					if (sVal.equalsIgnoreCase("OSBinary"))
+						exeType = EExeType.OSBINARY;
+					else if (sVal.equalsIgnoreCase("DotNet"))
+						exeType = EExeType.DOTNET;
+					else if (sVal.equalsIgnoreCase("Jar"))
+						exeType = EExeType.JAR;
 				} else if (sName.equalsIgnoreCase("WorkingDir")) {
 					workingDir = sVal;
@@ -116,4 +124,8 @@
 					iconFile = new File(Paths.getEditionBasePath(), sVal);
 				}
+			}
+			if (exeFile != null) {
+				if (exeFile.getName().toLowerCase().endsWith(".jar"))
+					exeType = EExeType.JAR;
 			}
 		} catch (FileNotFoundException e) {
@@ -203,4 +215,11 @@
 
 	/**
+	 * @return the exeType
+	 */
+	public EExeType getExeType() {
+		return exeType;
+	}
+
+	/**
 	 * @return the iconFile
 	 */
Index: AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java	(revision 672)
@@ -44,4 +44,5 @@
 
 	private File exeFile = null;
+	private EExeType exeType = EExeType.OSBINARY;
 	private File iconFile = null;
 	private String workingDir = "Base";
@@ -124,4 +125,5 @@
 
 			exeFile = mi.getExeFile();
+			exeType = mi.getExeType();
 			workingDir = mi.getWorkingDir();
 			iconFile = mi.getIconFile();
@@ -387,4 +389,11 @@
 
 	/**
+	 * @return Executable type of this tool
+	 */
+	public EExeType getExeType() {
+		return exeType;
+	}
+
+	/**
 	 * @return Icon file of this tool
 	 */
Index: AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 672)
@@ -44,4 +44,5 @@
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.Settings;
+import net.oni2.aeinstaller.backend.ToolLauncher;
 import net.oni2.aeinstaller.backend.Settings.Platform;
 import net.oni2.aeinstaller.backend.SizeFormatter;
@@ -229,12 +230,17 @@
 				TreeSet<Package> tools = PackageManager.getInstance()
 						.getUpdatableTools();
-				int size = 0;
 				JPanel panPackages = new JPanel(new GridLayout(0, 1));
 				execUpdates = new TreeSet<Package>();
 				execUpdates.addAll(mods);
 				execUpdates.addAll(tools);
+				final JLabel lblSize = new JLabel("<html>"
+						+ String.format(
+								bundle.getString("updatesAvailableSize.text"),
+								SizeFormatter.format(0, 3)) + "</html>");
+				int size = 0;
 				for (final Package m : mods) {
 					size += m.getZipSize();
-					JCheckBox check = new JCheckBox("Mod: " + m.getName());
+					JCheckBox check = new JCheckBox("Mod: " + m.getName()
+							+ " (" + SizeFormatter.format(size, 1) + ")");
 					check.setSelected(true);
 					check.addItemListener(new ItemListener() {
@@ -245,4 +251,12 @@
 							else
 								execUpdates.remove(m);
+							int s = 0;
+							for (Package p : execUpdates)
+								s += p.getZipSize();
+							lblSize.setText("<html>"
+									+ String.format(
+											bundle.getString("updatesAvailableSize.text"),
+											SizeFormatter.format(s, 3))
+									+ "</html>");
 						}
 					});
@@ -251,8 +265,30 @@
 				for (final Package m : tools) {
 					size += m.getZipSize();
-					JCheckBox check = new JCheckBox("Tool: " + m.getName());
+					JCheckBox check = new JCheckBox("Tool: " + m.getName()
+							+ " (" + SizeFormatter.format(size, 1) + ")");
 					check.setSelected(true);
+					check.addItemListener(new ItemListener() {
+						@Override
+						public void itemStateChanged(ItemEvent e) {
+							if (e.getStateChange() == ItemEvent.SELECTED)
+								execUpdates.add(m);
+							else
+								execUpdates.remove(m);
+							int s = 0;
+							for (Package p : execUpdates)
+								s += p.getZipSize();
+							lblSize.setText("<html>"
+									+ String.format(
+											bundle.getString("updatesAvailableSize.text"),
+											SizeFormatter.format(s, 3))
+									+ "</html>");
+						}
+					});
 					panPackages.add(check);
 				}
+				lblSize.setText("<html>"
+						+ String.format(
+								bundle.getString("updatesAvailableSize.text"),
+								SizeFormatter.format(size, 3)) + "</html>");
 				if (size > 0) {
 					// Build info dialog content
@@ -261,8 +297,4 @@
 							+ bundle.getString("updatesAvailable.text")
 							+ "</html>");
-					JLabel lblSize = new JLabel("<html>"
-							+ String.format(bundle
-									.getString("updatesAvailableSize.text"),
-									SizeFormatter.format(size, 3)) + "</html>");
 					packages.add(lblIntro, BorderLayout.NORTH);
 					packages.add(panPackages, BorderLayout.CENTER);
@@ -433,22 +465,8 @@
 		}
 		toolsMenuItems.clear();
-		for (Package m : PackageManager.getInstance().getInstalledTools()) {
+		for (final Package m : PackageManager.getInstance().getInstalledTools()) {
 			File exe = m.getExeFile();
 			if (exe != null && exe.exists()) {
 				JMenuItem item = new JMenuItem();
-				final Vector<String> params = new Vector<String>();
-				if (exe.getName().toLowerCase().endsWith(".jar")) {
-					File jre = null;
-					if (Settings.getPlatform() == Platform.WIN)
-						jre = new File(System.getProperties().getProperty(
-								"java.home"), "bin/javaw.exe");
-					else
-						jre = new File(System.getProperties().getProperty(
-								"java.home"), "bin/java");
-					params.add(jre.getPath());
-					params.add("-jar");
-				}
-				params.add(exe.getPath());
-				final File wd = m.getWorkingDir();
 				ImageIcon ico = null;
 				if (m.getIconFile() != null && m.getIconFile().exists()) {
@@ -464,6 +482,19 @@
 
 					@Override
-					public void actionPerformed(ActionEvent e) {
-						AppExecution.execute(params, wd);
+					public void actionPerformed(ActionEvent evt) {
+						try {
+							ToolLauncher.launch(m);
+						} catch (Exception ex) {
+							if (ex.getMessage().contains("JRE"))
+								JOptionPane.showMessageDialog(null,
+										bundle.getString("jreNotFound.text"),
+										bundle.getString("jreNotFound.title"),
+										JOptionPane.ERROR_MESSAGE);
+							if (ex.getMessage().contains(".NET"))
+								JOptionPane.showMessageDialog(null,
+										bundle.getString("dotNetNotFound.text"),
+										bundle.getString("dotNetNotFound.title"),
+										JOptionPane.ERROR_MESSAGE);
+						}
 					}
 				});
Index: AE/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties	(revision 671)
+++ AE/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties	(revision 672)
@@ -83,2 +83,7 @@
 doUpdate.title=Updating packages
 
+jreNotFound.text=This tool requires a JRE but it was not found.
+jreNotFound.title=No JRE found
+
+dotNetNotFound.text=This tool requires a .NET runtime but it was not found.
+dotNetNotFound.title=No .NET runtime found
