Index: AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 699)
@@ -1,2 +1,2 @@
 appname=AE Installer 2
-appversion=0.99s
+appversion=0.99t
Index: AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/AEInstaller2.java	(revision 699)
@@ -21,4 +21,5 @@
 import javax.swing.UIManager.LookAndFeelInfo;
 
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 import net.oni2.aeinstaller.backend.DotNet;
 import net.oni2.aeinstaller.backend.Paths;
@@ -64,5 +65,5 @@
 	
 	private static void initBundles() {
-		File localesDir = new File(Paths.getInstallerPath(), "locales");
+		File localesDir = CaseInsensitiveFile.getCaseInsensitiveFile(Paths.getInstallerPath(), "locales");
 		if (localesDir.isDirectory())
 			addClassPath(localesDir);
Index: AE/installer2/src/net/oni2/aeinstaller/backend/CaseInsensitiveFile.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/CaseInsensitiveFile.java	(revision 699)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/CaseInsensitiveFile.java	(revision 699)
@@ -0,0 +1,34 @@
+package net.oni2.aeinstaller.backend;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+/**
+ * @author Christian Illy
+ */
+public class CaseInsensitiveFile {
+	/**
+	 * Get a File for the given parent path and a child name. Return the name as
+	 * passed to the function if either parent or a file named that way does not
+	 * exist.
+	 * 
+	 * @param parent
+	 *            Parent path
+	 * @param name
+	 *            Name of file
+	 * @return File
+	 */
+	public static File getCaseInsensitiveFile(File parent, final String name) {
+		if (parent.exists()) {
+			for (File f : parent.listFiles(new FilenameFilter() {
+				@Override
+				public boolean accept(File dir, String fname) {
+					return fname.equalsIgnoreCase(name);
+				}
+			})) {
+				return f;
+			}
+		}
+		return new File(parent, name);
+	}
+}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/Paths.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/Paths.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/Paths.java	(revision 699)
@@ -92,5 +92,5 @@
 	 */
 	public static File getVanillaGDF() {
-		return new File(getOniBasePath(), "GameDataFolder");
+		return CaseInsensitiveFile.getCaseInsensitiveFile(getOniBasePath(), "GameDataFolder");
 	}
 
Index: AE/installer2/src/net/oni2/aeinstaller/backend/oni/Installer.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/oni/Installer.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/oni/Installer.java	(revision 699)
@@ -22,4 +22,5 @@
 
 import net.oni2.aeinstaller.AEInstaller2;
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.Settings;
@@ -111,92 +112,74 @@
 	/**
 	 * @param tools
-	 *            Tools to install
+	 *            Tools to (un)install
+	 * @param uninstall
+	 *            Uninstall tools or install?
 	 */
-	public static void installTools(TreeSet<Package> tools) {
+	public static void installTools(TreeSet<Package> tools, boolean uninstall) {
 		TreeSet<Integer> installed = getInstalledTools();
 		for (Package m : tools) {
-			File plain = new File(m.getLocalPath(), "plain");
-			if (plain.exists()) {
-				if (m.hasSeparatePlatformDirs()) {
-					File plainCommon = new File(plain, "common");
-					File plainMac = new File(plain, "mac_only");
-					File plainWin = new File(plain, "win_only");
-					if (plainCommon.exists())
-						copyToolsFiles(plainCommon);
-					if (Settings.getPlatform() == Platform.MACOS
-							&& plainMac.exists())
-						copyToolsFiles(plainMac);
-					else if (plainWin.exists())
-						copyToolsFiles(plainWin);
-				} else {
-					copyToolsFiles(plain);
-				}
-			}
-			installed.add(m.getPackageNumber());
-		}
-		writeInstalledTools(installed);
-	}
-
-	/**
-	 * @param tools
-	 *            Tools to uninstall
-	 */
-	public static void uninstallTools(TreeSet<Package> tools) {
-		TreeSet<Integer> installed = getInstalledTools();
-		for (Package m : tools) {
-			if (installed.contains(m.getPackageNumber())) {
-				File plain = new File(m.getLocalPath(), "plain");
+			if (!uninstall || installed.contains(m.getPackageNumber())) {
+				File plain = CaseInsensitiveFile.getCaseInsensitiveFile(
+						m.getLocalPath(), "plain");
 				if (plain.exists()) {
 					if (m.hasSeparatePlatformDirs()) {
-						File plainCommon = new File(plain, "common");
-						File plainMac = new File(plain, "mac_only");
-						File plainWin = new File(plain, "win_only");
+						File plainCommon = CaseInsensitiveFile
+								.getCaseInsensitiveFile(plain, "common");
+						File plainMac = CaseInsensitiveFile
+								.getCaseInsensitiveFile(plain, "mac_only");
+						File plainWin = CaseInsensitiveFile
+								.getCaseInsensitiveFile(plain, "win_only");
 						if (plainCommon.exists())
-							removeToolsFiles(plainCommon,
-									Paths.getEditionBasePath());
+							copyRemoveToolsFiles(plainCommon,
+									Paths.getEditionBasePath(), uninstall);
 						if (Settings.getPlatform() == Platform.MACOS
 								&& plainMac.exists())
-							removeToolsFiles(plainMac,
-									Paths.getEditionBasePath());
+							copyRemoveToolsFiles(plainMac,
+									Paths.getEditionBasePath(), uninstall);
 						else if (plainWin.exists())
-							removeToolsFiles(plainWin,
-									Paths.getEditionBasePath());
+							copyRemoveToolsFiles(plainWin,
+									Paths.getEditionBasePath(), uninstall);
 					} else {
-						removeToolsFiles(plain, Paths.getEditionBasePath());
+						copyRemoveToolsFiles(plain, Paths.getEditionBasePath(),
+								uninstall);
 					}
 				}
 			}
-			installed.remove(m.getPackageNumber());
+			if (uninstall)
+				installed.remove(m.getPackageNumber());
+			else
+				installed.add(m.getPackageNumber());
 		}
 		writeInstalledTools(installed);
 	}
 
-	private static void copyToolsFiles(File srcFolder) {
+	private static void copyRemoveToolsFiles(File srcFolder, File targetFolder,
+			boolean remove) {
 		for (File f : srcFolder.listFiles()) {
 			try {
 				if (f.isDirectory())
-					FileUtils.copyDirectoryToDirectory(f,
-							Paths.getEditionBasePath());
-				else
-					FileUtils
-							.copyFileToDirectory(f, Paths.getEditionBasePath());
+					copyRemoveToolsFiles(f,
+							CaseInsensitiveFile.getCaseInsensitiveFile(
+									targetFolder, f.getName()), remove);
+				else {
+					File targetFile = CaseInsensitiveFile
+							.getCaseInsensitiveFile(targetFolder,
+									f.getName());
+					if (remove) {
+						if (targetFile.exists())
+							targetFile.delete();
+					} else {
+						if (!targetFile.getName().equals(f.getName()))
+							targetFile.delete();
+						FileUtils.copyFileToDirectory(f, targetFolder);
+					}
+				}
 			} catch (IOException e) {
 				e.printStackTrace();
 			}
 		}
-	}
-
-	private static void removeToolsFiles(File srcFolder, File target) {
-		for (File f : srcFolder.listFiles()) {
-			if (f.isDirectory())
-				removeToolsFiles(f, new File(target, f.getName()));
-			else {
-				File targetFile = new File(target, f.getName());
-				if (targetFile.exists())
-					targetFile.delete();
-			}
-		}
-		if (target.list().length == 0)
-			target.delete();
+		if (remove)
+			if (targetFolder.list().length == 0)
+				targetFolder.delete();
 	}
 
@@ -258,5 +241,6 @@
 				}
 			})) {
-				File ignore = new File(f, "ignore.txt");
+				File ignore = CaseInsensitiveFile.getCaseInsensitiveFile(f,
+						"ignore.txt");
 				if (!ignore.exists()) {
 					try {
@@ -283,10 +267,14 @@
 				unlockLevels.add(lev);
 
-			File oni = new File(m.getLocalPath(), "oni");
+			File oni = CaseInsensitiveFile.getCaseInsensitiveFile(
+					m.getLocalPath(), "oni");
 			if (oni.exists()) {
 				if (m.hasSeparatePlatformDirs()) {
-					File oniCommon = new File(oni, "common");
-					File oniMac = new File(oni, "mac_only");
-					File oniWin = new File(oni, "win_only");
+					File oniCommon = CaseInsensitiveFile
+							.getCaseInsensitiveFile(oni, "common");
+					File oniMac = CaseInsensitiveFile.getCaseInsensitiveFile(
+							oni, "mac_only");
+					File oniWin = CaseInsensitiveFile.getCaseInsensitiveFile(
+							oni, "win_only");
 					if (oniCommon.exists())
 						foldersOni.add(oniCommon);
@@ -301,10 +289,14 @@
 			}
 
-			File patches = new File(m.getLocalPath(), "patches");
+			File patches = CaseInsensitiveFile.getCaseInsensitiveFile(
+					m.getLocalPath(), "patches");
 			if (patches.exists()) {
 				if (m.hasSeparatePlatformDirs()) {
-					File patchesCommon = new File(patches, "common");
-					File patchesMac = new File(patches, "mac_only");
-					File patchesWin = new File(patches, "win_only");
+					File patchesCommon = CaseInsensitiveFile
+							.getCaseInsensitiveFile(patches, "common");
+					File patchesMac = CaseInsensitiveFile
+							.getCaseInsensitiveFile(patches, "mac_only");
+					File patchesWin = CaseInsensitiveFile
+							.getCaseInsensitiveFile(patches, "win_only");
 					if (patchesCommon.exists())
 						foldersPatches.add(patchesCommon);
@@ -367,10 +359,14 @@
 
 		for (Package m : mods.descendingSet()) {
-			File bsl = new File(m.getLocalPath(), "bsl");
+			File bsl = CaseInsensitiveFile.getCaseInsensitiveFile(
+					m.getLocalPath(), "bsl");
 			if (bsl.exists()) {
 				if (m.hasSeparatePlatformDirs()) {
-					File bslCommon = new File(bsl, "common");
-					File bslMac = new File(bsl, "mac_only");
-					File bslWin = new File(bsl, "win_only");
+					File bslCommon = CaseInsensitiveFile
+							.getCaseInsensitiveFile(bsl, "common");
+					File bslMac = CaseInsensitiveFile.getCaseInsensitiveFile(
+							bsl, "mac_only");
+					File bslWin = CaseInsensitiveFile.getCaseInsensitiveFile(
+							bsl, "win_only");
 					if ((Settings.getPlatform() == Platform.MACOS && bslMac
 							.exists())
@@ -401,9 +397,13 @@
 
 		Vector<File> sources = new Vector<File>();
-		File bsl = new File(sourceMod.getLocalPath(), "bsl");
+		File bsl = CaseInsensitiveFile.getCaseInsensitiveFile(
+				sourceMod.getLocalPath(), "bsl");
 		if (sourceMod.hasSeparatePlatformDirs()) {
-			File bslCommon = new File(bsl, "common");
-			File bslMac = new File(bsl, "mac_only");
-			File bslWin = new File(bsl, "win_only");
+			File bslCommon = CaseInsensitiveFile.getCaseInsensitiveFile(bsl,
+					"common");
+			File bslMac = CaseInsensitiveFile.getCaseInsensitiveFile(bsl,
+					"mac_only");
+			File bslWin = CaseInsensitiveFile.getCaseInsensitiveFile(bsl,
+					"win_only");
 			if (Settings.getPlatform() == Platform.MACOS && bslMac.exists()) {
 				for (File f : bslMac.listFiles(dirFileFilter)) {
@@ -442,5 +442,6 @@
 			if (!targetPath.exists())
 				targetPath.mkdir();
-			if (!(new File(targetPath, "ignore.txt").exists())) {
+			if (!(CaseInsensitiveFile.getCaseInsensitiveFile(targetPath,
+					"ignore.txt").exists())) {
 				for (File fbsl : f.listFiles()) {
 					if (fbsl.getName().toLowerCase().endsWith(".bsl")) {
@@ -551,5 +552,5 @@
 				e.printStackTrace();
 			}
-			
+
 			oniLevelFolders.get(level).add(levelFolder);
 		}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/oni/OniSplit.java	(revision 699)
@@ -5,7 +5,8 @@
 import java.util.Vector;
 
+import net.oni2.aeinstaller.backend.AppExecution;
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 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.Platform;
@@ -238,6 +239,6 @@
 
 	private static File getProgramFile() {
-		return new File(new File(Paths.getEditionBasePath(), "Tools"),
-				"Onisplit.exe");
+		File toolsPath = CaseInsensitiveFile.getCaseInsensitiveFile(Paths.getEditionBasePath(), "Tools");
+		return CaseInsensitiveFile.getCaseInsensitiveFile(toolsPath, "Onisplit.exe");
 	}
 }
Index: AE/installer2/src/net/oni2/aeinstaller/backend/oni/XMLTools.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/oni/XMLTools.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/oni/XMLTools.java	(revision 699)
@@ -6,4 +6,5 @@
 
 import net.oni2.aeinstaller.backend.AppExecution;
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 import net.oni2.aeinstaller.backend.DotNet;
 import net.oni2.aeinstaller.backend.Paths;
@@ -48,6 +49,6 @@
 
 	private static File getProgramFile() {
-		return new File(new File(Paths.getEditionBasePath(), "Tools"),
-				"xmlTools.exe");
+		File toolsPath = CaseInsensitiveFile.getCaseInsensitiveFile(Paths.getEditionBasePath(), "Tools");
+		return CaseInsensitiveFile.getCaseInsensitiveFile(toolsPath, "xmlTools.exe");
 	}
 }
Index: AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/packages/Mod_Info.java	(revision 699)
@@ -9,4 +9,5 @@
 import java.util.HashSet;
 
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 import net.oni2.aeinstaller.backend.Paths;
 
@@ -111,5 +112,5 @@
 					}
 				} else if (sName.equalsIgnoreCase("ExeName")) {
-					exeFile = new File(Paths.getEditionBasePath(), sVal);
+					exeFile = CaseInsensitiveFile.getCaseInsensitiveFile(Paths.getEditionBasePath(), sVal);
 				} else if (sName.equalsIgnoreCase("ExeType")) {
 					if (sVal.equalsIgnoreCase("OSBinary"))
@@ -122,5 +123,5 @@
 					workingDir = sVal;
 				} else if (sName.equalsIgnoreCase("IconName")) {
-					iconFile = new File(Paths.getEditionBasePath(), sVal);
+					iconFile = CaseInsensitiveFile.getCaseInsensitiveFile(Paths.getEditionBasePath(), sVal);
 				}
 			}
Index: AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/backend/packages/Package.java	(revision 699)
@@ -14,4 +14,5 @@
 import org.apache.commons.io.FileUtils;
 
+import net.oni2.aeinstaller.backend.CaseInsensitiveFile;
 import net.oni2.aeinstaller.backend.Paths;
 import net.oni2.aeinstaller.backend.Settings;
@@ -105,7 +106,7 @@
 	 */
 	public void updateLocalData() {
-		File config = new File(getLocalPath(), "Mod_Info.cfg");
+		File config = CaseInsensitiveFile.getCaseInsensitiveFile(getLocalPath(), "Mod_Info.cfg");
 		File aeicfg = new File(getLocalPath(), "aei.cfg");
-		File plain = new File(getLocalPath(), "plain");
+		File plain = CaseInsensitiveFile.getCaseInsensitiveFile(getLocalPath(), "plain");
 		if (config.exists()) {
 			Mod_Info mi = new Mod_Info(config, packageNumber);
Index: AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 699)
@@ -352,5 +352,5 @@
 							tools.add(m);
 					if (tools.size() > 0) {
-						Installer.installTools(tools);
+						Installer.installTools(tools, false);
 					}
 				}
@@ -552,5 +552,5 @@
 			}
 			evt.setProgressMessage(bundle.getString("coreToolsInstall.title"));
-			Installer.installTools(PackageManager.getInstance().getCoreTools());
+			Installer.installTools(PackageManager.getInstance().getCoreTools(), false);
 		}
 	}
@@ -701,5 +701,5 @@
 
 			if (actuallyTools.size() > 0) {
-				Installer.installTools(actuallyTools);
+				Installer.installTools(actuallyTools, false);
 			}
 		}
Index: AE/installer2/src/net/oni2/aeinstaller/gui/toolmanager/ToolManager.java
===================================================================
--- AE/installer2/src/net/oni2/aeinstaller/gui/toolmanager/ToolManager.java	(revision 698)
+++ AE/installer2/src/net/oni2/aeinstaller/gui/toolmanager/ToolManager.java	(revision 699)
@@ -96,5 +96,5 @@
 				TreeSet<Package> tools = new TreeSet<Package>();
 				tools.add(selectedPackage);
-				Installer.uninstallTools(tools);
+				Installer.installTools(tools, true);
 			} else {
 				if (!selectedPackage.isLocalAvailable()) {
@@ -122,5 +122,5 @@
 				TreeSet<Package> tools = new TreeSet<Package>();
 				tools.add(selectedPackage);
-				Installer.installTools(tools);
+				Installer.installTools(tools, false);
 			}
 		}
