diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 41cd77b45d58bf49b30980e0648537c930765b47..d14de1c3012440f061c797e203f66e240e53b861 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1243,14 +1243,14 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
 void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 {
        sRegisteredAttachments.insert(item_id);
-       dumpAttachmentSet(sRegisteredAttachments,"after register:");
+       //dumpAttachmentSet(sRegisteredAttachments,"after register:");
 
 	   if (sAttachmentInvLinkEnabled)
 	   {
 		   LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		   if (item)
 		   {
-			   LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
+			   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
 			   LLAppearanceManager::wearItem(item,false);  // Add COF link for item.
 			   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 			   gInventory.notifyObservers();
@@ -1258,7 +1258,7 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 	   }
 	   else
 	   {
-		   llinfos << "no link changes, inv link not enabled" << llendl;
+		   //llinfos << "no link changes, inv link not enabled" << llendl;
 	   }
 }
 
@@ -1266,11 +1266,11 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
 {
        sRegisteredAttachments.erase(item_id);
-       dumpAttachmentSet(sRegisteredAttachments,"after unregister:");
+       //dumpAttachmentSet(sRegisteredAttachments,"after unregister:");
 
 	   if (sAttachmentInvLinkEnabled)
 	   {
-		   LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
+		   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
 		   LLAppearanceManager::removeItemLinks(item_id, false);
 		   // BAP - needs to change for label to track link.
 		   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
@@ -1278,6 +1278,6 @@ void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
 	   }
 	   else
 	   {
-		   llinfos << "no link changes, inv link not enabled" << llendl;
+		   //llinfos << "no link changes, inv link not enabled" << llendl;
 	   }
 }
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b41695fd3419b86ddaea79b976987f0f3d580197..2693396841fc6d22667f05ac6961b957aa17615c 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -81,6 +81,10 @@ BOOL LLInventoryModel::sTimelyFetchPending = FALSE;
 LLFrameTimer LLInventoryModel::sFetchTimer;
 S16 LLInventoryModel::sBulkFetchCount = 0;
 
+// Increment this if the inventory contents change in a non-backwards-compatible way.
+// For viewer 2, the addition of link items makes a pre-viewer-2 cache incorrect.
+const S32 LLInventoryModel::sCurrentInvCacheVersion = 2;
+
 // RN: for some reason, using std::queue in the header file confuses the compiler which things it's an xmlrpc_queue
 static std::deque<LLUUID> sFetchQueue;
 
@@ -2109,7 +2113,8 @@ bool LLInventoryModel::loadSkeleton(
 				llinfos << "Unable to gunzip " << gzip_filename << llendl;
 			}
 		}
-		if(loadFromFile(inventory_filename, categories, items))
+		bool is_cache_obsolete = false;
+		if(loadFromFile(inventory_filename, categories, items, is_cache_obsolete))
 		{
 			// We were able to find a cache of files. So, use what we
 			// found to generate a set of categories we should add. We
@@ -2244,6 +2249,12 @@ bool LLInventoryModel::loadSkeleton(
 			// clean up the gunzipped file.
 			LLFile::remove(inventory_filename);
 		}
+		if(is_cache_obsolete)
+		{
+			// If out of date, remove the gzipped file too.
+			llwarns << "Inv cache out of date, removing" << llendl;
+			LLFile::remove(gzip_filename);
+		}
 		categories.clear(); // will unref and delete entries
 	}
 
@@ -2642,7 +2653,8 @@ bool LLUUIDAndName::operator>(const LLUUIDAndName& rhs) const
 // static
 bool LLInventoryModel::loadFromFile(const std::string& filename,
 									LLInventoryModel::cat_array_t& categories,
-									LLInventoryModel::item_array_t& items)
+									LLInventoryModel::item_array_t& items,
+									bool &is_cache_obsolete)
 {
 	if(filename.empty())
 	{
@@ -2659,11 +2671,32 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 	// *NOTE: This buffer size is hard coded into scanf() below.
 	char buffer[MAX_STRING];		/*Flawfinder: ignore*/
 	char keyword[MAX_STRING];		/*Flawfinder: ignore*/
+	char value[MAX_STRING];			/*Flawfinder: ignore*/
+	is_cache_obsolete = true;  		// Obsolete until proven current
 	while(!feof(file) && fgets(buffer, MAX_STRING, file)) 
 	{
-		sscanf(buffer, " %254s", keyword);	/* Flawfinder: ignore */
-		if(0 == strcmp("inv_category", keyword))
+		sscanf(buffer, " %126s %126s", keyword, value);	/* Flawfinder: ignore */
+		if(0 == strcmp("inv_cache_version", keyword))
 		{
+			S32 version;
+			int succ = sscanf(value,"%d",&version);
+			if ((1 == succ) && (version == sCurrentInvCacheVersion))
+			{
+				// Cache is up to date
+				is_cache_obsolete = false;
+				continue;
+			}
+			else
+			{
+				// Cache is out of date
+				break;
+			}
+		}
+		else if(0 == strcmp("inv_category", keyword))
+		{
+			if (is_cache_obsolete)
+				break;
+			
 			LLPointer<LLViewerInventoryCategory> inv_cat = new LLViewerInventoryCategory(LLUUID::null);
 			if(inv_cat->importFileLocal(file))
 			{
@@ -2677,6 +2710,9 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 		}
 		else if(0 == strcmp("inv_item", keyword))
 		{
+			if (is_cache_obsolete)
+				break;
+
 			LLPointer<LLViewerInventoryItem> inv_item = new LLViewerInventoryItem;
 			if( inv_item->importFileLocal(file) )
 			{
@@ -2708,6 +2744,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
 		}
 	}
 	fclose(file);
+	if (is_cache_obsolete)
+		return false;
 	return true;
 }
 
@@ -2729,6 +2767,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
 		return false;
 	}
 
+	fprintf(file, "\tinv_cache_version\t%d\n",sCurrentInvCacheVersion);
 	S32 count = categories.count();
 	S32 i;
 	for(i = 0; i < count; ++i)
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index aba0a619dba03e91ca1b19ed114bac55e770b420..faf026887a91f2a90da901f12ab0aa0849ebd143 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -446,7 +446,8 @@ class LLInventoryModel
 	// file import/export.
 	static bool loadFromFile(const std::string& filename,
 							 cat_array_t& categories,
-							 item_array_t& items); 
+							 item_array_t& items,
+							 bool& is_cache_obsolete); 
 	static bool saveToFile(const std::string& filename,
 						   const cat_array_t& categories,
 						   const item_array_t& items); 
@@ -518,6 +519,9 @@ class LLInventoryModel
 	static F32 sMaxTimeBetweenFetches;
 	static S16 sBulkFetchCount;
 
+	// Expected inventory cache version
+	const static S32 sCurrentInvCacheVersion;
+	
 	// This flag is used to handle an invalid inventory state.
 	bool mIsAgentInvUsable;