diff --git a/doc/contributions.txt b/doc/contributions.txt
index cdda70a5c2ca23976a2a13176ba0302ad3c47a68..208bc534bfd669aea967662f0c1aeb361ff97e11 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -95,6 +95,7 @@ Gigs Taggart
 	VWR-101
 	VWR-166
 	VWR-234
+	VWR-315
 	VWR-326
 	VWR-493
 	VWR-1203
diff --git a/indra/llcharacter/llmotioncontroller.cpp b/indra/llcharacter/llmotioncontroller.cpp
index bef5ea5dbba422572a6098bcbfd746e7c4f7eb77..83f16e1556be0451f50fd45c899d57df41b60fcc 100644
--- a/indra/llcharacter/llmotioncontroller.cpp
+++ b/indra/llcharacter/llmotioncontroller.cpp
@@ -743,6 +743,10 @@ void LLMotionController::updateMotion()
 	{
 		motion_set_t::iterator curiter = iter++;
 		LLMotion* motionp = *curiter;
+		if( !motionp)
+		{
+			continue; // maybe shouldn't happen but i've seen it -MG
+		}
 		LLMotion::LLMotionInitStatus status = motionp->onInitialize(mCharacter);
 		if (status == LLMotion::STATUS_SUCCESS)
 		{
diff --git a/indra/llimage/llimageworker.cpp b/indra/llimage/llimageworker.cpp
index 9a200cdf61a3f7017b99792511f8652e85b566c8..75cf24947dc4b282b3f148312f6dc038fa088384 100644
--- a/indra/llimage/llimageworker.cpp
+++ b/indra/llimage/llimageworker.cpp
@@ -79,10 +79,7 @@ bool LLImageWorker::doWork(S32 param)
 		}
 		else
 		{
-			S32 nc = param ? 1 : mFormattedImage->getComponents();
-			mDecodedImage = new LLImageRaw(mFormattedImage->getWidth(),
-										   mFormattedImage->getHeight(),
-										   nc);
+			mDecodedImage = new LLImageRaw(); // allow possibly smaller size set during decoding
 		}
 	}
 	if (!decoded)
diff --git a/indra/llimagej2coj/llimagej2coj.cpp b/indra/llimagej2coj/llimagej2coj.cpp
index 68a3152f0aa9ad2269ac09875fbf0bf86762eb82..7def8ca07fc4561276a5e416f02248ad74ee6f8a 100644
--- a/indra/llimagej2coj/llimagej2coj.cpp
+++ b/indra/llimagej2coj/llimagej2coj.cpp
@@ -10,7 +10,6 @@
 #include "llimagej2coj.h"
 
 // this is defined so that we get static linking.
-#define OPJ_STATIC
 #include "openjpeg/openjpeg.h"
 
 #include "lltimer.h"
diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h
index 8aa03628f2ba688c5535bf2be3bd30fad7ba885e..93cd16c13a1e64a54ca13cec7a6712711b15133c 100644
--- a/indra/llmath/llquantize.h
+++ b/indra/llmath/llquantize.h
@@ -20,6 +20,18 @@ const U8 FIRSTVALIDCHAR = 54;
 const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null 
 
 
+inline U16 F32_to_U16_ROUND(F32 val, F32 lower, F32 upper)
+{
+	val = llclamp(val, lower, upper);
+	// make sure that the value is positive and normalized to <0, 1>
+	val -= lower;
+	val /= (upper - lower);
+
+	// round the value.   Sreturn the U16
+	return (U16)(llround(val*U16MAX));
+}
+
+
 inline U16 F32_to_U16(F32 val, F32 lower, F32 upper)
 {
 	val = llclamp(val, lower, upper);
@@ -47,6 +59,19 @@ inline F32 U16_to_F32(U16 ival, F32 lower, F32 upper)
 	return val;
 }
 
+
+inline U8 F32_to_U8_ROUND(F32 val, F32 lower, F32 upper)
+{
+	val = llclamp(val, lower, upper);
+	// make sure that the value is positive and normalized to <0, 1>
+	val -= lower;
+	val /= (upper - lower);
+
+	// return the rounded U8
+	return (U8)(llround(val*U8MAX));
+}
+
+
 inline U8 F32_to_U8(F32 val, F32 lower, F32 upper)
 {
 	val = llclamp(val, lower, upper);
diff --git a/indra/llmath/llquaternion.cpp b/indra/llmath/llquaternion.cpp
index 8b2808164f08db48ca175edf95a55978d9cb5f2f..d5fe93118737a823eb0873f9f10d9cc8750d2bb3 100644
--- a/indra/llmath/llquaternion.cpp
+++ b/indra/llmath/llquaternion.cpp
@@ -87,23 +87,27 @@ void	LLQuaternion::quantize16(F32 lower, F32 upper)
 	F32 z = mQ[VZ];
 	F32 s = mQ[VS];
 
-	x = U16_to_F32(F32_to_U16(x, lower, upper), lower, upper);
-	y = U16_to_F32(F32_to_U16(y, lower, upper), lower, upper);
-	z = U16_to_F32(F32_to_U16(z, lower, upper), lower, upper);
-	s = U16_to_F32(F32_to_U16(s, lower, upper), lower, upper);
+	x = U16_to_F32(F32_to_U16_ROUND(x, lower, upper), lower, upper);
+	y = U16_to_F32(F32_to_U16_ROUND(y, lower, upper), lower, upper);
+	z = U16_to_F32(F32_to_U16_ROUND(z, lower, upper), lower, upper);
+	s = U16_to_F32(F32_to_U16_ROUND(s, lower, upper), lower, upper);
 
 	mQ[VX] = x;
 	mQ[VY] = y;
 	mQ[VZ] = z;
 	mQ[VS] = s;
+
+	normQuat();
 }
 
 void	LLQuaternion::quantize8(F32 lower, F32 upper)
 {
-	mQ[VX] = U8_to_F32(F32_to_U8(mQ[VX], lower, upper), lower, upper);
-	mQ[VY] = U8_to_F32(F32_to_U8(mQ[VY], lower, upper), lower, upper);
-	mQ[VZ] = U8_to_F32(F32_to_U8(mQ[VZ], lower, upper), lower, upper);
-	mQ[VS] = U8_to_F32(F32_to_U8(mQ[VS], lower, upper), lower, upper);
+	mQ[VX] = U8_to_F32(F32_to_U8_ROUND(mQ[VX], lower, upper), lower, upper);
+	mQ[VY] = U8_to_F32(F32_to_U8_ROUND(mQ[VY], lower, upper), lower, upper);
+	mQ[VZ] = U8_to_F32(F32_to_U8_ROUND(mQ[VZ], lower, upper), lower, upper);
+	mQ[VS] = U8_to_F32(F32_to_U8_ROUND(mQ[VS], lower, upper), lower, upper);
+
+	normQuat();
 }
 
 // LLVector3 Magnitude and Normalization Functions
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index 7b07dfd0e0853cab5e80562d6581801c3477b4a3..142e6a50e8e9f73507ed6a9d26efbd9351522562 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -316,7 +316,7 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
 
 	while (mZStream.avail_out > 0)
 	{
-		if (mZStream.avail_in == 0  &&  !mZInputExhausted)
+		if (mZStream.avail_in == 0 && !mZInputExhausted)
 		{
 			S32 to_read = llmin(COMPRESSED_INPUT_BUFFER_SIZE,
 							(S32)(mVFile->getSize() - mVFile->tell()));
@@ -324,14 +324,9 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
 			if ( to_read > 0 )
 			{
 				mVFile->read((U8*)mZInputBuffer, to_read); /*Flawfinder: ignore*/
+				mZStream.next_in = (Bytef*)mZInputBuffer;
+				mZStream.avail_in = mVFile->getLastBytesRead();
 			}
-			else
-			{
-				llwarns << "LLHTTPAssetRequest::readCompressedData has zero read length" << llendl;
-				break;
-			}
-			mZStream.next_in = (Bytef*)mZInputBuffer;
-			mZStream.avail_in = mVFile->getLastBytesRead();
 
 			mZInputExhausted = mZStream.avail_in == 0;
 		}
@@ -339,8 +334,13 @@ size_t LLHTTPAssetRequest::readCompressedData(void* data, size_t size)
 		int r = deflate(&mZStream,
 					mZInputExhausted ? Z_FINISH : Z_NO_FLUSH);
 
-		if (r == Z_STREAM_END || r < 0)
+		if (r == Z_STREAM_END || r < 0 || mZInputExhausted)
 		{
+			if (r < 0)
+			{
+				llwarns << "LLHTTPAssetRequest::readCompressedData: deflate returned error code " 
+						<< (S32) r << llendl;
+			}
 			break;
 		}
 	}
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index ccf18a3506c6e6cc889db74659b6867f27cf3732..30feb85b2c82537a67ac32ec78d18774e596aa04 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -135,7 +135,8 @@ LLLineEditor::LLLineEditor(const LLString& name, const LLRect& rect,
 		mHandleEditKeysDirectly( FALSE ),
 		mSelectAllonFocusReceived( FALSE ),
 		mPassDelete(FALSE),
-		mReadOnly(FALSE)
+		mReadOnly(FALSE),
+		mLastIMEPosition( -1, -1 )
 {
 	llassert( max_length_bytes > 0 );
 
@@ -1609,6 +1610,17 @@ void LLLineEditor::draw()
 						LLFontGL::NORMAL,
 						1);
 				}
+
+				// Make sure the IME is in the right place
+				S32 pixels_after_scroll = findPixelNearestPos();	// RCalculcate for IME position
+				LLRect screen_pos = getScreenRect();
+				LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - UI_LINEEDITOR_V_PAD );
+				if ( ime_pos.mX != mLastIMEPosition.mX || ime_pos.mY != mLastIMEPosition.mY )
+				{
+					mLastIMEPosition.mX = ime_pos.mX;
+					mLastIMEPosition.mY = ime_pos.mY;
+					getWindow()->setLanguageTextInput( ime_pos );
+				}
 			}
 		}
 
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index db6aea84323d2b0f4444cb72d188b41bf5b22e5b..6de2fc3ebaa787e0d66373cd6904768e3745bd66 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -256,6 +256,8 @@ class LLLineEditor
 
 	S32			mBorderThickness;
 
+	LLCoordGL	mLastIMEPosition;		// Last screen position used for the IME editor
+
 	BOOL		mIgnoreArrowKeys;
 	BOOL		mIgnoreTab;
 	BOOL		mDrawAsterixes;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 52f8c19ebda6bbcae902a2b4d3aef0e8e1c04a16..1ec62f69278227437ae0bac9d12e53e1ab833274 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -286,7 +286,8 @@ LLTextEditor::LLTextEditor(
 	mMouseDownX(0),
 	mMouseDownY(0),
 	mLastSelectionX(-1),
-	mLastSelectionY(-1)
+	mLastSelectionY(-1),
+	mLastIMEPosition(-1,-1)
 {
 	mSourceID.generate();
 
@@ -2799,7 +2800,15 @@ void LLTextEditor::drawCursor()
 						1);
 				}
 
-
+				// Make sure the IME is in the right place
+				LLRect screen_pos = getScreenRect();
+				LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_left), screen_pos.mBottom + llfloor(cursor_top) );
+				if ( ime_pos.mX != mLastIMEPosition.mX || ime_pos.mY != mLastIMEPosition.mY )
+				{
+					mLastIMEPosition.mX = ime_pos.mX;
+					mLastIMEPosition.mY = ime_pos.mY;
+					getWindow()->setLanguageTextInput( ime_pos );
+				}
 			}
 		}
 	}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 7c7ec9c13b7c17b1a1f85ba417d96d8a08667b9a..e19e7990339e9fe8ddb298b183ef66258e27ad31 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -414,6 +414,8 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler
 
 	BOOL			mParseHTML;
 	LLString		mHTML;
+
+	LLCoordGL		mLastIMEPosition;		// Last position of the IME editor
 };
 
 class LLTextSegment
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 1347d8e94ca426ac6dbb2e79a8d31897a898eaa8..f1c188f8e96fe217a0dbdf9af83c3a507736bd04 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -200,7 +200,7 @@ class LLWindow
 	
 	// control platform's Language Text Input mechanisms.
 	virtual void allowLanguageTextInput( BOOL b ) {};
-	virtual void setLanguageTextInput( LLCoordWindow pos ) {};
+	virtual void setLanguageTextInput( const LLCoordGL & pos ) {};
 
 protected:
 	LLWindow(BOOL fullscreen, U32 flags);
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 299ccc39f33685bf5b518b4d98d487506d092bfe..cb108143f4d35acbe85751e6065cbe88f23ab75f 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -65,11 +65,10 @@ void show_window_creation_error(const char* title)
 //static
 BOOL LLWindowWin32::sIsClassRegistered = FALSE;
 
-BOOL	LLWindowWin32::sLanguageTextInputAllowed = TRUE; /* XXX */
-BOOL	LLWindowWin32::sWinIMEOpened = FALSE;
-HKL		LLWindowWin32::sWinInputLocale;
-DWORD	LLWindowWin32::sWinIMEConversionMode;
-DWORD	LLWindowWin32::sWinIMESentenceMode;
+BOOL	LLWindowWin32::sLanguageTextInputAllowed = TRUE;
+HKL		LLWindowWin32::sWinInputLocale = 0;
+DWORD	LLWindowWin32::sWinIMEConversionMode = IME_CMODE_NATIVE;
+DWORD	LLWindowWin32::sWinIMESentenceMode = IME_SMODE_AUTOMATIC;
 
 // The following class LLWinImm delegates Windows IMM APIs.
 // We need this because some language versions of Windows,
@@ -87,13 +86,15 @@ class LLWinImm
 
 public:
 	// Wrappers for IMM API.
-	static BOOL		isIME(HKL hkl)															{ return sTheInstance.mImmIsIME(hkl); }
-	static HIMC		getContext(HWND hwnd)													{ return sTheInstance.mImmGetContext(hwnd); }
-	static BOOL		releaseContext(HWND hwnd, HIMC himc)									{ return sTheInstance.mImmReleaseContext(hwnd, himc); }
-	static BOOL		getOpenStatus(HIMC himc)												{ return sTheInstance.mImmGetOpenStatus(himc); }
-	static BOOL		setOpenStatus(HIMC himc, BOOL status)									{ return sTheInstance.mImmSetOpenStatus(himc, status); }
-	static BOOL		getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)	{ return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); }
-	static BOOL		setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)		{ return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); }
+	static BOOL		isIME(HKL hkl);															
+	static HIMC		getContext(HWND hwnd);													
+	static BOOL		releaseContext(HWND hwnd, HIMC himc);
+	static BOOL		getOpenStatus(HIMC himc);												
+	static BOOL		setOpenStatus(HIMC himc, BOOL status);									
+	static BOOL		getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence);	
+	static BOOL		setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence);		
+	static BOOL		getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);					
+	static BOOL		setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form);					
 
 private:
 	LLWinImm();
@@ -108,6 +109,8 @@ class LLWinImm
 	BOOL		(WINAPI *mImmSetOpenStatus)(HIMC, BOOL);
 	BOOL		(WINAPI *mImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
 	BOOL		(WINAPI *mImmSetConversionStatus)(HIMC, DWORD, DWORD);
+	BOOL		(WINAPI *mImmGetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
+	BOOL		(WINAPI *mImmSetCompostitionWindow)(HIMC, LPCOMPOSITIONFORM);
 
 private:
 	HMODULE		mHImmDll;
@@ -116,8 +119,13 @@ class LLWinImm
 
 LLWinImm LLWinImm::sTheInstance;
 
-LLWinImm::LLWinImm()
+LLWinImm::LLWinImm() : mHImmDll(NULL)
 {
+	// Check system metrics 
+	if ( !GetSystemMetrics( SM_DBCSENABLED ) )
+		return;
+	
+
 	mHImmDll = LoadLibraryA("Imm32");
 	if (mHImmDll != NULL)
 	{
@@ -128,13 +136,18 @@ LLWinImm::LLWinImm()
 		mImmSetOpenStatus       = (BOOL (WINAPI *)(HIMC, BOOL))             GetProcAddress(mHImmDll, "ImmSetOpenStatus");
 		mImmGetConversionStatus = (BOOL (WINAPI *)(HIMC, LPDWORD, LPDWORD)) GetProcAddress(mHImmDll, "ImmGetConversionStatus");
 		mImmSetConversionStatus = (BOOL (WINAPI *)(HIMC, DWORD, DWORD))     GetProcAddress(mHImmDll, "ImmSetConversionStatus");
+		mImmGetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM))   GetProcAddress(mHImmDll, "ImmGetCompositionWindow");
+		mImmSetCompostitionWindow = (BOOL (WINAPI *)(HIMC, LPCOMPOSITIONFORM))   GetProcAddress(mHImmDll, "ImmSetCompositionWindow");
+
 		if (mImmIsIME == NULL ||
 			mImmGetContext == NULL ||
 			mImmReleaseContext == NULL ||
 			mImmGetOpenStatus == NULL ||
 			mImmSetOpenStatus == NULL ||
 			mImmGetConversionStatus == NULL ||
-			mImmSetConversionStatus == NULL)
+			mImmSetConversionStatus == NULL ||
+			mImmGetCompostitionWindow == NULL ||
+			mImmSetCompostitionWindow == NULL)
 		{
 			// If any of the above API entires are not found, we can't use IMM API.  
 			// So, turn off the IMM support.  We should log some warning message in 
@@ -145,10 +158,96 @@ LLWinImm::LLWinImm()
 			// is one of disadvantages to use static constraction to DLL loading. 
 			FreeLibrary(mHImmDll);
 			mHImmDll = NULL;
+
+			// If we unload the library, make sure all the function pointers are cleared
+			mImmIsIME = NULL;
+			mImmGetContext = NULL;
+			mImmReleaseContext = NULL;
+			mImmGetOpenStatus = NULL;
+			mImmSetOpenStatus = NULL;
+			mImmGetConversionStatus = NULL;
+			mImmSetConversionStatus = NULL;
+			mImmGetCompostitionWindow = NULL;
+			mImmSetCompostitionWindow = NULL;
 		}
 	}
 }
 
+
+// static 
+BOOL	LLWinImm::isIME(HKL hkl)															
+{ 
+	if ( sTheInstance.mImmIsIME )
+		return sTheInstance.mImmIsIME(hkl); 
+	return FALSE;
+}
+
+// static 
+HIMC		LLWinImm::getContext(HWND hwnd)
+{
+	if ( sTheInstance.mImmGetContext )
+		return sTheInstance.mImmGetContext(hwnd); 
+	return 0;
+}
+
+//static 
+BOOL		LLWinImm::releaseContext(HWND hwnd, HIMC himc)
+{ 
+	if ( sTheInstance.mImmIsIME )
+		return sTheInstance.mImmReleaseContext(hwnd, himc); 
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::getOpenStatus(HIMC himc)
+{ 
+	if ( sTheInstance.mImmGetOpenStatus )
+		return sTheInstance.mImmGetOpenStatus(himc); 
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::setOpenStatus(HIMC himc, BOOL status)									
+{ 
+	if ( sTheInstance.mImmSetOpenStatus )
+		return sTheInstance.mImmSetOpenStatus(himc, status); 
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::getConversionStatus(HIMC himc, LPDWORD conversion, LPDWORD sentence)	
+{ 
+	if ( sTheInstance.mImmGetConversionStatus )
+		return sTheInstance.mImmGetConversionStatus(himc, conversion, sentence); 
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::setConversionStatus(HIMC himc, DWORD conversion, DWORD sentence)		
+{ 
+	if ( sTheInstance.mImmSetConversionStatus )
+		return sTheInstance.mImmSetConversionStatus(himc, conversion, sentence); 
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::getCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)					
+{ 
+	if ( sTheInstance.mImmGetCompostitionWindow )
+		return sTheInstance.mImmGetCompostitionWindow(himc, form);	
+	return FALSE;
+}
+
+// static 
+BOOL		LLWinImm::setCompositionWindow(HIMC himc, LPCOMPOSITIONFORM form)					
+{ 
+	if ( sTheInstance.mImmSetCompostitionWindow )
+		return sTheInstance.mImmSetCompostitionWindow(himc, form);	
+	return FALSE;
+}
+
+
+// ----------------------------------------------------------------------------------------
 LLWinImm::~LLWinImm()
 {
 	if (mHImmDll != NULL)
@@ -3202,53 +3301,74 @@ void LLWindowWin32::focusClient()
 
 void LLWindowWin32::allowLanguageTextInput(BOOL b)
 {
-	if (b == sLanguageTextInputAllowed || !LLWinImm::isAvailable())
+	if ( !LLWinImm::isAvailable() )
 	{
-		/* Not actually allowing/disallowing.  Do nothing.  */
 		return;
 	}
 	sLanguageTextInputAllowed = b;
 
 	if (b)
 	{
-		/* Allowing: Restore the previous IME status, 
-		   so that the user has a feeling that the previous 
-		   text input continues naturally.  Be careful, however,
-		   the IME status is meaningful only during the user keeps 
-		   using same Input Locale (aka Keyboard Layout).  */
-		if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
+		// Allowing: Restore the previous IME status, so that the user has a feeling that the previous 
+		// text input continues naturally.  Be careful, however, the IME status is meaningful only during the user keeps 
+		// using same Input Locale (aka Keyboard Layout).
+		HIMC himc = LLWinImm::getContext(mWindowHandle);
+		LLWinImm::setOpenStatus(himc, TRUE);
+		if (GetKeyboardLayout(0) == sWinInputLocale && sWinIMEConversionMode != IME_CMODE_RESERVED)
 		{
-			HIMC himc = LLWinImm::getContext(mWindowHandle);
-			LLWinImm::setOpenStatus(himc, TRUE);
 			LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
-			LLWinImm::releaseContext(mWindowHandle, himc);
+			sWinIMEConversionMode = IME_CMODE_RESERVED;		// Set saved state so we won't do this repeatedly
 		}
+		LLWinImm::releaseContext(mWindowHandle, himc);
 	}
 	else
 	{
-		/* Disallowing: Turn off the IME so that succeeding 
-		   key events bypass IME and come to us directly.
-		   However, do it after saving the current IME 
-		   status.  We need to restore the status when
-		   allowing language text input again.  */
+		// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
+		// However, do it after saving the current IME  status.  We need to restore the status when
+		//   allowing language text input again.
 		sWinInputLocale = GetKeyboardLayout(0);
-		sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
-		if (sWinIMEOpened)
+		if ( LLWinImm::isIME(sWinInputLocale) )
 		{
 			HIMC himc = LLWinImm::getContext(mWindowHandle);
-			sWinIMEOpened = LLWinImm::getOpenStatus(himc);
-			if (sWinIMEOpened)
+			if ( LLWinImm::getOpenStatus(himc) )
 			{
 				LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
 
-				/* We need both ImmSetConversionStatus and ImmSetOpenStatus here
-				   to surely disable IME's keyboard hooking, because Some IME reacts 
-				   only on the former and some other on the latter...  */
+				// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's 
+				// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
 				LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
 				LLWinImm::setOpenStatus(himc, FALSE);
 			}
 			LLWinImm::releaseContext(mWindowHandle, himc);
+ 		}
+	}
+
+}
+
+
+// Put the IME window at the right place (near current text input).   Point coordinates should be the top of the current text line.
+void LLWindowWin32::setLanguageTextInput( const LLCoordGL & position )
+{
+	if (sLanguageTextInputAllowed && LLWinImm::isAvailable())
+	{
+		HIMC himc = LLWinImm::getContext(mWindowHandle);
+
+		LLCoordWindow win_pos;
+		convertCoords( position, &win_pos );
+
+		if ( win_pos.mX >= 0 && win_pos.mY >= 0 )
+		{
+			COMPOSITIONFORM ime_form;
+			memset( &ime_form, 0, sizeof(ime_form) );
+			ime_form.dwStyle = CFS_POINT;
+			ime_form.ptCurrentPos.x = win_pos.mX;
+			ime_form.ptCurrentPos.y = win_pos.mY;
+
+			LLWinImm::setCompositionWindow( himc, &ime_form );
 		}
+
+		LLWinImm::releaseContext(mWindowHandle, himc);
+
 	}
 }
 
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 5eb2cfbb79ba3ea048952c5aa2bf7a7307f9c76d..cb105c2128f5f98136d7dc3b164abd2b2f404c8c 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -87,6 +87,7 @@ class LLWindowWin32 : public LLWindow
 	/*virtual*/ void focusClient();
 
 	/*virtual*/ void allowLanguageTextInput(BOOL b);
+	/*virtual*/ void setLanguageTextInput( const LLCoordGL & pos );
 
 protected:
 	LLWindowWin32(
@@ -156,11 +157,10 @@ class LLWindowWin32 : public LLWindow
 	BOOL		mMousePositionModified;
 	BOOL		mInputProcessingPaused;
 
-	// The following five variables are for Language Text Input control.
+	// The following variables are for Language Text Input control.
 	// They are all static, since one context is shared by all LLWindowWin32
 	// instances.
 	static BOOL		sLanguageTextInputAllowed;
-	static BOOL		sWinIMEOpened;
 	static HKL		sWinInputLocale;
 	static DWORD	sWinIMEConversionMode;
 	static DWORD	sWinIMESentenceMode;
diff --git a/indra/lscript/lscript_byteconvert.h b/indra/lscript/lscript_byteconvert.h
index d30c84b28c61ab18b2ce8992c9c077656c13b993..d960eb8c662bc660696faa331d851fdcfac94ca4 100644
--- a/indra/lscript/lscript_byteconvert.h
+++ b/indra/lscript/lscript_byteconvert.h
@@ -761,9 +761,17 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven
 		major_version = LSL2_MAJOR_VERSION_TWO;
 		state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
 	}
+	if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 
 	// get the actual position in memory of the desired state
 	S32 state_offset = sr + bytestream2integer(stream, state_offset_offset);
+	if ( state_offset < 0 || state_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 
 	// save that value
 	S32 state_offset_base = state_offset;
@@ -773,18 +781,32 @@ inline S32 get_state_event_opcoode_start(U8 *stream, S32 state, LSCRIPTStateEven
 
 	// get the location of the event offset
 	S32 event_offset = event_jump_offset + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event);
+	if ( event_offset < 0 || event_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 
 	// now, jump to the event
 	S32 event_start = bytestream2integer(stream, event_offset);
+	if ( event_start < 0 || event_start > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 	event_start += event_jump_offset;
 
 	S32 event_start_original = event_start;
 
 	// now skip past the parameters
 	S32 opcode_offset = bytestream2integer(stream, event_start);
+	if ( opcode_offset < 0 || opcode_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
+
 	return opcode_offset + event_start_original;
 }
 
+
 inline U64 get_handled_events(U8 *stream, S32 state)
 {
 	U64 retvalue = 0;
@@ -809,6 +831,7 @@ inline U64 get_handled_events(U8 *stream, S32 state)
 	return retvalue;
 }
 
+// Returns -1 on error
 inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType event)
 {
 	// get the start of the state table
@@ -829,21 +852,39 @@ inline S32 get_event_stack_size(U8 *stream, S32 state, LSCRIPTStateEventType eve
 		state_offset_offset = sr + LSCRIPTDataSize[LST_INTEGER] + LSCRIPTDataSize[LST_INTEGER]*3*state;
 	}
 
+	if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
+
 	S32 state_offset = bytestream2integer(stream, state_offset_offset);
 	state_offset += sr;
 
 	state_offset_offset = state_offset;
+	if ( state_offset_offset < 0 || state_offset_offset > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 
 	// skip to jump table
 	S32 jump_table = bytestream2integer(stream, state_offset_offset);
 
 	jump_table += state_offset;
+	if ( jump_table < 0 || jump_table > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
 
 	// get the position of the jump to the desired state
 	S32 stack_size_offset = jump_table + LSCRIPTDataSize[LST_INTEGER]*2*get_event_handler_jump_position(get_event_register(stream, LREG_ER, major_version), event) + LSCRIPTDataSize[LST_INTEGER];
 
 	// get the handled events
 	S32 stack_size = bytestream2integer(stream, stack_size_offset);
+	if ( stack_size < 0 || stack_size > TOP_OF_MEMORY )
+	{
+		return -1;
+	}
+
 	return stack_size;
 }
 
diff --git a/indra/lscript/lscript_execute.h b/indra/lscript/lscript_execute.h
index 84cd6e3b0a7ba869c1565f01c7d413066c0c6f31..1c2952f5ae2dc4d10ad057f686df7c22b618a9ea 100644
--- a/indra/lscript/lscript_execute.h
+++ b/indra/lscript/lscript_execute.h
@@ -359,6 +359,10 @@ class LLScriptExecute
 	LLScriptEventData		mEventData;
 
 	static S64 sGlobalInstructionCount;
+
+private:
+	void		recordBoundaryError( const LLUUID &id );
+	void		setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id );
 };
 
 #endif
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index b166e922a27621c34e36dbacfcbebf6c37bdf870..d00d3372ce823db011bb234d5240c87dab199821 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -245,6 +245,32 @@ void LLScriptExecute::init()
 
 }
 
+
+// Utility routine for when there's a boundary error parsing bytecode
+void LLScriptExecute::recordBoundaryError( const LLUUID &id )
+{
+	set_fault(mBuffer, LSRF_BOUND_CHECK_ERROR);
+	llwarns << "Script boundary error for ID " << id << llendl;
+}
+
+
+//	set IP to the event handler with some error checking
+void LLScriptExecute::setStateEventOpcoodeStartSafely( S32 state, LSCRIPTStateEventType event, const LLUUID &id )
+{
+	S32			opcode_start = get_state_event_opcoode_start( mBuffer, state, event );
+	if ( opcode_start == -1 )
+	{
+		recordBoundaryError( id );
+	}
+	else
+	{
+		set_ip( mBuffer, opcode_start );
+	}
+}
+
+
+
+
 S32 lscript_push_variable(LLScriptLibData *data, U8 *buffer);
 
 U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &state_transition)
@@ -353,14 +379,20 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
 
 		//			now, push any additional stack space
 					S32 additional_size = get_event_stack_size(mBuffer, current_state, LSTT_STATE_EXIT);
-					lscript_pusharge(mBuffer, additional_size);
-
-					sp = get_register(mBuffer, LREG_SP);
-					sp += additional_size;
-					set_bp(mBuffer, sp);
-	//				set IP to the event handler
-					S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, LSTT_STATE_EXIT);
-					set_ip(mBuffer, opcode_start);
+					if ( additional_size == -1 )
+					{	
+						recordBoundaryError( id );
+					}
+					else
+					{
+						lscript_pusharge(mBuffer, additional_size);
+
+						sp = get_register(mBuffer, LREG_SP);
+						sp += additional_size;
+						set_bp(mBuffer, sp);
+		//				set IP to the event handler
+						setStateEventOpcoodeStartSafely( current_state, LSTT_STATE_EXIT, id );
+					}
 					return NO_DELETE_FLAG;
 				}
 			}
@@ -411,20 +443,27 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
 			current_events &= ~LSCRIPTStateBitField[event];
 			set_event_register(mBuffer, LREG_CE, current_events, major_version);
 //			now, push any additional stack space
-			S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
-			lscript_pusharge(mBuffer, additional_size);
+			S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+			if ( additional_size == -1 )
+			{	// b_done will be set, so we'll exit the loop at the bottom
+				recordBoundaryError( id );
+			}
+			else
+			{
+				additional_size -= size;
+				lscript_pusharge(mBuffer, additional_size);
 
 //			now set the bp correctly
-			sp = get_register(mBuffer, LREG_SP);
-			sp += additional_size + size;
-			set_bp(mBuffer, sp);
+				sp = get_register(mBuffer, LREG_SP);
+				sp += additional_size + size;
+				set_bp(mBuffer, sp);
 //			set IP to the function
-			S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
-			set_ip(mBuffer, opcode_start);
+				setStateEventOpcoodeStartSafely( current_state, event, id );
+			}
 			b_done = TRUE;
 		}
 		else if (  (current_events & LSCRIPTStateBitField[LSTT_REZ])
-				 &&(current_events & event_register))
+				&&(current_events & event_register))
 		{
 			for (eventdata = mEventData.mEventDataList.getFirstData(); eventdata; eventdata = mEventData.mEventDataList.getNextData())
 			{
@@ -449,17 +488,24 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
 						data++;
 					}
 		//			now, push any additional stack space
-					S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
-					lscript_pusharge(mBuffer, additional_size);
-
-		//			now set the bp correctly
-					sp = get_register(mBuffer, LREG_SP);
-					sp += additional_size + size;
-					set_bp(mBuffer, sp);
-		//			set IP to the function
-					S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
-					set_ip(mBuffer, opcode_start);
-					mEventData.mEventDataList.deleteCurrentData();
+					S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+					if ( additional_size == -1 )
+					{	// b_done will be set, so we'll exit the loop at the bottom
+						recordBoundaryError( id );
+					}
+					else
+					{
+						additional_size -= size;
+						lscript_pusharge(mBuffer, additional_size);
+
+			//			now set the bp correctly
+						sp = get_register(mBuffer, LREG_SP);
+						sp += additional_size + size;
+						set_bp(mBuffer, sp);
+			//			set IP to the function
+						setStateEventOpcoodeStartSafely( current_state, event, id );
+						mEventData.mEventDataList.deleteCurrentData();
+					}
 					b_done = TRUE;
 					break;
 				}
@@ -496,16 +542,23 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
 					}
 					b_done = TRUE;
 		//			now, push any additional stack space
-					S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
-					lscript_pusharge(mBuffer, additional_size);
-
-		//			now set the bp correctly
-					sp = get_register(mBuffer, LREG_SP);
-					sp += additional_size + size;
-					set_bp(mBuffer, sp);
-		//			set IP to the function
-					S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
-					set_ip(mBuffer, opcode_start);
+					S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+					if ( additional_size == -1 )
+					{	// b_done was just set, so we'll exit the loop at the bottom
+						recordBoundaryError( id );
+					}
+					else
+					{
+						additional_size -= size;
+						lscript_pusharge(mBuffer, additional_size);
+
+			//			now set the bp correctly
+						sp = get_register(mBuffer, LREG_SP);
+						sp += additional_size + size;
+						set_bp(mBuffer, sp);
+			//			set IP to the function
+						setStateEventOpcoodeStartSafely( current_state, event, id );
+					}
 				}
 				else
 				{
@@ -530,23 +583,30 @@ U32 LLScriptExecute::run(BOOL b_print, const LLUUID &id, char **errorstr, BOOL &
 					current_events &= ~LSCRIPTStateBitField[event];
 					set_event_register(mBuffer, LREG_CE, current_events, major_version);
 		//			now, push any additional stack space
-					S32 additional_size = get_event_stack_size(mBuffer, current_state, event) - size;
-					lscript_pusharge(mBuffer, additional_size);
-
-		//			now set the bp correctly
-					sp = get_register(mBuffer, LREG_SP);
-					sp += additional_size + size;
-					set_bp(mBuffer, sp);
-		//			set IP to the function
-					S32			opcode_start = get_state_event_opcoode_start(mBuffer, current_state, event);
-					set_ip(mBuffer, opcode_start);
+					S32 additional_size = get_event_stack_size(mBuffer, current_state, event);
+					if ( additional_size == -1 )
+					{	// b_done will be set, so we'll exit the loop at the bottom
+						recordBoundaryError( id );
+					}
+					else
+					{
+						additional_size -= size;
+						lscript_pusharge(mBuffer, additional_size);
+
+			//			now set the bp correctly
+						sp = get_register(mBuffer, LREG_SP);
+						sp += additional_size + size;
+						set_bp(mBuffer, sp);
+			//			set IP to the function
+						setStateEventOpcoodeStartSafely( current_state, event, id );
+					}
 				}
 				b_done = TRUE;
 			}
-		}
+		}	// while (!b_done)
+	} // end of else ...  in state processing code
 
-		return NO_DELETE_FLAG;
-	}
+	return NO_DELETE_FLAG;
 }
 
 BOOL run_noop(U8 *buffer, S32 &offset, BOOL b_print, const LLUUID &id)
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index ac967c4853084301530b134b17a19be8f1eb83c7..f720fc0ec1fc2fa06a8cecfb7ecf54e9a85bbd19 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -84,7 +84,30 @@ export SL_ENV='LD_LIBRARY_PATH="`pwd`"/lib:"`pwd`"/app_settings/mozilla-runtime-
 export SL_CMD='$LL_WRAPPER bin/do-not-directly-run-secondlife-bin'
 export SL_OPT="`cat gridargs.dat` $@"
 
-eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || echo Unclean shutdown.
+# Run the program
+eval ${SL_ENV} ${SL_CMD} ${SL_OPT} || LL_RUN_ERR=runerr
+
+# Handle any resulting errors
+if [ -n "$LL_RUN_ERR" ]; then
+	LL_RUN_ERR_MSG=""
+	if [ "$LL_RUN_ERR" = "runerr" ]; then
+		# generic error running the binary
+		echo '*** Unclean shutdown. ***'
+		if [ "`arch`" = "x86_64" ]; then
+			echo
+			cat << EOFMARKER
+You are running the Second Life Viewer on a x86_64 platform.  The
+most common problems when launching the Viewer (particularly
+'bin/do-not-directly-run-secondlife-bin: not found' and 'error while
+loading shared libraries') may be solved by installing your Linux
+distribution's 32-bit compatibility packages.
+For example, on Ubuntu and other Debian-based Linuxes you might run:
+$ sudo apt-get install ia32-libs ia32-libs-gtk ia32-libs-kde ia32-libs-sdl
+EOFMARKER
+		fi
+	fi
+fi
+	
 
 echo
 echo '*********************************************************'
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ead985a9929418c2dd1f5f75ab7cc1580f047d67..a37044f3642f8785c2dea7cebf6bb4480f475880 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -306,7 +306,7 @@ LLUUID LLInventoryModel::findCatUUID(LLAssetType::EType preferred_type)
 }
 
 // Convenience function to create a new category. You could call
-// updateCatgory() with a newly generated UUID category, but this
+// updateCategory() with a newly generated UUID category, but this
 // version will take care of details like what the name should be
 // based on preferred type. Returns the UUID of the new category.
 LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index a2cc0f5a81846cc260481acb9a9e05ee40c8b1b6..844afca629fbf6c72e80eac3346710c7e6fdb5d3 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -495,7 +495,6 @@ bool LLPanelGroupGeneral::apply(LLString& mesg)
 	gAgent.setUserGroupFlags(mGroupID, receive_notices, list_in_profile);
 
 	mChanged = FALSE;
-	notifyObservers();
 
 	return true;
 }
@@ -810,6 +809,7 @@ void LLPanelGroupGeneral::updateChanged()
 		mSpinEnrollmentFee,
 		mCtrlReceiveNotices,
 		mCtrlListGroup,
+		mActiveTitleLabel,
 		mComboActiveTitle
 	};
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 0fbcd93b0b940be61dacc445563ea51826e6b023..5fbe3f0c8e3f063de96dbdfd84d40ee4473d4bf1 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -4783,19 +4783,17 @@ void LLSelectMgr::updateSilhouettes()
 			 iter != roots.end(); iter++)
 		{
 			LLViewerObject* objectp = *iter;
-			LLSelectNode* rect_select_node = new LLSelectNode(objectp, TRUE);
-			rect_select_node->selectAllTEs(TRUE);
+			LLSelectNode* rect_select_root_node = new LLSelectNode(objectp, TRUE);
+			rect_select_root_node->selectAllTEs(TRUE);
 
 			if (!canSelectObject(objectp))
 			{
 				continue;
 			}
 
-			mHighlightedObjects->addNode(rect_select_node);
-
 			if (!select_linked_set)
 			{
-				rect_select_node->mIndividualSelection = TRUE;
+				rect_select_root_node->mIndividualSelection = TRUE;
 			}
 			else
 			{
@@ -4808,11 +4806,14 @@ void LLSelectMgr::updateSilhouettes()
 						continue;
 					}
 
-					rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE);
+					LLSelectNode* rect_select_node = new LLSelectNode(objectp->mChildList[i], TRUE);
 					rect_select_node->selectAllTEs(TRUE);
-					mHighlightedObjects->addNode(rect_select_node);
+					mHighlightedObjects->addNodeAtEnd(rect_select_node);
 				}
 			}
+
+			// Add the root last, to preserve order for link operations.
+			mHighlightedObjects->addNodeAtEnd(rect_select_root_node);
 		}
 
 		num_sils_genned	= 0;
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index cdfc6c2ebfb1a5a2a81c898860e1a032fc599a90..d5abfbdab6fbd1205a8d0c7c5ad1ab64147b0c9d 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -262,9 +262,11 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
 			{
 				LLCoordGL mouse_pos;
 				LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal());
-				gCamera->projectPosAgentToScreen(focus_pos, mouse_pos);
-
-				LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
+				BOOL success = gCamera->projectPosAgentToScreen(focus_pos, mouse_pos);
+				if (success)
+				{
+					LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
+				}
 			}
 			else if (mMouseSteering)
 			{
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6b38bd1765c97480406b1c8b3b9ca073a05d0bb8..2078bd47f5db8c9bea9a54786659418d8b540863 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -140,6 +140,11 @@ def construct(self):
                 # For using FMOD for sound... DJS
                 self.path("fmod.dll")
 
+                # For textures
+                if self.prefix(src="../../libraries/i686-win32/lib_release", dst=""):
+                        self.path("openjpeg.dll")
+                        self.end_prefix()
+
                 # Mozilla appears to force a dependency on these files so we need to ship it (CP)
                 self.path("msvcr71.dll")
                 self.path("msvcp71.dll")
@@ -482,6 +487,7 @@ def construct(self):
                         self.path("libuuid.so", "libuuid.so.1")
                         self.path("libSDL-1.2.so.0")
                         self.path("libELFIO.so")
+                        self.path("libopenjpeg.so.2")
                         #self.path("libtcmalloc.so.0") - bugged
                         #self.path("libstacktrace.so.0") - probably bugged
                         self.path("libllkdu.so", "../bin/libllkdu.so") # llkdu goes in bin for some reason