diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 0c59ba9a6dcfd0fd7c065c4be8c81d428a9dd03f..535cb368bdbdefe7adeb6c8f831612f6c14d946f 100755
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -342,11 +342,6 @@ void LLFloaterColorPicker::setCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
 	curG = curGIn;
 	curB = curBIn;
 
-	if (mApplyImmediateCheck->get())
-	{
-		LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
-	}
-
 	// update corresponding HSL values and
 	LLColor3(curRIn, curGIn, curBIn).calcHSL(&curH, &curS, &curL);
 
@@ -374,11 +369,6 @@ void LLFloaterColorPicker::setCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
 
 	// update corresponding RGB values and
 	hslToRgb ( curH, curS, curL, curR, curG, curB );
-
-	if (mApplyImmediateCheck->get())
-	{
-		LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
-	}
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -467,7 +457,8 @@ void LLFloaterColorPicker::onImmediateCheck( LLUICtrl* ctrl, void* data)
 
 void LLFloaterColorPicker::onColorSelect( const LLTextureEntry& te )
 {
-	setCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]);
+	// Pipete
+	selectCurRgb(te.getColor().mV[VRED], te.getColor().mV[VGREEN], te.getColor().mV[VBLUE]);
 }
 
 void LLFloaterColorPicker::onMouseCaptureLost()
@@ -642,6 +633,28 @@ const LLColor4& LLFloaterColorPicker::getComplimentaryColor ( const LLColor4& ba
 	return LLColor4::black;
 }
 
+//////////////////////////////////////////////////////////////////////////////
+// set current RGB and rise change event if needed.
+void LLFloaterColorPicker::selectCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn )
+{
+	setCurRgb(curRIn, curGIn, curBIn);
+	if (mApplyImmediateCheck->get())
+	{
+		LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// set current HSL and rise change event if needed.
+void LLFloaterColorPicker::selectCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn )
+{
+	setCurHsl(curHIn, curSIn, curLIn);
+	if (mApplyImmediateCheck->get())
+	{
+		LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////////
 // draw color palette
 void LLFloaterColorPicker::drawPalette ()
@@ -736,7 +749,7 @@ void LLFloaterColorPicker::onTextEntryChanged ( LLUICtrl* ctrl )
 		}
 
 		// update current RGB (and implicitly HSL)
-		setCurRgb ( rVal, gVal, bVal );
+		selectCurRgb ( rVal, gVal, bVal );
 
 		updateTextEntry ();
 	}
@@ -759,15 +772,10 @@ void LLFloaterColorPicker::onTextEntryChanged ( LLUICtrl* ctrl )
 			lVal = (F32)ctrl->getValue().asReal() / 100.0f;
 
 		// update current HSL (and implicitly RGB)
-		setCurHsl ( hVal, sVal, lVal );
+		selectCurHsl ( hVal, sVal, lVal );
 
 		updateTextEntry ();
 	}
-
-	if (mApplyImmediateCheck->get())
-	{
-		LLColorSwatchCtrl::onColorChanged ( getSwatch (), LLColorSwatchCtrl::COLOR_CHANGE );
-	}
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -780,7 +788,7 @@ BOOL LLFloaterColorPicker::updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
 		 yPosIn >= mRGBViewerImageTop - mRGBViewerImageHeight )
 	{
 		// update HSL (and therefore RGB) based on new H & S and current L
-		setCurHsl ( ( ( F32 )xPosIn - ( F32 )mRGBViewerImageLeft ) / ( F32 )mRGBViewerImageWidth,
+		selectCurHsl ( ( ( F32 )xPosIn - ( F32 )mRGBViewerImageLeft ) / ( F32 )mRGBViewerImageWidth,
 					( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight,
 					getCurL () );
 
@@ -795,7 +803,7 @@ BOOL LLFloaterColorPicker::updateRgbHslFromPoint ( S32 xPosIn, S32 yPosIn )
 	{
 
 		// update HSL (and therefore RGB) based on current HS and new L
-		 setCurHsl ( getCurH (),
+		 selectCurHsl ( getCurH (),
 					 getCurS (),
 					( ( F32 )yPosIn - ( ( F32 )mRGBViewerImageTop - ( F32 )mRGBViewerImageHeight ) ) / ( F32 )mRGBViewerImageHeight );
 
@@ -887,7 +895,7 @@ BOOL LLFloaterColorPicker::handleMouseDown ( S32 x, S32 y, MASK mask )
 		{
 			LLColor4 selected = *mPalette [ index ];
 
-			setCurRgb ( selected [ 0 ], selected [ 1 ], selected [ 2 ] );
+			selectCurRgb ( selected [ 0 ], selected [ 1 ], selected [ 2 ] );
 
 			if (mApplyImmediateCheck->get())
 			{
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index d4d22b643a79d8830160c42e0ae145a627510836..8c16ebdf0343c2843f166ee50524cc33751d003a 100755
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -122,6 +122,9 @@ class LLFloaterColorPicker
 		static void onImmediateCheck ( LLUICtrl* ctrl, void* data );
 			   void onColorSelect( const class LLTextureEntry& te );
 	private:
+		// mutators for color values, can raise event to preview changes at object
+		void selectCurRgb ( F32 curRIn, F32 curGIn, F32 curBIn );
+		void selectCurHsl ( F32 curHIn, F32 curSIn, F32 curLIn );
 		// draws color selection palette
 		void drawPalette ();
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 02e05d3d9a8978b8aeaed28d9f11c793d79257df..ced2635520594853ad795aaded3426bb700e2508 100755
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -242,6 +242,8 @@ BOOL	LLPanelFace::postBuild()
 	if(mShinyColorSwatch)
 	{
 		mShinyColorSwatch->setCommitCallback(boost::bind(&LLPanelFace::onCommitShinyColor, this, _2));
+		mShinyColorSwatch->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelShinyColor, this, _2));
+		mShinyColorSwatch->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectShinyColor, this, _2));
 		mShinyColorSwatch->setFollowsTop();
 		mShinyColorSwatch->setFollowsLeft();
 		mShinyColorSwatch->setCanApplyImmediately(TRUE);
@@ -1463,12 +1465,23 @@ void LLPanelFace::onCancelColor(const LLSD& data)
 	LLSelectMgr::getInstance()->selectionRevertColors();
 }
 
+void LLPanelFace::onCancelShinyColor(const LLSD& data)
+{
+	LLSelectMgr::getInstance()->selectionRevertShinyColors();
+}
+
 void LLPanelFace::onSelectColor(const LLSD& data)
 {
 	LLSelectMgr::getInstance()->saveSelectedObjectColors();
 	sendColor();
 }
 
+void LLPanelFace::onSelectShinyColor(const LLSD& data)
+{
+	LLSelectedTEMaterial::setSpecularLightColor(this, getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+	LLSelectMgr::getInstance()->saveSelectedShinyColors();
+}
+
 // static
 void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
 {
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index e32f039921ef2efad490c5e515d075707b89d1b7..9823e84cd9e2bdf514eac5959c2de4a52e92e555 100755
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -143,7 +143,9 @@ class LLPanelFace : public LLPanel
 	void 	onCommitShinyColor(const LLSD& data);
 	void 	onCommitAlpha(const LLSD& data);
 	void 	onCancelColor(const LLSD& data);
+	void 	onCancelShinyColor(const LLSD& data);
 	void 	onSelectColor(const LLSD& data);
+	void 	onSelectShinyColor(const LLSD& data);
 
 	void 	onCloseTexturePicker(const LLSD& data);
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index eb3a4c37d99d7f43a4af2fa421f76d19b34a92da..2a0a2f31bec9db5790ca5359df650d1ceeea59f4 100755
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1766,6 +1766,40 @@ void LLSelectMgr::selectionRevertColors()
 	getSelection()->applyToObjects(&sendfunc);
 }
 
+void LLSelectMgr::selectionRevertShinyColors()
+{
+	struct f : public LLSelectedTEFunctor
+	{
+		LLObjectSelectionHandle mSelectedObjects;
+		f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+		bool apply(LLViewerObject* object, S32 te)
+		{
+			if (object->permModify())
+			{
+				LLSelectNode* nodep = mSelectedObjects->findNode(object);
+				if (nodep && te < (S32)nodep->mSavedShinyColors.size())
+				{
+					LLColor4 color = nodep->mSavedShinyColors[te];
+					// update viewer side color in anticipation of update from simulator
+					LLMaterialPtr old_mat = object->getTE(te)->getMaterialParams();
+					if (!old_mat.isNull())
+					{
+						LLMaterialPtr new_mat = gFloaterTools->getPanelFace()->createDefaultMaterial(old_mat);
+						new_mat->setSpecularLightColor(color);
+						object->getTE(te)->setMaterialParams(new_mat);
+						LLMaterialMgr::getInstance()->put(object->getID(), te, *new_mat);
+					}
+				}
+			}
+			return true;
+		}
+	} setfunc(mSelectedObjects);
+	getSelection()->applyToTEs(&setfunc);
+
+	LLSelectMgrSendFunctor sendfunc;
+	getSelection()->applyToObjects(&sendfunc);
+}
+
 BOOL LLSelectMgr::selectionRevertTextures()
 {
 	struct f : public LLSelectedTEFunctor
@@ -4501,6 +4535,19 @@ void LLSelectMgr::saveSelectedObjectColors()
 	getSelection()->applyToNodes(&func);	
 }
 
+void LLSelectMgr::saveSelectedShinyColors()
+{
+	struct f : public LLSelectedNodeFunctor
+	{
+		virtual bool apply(LLSelectNode* node)
+		{
+			node->saveShinyColors();
+			return true;
+		}
+	} func;
+	getSelection()->applyToNodes(&func);
+}
+
 void LLSelectMgr::saveSelectedObjectTextures()
 {
 	// invalidate current selection so we update saved textures
@@ -5752,6 +5799,7 @@ LLSelectNode::LLSelectNode(LLViewerObject* object, BOOL glow)
 	mCreationDate(0)
 {
 	saveColors();
+	saveShinyColors();
 }
 
 LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
@@ -5797,6 +5845,11 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
 	{
 		mSavedColors.push_back(*color_iter);
 	}
+	mSavedShinyColors.clear();
+	for (color_iter = nodep.mSavedShinyColors.begin(); color_iter != nodep.mSavedShinyColors.end(); ++color_iter)
+	{
+		mSavedShinyColors.push_back(*color_iter);
+	}
 	
 	saveTextures(nodep.mSavedTextures);
 }
@@ -5880,6 +5933,26 @@ void LLSelectNode::saveColors()
 	}
 }
 
+void LLSelectNode::saveShinyColors()
+{
+	if (mObject.notNull())
+	{
+		mSavedShinyColors.clear();
+		for (S32 i = 0; i < mObject->getNumTEs(); i++)
+		{
+			const LLMaterialPtr mat = mObject->getTE(i)->getMaterialParams();
+			if (!mat.isNull())
+			{
+				mSavedShinyColors.push_back(mat->getSpecularLightColor());
+			}
+			else
+			{
+				mSavedShinyColors.push_back(LLColor4::white);
+			}
+		}
+	}
+}
+
 void LLSelectNode::saveTextures(const uuid_vec_t& textures)
 {
 	if (mObject.notNull())
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index a68328167a3a2cccd2a2679abe13689ad900da6c..9906dfd52429365f102f95f52513415bd8dcadee 100755
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -179,6 +179,7 @@ class LLSelectNode
 	void setObject(LLViewerObject* object);
 	// *NOTE: invalidate stored textures and colors when # faces change
 	void saveColors();
+	void saveShinyColors();
 	void saveTextures(const uuid_vec_t& textures);
 	void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
 
@@ -215,6 +216,7 @@ class LLSelectNode
 	std::string		mSitName;
 	U64				mCreationDate;
 	std::vector<LLColor4>	mSavedColors;
+	std::vector<LLColor4>	mSavedShinyColors;
 	uuid_vec_t		mSavedTextures;
 	std::vector<LLVector3>  mTextureScaleRatios;
 	std::vector<LLVector3>	mSilhouetteVertices;	// array of vertices to render silhouette of object
@@ -545,6 +547,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	////////////////////////////////////////////////////////////////
 	void saveSelectedObjectTransform(EActionType action_type);
 	void saveSelectedObjectColors();
+	void saveSelectedShinyColors();
 	void saveSelectedObjectTextures();
 
 	// Sets which texture channel to query for scale and rot of display
@@ -573,6 +576,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
 	void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
 	void selectionRevertColors();
+	void selectionRevertShinyColors();
 	BOOL selectionRevertTextures();
 	void selectionSetBumpmap( U8 bumpmap );
 	void selectionSetTexGen( U8 texgen );