diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 29cf231d45d8a18d1364765deb706155b96fc7af..072e5a82b47ae2cc30800f4f888b7cc249cb5027 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -407,7 +407,7 @@ LLAgent::LLAgent() :
 	mNextFidgetTime(0.f),
 	mCurrentFidget(0),
 	mFirstLogin(FALSE),
-	mGenderChosen(FALSE),
+	mOutfitChosen(FALSE),
 	
 	mVoiceConnected(false),
 
@@ -1853,7 +1853,7 @@ BOOL LLAgent::needsRenderAvatar()
 		return FALSE;
 	}
 
-	return mShowAvatar && mGenderChosen;
+	return mShowAvatar && mOutfitChosen;
 }
 
 // TRUE if we need to render your own avatar's head.
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index d0a48207b5efc3a6a00ecdf73a98e4146432138e..f2a42347b73c3c6036492d9ffcf72fb5e9a6fa1e 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -161,12 +161,13 @@ class LLAgent : public LLOldEvents::LLObservable
 	// Gender
 	//--------------------------------------------------------------------
 public:
-	// On the very first login, gender isn't chosen until the user clicks
-	// in a dialog.  We don't render the avatar until they choose.
-	BOOL 			isGenderChosen() const 	{ return mGenderChosen; }
-	void			setGenderChosen(BOOL b)	{ mGenderChosen = b; }
+	// On the very first login, outfit needs to be chosen by some
+	// mechanism, usually by loading the requested initial outfit.  We
+	// don't render the avatar until the choice is made.
+	BOOL 			isOutfitChosen() const 	{ return mOutfitChosen; }
+	void			setOutfitChosen(BOOL b)	{ mOutfitChosen = b; }
 private:
-	BOOL			mGenderChosen;
+	BOOL			mOutfitChosen;
 
 /**                    Identity
  **                                                                            **
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 798b733efb20704901a26fdc482438e001ed4042..96ce8d1f6de5e340ad384692e65ecb85f84b5f75 100755
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -175,10 +175,6 @@ void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
 {
 	llassert(avatar);
 	setAvatarAppearance(avatar);
-	gAgentWearables.notifyLoadingStarted();
-	callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
-						   boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF,
-									   LLAppearanceMgr::getInstance(), true, true, no_op));
 }
 
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0bf25271954fdc0db9dcdd3ad9af081dc73e41ce..43ba66f8c5f05f999f2b1a6d33c7ad3f71e1640d 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -4004,7 +4004,7 @@ class LLWearFolderHandler : public LLCommandHandler
 			LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
 
 			// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
-			gAgent.setGenderChosen(TRUE);
+			gAgent.setOutfitChosen(TRUE);
 		}
 
 		// release avatar picker keyboard focus
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 239227b904535679693a37f91c1f88a1f27b5622..09147afb23c41e695f3fe60414c3d337173c0ea9 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2020,7 +2020,7 @@ bool idle_startup()
 	{
 		display_startup();
 		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
-
+		
 		// We now have an inventory skeleton, so if this is a user's first
 		// login, we can start setting up their clothing and avatar 
 		// appearance.  This helps to avoid the generic "Ruth" avatar in
@@ -2029,20 +2029,42 @@ bool idle_startup()
 			&& !sInitialOutfit.empty()    // registration set up an outfit
 			&& !sInitialOutfitGender.empty() // and a gender
 			&& isAgentAvatarValid()	  // can't wear clothes without object
-			&& !gAgent.isGenderChosen() ) // nothing already loading
+			&& !gAgent.isOutfitChosen()) // nothing already loading
 		{
 			// Start loading the wearables, textures, gestures
 			LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
 		}
+		// If not first login, we need to fetch COF contents and
+		// compute appearance from that.
+		if (isAgentAvatarValid() && !gAgent.isFirstLogin() && !gAgent.isOutfitChosen())
+		{
+			gAgentWearables.notifyLoadingStarted();
+			callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
+								   boost::bind(&LLAppearanceMgr::updateAppearanceFromCOF,
+											   LLAppearanceMgr::getInstance(), true, true, no_op));
+			LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
+			gAgent.setOutfitChosen(TRUE);
+		}
 
 		display_startup();
 
 		// wait precache-delay and for agent's avatar or a lot longer.
-		if(((timeout_frac > 1.f) && isAgentAvatarValid())
-		   || (timeout_frac > 3.f))
+		if ((timeout_frac > 1.f) && isAgentAvatarValid())
 		{
 			LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
 		}
+		else if (timeout_frac > 10.f) 
+		{
+			// If we exceed the wait above while isAgentAvatarValid is
+			// not true yet, we will change startup state and
+			// eventually (once avatar does get created) wind up at
+			// the gender chooser. This should occur only in very
+			// unusual circumstances, so set the timeout fairly high
+			// to minimize mistaken hits here.
+			llwarns << "Wait for valid avatar state exceeded " 
+					<< timeout.getElapsedTimeF32() << " will invoke gender chooser" << llendl; 
+			LLStartUp::setStartupState( STATE_WEARABLES_WAIT );
+		}
 		else
 		{
 			update_texture_fetch();
@@ -2062,12 +2084,11 @@ bool idle_startup()
 		const F32 wearables_time = wearables_timer.getElapsedTimeF32();
 		const F32 MAX_WEARABLES_TIME = 10.f;
 
-#if 0
-		if (!gAgent.isGenderChosen() && isAgentAvatarValid())
+		if (!gAgent.isOutfitChosen() && isAgentAvatarValid())
 		{
-			// No point in waiting for clothing, we don't even
-			// know what gender we are.  Pop a dialog to ask and
-			// proceed to draw the world. JC
+			// No point in waiting for clothing, we don't even know
+			// what outfit we want.  Pop up a gender chooser dialog to
+			// ask and proceed to draw the world. JC
 			//
 			// *NOTE: We might hit this case even if we have an
 			// initial outfit, but if the load hasn't started
@@ -2078,13 +2099,12 @@ bool idle_startup()
 			LLStartUp::setStartupState( STATE_CLEANUP );
 			return TRUE;
 		}
-#endif
 		
 		display_startup();
 
-		if (wearables_time > MAX_WEARABLES_TIME)
+		if (gAgent.isOutfitChosen() && (wearables_time > MAX_WEARABLES_TIME))
 		{
-			LLNotificationsUtil::add("ClothingLoading");
+			llwarns << "wearables_time " << wearables_time << "exceeded max wait of " << MAX_WEARABLES_TIME << llendl;
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
 			LLStartUp::setStartupState( STATE_CLEANUP );
 			return TRUE;
@@ -2096,7 +2116,7 @@ bool idle_startup()
 			if (isAgentAvatarValid()
 				&& gAgentAvatarp->isFullyLoaded())
 			{
-				//llinfos << "avatar fully loaded" << llendl;
+				LL_DEBUGS("Avatar") << "avatar fully loaded" << llendl;
 				LLStartUp::setStartupState( STATE_CLEANUP );
 				return TRUE;
 			}
@@ -2107,7 +2127,7 @@ bool idle_startup()
 			if ( gAgentWearables.areWearablesLoaded() )
 			{
 				// We have our clothing, proceed.
-				//llinfos << "wearables loaded" << llendl;
+				LL_DEBUGS("Avatar") << "wearables loaded" << llendl;
 				LLStartUp::setStartupState( STATE_CLEANUP );
 				return TRUE;
 			}
@@ -2601,9 +2621,7 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 		lldebugs << "initial outfit category id: " << cat_id << llendl;
 	}
 
-	// This is really misnamed -- it means we have started loading
-	// an outfit/shape that will give the avatar a gender eventually. JC
-	gAgent.setGenderChosen(TRUE);
+	gAgent.setOutfitChosen(TRUE);
 }
 
 //static
@@ -3364,7 +3382,11 @@ bool process_login_success_response()
 		flag = login_flags["gendered"].asString();
 		if(flag == "Y")
 		{
-			gAgent.setGenderChosen(TRUE);
+			// We don't care about this flag anymore; now base whether
+			// outfit is chosen on COF contents, initial outfit
+			// requested and available, etc.
+
+			//gAgent.setGenderChosen(TRUE);
 		}
 		
 		bool pacific_daylight_time = false;