Index: AE/Installer/trunk/source/aeinstallerapp.cpp
===================================================================
--- AE/Installer/trunk/source/aeinstallerapp.cpp	(revision 505)
+++ AE/Installer/trunk/source/aeinstallerapp.cpp	(revision 506)
@@ -115,7 +115,7 @@
 	if (updateStatus) // updateStatus was set when MainWindow::CreateControls() was called during initialization of the window
 	{
-		string updateMsg = "An update for the Anniversary Edition is available.\n"; // for some reason we can't set the initial value while using the '+' operator...
-		updateMsg = updateMsg + "Do you wish to update to Edition version " + updateAE.AEVersion + "?\n" +
-						        "(Current version is " + currentAE.AEVersion + ")\n"; // ...so we tack the rest on in a second command
+		string updateMsg = "An update for the Anniversary Edition is available.\n"
+						   "Do you wish to update to Edition version " + updateAE.AEVersion + "?\n"
+						   "(Current version is " + currentAE.AEVersion + ")\n"; // ...so we tack the rest on in a second command
 		wxMessageDialog* updateNotification;
 		
@@ -140,5 +140,5 @@
 					ProcessAEUpdate(&currentAE, &updateAE, &installerJustUpdated);
 				break;
-			case UPDATE_THIRD_PARTY: // there's an update with no globalization or Installer strings attached
+			case UPDATE_PKG_AVAIL: // there's an update with no globalization or Installer strings attached
 				updateMsg = (string)"One or more third party update(s) for Anniversary Edition package(s) are available.\n" +
 					(string)"Please note that the AE team assumes no responsibility for the content of third party mods" +
@@ -147,5 +147,5 @@
 				updateNotification = new wxMessageDialog(TheWindow, updateMsg.c_str(), "AE Installer Alert", wxYES_NO | wxICON_EXCLAMATION, wxDefaultPosition);
 				if (updateNotification->ShowModal() == wxID_YES)
-					ProcessThirdPartyUpdates();	
+					ProcessPackageUpdates("../updates", "./packages");
 				break;
 			case UPDATE_GLOB_AVAIL:	// there's an update with globalization strings attached
Index: AE/Installer/trunk/source/globals.h
===================================================================
--- AE/Installer/trunk/source/globals.h	(revision 505)
+++ AE/Installer/trunk/source/globals.h	(revision 506)
@@ -41,5 +41,5 @@
 
 //#pragma mark DEFINES
-#define INSTALLER_VERSION		 "1.2" // only place we need to change this
+#define INSTALLER_VERSION		 "1.1" // only place we need to change this
 #define UPDATE_LOG_READ_ERR		-1
 #define UPDATE_INST_REPL_ERR	-2
@@ -50,5 +50,5 @@
 #define UPDATE_INST_AVAIL		 3
 #define UPDATE_CONT_UPD			 4
-#define UPDATE_THIRD_PARTY		 5
+#define UPDATE_PKG_AVAIL		 5
 //#pragma mark STRUCTS
 struct ModPackage
@@ -99,5 +99,5 @@
 bool ProcessInstallerUpdate(Install_info_cfg *, Install_info_cfg *);
 bool ProcessAEUpdate(Install_info_cfg *, Install_info_cfg *, bool *);
-bool ProcessThirdPartyUpdates(void);
+void ProcessPackageUpdates(string, string);
 void callRefreshMods(void);
 string escapePath(string input);
Index: AE/Installer/trunk/source/installer.cpp
===================================================================
--- AE/Installer/trunk/source/installer.cpp	(revision 505)
+++ AE/Installer/trunk/source/installer.cpp	(revision 506)
@@ -232,5 +232,6 @@
 				
 				if ( strcmp(levels[i].c_str(), "0") ){
-					system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final ../GameDataFolder/level" + levels[i] + "_Final/AKEV/AKEV*.oni").c_str());
+					system((strOniSplit + " -move:overwrite ../GameDataFolder/level" + levels[i] + "_Final ../GameDataFolder/level" + levels[i] +
+							"_Final/AKEV/AKEV*.oni").c_str());
 					remove(  "../GameDataFolder/level" + levels[i] + "_Final/AKEV" );
 				}
@@ -246,5 +247,6 @@
 		{
 			logfile << "\tReimporting level" << levels[i] << "_Final.oni\n";
-			setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " reimporting level" + levels[i]+"_Final.oni");
+			setStatusArea("Step " + lexical_cast<std::string>(parts_done + 1) + "/" + lexical_cast<std::string>(total_steps) + " reimporting level" +
+						  levels[i] + "_Final.oni");
 			logfile << (strOniSplit + " " + strImportOption + " ../GameDataFolder/level" + levels[i] + "_Final VanillaDats/level" + levels[i] + "_Final/level" 
 						+ levels[i] + "_Final/level" + levels[i] + "_Final.oni >> Globalize.log").c_str() << '\n';
@@ -307,5 +309,5 @@
 		 Tests for presence of prefs with [ -f ] before doing anything so it doesn't create a partial prefs file -- just in case user has never
 		 run Oni before :-p */
-		string fullAEpath = escapePath(system_complete(".").parent_path().parent_path().string()); // get full path for Edition/ (Oni wants the folder that *contains* the GDF)
+		string fullAEpath = escapePath(system_complete(".").parent_path().parent_path().string()); // get full path for Edition/ (Oni wants folder that *contains* the GDF)
 		//bad Iritscen, bad! fixed buffers can cause crashes.
 		/*char prefsCommand[300] = "[ -f ~/Library/Preferences/com.godgames.oni.plist ] && defaults write com.godgames.oni RetailInstallationPath -string '";
@@ -375,14 +377,5 @@
 
 ModPackage fileToModPackage(fstream &file, string modName)
-{
-	/*
-	 This converts a file to a ModPackage struct.
-	 
-	 A few notes...
-	 "iter" is the current word we are on. I should have named it "token" or something, but I don't have multiple iterators, so its ok.
-	 I refer to (*iter) at the beginning of each if statement block. I could probably store it as a variable, but I'm pretty sure that dereferencing a pointer\iterator isn't much
-	 slower than reading a variable.
-	 */
-	
+{	
 	ModPackage package;
 	string line;
@@ -576,5 +569,6 @@
 						
 						setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
-						setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
+						setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +
+									  dir_itr->path().filename() + " ");
 						
 						system(importCommand.c_str());
@@ -632,5 +626,6 @@
 					
 					setProgressBar( (int)(1000 * (float)(j-1) / (float)numberOfDats) ); //100% * dat we're on / total dats
-					setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +  dir_itr->path().filename() + " ");
+					setStatusArea("Step " + lexical_cast<std::string>(j) + '/' + lexical_cast<std::string>(numberOfDats)+ ": Importing " +
+								  dir_itr->path().filename() + " ");
 					system(importCommand.c_str());
 					j++;
@@ -709,5 +704,5 @@
 void copyBSL(string copypath, vector<string>& BSLfolders, ModPackage pkg)
 {
-	ofstream BSLlog("BSL2.log", ios::app );
+	ofstream BSLlog("BSL.log", ios::app );
 	
 	try {
@@ -817,4 +812,5 @@
 |							   launches, this function will be called again but will	|
 |							   return UPDATE_SIMP_AVAIL or UPDATE_GLOB_AVAIL)			|
+|  UPDATE_PKG_AVAIL			-- A newer version of individual package(s) is available	|
 \* UPDATE_CONT_UPD			-- Currently unused										   */
 int GetUpdateStatus(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated)
@@ -931,5 +927,5 @@
 								newUpdateLog << "Installer was updated to:\n";
 								newUpdateLog << newUpdateLine.c_str();
-								*installerJustUpdated = true; // this value is indirectly returned to AEInstallerAp::OnInit()
+								*installerJustUpdated = true; // this value is indirectly returned to AEInstallerApp::OnInit()
 								doneReadingFile = true;
 								newUpdateLog.close();
@@ -970,51 +966,48 @@
 		}
 	}
-	try {
-	directory_iterator end;
-	if(exists("../updates")){
-	for ( directory_iterator install_iter( "../updates" );
-		 install_iter != end;
-		 ++install_iter )
-	{
-
-		ModPackage installedPackage, updatePackage;
-		if ( is_directory( install_iter->path() ) && exists( install_iter->path().string() + "/Mod_Info.cfg" ) ) {
-			fstream file;
-			file.open( (install_iter->path().string() + "/Mod_Info.cfg").c_str());	
-			if (!file.fail())
-			{
-				ModPackage updatePackage = fileToModPackage(file, install_iter->path().filename());
-			}
-			else 
-			{
-				file.close();
-				continue;
-			}
-			if(!exists("packages" + install_iter->path().filename() + "/Mod_Info.cfg"));
-			file.close();
-			file.open( ("packages" + install_iter->path().filename() + "/Mod_Info.cfg").c_str());
-			if (!file.fail())
-			{
-				ModPackage installedPackage = fileToModPackage(file, install_iter->path().filename());
-			}
-			else
-			{
-				file.close();
-				return UPDATE_THIRD_PARTY;
-			}
-			file.close();
-			if(updatePackage.modStringVersion > installedPackage.modStringVersion) {
-				return UPDATE_THIRD_PARTY;
-			}
-			
-		}
-		}
-		
-	}
+	try
+	{
+		directory_iterator end;
+		if (exists("../updates"))
+		{
+			for (directory_iterator install_iter("../updates"); install_iter != end; ++install_iter)
+			{
+				ModPackage installedPackage, updatePackage;
+				if (is_directory(install_iter->path()) && exists(install_iter->path().string() + "/Mod_Info.cfg"))
+				{
+					fstream file;
+					file.open((install_iter->path().string() + "/Mod_Info.cfg").c_str());
+					if (!file.fail())
+						ModPackage updatePackage = fileToModPackage(file, install_iter->path().filename());
+					else
+					{
+						file.close();
+						continue;
+					}
+					if (exists("packages" + install_iter->path().filename() + "/Mod_Info.cfg"))
+					{
+						file.close();
+						file.open(("packages" + install_iter->path().filename() + "/Mod_Info.cfg").c_str());
+						if (!file.fail())
+							ModPackage installedPackage = fileToModPackage(file, install_iter->path().filename());
+						file.close();
+						if (updatePackage.modStringVersion > installedPackage.modStringVersion)
+						{
+							if (updatePackage.installerVersion <= INSTALLER_VERSION)
+								return UPDATE_PKG_AVAIL;
+						}
+					}
+					else
+					{
+						file.close();
+						return UPDATE_PKG_AVAIL;
+					}
+				}
+			}
+		}
 	}
 	catch (exception & ex) {
 	//	setStatusArea("Warning, handled exception: " + (string)ex.what());
 	}
-	
 
 	return UPDATE_NO_UPD_AVAIL;
@@ -1243,5 +1236,4 @@
 	string popenCommand = "../updates/" + strEUFN + "/install/";
 #ifdef WIN32
-	// TODO: Fill in Windows equivalent of code below :-3
 	popenCommand = "replace_installer.bat";
 #else
@@ -1273,74 +1265,4 @@
 	return true; // returning 'true' tells the Installer to quit itself ASAP so it can be replaced by the process that is now running
 }
-//strPathToEUFNPackages
-
-void CrawlPackages(string pathToUpdate, string strPathToPackages) {
-	try{
-		directory_iterator end;
-		for ( directory_iterator update_iter( pathToUpdate );
-			update_iter != end;
-			++update_iter )
-		{
-
-			ModPackage installedPackage, updatePackage;
-			string updateStr = update_iter->path().string() + "/Mod_Info.cfg";
-			if ( !boost::iequals(update_iter->path().filename(),"Edition")
-				&& !boost::iequals(update_iter->path().filename(),"Edition-patch")
-				&& is_directory( update_iter->path() ) 
-				&& exists( update_iter->path().string() + "/Mod_Info.cfg" ) ) 
-			{
-				bool update = 0;
-				fstream file;
-				file.open( (update_iter->path().string() + "/Mod_Info.cfg").c_str());	
-				if (!file.fail())
-				{
-					updatePackage = fileToModPackage(file, update_iter->path().filename());
-				}
-				else 
-				{
-					file.close();
-					continue;
-				}
-				if(!exists(strPathToPackages + "/" + update_iter->path().filename() + "/Mod_Info.cfg"));
-				file.close();
-				file.clear();
-				file.open((strPathToPackages + "/" + update_iter->path().filename() + "/Mod_Info.cfg").c_str());
-				if (!file.fail())
-				{
-					installedPackage = fileToModPackage(file, update_iter->path().filename());
-					file.close();
-					if(updatePackage.modStringVersion > installedPackage.modStringVersion) {
-						remove_all((path)(strPathToPackages +  "/" + installedPackage.modStringName));			
-						update = 1;
-					}
-				}
-				else
-				{
-					file.close();
-					update = 1;
-				}
-				file.close();
-
-				if(update) {
-					rename((path)(pathToUpdate + "/" + updatePackage.modStringName), (path)(strPathToPackages + "/" + updatePackage.modStringName));
-
-				}
-			}
-		}
-	}
-	catch (exception & ex) {
-		//	ex.what();
-		setStatusArea("Warning, handled exception: " + (string)ex.what());
-	}
-}
-
-
-bool ProcessThirdPartyUpdates() {
-CrawlPackages( "../updates",  "./packages");
-return true;
-	//	globalPackages = getPackages(); 
-//	refreshMods(globalInstalledMods);
-}
-
 
 bool ProcessAEUpdate(Install_info_cfg *currentAE, Install_info_cfg *updateAE, bool *installerJustUpdated)
@@ -1369,7 +1291,6 @@
 	bool readingVerAndDate = false;
 	
-	// TODO: Fill in Windows equivalent of code below
 #ifdef WIN32
-	string strTrashDir = "Trash\\";
+	string strTrashDir = "Trash\\"; // string unused in Windows because files are simply deleted
 #else
 	FILE *fUserName = NULL;
@@ -1508,5 +1429,5 @@
 	}
 	
-	CrawlPackages( strPathToEUFNPackages,  strPathToPackages);
+	ProcessPackageUpdates(strPathToEUFNPackages, strPathToPackages);
 	
 	// Next, we get a list of which files and folders in the update's Globalize folder to move over; all files not starting with '.' will be moved...
@@ -1568,4 +1489,89 @@
 
 	return true;
+}
+
+void ProcessPackageUpdates(string pathToUpdate, string strPathToPackages)
+{
+	ptime startTime(second_clock::local_time());
+#ifdef WIN32
+	string strTrashDir = "Trash\\"; // string unused in Windows because files are simply deleted
+#else
+	FILE *fUserName = NULL;
+	char chrUserName[32];
+	fUserName = popen("whoami", "r");
+	fgets(chrUserName, sizeof(chrUserName), fUserName);
+	pclose(fUserName);
+	string strUserName = (string)chrUserName; // stringsblaaarrrgggghhhh
+	int endOfName = strUserName.find("\n", 0);
+	string strTrashDir = "/Users/" + strUserName.substr(0, endOfName) + "/.Trash/";
+	bool needNewTrashDir = true;
+	tm tmStartTime = to_tm(startTime);
+#endif
+	
+	try
+	{
+		directory_iterator end;
+		for (directory_iterator update_iter(pathToUpdate); update_iter != end; ++update_iter)
+		{
+			ModPackage installedPackage, updatePackage;
+			string updtPath = update_iter->path().string();
+			string updtFolder = update_iter->path().filename();
+			string updtModInfo = updtPath + "/Mod_Info.cfg";
+			string instModInfo = strPathToPackages + "/" + updtFolder + "/Mod_Info.cfg";
+			if (!boost::iequals(updtFolder, "Edition")
+				&& !boost::iequals(updtFolder, "Edition-patch")
+				&& is_directory(update_iter->path()) 
+				&& exists(updtModInfo)) 
+			{
+				fstream file;
+				file.open((updtModInfo).c_str());	
+				if (!file.fail())
+					updatePackage = fileToModPackage(file, updtFolder);
+				else
+				{
+					file.close();
+					continue;
+				}
+				if (exists(instModInfo))
+				{
+					file.close();
+					file.clear();
+					file.open(instModInfo.c_str());
+					if (!file.fail())
+					{
+						installedPackage = fileToModPackage(file, updtFolder);
+						file.close();
+						if (updatePackage.modStringVersion > installedPackage.modStringVersion)
+						{
+							if (updatePackage.installerVersion <= INSTALLER_VERSION)
+							{
+#ifdef WIN32
+								remove_all((path)(strPathToPackages +  "/" + installedPackage.modStringName));
+#else
+								if (needNewTrashDir)
+								{
+									strTrashDir = strTrashDir + "Old_packages_" + boost::lexical_cast<string>(tmStartTime.tm_hour) + "-" +
+												  boost::lexical_cast<string>(tmStartTime.tm_min) + "-" + boost::lexical_cast<string>(tmStartTime.tm_sec) + "/";
+									create_directory(strTrashDir);
+									needNewTrashDir = false;
+								}
+								rename((path)(strPathToPackages +  "/" + installedPackage.modStringName), (path)(strTrashDir + installedPackage.modStringName));
+#endif
+								rename((path)(pathToUpdate + "/" + updatePackage.modStringName), (path)(strPathToPackages + "/" + updatePackage.modStringName));
+							}
+						}
+					}
+					else
+						file.close();
+				}
+				file.close();
+				file.clear();
+			}
+		}
+	}
+	catch (exception & ex)
+	{
+		setStatusArea("Warning, handled exception: " + (string)ex.what());
+	}
 }
 
