Index: /java/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties
===================================================================
--- /java/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties	(revision 809)
+++ /java/installer2/locales/net/oni2/aeinstaller/localization/MainWin_de.properties	(revision 810)
@@ -98,4 +98,6 @@
 wineNotFound.title=Wine nicht gefunden
 
+notInstalled.text=Du musst mindestens einmal auf den Installieren-Knopf\nklicken, auch wenn du jetzt keine Mods selektieren willst.
+notInstalled.title=Nicht installiert
 oniExeNotFound.text=Oni's Programmdatei wurde nicht gefunden.
 oniExeNotFound.title=Oni nicht gefunden
Index: /java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties
===================================================================
--- /java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 809)
+++ /java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 810)
@@ -1,2 +1,2 @@
 appname=AE Installer 2
-appversion=.02
+appversion=.04
Index: /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java
===================================================================
--- /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java	(revision 809)
+++ /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java	(revision 810)
@@ -113,5 +113,4 @@
 		}
 		HashSet<String> levelsAffectedNow = new HashSet<String>();
-		// TODO: fill set
 
 		File IGMD = new File(Paths.getEditionGDF(), "IGMD");
@@ -234,7 +233,11 @@
 		applyPatches(levels, foldersPatches, listener, log);
 
-		TreeSet<String> levelsAffectedBoth = new TreeSet<String>();
-		levelsAffectedBoth.addAll(levelsAffectedBefore);
-		levelsAffectedBoth.addAll(levelsAffectedNow);
+		TreeSet<String> levelsAffectedBoth = null;
+		if (levelsAffectedBefore != null) {
+			levelsAffectedBoth = new TreeSet<String>();
+			levelsAffectedBoth.addAll(levelsAffectedBefore);
+			levelsAffectedBoth.addAll(levelsAffectedNow);
+		}
+
 		combineBinaryFiles(levels, levelsAffectedBoth, listener, log);
 		combineBSLFolders(mods, listener, log);
@@ -539,5 +542,6 @@
 					"Installing level " + l);
 
-			if (levelsUpdated.contains(l.toLowerCase())) {
+			if ((levelsUpdated == null)
+					|| levelsUpdated.contains(l.toLowerCase())) {
 				ApplicationInvocationResult res = OniSplit.packLevel(
 						oniLevelFolders.get(l), new File(Paths.getEditionGDF(),
Index: /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/ModInstallationList.java
===================================================================
--- /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/ModInstallationList.java	(revision 809)
+++ /java/installer2/src/net/oni2/aeinstaller/backend/oni/management/ModInstallationList.java	(revision 810)
@@ -30,25 +30,57 @@
 		return instance;
 	}
-	
+
+	/**
+	 * @return Currently installed mods
+	 */
 	public TreeSet<Integer> getInstalledMods() {
 		return mods;
 	}
-	
+
+	/**
+	 * Check if given mod is installed
+	 * 
+	 * @param packageId
+	 *            Package Id to check for
+	 * @return Is mod installed?
+	 */
 	public boolean isInstalled(int packageId) {
 		return mods.contains(packageId);
 	}
-	
+
+	/**
+	 * Set the mods that are installed by a new installation
+	 * 
+	 * @param mods
+	 *            List of installed mods
+	 */
 	public void setInstalledMods(TreeSet<Integer> mods) {
 		this.mods = mods;
 	}
-	
+
+	/**
+	 * @return List of affected levels by current installation
+	 */
 	public HashSet<String> getAffectedLevels() {
 		return affectedLevels;
 	}
-	
+
+	/**
+	 * Check if given level is affected by current mod installation
+	 * 
+	 * @param level
+	 *            Level name (e.g. level1_Final)
+	 * @return Is level affected?
+	 */
 	public boolean isLevelAffected(String level) {
 		return affectedLevels.contains(level.toLowerCase());
 	}
-	
+
+	/**
+	 * Set the levels that are affected by a new mod installation
+	 * 
+	 * @param levels
+	 *            List of affected level
+	 */
 	public void setAffectedLevels(HashSet<String> levels) {
 		affectedLevels.clear();
@@ -57,5 +89,11 @@
 		}
 	}
-	
+
+	/**
+	 * Check if the current state of the ModInstallationList was loaded from the
+	 * mod_installation.xml
+	 * 
+	 * @return Loaded from file?
+	 */
 	public boolean isLoadedFromFile() {
 		return isLoaded;
Index: /java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java
===================================================================
--- /java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 809)
+++ /java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 810)
@@ -476,8 +476,8 @@
 					p.getName()));
 		b.append("[/code]");
-		
+
 		StringSelection selection = new StringSelection(b.toString());
-	    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
-	    clipboard.setContents(selection, selection);
+		Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
+		clipboard.setContents(selection, selection);
 	}
 
@@ -894,18 +894,25 @@
 
 	private void oni(boolean windowed) {
-		try {
-			OniLauncher.launch(windowed);
-		} catch (FileNotFoundException e) {
+		if (!Paths.getEditionGDF().isDirectory()) {
 			JOptionPane.showMessageDialog(this,
-					bundle.getString("oniExeNotFound.text"),
-					bundle.getString("oniExeNotFound.title"),
-					JOptionPane.ERROR_MESSAGE);
-			e.printStackTrace();
-		} catch (ERuntimeNotInstalledException e) {
-			JOptionPane.showMessageDialog(this,
-					bundle.getString("wineNotFound.text"),
-					bundle.getString("wineNotFound.title"),
-					JOptionPane.ERROR_MESSAGE);
-			e.printStackTrace();
+					bundle.getString("notInstalled.text"),
+					bundle.getString("notInstalled.title"),
+					JOptionPane.WARNING_MESSAGE);
+		} else {
+			try {
+				OniLauncher.launch(windowed);
+			} catch (FileNotFoundException e) {
+				JOptionPane.showMessageDialog(this,
+						bundle.getString("oniExeNotFound.text"),
+						bundle.getString("oniExeNotFound.title"),
+						JOptionPane.ERROR_MESSAGE);
+				e.printStackTrace();
+			} catch (ERuntimeNotInstalledException e) {
+				JOptionPane.showMessageDialog(this,
+						bundle.getString("wineNotFound.text"),
+						bundle.getString("wineNotFound.title"),
+						JOptionPane.ERROR_MESSAGE);
+				e.printStackTrace();
+			}
 		}
 	}
Index: /java/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties
===================================================================
--- /java/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties	(revision 809)
+++ /java/installer2/src/net/oni2/aeinstaller/localization/MainWin.properties	(revision 810)
@@ -98,4 +98,6 @@
 wineNotFound.title=Wine not found
 
+notInstalled.text=You have to hit the install button at least once,\neven if you do not want to select any mods right now.
+notInstalled.title=Not installed
 oniExeNotFound.text=Oni's executable was not found.
 oniExeNotFound.title=Oni not found
