Index: java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/AEInstaller.properties	(revision 1019)
@@ -1,2 +1,2 @@
 appname=AE Installer 2
-appversion=.20
+appversion=.21
Index: java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/backend/oni/management/Installer.java	(revision 1019)
@@ -610,8 +610,8 @@
 
 		for (Package p : mods) {
-			ToolFileIterator.iteratePlatformToolFiles(p,
+			ToolFileIterator.iteratePlatformToolFiles(p, false,
 					new ToolFileIteratorEntry() {
 						@Override
-						public void toolFile(File source, File target) {
+						public void toolFile(File source, File target, boolean isDir) {
 							copyPlainFile(source, target, log);
 						}
Index: java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIterator.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIterator.java	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIterator.java	(revision 1019)
@@ -19,8 +19,10 @@
 	 * @param tool
 	 *            Tool to iterate over
+	 * @param handleAppAsFiles
+	 *            Whether or not to handle MacOS .app folders as a single file
 	 * @param handler
 	 *            Handler to handle found files
 	 */
-	public static void iteratePlatformToolFiles(Package tool,
+	public static void iteratePlatformToolFiles(Package tool, boolean handleAppAsFiles,
 			ToolFileIteratorEntry handler) {
 		File plain = CaseInsensitiveFile.getCaseInsensitiveFile(
@@ -35,25 +37,25 @@
 						plain, "win_only");
 				if (plainCommon.exists())
-					iterateFiles(plainCommon, Paths.getEditionBasePath(),
+					iterateFiles(plainCommon, Paths.getEditionBasePath(), handleAppAsFiles,
 							handler);
 				if (PlatformInformation.getPlatform() == Platform.MACOS
 						&& plainMac.exists())
-					iterateFiles(plainMac, Paths.getEditionBasePath(), handler);
+					iterateFiles(plainMac, Paths.getEditionBasePath(), handleAppAsFiles, handler);
 				else if (plainWin.exists())
-					iterateFiles(plainWin, Paths.getEditionBasePath(), handler);
+					iterateFiles(plainWin, Paths.getEditionBasePath(), handleAppAsFiles, handler);
 			} else {
-				iterateFiles(plain, Paths.getEditionBasePath(), handler);
+				iterateFiles(plain, Paths.getEditionBasePath(), handleAppAsFiles, handler);
 			}
 		}
 	}
 
-	private static void iterateFiles(File srcFolder, File targetFolder,
+	private static void iterateFiles(File srcFolder, File targetFolder, boolean handleAppAsFiles,
 			ToolFileIteratorEntry handler) {
 		for (File f : srcFolder.listFiles()) {
-			if (f.isDirectory())
+			if (f.isDirectory() && (!f.getName().endsWith(".app") || !handleAppAsFiles))
 				iterateFiles(f, CaseInsensitiveFile.getCaseInsensitiveFile(
-						targetFolder, f.getName()), handler);
+						targetFolder, f.getName()), handleAppAsFiles, handler);
 			else {
-				handler.toolFile(f, new File(targetFolder, f.getName()));
+				handler.toolFile(f, new File(targetFolder, f.getName()), f.isDirectory());
 			}
 		}
Index: java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIteratorEntry.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIteratorEntry.java	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolFileIteratorEntry.java	(revision 1019)
@@ -14,5 +14,7 @@
 	 * @param target
 	 *            Target of file if installed
+	 * @param isFolder
+	 *            Is source a folder instead of a file? (MacOS .app folder)
 	 */
-	public void toolFile(File source, File target);
+	public void toolFile(File source, File target, boolean isFolder);
 }
Index: java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolsManager.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolsManager.java	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/backend/oni/management/tools/ToolsManager.java	(revision 1019)
@@ -26,8 +26,8 @@
 		final ToolInstallationList til = ToolInstallationList.getInstance();
 		for (final Package m : PackageManager.getInstance().getInstalledTools()) {
-			ToolFileIterator.iteratePlatformToolFiles(m,
+			ToolFileIterator.iteratePlatformToolFiles(m, false,
 					new ToolFileIteratorEntry() {
 						@Override
-						public void toolFile(File source, File target) {
+						public void toolFile(File source, File target, boolean isDir) {
 							byte[] chkSrc = FileChecksum
 									.calculateFileMD5(source);
@@ -56,9 +56,9 @@
 			if (!uninstall) { // Install:
 				final HashSet<String> files = new HashSet<String>();
-				ToolFileIterator.iteratePlatformToolFiles(m,
+				ToolFileIterator.iteratePlatformToolFiles(m, true,
 						new ToolFileIteratorEntry() {
 							@Override
-							public void toolFile(File source, File target) {
-								copyToolsFiles(source, target, files);
+							public void toolFile(File source, File target, boolean isDir) {
+								copyToolsFiles(source, target, isDir, files);
 							}
 						});
@@ -74,5 +74,5 @@
 	}
 
-	private static void copyToolsFiles(File src, File target,
+	private static void copyToolsFiles(File src, File target, boolean isDir,
 			HashSet<String> files) {
 		try {
@@ -80,14 +80,22 @@
 					target.getParentFile(), target.getName());
 
-			// Case mismatch?
-			if (!targetFile.getName().equals(src.getName()))
-				targetFile.delete();
-
 			files.add(target.getPath().replace(
 					Paths.getEditionBasePath().getPath(), ""));
 
-			FileUtils.copyFile(src, target);
-			if (src.canExecute())
-				target.setExecutable(true);
+			if (isDir) {
+				if (targetFile.exists()) {
+					FileUtils.deleteDirectory(targetFile);
+				}
+				
+				FileUtils.copyDirectory(src, target, true);	
+			} else {
+				// Case mismatch?
+				if (!targetFile.getName().equals(src.getName()))
+					targetFile.delete();
+
+				FileUtils.copyFile(src, target);
+				if (src.canExecute())
+					target.setExecutable(true);
+			}
 		} catch (IOException e) {
 			e.printStackTrace();
@@ -102,6 +110,14 @@
 				File targetFolder = targetFile.getParentFile();
 
-				if (targetFile.exists())
-					targetFile.delete();
+				if (targetFile.exists()) {
+					if (targetFile.isDirectory()) {
+						try {
+							FileUtils.deleteDirectory(targetFile);
+						} catch (IOException e) {
+							e.printStackTrace();
+						}
+					} else
+						targetFile.delete();
+				}
 				if (targetFolder.list().length == 0)
 					targetFolder.delete();
Index: java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java
===================================================================
--- java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 1018)
+++ java/installer2/src/net/oni2/aeinstaller/gui/MainWin.java	(revision 1019)
@@ -209,4 +209,6 @@
 	private void exit() {
 		dispose();
+		System.out.flush();
+		System.err.flush();
 		System.exit(0);
 	}
