diff --git a/MeshLib/MeshEditing/ElementValueModification.cpp b/MeshLib/MeshEditing/ElementValueModification.cpp
index 6f54233b804637d45785cb459f9f1d7ebc9065dc..d1ec306f709327a2e4400899ea6ba7c40ce8bee1 100644
--- a/MeshLib/MeshEditing/ElementValueModification.cpp
+++ b/MeshLib/MeshEditing/ElementValueModification.cpp
@@ -21,88 +21,105 @@
 #include "MeshLib/Mesh.h"
 #include "MeshLib/Elements/Element.h"
 
-
 namespace MeshLib {
 
-std::vector<unsigned> ElementValueModification::getMeshValues(const MeshLib::Mesh &mesh)
+bool ElementValueModification::replace(MeshLib::Mesh &mesh,
+	std::string const& property_name, unsigned old_value, unsigned new_value,
+	bool replace_if_exists)
 {
-	const std::size_t nElements (mesh.getNElements());
-	std::vector<unsigned> value_mapping;
-	for (unsigned i=0; i<nElements; ++i)
-	{
-		bool exists(false);
-		unsigned value (mesh.getElement(i)->getValue());
-		const unsigned nValues (value_mapping.size());
-		for (unsigned j=0; j<nValues; ++j)
-		{
-			if (value == value_mapping[j])
-			{
-				exists = true;
-				break;
-			}
-		}
-		if (!exists)
-			value_mapping.push_back(value);
-	}
+	boost::optional<MeshLib::PropertyVector<int> &> optional_property_value_vec(
+		mesh.getProperties().getPropertyVector<int>(property_name)
+	);
 
-	std::sort(value_mapping.begin(), value_mapping.end());
-	return value_mapping;
-}
+	if (!optional_property_value_vec) {
+		return false;
+	}
 
-bool ElementValueModification::replace(MeshLib::Mesh &mesh, unsigned old_value, unsigned new_value, bool replace_if_exists)
-{
-	std::vector<unsigned> value_mapping (ElementValueModification::getMeshValues(mesh));
-
-	if (!replace_if_exists)
-	{
-		const unsigned nValues (value_mapping.size());
-		for (unsigned j=0; j<nValues; ++j)
-		{
-			if (new_value == value_mapping[j])
-			{
-				WARN ("ElementValueModification::replaceElementValue() - Replacement value is already taken, no changes have been made.");
+	MeshLib::PropertyVector<int> & property_value_vec(
+		optional_property_value_vec.get()
+	);
+	const std::size_t n_property_values(property_value_vec.size());
+
+	if (!replace_if_exists) {
+		for (std::size_t i=0; i<n_property_values; ++i) {
+			if (property_value_vec[i] == new_value) {
+				WARN ("ElementValueModification::replaceElementValue() "
+					"- Replacement value \"%d\" is already taken, "
+					"no changes have been made.", new_value);
 				return false;
 			}
 		}
 	}
-	const std::size_t nElements (mesh.getNElements());
-	std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements()));
-	for (unsigned i=0; i<nElements; ++i)
-	{
-		if (elements[i]->getValue() == old_value)
-			elements[i]->setValue(new_value);
+
+	for (std::size_t i=0; i<n_property_values; ++i) {
+		if (property_value_vec[i] == old_value)
+			property_value_vec[i] = new_value;
 	}
+
 	return true;
 }
 
+bool ElementValueModification::replace(MeshLib::Mesh &mesh,
+	unsigned old_value, unsigned new_value, bool replace_if_exists)
+{
+	return replace(mesh, "MaterialIDs", old_value, new_value, replace_if_exists);
+}
+
 unsigned ElementValueModification::condense(MeshLib::Mesh &mesh)
 {
-	std::vector<unsigned> value_mapping (ElementValueModification::getMeshValues(mesh));
-	std::vector<unsigned> reverse_mapping(value_mapping.back()+1, 0);
+	boost::optional<MeshLib::PropertyVector<int> &>
+		optional_property_value_vec(
+			mesh.getProperties().getPropertyVector<int>("MaterialIDs")
+		);
+
+	if (!optional_property_value_vec) {
+		return 0;
+	}
+
+	MeshLib::PropertyVector<int> & property_value_vector(
+		optional_property_value_vec.get()
+	);
+	std::vector<int> value_mapping(
+		getSortedPropertyValues(property_value_vector)
+	);
+
+	std::vector<int> reverse_mapping(value_mapping.back()+1, 0);
 	const unsigned nValues (value_mapping.size());
 	for (unsigned i=0; i<nValues; ++i)
 		reverse_mapping[value_mapping[i]] = i;
 
-	const std::size_t nElements (mesh.getNElements());
-	std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements()));
-	for (unsigned i=0; i<nElements; ++i)
-		elements[i]->setValue(reverse_mapping[elements[i]->getValue()]);
+	std::size_t const n_property_values(property_value_vector.size());
+	for (std::size_t i=0; i<n_property_values; ++i)
+		property_value_vector[i] = reverse_mapping[property_value_vector[i]];
 
 	return nValues;
 }
 
 unsigned ElementValueModification::setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value)
 {
-	std::vector<MeshLib::Element*> &elements (const_cast<std::vector<MeshLib::Element*>&>(mesh.getElements()));
-	unsigned nValues = 0;
-	for (auto e : elements) {
-		if (e->getGeomType()!=ele_type)
+	boost::optional<MeshLib::PropertyVector<unsigned> &>
+		optional_property_value_vec(
+			mesh.getProperties().getPropertyVector<unsigned>("MaterialIDs")
+		);
+
+	if (!optional_property_value_vec) {
+		return 0;
+	}
+
+	MeshLib::PropertyVector<unsigned> & property_value_vector(
+		optional_property_value_vec.get()
+	);
+
+	std::vector<MeshLib::Element*> const& elements(mesh.getElements());
+	std::size_t cnt(0);
+	for (std::size_t k(0); k<elements.size(); k++) {
+		if (elements[k]->getGeomType()!=ele_type)
 			continue;
-		e->setValue(new_value);
-		nValues++;
+		property_value_vector[k] = new_value;
+		cnt++;
 	}
 
-	return nValues;
+	return cnt;
 }
 
 } // end namespace MeshLib
diff --git a/MeshLib/MeshEditing/ElementValueModification.h b/MeshLib/MeshEditing/ElementValueModification.h
index df72deaaf0514f470adb4aa0f1a8191cf25330c7..cb2a2128f2f8522c8baf2c867b51d04dd632e391 100644
--- a/MeshLib/MeshEditing/ElementValueModification.h
+++ b/MeshLib/MeshEditing/ElementValueModification.h
@@ -17,7 +17,11 @@
 
 #include <vector>
 
+#include <boost/optional.hpp>
+
 #include "MeshLib/MeshEnums.h"
+#include "MeshLib/Mesh.h"
+#include "MeshLib/PropertyVector.h"
 
 namespace MeshLib {
 // forward declarations
@@ -37,13 +41,40 @@ public:
 	/// Returns true if successful or false if the value is already taken.
 	static bool replace(MeshLib::Mesh &mesh, unsigned old_value, unsigned new_value, bool replace_if_exists = false);
 
+	static bool replace(MeshLib::Mesh &mesh, std::string const& property_name,
+		unsigned old_value, unsigned new_value, bool replace_if_exists = false);
+
 	/// Sets new value for all elements having the given element type
 	/// Returns the number of elements having the given element type
 	static unsigned setByElementType(MeshLib::Mesh &mesh, MeshElemType ele_type, unsigned new_value);
 
 private:
-	/// Returns the values of elements within the mesh
-	static std::vector<unsigned> getMeshValues(const MeshLib::Mesh &mesh);
+	/// Returns sorted values of properties within the PropertyVector
+	/// These values are stored in a vector.
+	template <typename T>
+	static std::vector<T> getSortedPropertyValues(
+		MeshLib::PropertyVector<T> const& property_vector)
+	{
+		std::vector<T> value_mapping;
+		const std::size_t n_property_values(property_vector.size());
+		for (std::size_t i=0; i<n_property_values; ++i) {
+			bool exists(false);
+			T const& value (property_vector[i]);
+			std::size_t const size(value_mapping.size());
+			for (unsigned j=0; j<size; ++j) {
+				if (value == value_mapping[j]) {
+					exists = true;
+					break;
+				}
+			}
+			if (!exists)
+				value_mapping.push_back(value);
+		}
+
+		std::sort(value_mapping.begin(), value_mapping.end());
+		return value_mapping;
+	}
+
 };
 
 } // end namespace MeshLib