diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h
index fd35045e457aaa5ce2658845e9232c9d04fffa98..dc3484309c7308a01bfaa6365ef5ba09c25c9727 100644
--- a/indra/llprimitive/llmaterial.h
+++ b/indra/llprimitive/llmaterial.h
@@ -32,8 +32,10 @@
 #include "llmaterialid.h"
 #include "llsd.h"
 #include "v4coloru.h"
+#include "llpointer.h"
+#include "llrefcount.h"
 
-class LLMaterial
+class LLMaterial : public LLRefCount
 {
 public:
 
@@ -115,6 +117,6 @@ class LLMaterial
 	U8			mAlphaMaskCutoff;
 };
 
-typedef boost::shared_ptr<LLMaterial> LLMaterialPtr;
+typedef LLPointer<LLMaterial> LLMaterialPtr;
 
 #endif // LL_LLMATERIAL_H
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 23b15b697c21876841a6074a7c3e450f9e0bf6e8..691216e0355e413dc2ea1713d4f0ea0ee0715035 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -535,6 +535,10 @@ S32 LLTextureEntry::setMaterialID(const LLMaterialID& pMaterialID)
 	if (mMaterialID != pMaterialID)
 	{
 		mMaterialID = pMaterialID;
+		if (mMaterialID.isNull())
+		{
+			setMaterialParams(NULL);
+		}
 		return TEM_CHANGE_TEXTURE;
 	}
 	return TEM_CHANGE_NONE;
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 4dad363eb8017b768c988227cdb8acbb59ce9beb..43001e7d2c5ac771810df467cfb5e0fd65e3c324 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -301,10 +301,17 @@ void LLPanelFace::sendBump()
 	if (bumpiness < BUMPY_TEXTURE)
 	{
 		LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
-		texture_ctrl->setImageAssetID(LLUUID());
+		//texture_ctrl->setImageAssetID(LLUUID());
+		texture_ctrl->clear();
+		LLSD dummy_data;
+		onSelectMaterialTexture(dummy_data);
 	}
 	U8 bump = (U8) bumpiness & TEM_BUMP_MASK;
 	LLSelectMgr::getInstance()->selectionSetBumpmap( bump );
+
+	//refresh material state (in case this change impacts material params)
+	LLSD dummy_data;
+	onCommitMaterialTexture(dummy_data);
 }
 
 void LLPanelFace::sendTexGen()
@@ -592,7 +599,7 @@ void LLPanelFace::sendTextureInfo()
 }
 
 void LLPanelFace::getState()
-{
+{ //set state of UI to match state of texture entry(ies)  (calls setEnabled, setValue, etc, but NOT setVisible)
 	LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
 
 	if( objectp
@@ -760,24 +767,45 @@ void LLPanelFace::getState()
 				getChildView("button align")->setEnabled(editable);
 			}
 			
+			// Specular map
+			struct alpha_get : public LLSelectedTEGetFunctor<U8>
 			{
-				// Default alpha mode to None if texture has no alpha, or Alpha Blending if present
-				// Will be overridden later if a material is present for this face
-				S32 default_alpha = ALPHAMODE_NONE;
-				if (mIsAlpha)
+				U8 get(LLViewerObject* object, S32 te_index)
 				{
-					default_alpha = ALPHAMODE_BLEND;
+					U8 ret = 1;
+					
+					LLMaterial* mat = object->getTE(te_index)->getMaterialParams().get();
+
+					if (mat)
+					{
+						ret = mat->getDiffuseAlphaMode();
+					}
+									
+					return ret;
 				}
+			} alpha_get_func;
+			
+			U8 alpha_mode = 1;
+			LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &alpha_get_func, alpha_mode);
+			
+			{
 				LLCtrlSelectionInterface* combobox_alphamode =
-				      childGetSelectionInterface("combobox alphamode");
+				childGetSelectionInterface("combobox alphamode");
+
 				if (combobox_alphamode)
 				{
-					combobox_alphamode->selectNthItem(default_alpha);
+					if (!mIsAlpha)
+					{
+						alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+					}
+					
+					combobox_alphamode->selectNthItem(alpha_mode);
 				}
 				else
 				{
 					llwarns << "failed childGetSelectionInterface for 'combobox alphamode'" << llendl;
 				}
+
 				updateAlphaControls(getChild<LLComboBox>("combobox alphamode"),this);
 			}
 			
@@ -1432,7 +1460,8 @@ void LLPanelFace::getState()
 		// Materials
 		{
 			mMaterialID = LLMaterialID::null;
-			mMaterial.reset();
+			mMaterial = NULL;
+
 			struct f1 : public LLSelectedTEGetFunctor<LLMaterialID>
 			{
 				LLMaterialID get(LLViewerObject* object, S32 te_index)
@@ -1515,10 +1544,13 @@ void LLPanelFace::refresh()
 }
 
 void LLPanelFace::onMaterialLoaded(const LLMaterialID& material_id, const LLMaterialPtr material)
-{
+{ //laying out UI based on material parameters (calls setVisible on various components)
 	LL_DEBUGS("Materials") << "Loaded material " << material_id.asString() << material->asLLSD() << LL_ENDL;
-	mMaterial = material;
-
+	
+	//make a local copy of the material for editing 
+	// (prevents local edits from overwriting client state on shared materials)
+	mMaterial = new LLMaterial(*material);
+	
 	// Alpha
 	LLCtrlSelectionInterface* combobox_alphamode =
 	      childGetSelectionInterface("combobox alphamode");
@@ -1586,30 +1618,21 @@ void LLPanelFace::updateMaterial()
 	U32 alpha_mode = comboAlphaMode->getCurrentIndex();
 	U32 bumpiness = comboBumpiness->getCurrentIndex();
 	U32 shininess = comboShininess->getCurrentIndex();
-	if ((mIsAlpha && (alpha_mode != ALPHAMODE_BLEND))
+	if ((mIsAlpha && (alpha_mode != LLMaterial::DIFFUSE_ALPHA_MODE_BLEND))
 		|| (bumpiness == BUMPY_TEXTURE)
 		|| (shininess == SHINY_TEXTURE))
 	{
 		// The user's specified something that needs a material.
+		bool new_material = false;
 		if (!mMaterial)
 		{
+			new_material = true;
 			mMaterial = LLMaterialPtr(new LLMaterial());
-			//set defaults according to UI spec
-			mMaterial->setSpecularLightColor(LLColor4U::white);
-			mMaterial->setSpecularLightExponent((U8) (255*0.2f));
-			mMaterial->setEnvironmentIntensity(0);
-			mMaterial->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-			mMaterial->setAlphaMaskCutoff(0);
-		}
-		else
-		{
-			mMaterial->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
-			mMaterial->setSpecularLightExponent((U8)(255*getChild<LLUICtrl>("glossiness")->getValue().asReal()));
-			mMaterial->setEnvironmentIntensity((U8)(255*getChild<LLUICtrl>("environment")->getValue().asReal()));
-			mMaterial->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex());
-			mMaterial->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger()));
 		}
 
+		mMaterial->setDiffuseAlphaMode(getChild<LLComboBox>("combobox alphamode")->getCurrentIndex());
+		mMaterial->setAlphaMaskCutoff((U8)(getChild<LLUICtrl>("maskcutoff")->getValue().asInteger()));
+				
 		if (bumpiness == BUMPY_TEXTURE)
 		{
 			LL_DEBUGS("Materials") << "Setting bumpy texture, bumpiness = " << bumpiness  << LL_ENDL;
@@ -1637,6 +1660,20 @@ void LLPanelFace::updateMaterial()
 			mMaterial->setSpecularRepeat(getChild<LLUICtrl>("shinyScaleU")->getValue().asReal(),
 							getChild<LLUICtrl>("shinyScaleV")->getValue().asReal());
 			mMaterial->setSpecularRotation(getChild<LLUICtrl>("shinyRot")->getValue().asReal()*DEG_TO_RAD);
+
+			//override shininess to 0.2f if this is a new material
+			if (new_material)
+			{
+				mMaterial->setSpecularLightColor(LLColor4U::white);
+				mMaterial->setSpecularLightExponent((U8) (0.2f*255.f));
+				mMaterial->setEnvironmentIntensity(0);
+			}
+			else
+			{
+				mMaterial->setSpecularLightColor(getChild<LLColorSwatchCtrl>("shinycolorswatch")->get());
+				mMaterial->setSpecularLightExponent((U8)(255*getChild<LLUICtrl>("glossiness")->getValue().asReal()));
+				mMaterial->setEnvironmentIntensity((U8)(255*getChild<LLUICtrl>("environment")->getValue().asReal()));
+			}
 		}
 		else
 		{
@@ -1645,6 +1682,8 @@ void LLPanelFace::updateMaterial()
 			mMaterial->setSpecularOffset(0.0f,0.0f);
 			mMaterial->setSpecularRepeat(1.0f,1.0f);
 			mMaterial->setSpecularRotation(0.0f);
+			mMaterial->setSpecularLightExponent(0);
+			mMaterial->setEnvironmentIntensity(0);
 		}
 		
 		LL_DEBUGS("Materials") << "Updating material: " << mMaterial->asLLSD() << LL_ENDL;
@@ -1656,7 +1695,7 @@ void LLPanelFace::updateMaterial()
 		if (mMaterial || !mMaterialID.isNull())
 		{
 			LL_DEBUGS("Materials") << "Resetting material entry" << LL_ENDL;
-			mMaterial.reset();
+			mMaterial = NULL;
 			mMaterialID = LLMaterialID::null;
 			// Delete existing material entry...
 			LLSelectMgr::getInstance()->selectionRemoveMaterial();
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index f1b54e0e01c1b6efac9e6ac1fbaf86f040c5871d..286604e3677257f890bdad77878a39d3d0fa4968 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -4045,7 +4045,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
 	const LLUUID& image_id = getTE(te)->getID();
 	mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	
-	if (getTE(te)->getMaterialParams() != NULL)
+	if (getTE(te)->getMaterialParams().notNull())
 	{
 		const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
 		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, TRUE, LLViewerTexture::BOOST_BUMP, LLViewerTexture::LOD_TEXTURE);
@@ -4094,7 +4094,12 @@ S32 LLViewerObject::setTENormalMapCore(const U8 te, const LLUUID& uuid, LLHost h
 	//	uuid == LLUUID::null)
 	{
 		retval = TEM_CHANGE_TEXTURE;
-		getTE(te)->getMaterialParams()->setNormalID(uuid);
+		LLTextureEntry* tep = getTE(te);
+		LLMaterial* mat = tep->getMaterialParams();
+		if (mat)
+		{
+			mat->setNormalID(uuid);
+		}
 		mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_BUMP, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
 		setChanged(TEXTURE);
 		if (mDrawable.notNull())
@@ -4112,7 +4117,12 @@ S32 LLViewerObject::setTESpecularMapCore(const U8 te, const LLUUID& uuid, LLHost
 	//	uuid == LLUUID::null)
 	{
 		retval = TEM_CHANGE_TEXTURE;
-		getTE(te)->getMaterialParams()->setSpecularID(uuid);
+		LLTextureEntry* tep = getTE(te);
+		LLMaterial* mat = tep->getMaterialParams();
+		if (mat)
+		{
+			mat->setSpecularID(uuid);
+		}
 		mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
 		setChanged(TEXTURE);
 		if (mDrawable.notNull())
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 8a1f00aa0e950f561a46fedfcb013bf254656733..43c57602f5fdc279df7250d5ae08ab872666924f 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -892,7 +892,7 @@ LLFace* LLVOVolume::addFace(S32 f)
 {
 	const LLTextureEntry* te = getTE(f);
 	LLViewerTexture* imagep = getTEImage(f);
-	if (te->getMaterialParams() != NULL)
+	if (te->getMaterialParams().notNull())
 	{
 		LLViewerTexture* normalp = getTENormalMap(f);
 		LLViewerTexture* specularp = getTESpecularMap(f);
@@ -1395,7 +1395,7 @@ void LLVOVolume::regenFaces()
 
 		facep->setTEOffset(i);
 		facep->setTexture(getTEImage(i));
-		if (facep->getTextureEntry()->getMaterialParams() != NULL)
+		if (facep->getTextureEntry()->getMaterialParams().notNull())
 		{
 			facep->setNormalMap(getTENormalMap(i));
 			facep->setSpecularMap(getTESpecularMap(i));
@@ -1986,19 +1986,15 @@ void LLVOVolume::setTEMaterialParamsCallback(const LLMaterialID &pMaterialID, co
 
 S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
 {
-	if (!pMaterialID.isNull())
+	S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
+	if (res)
 	{
-		S32 res = LLViewerObject::setTEMaterialID(te, pMaterialID);
-		if (res)
-		{
-			LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
-			LLMaterialMgr::instance().get(getRegion()->getRegionID(), pMaterialID, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2));
-			gPipeline.markTextured(mDrawable);
-			mFaceMappingChanged = TRUE;
-		}
-		return  res;
+		LL_DEBUGS("MaterialTEs") << " " << pMaterialID.asString() << LL_ENDL;
+		LLMaterialMgr::instance().get(getRegion()->getRegionID(), pMaterialID, boost::bind(&LLVOVolume::setTEMaterialParamsCallback, this, _1, _2));
+		gPipeline.markTextured(mDrawable);
+		mFaceMappingChanged = TRUE;
 	}
-	return 0;
+	return  res;
 }
 
 S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
@@ -4135,26 +4131,24 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 		draw_vec.push_back(draw_info);
 		draw_info->mTextureMatrix = tex_mat;
 		draw_info->mModelMatrix = model_mat;
-		if (!facep->getTextureEntry()->getMaterialID().isNull())
+		if (facep->getTextureEntry()->getMaterialParams().notNull())
+		{
+			// We have a material.  Update our draw info accordingly.
+			draw_info->mMaterialID = matid;
+			LLVector4 specColor;
+			specColor.mV[0] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[0] * (1.f / 255.f);
+			specColor.mV[1] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[1] * (1.f / 255.f);
+			specColor.mV[2] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[2] * (1.f / 255.f);
+			specColor.mV[3] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightExponent() * (1.f / 255.f);
+			draw_info->mSpecColor = specColor;
+			draw_info->mEnvIntensity = facep->getTextureEntry()->getMaterialParams()->getEnvironmentIntensity() * (1.f / 255.f);
+			draw_info->mAlphaMaskCutoff = facep->getTextureEntry()->getMaterialParams()->getAlphaMaskCutoff() * (1.f / 255.f);
+			draw_info->mDiffuseAlphaMode = facep->getTextureEntry()->getMaterialParams()->getDiffuseAlphaMode();
+			draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
+			draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+		} 
+		else 
 		{
-			
-			if (facep->getTextureEntry()->getMaterialParams() != NULL)
-			{
-				// We have a material.  Update our draw info accordingly.
-				draw_info->mMaterialID = matid;
-				LLVector4 specColor;
-				specColor.mV[0] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[0] * (1.f / 255.f);
-				specColor.mV[1] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[1] * (1.f / 255.f);
-				specColor.mV[2] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightColor().mV[2] * (1.f / 255.f);
-				specColor.mV[3] = facep->getTextureEntry()->getMaterialParams()->getSpecularLightExponent() * (1.f / 255.f);
-				draw_info->mSpecColor = specColor;
-				draw_info->mEnvIntensity = facep->getTextureEntry()->getMaterialParams()->getEnvironmentIntensity() * (1.f / 255.f);
-				draw_info->mAlphaMaskCutoff = facep->getTextureEntry()->getMaterialParams()->getAlphaMaskCutoff() * (1.f / 255.f);
-				draw_info->mDiffuseAlphaMode = facep->getTextureEntry()->getMaterialParams()->getDiffuseAlphaMode();
-				draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
-				draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
-			}
-		} else {
 			U8 shiny = facep->getTextureEntry()->getShiny();
 			float alpha[4] =
 			{
@@ -4662,7 +4656,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 						if (gPipeline.canUseWindLightShadersOnObjects()
 							&& LLPipeline::sRenderBump)
 						{
-							if (LLPipeline::sRenderDeferred && te->getMaterialParams() != NULL)
+							if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull())
 							{
 								LLMaterial* mat = te->getMaterialParams().get();
 								if (mat->getNormalID().notNull())
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index e156b3e07cdc4b095ad34fc9c0e9e5aee3fd9d35..5e2caa28a942a0409560232885f74d80342a957d 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -209,9 +209,11 @@
              layout="topleft"
              top_pad="4"
              left_delta="0"
+             increment="1"
              name="maskcutoff"
              width="80" />
             <texture_picker
+             allow_no_texture="true"
              can_apply_immediately="true"
              default_image_name="Default"
              fallback_image="locked_image.j2c"
@@ -322,6 +324,7 @@
                  value="Use texture" />
             </combo_box>
             <texture_picker
+             allow_no_texture="true"
              can_apply_immediately="true"
              default_image_name="Default"
              fallback_image="locked_image.j2c"