diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 136e8d47d8c03afa501f3880989494c657aa84e2..53af26ced7682addab0bb15e1d2b529f7f7fc8e2 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -900,167 +900,167 @@ bool LLInventoryItem::fromLLSD(const LLSD& sd, bool is_new)
     // TODO - figure out if this should be moved into the noclobber fields above
     mThumbnailUUID.setNull();
 
-    // iterate as map to avoid making unnecessary temp copies of everything
-    LLSD::map_const_iterator i, end;
-    end = sd.endMap();
-    for (i = sd.beginMap(); i != end; ++i)
-    {
-        if (i->first == INV_ITEM_ID_LABEL)
-        {
-            mUUID = i->second;
-            continue;
-        }
+	const auto& sdMap = sd.map();
+	auto itEnd = sdMap.end();
 
-        if (i->first == INV_PARENT_ID_LABEL)
-        {
-            mParentUUID = i->second;
-            continue;
-        }
+	auto it = sdMap.find(INV_ITEM_ID_LABEL);
+	if (it != itEnd)
+	{
+		mUUID = it->second;
+	}
 
-        if (i->first == INV_THUMBNAIL_LABEL)
-        {
-            const LLSD &thumbnail_map = i->second;
-            if (thumbnail_map.has(INV_ASSET_ID_LABEL))
-            {
-                mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
-            }
-            /* Example:
-                <key> asset_id </key>
-                <uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
-                <key> perms </key>
-                <integer> 8 </integer>
-                <key>service</key>
-                <integer> 3 </integer>
-                <key>version</key>
-                <integer> 1 </key>
-            */
-          continue;
-      }
-        else if (i->first == INV_THUMBNAIL_ID_LABEL)
-        {
-            mThumbnailUUID = i->second.asUUID();
-            continue;
-        }
+	it = sdMap.find(INV_PARENT_ID_LABEL);
+	if (it != itEnd)
+	{
+		mParentUUID = it->second;
+	}
 
-        if (i->first == INV_PERMISSIONS_LABEL)
-        {
-            mPermissions = ll_permissions_from_sd(i->second);
-            continue;
-        }
+	it = sdMap.find(INV_THUMBNAIL_LABEL);
+	if (it != itEnd)
+	{
+		const LLSD& thumbnail_map = it->second;
+		if (thumbnail_map.has(INV_ASSET_ID_LABEL))
+		{
+			mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
+		}
+		/* Example:
+			<key> asset_id </key>
+			<uuid> acc0ec86 - 17f2 - 4b92 - ab41 - 6718b1f755f7 </uuid>
+			<key> perms </key>
+			<integer> 8 </integer>
+			<key>service</key>
+			<integer> 3 </integer>
+			<key>version</key>
+			<integer> 1 </key>
+		*/
+	}
+	else
+	{
+		it = sdMap.find(INV_THUMBNAIL_ID_LABEL);
+		if (it != itEnd)
+		{
+			mThumbnailUUID = it->second.asUUID();
+		}
+	}
 
-        if (i->first == INV_SALE_INFO_LABEL)
-        {
-            // Sale info used to contain next owner perm. It is now in
-            // the permissions. Thus, we read that out, and fix legacy
-            // objects. It's possible this op would fail, but it
-            // should pick up the vast majority of the tasks.
-            BOOL has_perm_mask = FALSE;
-            U32  perm_mask     = 0;
-            if (!mSaleInfo.fromLLSD(i->second, has_perm_mask, perm_mask))
-            {
-                return false;
-            }
-            if (has_perm_mask)
-            {
-                if (perm_mask == PERM_NONE)
-                {
-                    perm_mask = mPermissions.getMaskOwner();
-                }
-                // fair use fix.
-                if (!(perm_mask & PERM_COPY))
-                {
-                    perm_mask |= PERM_TRANSFER;
-                }
-                mPermissions.setMaskNext(perm_mask);
-            }
-            continue;
-        }
+	it = sdMap.find(INV_PERMISSIONS_LABEL);
+	if (it != itEnd)
+	{
+		mPermissions = ll_permissions_from_sd(it->second);
+	}
 
-        if (i->first == INV_SHADOW_ID_LABEL)
-        {
-            mAssetUUID = i->second;
-            LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
-            cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
-            continue;
-        }
+	it = sdMap.find(INV_SALE_INFO_LABEL);
+	if (it != itEnd)
+	{
+		// Sale info used to contain next owner perm. It is now in
+		// the permissions. Thus, we read that out, and fix legacy
+		// objects. It's possible this op would fail, but it
+		// should pick up the vast majority of the tasks.
+		BOOL has_perm_mask = FALSE;
+		U32  perm_mask = 0;
+		if (!mSaleInfo.fromLLSD(it->second, has_perm_mask, perm_mask))
+		{
+			return false;
+		}
+		if (has_perm_mask)
+		{
+			if (perm_mask == PERM_NONE)
+			{
+				perm_mask = mPermissions.getMaskOwner();
+			}
+			// fair use fix.
+			if (!(perm_mask & PERM_COPY))
+			{
+				perm_mask |= PERM_TRANSFER;
+			}
+			mPermissions.setMaskNext(perm_mask);
+		}
+	}
 
-        if (i->first == INV_ASSET_ID_LABEL)
-        {
-            mAssetUUID = i->second;
-            continue;
-        }
+	it = sdMap.find(INV_SHADOW_ID_LABEL);
+	if (it != itEnd)
+	{
+		mAssetUUID = it->second;
+		LLXORCipher cipher(MAGIC_ID.mData, UUID_BYTES);
+		cipher.decrypt(mAssetUUID.mData, UUID_BYTES);
+	}
 
-        if (i->first == INV_LINKED_ID_LABEL)
-        {
-            mAssetUUID = i->second;
-            continue;
-        }
+	it = sdMap.find(INV_ASSET_ID_LABEL);
+	if (it != itEnd)
+	{
+		mAssetUUID = it->second;
+	}
 
-        if (i->first == INV_ASSET_TYPE_LABEL)
-        {
-            LLSD const &label = i->second;
-            if (label.isString())
-            {
-                mType = LLAssetType::lookup(label.asString().c_str());
-            }
-            else if (label.isInteger())
-            {
-                S8 type = (U8) label.asInteger();
-                mType   = static_cast<LLAssetType::EType>(type);
-            }
-            continue;
-        }
+	it = sdMap.find(INV_LINKED_ID_LABEL);
+	if (it != itEnd)
+	{
+		mAssetUUID = it->second;
+	}
 
-        if (i->first == INV_INVENTORY_TYPE_LABEL)
-        {
-            LLSD const &label = i->second;
-            if (label.isString())
-            {
-                mInventoryType = LLInventoryType::lookup(label.asString().c_str());
-            }
-            else if (label.isInteger())
-            {
-                S8 type        = (U8) label.asInteger();
-                mInventoryType = static_cast<LLInventoryType::EType>(type);
-            }
-            continue;
-        }
+	it = sdMap.find(INV_ASSET_TYPE_LABEL);
+	if (it != itEnd)
+	{
+		LLSD const& label = it->second;
+		if (label.isString())
+		{
+			mType = LLAssetType::lookup(label.asString().c_str());
+		}
+		else if (label.isInteger())
+		{
+			S8 type = (U8)label.asInteger();
+			mType = static_cast<LLAssetType::EType>(type);
+		}
+	}
 
-        if (i->first == INV_FLAGS_LABEL)
-        {
-            LLSD const &label = i->second;
-            if (label.isBinary())
-            {
-                mFlags = ll_U32_from_sd(label);
-            }
-            else if (label.isInteger())
-            {
-                mFlags = label.asInteger();
-            }
-            continue;
-        }
+	it = sdMap.find(INV_INVENTORY_TYPE_LABEL);
+	if (it != itEnd)
+	{
+		LLSD const& label = it->second;
+		if (label.isString())
+		{
+			mInventoryType = LLInventoryType::lookup(label.asString().c_str());
+		}
+		else if (label.isInteger())
+		{
+			S8 type = (U8)label.asInteger();
+			mInventoryType = static_cast<LLInventoryType::EType>(type);
+		}
+	}
 
-        if (i->first == INV_NAME_LABEL)
-        {
-            mName = i->second.asString();
-            LLStringUtil::replaceNonstandardASCII(mName, ' ');
-            LLStringUtil::replaceChar(mName, '|', ' ');
-            continue;
-        }
+	it = sdMap.find(INV_FLAGS_LABEL);
+	if (it != itEnd)
+	{
+		LLSD const& label = it->second;
+		if (label.isBinary())
+		{
+			mFlags = ll_U32_from_sd(label);
+		}
+		else if (label.isInteger())
+		{
+			mFlags = label.asInteger();
+		}
+	}
 
-        if (i->first == INV_DESC_LABEL)
-        {
-            mDescription = i->second.asString();
-            LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
-            continue;
-        }
+	it = sdMap.find(INV_NAME_LABEL);
+	if (it != itEnd)
+	{
+		mName = it->second.asString();
+		LLStringUtil::replaceNonstandardASCII(mName, ' ');
+		LLStringUtil::replaceChar(mName, '|', ' ');
+	}
 
-        if (i->first == INV_CREATION_DATE_LABEL)
-        {
-            mCreationDate = i->second.asInteger();
-            continue;
-        }
-    }
+	it = sdMap.find(INV_DESC_LABEL);
+	if (it != itEnd)
+	{
+		mDescription = it->second.asString();
+		LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
+	}
+
+	it = sdMap.find(INV_CREATION_DATE_LABEL);
+	if (it != itEnd)
+	{
+		mCreationDate = it->second.asInteger();
+	}
 
 	// Need to convert 1.0 simstate files to a useful inventory type
 	// and potentially deal with bad inventory tyes eg, a landmark
@@ -1171,59 +1171,59 @@ bool LLInventoryCategory::fromLLSD(const LLSD& sd)
 {
 	mThumbnailUUID.setNull();
 
-	// iterate as map to avoid making unnecessary temp copies of everything
-	LLSD::map_const_iterator i, end;
-	end = sd.endMap();
-	for (i = sd.beginMap(); i != end; ++i)
+	const auto& sdMap = sd.map();
+	auto itEnd = sdMap.end();
+
+	auto it = sdMap.find(INV_FOLDER_ID_LABEL_WS);
+	if (it != itEnd)
 	{
-		if (i->first == INV_FOLDER_ID_LABEL_WS)
-		{
-			mUUID = i->second;
-			continue;
-		}
+		mUUID = it->second;
+	}
 
-		if (i->first == INV_PARENT_ID_LABEL)
-		{
-			mParentUUID = i->second;
-			continue;
-		}
+	it = sdMap.find(INV_PARENT_ID_LABEL);
+	if (it != itEnd)
+	{
+		mParentUUID = it->second;
+	}
 
-		if (i->first == INV_THUMBNAIL_LABEL)
+	it = sdMap.find(INV_THUMBNAIL_LABEL);
+	if (it != itEnd)
+	{
+		const LLSD& thumbnail_map = it->second;
+		if (thumbnail_map.has(INV_ASSET_ID_LABEL))
 		{
-			const LLSD& thumbnail_map = i->second;
-			if (thumbnail_map.has(INV_ASSET_ID_LABEL))
-			{
-				mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
-			}
-			continue;
+			mThumbnailUUID = thumbnail_map[INV_ASSET_ID_LABEL];
 		}
-		else if (i->first == INV_THUMBNAIL_ID_LABEL)
+	}
+	else
+	{
+		it = sdMap.find(INV_THUMBNAIL_ID_LABEL);
+		if (it != itEnd)
 		{
-			mThumbnailUUID = i->second;
-			continue;
+			mThumbnailUUID = it->second;
 		}
+	}
 
-		if (i->first == INV_ASSET_TYPE_LABEL)
-		{
-			S8 type = (U8)i->second.asInteger();
-			mPreferredType = static_cast<LLFolderType::EType>(type);
-			continue;
-		}
+	it = sdMap.find(INV_ASSET_TYPE_LABEL);
+	if (it != itEnd)
+	{
+		S8 type = (U8)it->second.asInteger();
+		mPreferredType = static_cast<LLFolderType::EType>(type);
+	}
 
-		if (i->first == INV_ASSET_TYPE_LABEL_WS)
-		{
-			S8 type = (U8)i->second.asInteger();
-			mPreferredType = static_cast<LLFolderType::EType>(type);
-			continue;
-		}
+	it = sdMap.find(INV_ASSET_TYPE_LABEL_WS);
+	if (it != itEnd)
+	{
+		S8 type = (U8)it->second.asInteger();
+		mPreferredType = static_cast<LLFolderType::EType>(type);
+	}
 
-		if (i->first == INV_NAME_LABEL)
-		{
-			mName = i->second.asString();
-			LLStringUtil::replaceNonstandardASCII(mName, ' ');
-			LLStringUtil::replaceChar(mName, '|', ' ');
-			continue;
-		}
+	it = sdMap.find(INV_NAME_LABEL);
+	if (it != itEnd)
+	{
+		mName = it->second.asString();
+		LLStringUtil::replaceNonstandardASCII(mName, ' ');
+		LLStringUtil::replaceChar(mName, '|', ' ');
 	}
 
     return true;
@@ -1366,49 +1366,46 @@ LLSD LLInventoryCategory::exportLLSD() const
 
 bool LLInventoryCategory::importLLSD(const LLSD& cat_data)
 {
-	// iterate as map to avoid making unnecessary temp copies of everything
-	LLSD::map_const_iterator i, end;
-	end = cat_data.endMap();
-	for (i = cat_data.beginMap(); i != end; ++i)
+	const auto& sdMap = cat_data.map();
+	auto itEnd = sdMap.end();
+
+	auto it = sdMap.find(INV_FOLDER_ID_LABEL);
+	if (it != itEnd)
 	{
-		if (i->first == INV_FOLDER_ID_LABEL)
-		{
-			setUUID(i->second.asUUID());
-			continue;
-		}
-		if (i->first == INV_PARENT_ID_LABEL)
-		{
-			setParent(i->second.asUUID());
-			continue;
-		}
-		if (i->first == INV_ASSET_TYPE_LABEL)
-		{
-			setType(LLAssetType::lookup(i->second.asString()));
-			continue;
-		}
-		if (i->first == INV_PREFERRED_TYPE_LABEL)
-		{
-			setPreferredType(LLFolderType::lookup(i->second.asString()));
-			continue;
-		}
-		if (i->first == INV_THUMBNAIL_LABEL)
-		{
-			LLUUID thumbnail_uuid;
-			const LLSD& thumbnail_data = i->second;
-			if (thumbnail_data.has(INV_ASSET_ID_LABEL))
-			{
-				thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
-			}
-			setThumbnailUUID(thumbnail_uuid);
-			continue;
-		}
-		if (i->first == INV_NAME_LABEL)
+		setUUID(it->second.asUUID());
+	}
+	it = sdMap.find(INV_PARENT_ID_LABEL);
+	if (it != itEnd)
+	{
+		setParent(it->second.asUUID());
+	}
+	it = sdMap.find(INV_ASSET_TYPE_LABEL);
+	if (it != itEnd)
+	{
+		setType(LLAssetType::lookup(it->second.asString()));
+	}
+	it = sdMap.find(INV_PREFERRED_TYPE_LABEL);
+	if (it != itEnd)
+	{
+		setPreferredType(LLFolderType::lookup(it->second.asString()));
+	}
+	it = sdMap.find(INV_THUMBNAIL_LABEL);
+	if (it != itEnd)
+	{
+		LLUUID thumbnail_uuid;
+		const LLSD& thumbnail_data = it->second;
+		if (thumbnail_data.has(INV_ASSET_ID_LABEL))
 		{
-			mName = i->second.asString();
-			LLStringUtil::replaceNonstandardASCII(mName, ' ');
-			LLStringUtil::replaceChar(mName, '|', ' ');
-			continue;
+			thumbnail_uuid = thumbnail_data[INV_ASSET_ID_LABEL].asUUID();
 		}
+		setThumbnailUUID(thumbnail_uuid);
+	}
+	it = sdMap.find(INV_NAME_LABEL);
+	if (it != itEnd)
+	{
+		mName = it->second.asString();
+		LLStringUtil::replaceNonstandardASCII(mName, ' ');
+		LLStringUtil::replaceChar(mName, '|', ' ');
 	}
 
 	return true;
diff --git a/indra/llinventory/llsettingsbase.cpp b/indra/llinventory/llsettingsbase.cpp
index 30249493be22ca4363741b21183caf82ee4d2bfe..55a9ad273dbad4376c9beb094701d1ef07794f07 100644
--- a/indra/llinventory/llsettingsbase.cpp
+++ b/indra/llinventory/llsettingsbase.cpp
@@ -172,18 +172,21 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c
 
     //llassert(mix >= 0.0f && mix <= 1.0f);
 
-    for (const auto& llsd_pair : settings.map())
+    const auto& other_map = other.map();
+    const auto& settings_map = settings.map();
+    for (const auto& llsd_pair : settings_map)
     {
         const std::string& key_name = llsd_pair.first;
         const LLSD& value = llsd_pair.second;
 
-        if (skip.find(key_name) != skip.end())
+        if (skip.contains(key_name))
             continue;
 
         LLSD other_value;
-        if (other.has(key_name))
+        auto it = other_map.find(key_name);
+        if (it != other_map.end())
         {
-            other_value = other[key_name];
+            other_value = it->second;
         }
         else
         {
@@ -211,13 +214,17 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c
 
     // Special handling cases
     // Flags
-    if (settings.has(SETTING_FLAGS))
     {
-        U32 flags = (U32)settings[SETTING_FLAGS].asInteger();
-        if (other.has(SETTING_FLAGS))
-            flags |= (U32)other[SETTING_FLAGS].asInteger();
+        auto it = settings_map.find(SETTING_FLAGS);
+        if (it != settings_map.end())
+        {
+            U32 flags = (U32)it->second.asInteger();
+            it = other_map.find(SETTING_FLAGS);
+            if (it != other_map.end())
+                flags |= (U32)it->second.asInteger();
 
-        newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
+            newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
+        }
     }
 
     // Now add anything that is in other but not in the settings
@@ -225,10 +232,10 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c
     {
         const std::string& key_name = llsd_pair.first;
 
-        if (skip.find(key_name) != skip.end())
+        if (skip.contains(key_name))
             continue;
 
-        if (settings.has(key_name))
+        if (settings_map.contains(key_name))
             continue;
 
         parammapping_t::const_iterator def_iter = defaults.find(key_name);
@@ -250,10 +257,10 @@ LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, c
     for (const auto& llsd_pair : other.map())
     {
         // TODO: Should I blend this in instead?
-        if (skip.find(llsd_pair.first) == skip.end())
+        if (!skip.contains(llsd_pair.first))
             continue;
 
-        if (!settings.has(llsd_pair.first))
+        if (!settings_map.contains(llsd_pair.first))
             continue;
     
         newSettings[llsd_pair.first] = llsd_pair.second;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index c2f2013216419a5c7f3fe1177a6628e90572dbbc..be2a4ad1e8a4cdb323a539c6e57423b4676d0e4e 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2435,11 +2435,13 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
 				continue;
 			}
 
-			const LLSD::Binary& pos = mdl_face["Position"];
-			const LLSD::Binary& norm = mdl_face["Normal"];
-			const LLSD::Binary& tangent = mdl_face["Tangent"];
-			const LLSD::Binary& tc = mdl_face["TexCoord0"];
-			const LLSD::Binary& idx = mdl_face["TriangleList"];
+			const LLSD::Binary& pos = mdl_face["Position"].asBinary();
+			const LLSD::Binary& norm = mdl_face["Normal"].asBinary();
+#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents
+			const LLSD::Binary& tangent = mdl_face["Tangent"].asBinary();
+#endif
+			const LLSD::Binary& tc = mdl_face["TexCoord0"].asBinary();
+			const LLSD::Binary& idx = mdl_face["TriangleList"].asBinary();
 
 			//copy out indices
             S32 num_indices = idx.size() / 2;
@@ -2628,7 +2630,7 @@ bool LLVolume::unpackVolumeFacesInternal(const LLSD& mdl)
                     continue;
                 }
 
-				const LLSD::Binary& weights = mdl_face["Weights"];
+				const LLSD::Binary& weights = mdl_face["Weights"].asBinary();
 
 				U32 idx = 0;
 
diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp
index ec4cd070ef61553182b6b4f05b8b6e454d074002..6a99f7650ca521743322e2dea0f3f181bb09e43a 100644
--- a/indra/llprimitive/llgltfmaterial.cpp
+++ b/indra/llprimitive/llgltfmaterial.cpp
@@ -729,6 +729,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data)
     if (am.isInteger())
     {
         mAlphaMode = (AlphaMode) am.asInteger();
+        mOverrideAlphaMode = true;
     }
 
     const LLSD& ac = data["ac"];
diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp
index 472287b8b591f856e366da9b1c2230ab8374e819..945453230625fcf4ce7d0591e9b8ada70ee89ce1 100644
--- a/indra/llprimitive/llmaterial.cpp
+++ b/indra/llprimitive/llmaterial.cpp
@@ -370,39 +370,112 @@ LLSD LLMaterial::asLLSD() const
 
 void LLMaterial::fromLLSD(const LLSD& material_data)
 {
-    mNormalID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_NORMAL_MAP_FIELD, LLSD::TypeUUID);
-
-    S32 normalOffsetXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD, LLSD::TypeInteger);
-    S32 normalOffsetYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger);
-    S32 normalRotInt     = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD, LLSD::TypeInteger);
-    S32 normalRepeatXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD, LLSD::TypeInteger);
-    S32 normalRepeatYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger);
-
-    mNormalOffsetX  = F32(normalOffsetXInt) / MATERIALS_MULTIPLIER;
-    mNormalOffsetY  = F32(normalOffsetYInt) / MATERIALS_MULTIPLIER;
-    mNormalRotation = F32(normalRotInt)     / MATERIALS_MULTIPLIER;
-    mNormalRepeatX  = F32(normalRepeatXInt) / MATERIALS_MULTIPLIER;
-    mNormalRepeatY  = F32(normalRepeatYInt) / MATERIALS_MULTIPLIER;
-
-    mSpecularID = getMaterialField<LLSD::UUID>(material_data, MATERIALS_CAP_SPECULAR_MAP_FIELD, LLSD::TypeUUID);
-
-    S32 specularOffsetXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD, LLSD::TypeInteger);
-    S32 specularOffsetYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD, LLSD::TypeInteger);
-    S32 specularRotInt     = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD, LLSD::TypeInteger);
-    S32 specularRepeatXInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD, LLSD::TypeInteger);
-    S32 specularRepeatYInt = getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD, LLSD::TypeInteger);
-
-    mSpecularOffsetX   = F32(specularOffsetXInt) / MATERIALS_MULTIPLIER;
-    mSpecularOffsetY   = F32(specularOffsetYInt) / MATERIALS_MULTIPLIER;
-    mSpecularRotation  = F32(specularRotInt)     / MATERIALS_MULTIPLIER;
-    mSpecularRepeatX  = F32(specularRepeatXInt) / MATERIALS_MULTIPLIER;
-    mSpecularRepeatY  = F32(specularRepeatYInt) / MATERIALS_MULTIPLIER;
-
-    mSpecularLightColor.setValue(getMaterialField<LLSD>(material_data, MATERIALS_CAP_SPECULAR_COLOR_FIELD, LLSD::TypeArray));
-    mSpecularLightExponent = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_SPECULAR_EXP_FIELD,       LLSD::TypeInteger);
-    mEnvironmentIntensity  = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ENV_INTENSITY_FIELD,      LLSD::TypeInteger);
-    mDiffuseAlphaMode      = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD, LLSD::TypeInteger);
-    mAlphaMaskCutoff       = (U8)getMaterialField<LLSD::Integer>(material_data, MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD,  LLSD::TypeInteger);
+    if (!material_data.isMap()) return;
+
+    const auto& material_map = material_data.map();
+    const auto& material_end = material_map.end();
+
+    auto it = material_map.find(MATERIALS_CAP_NORMAL_MAP_FIELD);
+    if (it != material_end)
+    {
+        mNormalID = it->second.asUUID();
+    }
+
+    it = material_map.find(MATERIALS_CAP_NORMAL_MAP_OFFSET_X_FIELD);
+    if (it != material_end)
+    {
+        mNormalOffsetX = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_NORMAL_MAP_OFFSET_Y_FIELD);
+    if (it != material_end)
+    {
+        mNormalOffsetY = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_NORMAL_MAP_ROTATION_FIELD);
+    if (it != material_end)
+    {
+        mNormalRotation = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_NORMAL_MAP_REPEAT_X_FIELD);
+    if (it != material_end)
+    {
+        mNormalRepeatX = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_NORMAL_MAP_REPEAT_Y_FIELD);
+    if (it != material_end)
+    {
+        mNormalRepeatY = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_FIELD);
+    if (it != material_end)
+    {
+        mSpecularID = it->second.asUUID();
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_OFFSET_X_FIELD);
+    if (it != material_end)
+    {
+        mSpecularOffsetX = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_OFFSET_Y_FIELD);
+    if (it != material_end)
+    {
+        mSpecularOffsetY = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_ROTATION_FIELD);
+    if (it != material_end)
+    {
+        mSpecularRotation = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_REPEAT_X_FIELD);
+    if (it != material_end)
+    {
+        mSpecularRepeatX = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_MAP_REPEAT_Y_FIELD);
+    if (it != material_end)
+    {
+        mSpecularRepeatY = F32(it->second.asInteger()) / MATERIALS_MULTIPLIER;
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_COLOR_FIELD);
+    if (it != material_end)
+    {
+        mSpecularLightColor.setValue(it->second);
+    }
+
+    it = material_map.find(MATERIALS_CAP_SPECULAR_EXP_FIELD);
+    if (it != material_end)
+    {
+        mSpecularLightExponent = (U8)it->second.asInteger();
+    }
+
+    it = material_map.find(MATERIALS_CAP_ENV_INTENSITY_FIELD);
+    if (it != material_end)
+    {
+        mEnvironmentIntensity = (U8)it->second.asInteger();
+    }
+
+    it = material_map.find(MATERIALS_CAP_DIFFUSE_ALPHA_MODE_FIELD);
+    if (it != material_end)
+    {
+        mDiffuseAlphaMode = (U8)it->second.asInteger();
+    }
+
+    it = material_map.find(MATERIALS_CAP_ALPHA_MASK_CUTOFF_FIELD);
+    if (it != material_end)
+    {
+        mAlphaMaskCutoff = (U8)it->second.asInteger();
+    }
 }
 
 bool LLMaterial::isNull() const
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 6bacde70789cfdc41b2c0b0519c6b69686a21aa1..e7e033ac9a9ffed1407a1ec99f0c43197bfb501d 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -2386,42 +2386,6 @@ void LLRenderMaterialParams::copy(const LLNetworkData& data)
     mEntries = param.mEntries;
 }
 
-LLSD LLRenderMaterialParams::asLLSD() const
-{
-    LLSD ret;
-
-    for (int i = 0; i < mEntries.size(); ++i)
-    {
-        ret[i]["te_idx"] = mEntries[i].te_idx;
-        ret[i]["id"] = mEntries[i].id;
-    }
-
-    return ret;
-}
-
-bool LLRenderMaterialParams::fromLLSD(LLSD& sd)
-{
-    if (sd.isArray())
-    {
-        mEntries.resize(sd.size());
-        for (int i = 0; i < sd.size(); ++i)
-        {
-            if (sd[i].has("te_idx") && sd.has("id"))
-            {
-                mEntries[i].te_idx = sd[i]["te_idx"].asInteger();
-                mEntries[i].id = sd[i]["id"].asUUID();
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    return false;
-}
 
 void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id)
 {
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 92dddabff98530b2294b495b4d3818d8768bb307..bf03ac88cfc201caa6c2b5571b4a73dcf3312a18 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -387,10 +387,7 @@ class LLRenderMaterialParams : public LLNetworkData
     BOOL unpack(LLDataPacker& dp) override;
     bool operator==(const LLNetworkData& data) const override;
     void copy(const LLNetworkData& data) override;
-    LLSD asLLSD() const;
-    operator LLSD() const { return asLLSD(); }
-    bool fromLLSD(LLSD& sd);
-
+    
     void setMaterial(U8 te_idx, const LLUUID& id);
     const LLUUID& getMaterial(U8 te_idx) const;
 
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 317f5c8e04bd4a62bcc6078b6529b94583d5b95d..5f3397845bf96aaeefb0f0eba02263c39c9c5fbe 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -254,12 +254,10 @@ void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color)
 	LLSD color_sd = color.getValue();
 	paragraph_color_segments[0]["color"]=color_sd;
 
-	for(LLSD::array_const_iterator color_segment_it = paragraph_color_segments.beginArray();
-		color_segment_it != paragraph_color_segments.endArray();
-		++color_segment_it)
+	for(const auto& color_segment_it : paragraph_color_segments.array())
 	{			
-		LLSD color_llsd = (*color_segment_it)["color"];
-		std::string color_str  = (*color_segment_it)["text"].asString();
+		LLSD color_llsd = color_segment_it["color"];
+		std::string color_str  = color_segment_it["text"].asString();
 
 		ParagraphColorSegment color_segment;
 		
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index e8da24d78a9f5c9c761ae989dea2c54159d7f4c0..184148d6185fb9a5fd25d555a6516ccea2ce311a 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -202,7 +202,7 @@ class LLMeshHeader
 {
 public:
 
-    LLMeshHeader() {}
+	LLMeshHeader() = default;
 
     explicit LLMeshHeader(const LLSD& header)
     {
@@ -211,7 +211,7 @@ class LLMeshHeader
 
     void fromLLSD(const LLSD& header)
     {
-        const char* lod[] =
+        static const char* lod[] =
         {
             "lowest_lod",
             "low_lod",
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 27d33084863bb5c29f538f0a59998ab04be139f2..b7a262f38b50a1fa92b29216d64b281ce54de217 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -775,6 +775,20 @@ void LLPanelVolume::sendIsReflectionProbe()
     }
     else
     {
+        if (value)
+        {
+            LLNotificationsUtil::add("CantSelectReflectionProbe");
+        }
+        else if (objectp->flagPhantom())
+        {
+            LLViewerObject* root = objectp->getRootEdit();
+            bool in_linkeset = root != objectp || objectp->numChildren() > 0;
+            if (in_linkeset)
+            {
+                // In linkset with a phantom flag
+                objectp->setFlags(FLAGS_PHANTOM, FALSE);
+            }
+        }
         volobjp->setIsReflectionProbe(value);
     }
 }
@@ -791,6 +805,7 @@ void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLS
         }
         LLVOVolume* volobjp = (LLVOVolume*)objectp;
 
+        LLNotificationsUtil::add("CantSelectReflectionProbe");
         volobjp->setIsReflectionProbe(true);
 
         { // has become a reflection probe, slam to a 10m sphere and pop up a message
@@ -1207,6 +1222,17 @@ void LLPanelVolume::onPasteLight()
         }
         else
         {
+            if (objectp->flagPhantom())
+            {
+                LLViewerObject* root = objectp->getRootEdit();
+                bool in_linkeset = root != objectp || objectp->numChildren() > 0;
+                if (in_linkeset)
+                {
+                    // In linkset with a phantom flag
+                    objectp->setFlags(FLAGS_PHANTOM, FALSE);
+                }
+            }
+
             volobjp->setIsReflectionProbe(false);
         }
     }
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 0282d2d171329fdc8ad911d28de48e9b298299bd..725ac76c5a104561c982e1407467704bb073b198 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -385,13 +385,12 @@ void LLViewerRegionImpl::requestBaseCapabilitiesCoro(U64 regionHandle)
             continue;
         }
 
-        LLSD::map_const_iterator iter;
-        for (iter = result.beginMap(); iter != result.endMap(); ++iter)
+        for (const auto& iter : result.map())
         {
-            regionp->setCapability(iter->first, iter->second);
+            regionp->setCapability(iter.first, iter.second);
 
             LL_DEBUGS("AppInit", "Capabilities")
-                << "Capability '" << iter->first << "' is '" << iter->second << "'" << LL_ENDL;
+                << "Capability '" << iter.first << "' is '" << iter.second << "'" << LL_ENDL;
         }
 
 #if 0
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index b6a7070e658c205a9f46ea700af117cca0babed8..2c88f768a450ab34e28b477170af7302eba705c0 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -7168,6 +7168,19 @@ Please try again.
     Not connected to a materials capable region.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="CantSelectReflectionProbe"
+   type="alertmodal">
+    <unique/>
+    You have placed a reflection probe, but 'Select Reflection Probes' is disabled. To be able to select reflection probes, check Build &gt; Options &gt; Select Reflection Probes.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Don't show again."
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="notifytip.tga"
    name="ScriptMissing"