diff --git a/MeshLib/MeshEditing/RemoveMeshComponents.cpp b/MeshLib/MeshEditing/RemoveMeshComponents.cpp
index 2409dc14474e42315035b1bf6502790dbf94ffbe..98cc70bf8940b44866220ba5872cd076a5a8d048 100644
--- a/MeshLib/MeshEditing/RemoveMeshComponents.cpp
+++ b/MeshLib/MeshEditing/RemoveMeshComponents.cpp
@@ -63,7 +63,7 @@ MeshLib::Mesh* removeElements(const MeshLib::Mesh& mesh, const std::vector<std::
 
 	// delete unused nodes
 	NodeSearch ns(mesh);
-	ns.searchByElementIDs(removed_element_ids, true);
+	ns.searchNodesConnectedToOnlyGivenElements(removed_element_ids);
 	auto &removed_node_ids(ns.getSearchedNodeIDs());
 	INFO("Removing total %d nodes...", removed_node_ids.size());
 	for (auto nodeid : removed_node_ids)
diff --git a/MeshLib/MeshSearch/ElementSearch.cpp b/MeshLib/MeshSearch/ElementSearch.cpp
index a8d165ef08749c064b5ab2176075e85da7c23131..e31d1eb6c8565717c62f853bb675b50ab79cea64 100644
--- a/MeshLib/MeshSearch/ElementSearch.cpp
+++ b/MeshLib/MeshSearch/ElementSearch.cpp
@@ -42,30 +42,33 @@ std::size_t ElementSearch::searchByMaterialID(int const matID)
 	return matchedIDs.size();
 }
 
-std::size_t ElementSearch::searchByElementType(MeshElemType eleType)
+template <typename Container, typename Predicate>
+std::vector<std::size_t> filter(Container const& container, Predicate const& p)
 {
-	const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
 	std::vector<std::size_t> matchedIDs;
 	std::size_t i = 0;
-	for (MeshLib::Element* ele : ele_vec) {
-		if (ele->getGeomType()==eleType)
+	for (auto value : container) {
+		if (p(value))
 			matchedIDs.push_back(i);
 		i++;
 	}
+	return matchedIDs;
+}
+
+std::size_t ElementSearch::searchByElementType(MeshElemType eleType)
+{
+	auto matchedIDs = filter(_mesh.getElements(),
+		[&](MeshLib::Element* e) { return e->getGeomType()==eleType; });
+
 	this->updateUnion(matchedIDs);
 	return matchedIDs.size();
 }
 
 std::size_t ElementSearch::searchByContent(double eps)
 {
-	const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
-	std::vector<std::size_t> matchedIDs;
-	std::size_t i = 0;
-	for (MeshLib::Element* ele : ele_vec) {
-		if (ele->getContent() < eps)
-			matchedIDs.push_back(i);
-		i++;
-	}
+	auto matchedIDs = filter(_mesh.getElements(),
+		[&eps](MeshLib::Element* e) { return e->getContent() < eps; });
+
 	this->updateUnion(matchedIDs);
 	return matchedIDs.size();
 }
@@ -73,20 +76,15 @@ std::size_t ElementSearch::searchByContent(double eps)
 std::size_t ElementSearch::searchByBoundingBox(
 	GeoLib::AABB<MathLib::Point3d> const& aabb)
 {
-	const std::vector<MeshLib::Element*> &ele_vec (this->_mesh.getElements());
+	auto matchedIDs = filter(_mesh.getElements(),
+		[&aabb](MeshLib::Element* e) {
+			std::size_t const nElemNodes (e->getNBaseNodes());
+			for (std::size_t n=0; n < nElemNodes; ++n)
+				if (aabb.containsPoint(*e->getNode(n)))
+					return true;	// any node of element is in aabb.
+			return false;	// no nodes of element are in aabb.
+		});
 
-	std::vector<std::size_t> matchedIDs;
-	const std::size_t n_elems(ele_vec.size());
-	for (std::size_t i = 0; i<n_elems; i++)
-	{
-		std::size_t nElemNodes (ele_vec[i]->getNBaseNodes());
-		for (std::size_t j=0; j<nElemNodes; ++j)
-			if (!aabb.containsPoint(*ele_vec[i]->getNode(j)))
-			{
-				matchedIDs.push_back(i);
-				break;
-			}
-	}
 	this->updateUnion(matchedIDs);
 	return matchedIDs.size();
 }
@@ -94,16 +92,16 @@ std::size_t ElementSearch::searchByBoundingBox(
 std::size_t ElementSearch::searchByNodeIDs(const std::vector<std::size_t> &nodes)
 {
 	std::vector<std::size_t> connected_elements;
-	std::for_each(nodes.begin(), nodes.end(),
-		[&](std::size_t node_id)
-		{
-			for (auto* e : _mesh.getNode(node_id)->getElements()) {
-				connected_elements.push_back(e->getID());
-			}
-		});
+	for (std::size_t node_id : nodes)
+	{
+		for (auto* e : _mesh.getNode(node_id)->getElements()) {
+			connected_elements.push_back(e->getID());
+		}
+	}
 	std::sort(connected_elements.begin(), connected_elements.end());
 	auto it = std::unique(connected_elements.begin(), connected_elements.end());
 	connected_elements.resize(std::distance(connected_elements.begin(),it));
+
 	this->updateUnion(connected_elements);
 	return connected_elements.size();
 }
diff --git a/MeshLib/MeshSearch/NodeSearch.cpp b/MeshLib/MeshSearch/NodeSearch.cpp
index 81efa477843fe4a1fecdb72297ed2b8fedae32dc..cd5587d0531c028732f0d52306c8f0e9d81f0d9d 100644
--- a/MeshLib/MeshSearch/NodeSearch.cpp
+++ b/MeshLib/MeshSearch/NodeSearch.cpp
@@ -24,38 +24,33 @@ NodeSearch::NodeSearch(const MeshLib::Mesh &mesh)
 {
 }
 
-std::size_t NodeSearch::searchByElementIDs(const std::vector<std::size_t> &elements, bool only_match_all_connected_elements)
+std::size_t NodeSearch::searchNodesConnectedToOnlyGivenElements(
+		const std::vector<std::size_t> &elements)
 {
-	std::vector<std::size_t> connected_nodes;
-	if (only_match_all_connected_elements)
+	// Find out by how many elements a node would be removed.
+	//
+	// Note: If there are only few elements to be removed, using a different
+	// algorithm might be more memory efficient.
+	std::vector<std::size_t> node_marked_counts(_mesh.getNNodes(), 0);
+
+	for(std::size_t eid : elements)
 	{
-		std::vector<std::size_t> node_marked_counts(_mesh.getNNodes(), 0); //this approach is not optimum for memory size
-		std::for_each(elements.begin(), elements.end(),
-			[&](std::size_t eid)
-			{
-				auto* e = _mesh.getElement(eid);
-				for (unsigned i=0; i<e->getNBaseNodes(); i++) {
-					node_marked_counts[e->getNodeIndex(i)]++;
-				}
-			});
-		for (std::size_t i=0; i<node_marked_counts.size(); i++)
-		{
-			if (node_marked_counts[i] == _mesh.getNode(i)->getElements().size())
-				connected_nodes.push_back(i);
+		auto* e = _mesh.getElement(eid);
+		for (unsigned i=0; i<e->getNBaseNodes(); i++) {
+			node_marked_counts[e->getNodeIndex(i)]++;
 		}
-	} else {
-		std::for_each(elements.begin(), elements.end(),
-			[&](std::size_t eid)
-			{
-				auto* e = _mesh.getElement(eid);
-				for (unsigned i=0; i<e->getNBaseNodes(); i++) {
-					connected_nodes.push_back(e->getNodeIndex(i));
-				}
-			});
-		std::sort(connected_nodes.begin(), connected_nodes.end());
-		auto it = std::unique(connected_nodes.begin(), connected_nodes.end());
-		connected_nodes.resize(std::distance(connected_nodes.begin(),it));
 	}
+
+
+	// Push back nodes which counts are equal to number of connected elements to
+	// that node.
+	std::vector<std::size_t> connected_nodes;
+	for (std::size_t i=0; i<node_marked_counts.size(); i++)
+	{
+		if (node_marked_counts[i] == _mesh.getNode(i)->getElements().size())
+			connected_nodes.push_back(i);
+	}
+
 	this->updateUnion(connected_nodes);
 	return connected_nodes.size();
 }
diff --git a/MeshLib/MeshSearch/NodeSearch.h b/MeshLib/MeshSearch/NodeSearch.h
index 8a8df377faf2451ba521535ec333c3d7539b65fc..ad2b36a6b1565f7147b0ea96ad8112957a3b32d0 100644
--- a/MeshLib/MeshSearch/NodeSearch.h
+++ b/MeshLib/MeshSearch/NodeSearch.h
@@ -29,8 +29,9 @@ public:
 	/// return marked node IDs
 	const std::vector<std::size_t>& getSearchedNodeIDs() const {return _marked_nodes; }
 
-	/// Marks all nodes connecting to any of the given elements
-	std::size_t searchByElementIDs(const std::vector<std::size_t> &element_ids, bool only_match_all_connected_elements = false);
+	/// Marks all nodes connected to any of the given elements ids.
+    /// \return number of connected nodes.
+	std::size_t searchNodesConnectedToOnlyGivenElements(const std::vector<std::size_t> &element_ids);
 
 	/// Marks all unused nodes
 	std::size_t searchUnused();