diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index 40ca7b074..1e7fae3b5 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -2026,58 +2026,69 @@ void GCode::process_layer(
                        layer.lslices[i].contour.contains(point);
             };
 
-            for (size_t region_id = 0; region_id < print.regions().size(); ++ region_id) {
-                const LayerRegion *layerm = (region_id < layer.regions().size()) ? layer.regions()[region_id] : nullptr;
+            for (size_t region_id = 0; region_id < layer.regions().size(); ++ region_id) {
+                const LayerRegion *layerm = layer.regions()[region_id];
                 if (layerm == nullptr)
                     continue;
                 const PrintRegion &region = *print.regions()[region_id];
 
-
                 // Now we must process perimeters and infills and create islands of extrusions in by_region std::map.
                 // It is also necessary to save which extrusions are part of MM wiping and which are not.
                 // The process is almost the same for perimeters and infills - we will do it in a cycle that repeats twice:
-                for (std::string entity_type("infills") ; entity_type != "done" ; entity_type = entity_type=="infills" ? "perimeters" : "done") {
-
-                    const ExtrusionEntitiesPtr& source_entities = entity_type=="infills" ? layerm->fills.entities : layerm->perimeters.entities;
-
-                    for (const ExtrusionEntity *ee : source_entities) {
-                        // fill represents infill extrusions of a single island.
-                        const auto *fill = dynamic_cast<const ExtrusionEntityCollection*>(ee);
-                        if (fill->entities.empty()) // This shouldn't happen but first_point() would fail.
+                std::vector<unsigned int> printing_extruders;
+                for (const ObjectByExtruder::Island::Region::Type entity_type : { ObjectByExtruder::Island::Region::INFILL, ObjectByExtruder::Island::Region::PERIMETERS }) {
+                    for (const ExtrusionEntity *ee : (entity_type == ObjectByExtruder::Island::Region::INFILL) ? layerm->fills.entities : layerm->perimeters.entities) {
+                        // extrusions represents infill or perimeter extrusions of a single island.
+                        assert(dynamic_cast<const ExtrusionEntityCollection*>(ee) != nullptr);
+                        const auto *extrusions = static_cast<const ExtrusionEntityCollection*>(ee);
+                        if (extrusions->entities.empty()) // This shouldn't happen but first_point() would fail.
                             continue;
 
                         // This extrusion is part of certain Region, which tells us which extruder should be used for it:
-                        int correct_extruder_id = Print::get_extruder(*fill, region);
+                        int correct_extruder_id = Print::get_extruder(*extrusions, region);
 
                         // Let's recover vector of extruder overrides:
-                        const ExtruderPerCopy* entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(fill, correct_extruder_id, layer_to_print.object()->copies().size());
+                        const WipingExtrusions::ExtruderPerCopy *entity_overrides = const_cast<LayerTools&>(layer_tools).wiping_extrusions().get_extruder_overrides(extrusions, correct_extruder_id, layer_to_print.object()->copies().size());
+                        printing_extruders.clear();
+                        if (entity_overrides == nullptr) {
+                        	printing_extruders.emplace_back(correct_extruder_id);
+                        } else {
+                        	printing_extruders.reserve(entity_overrides->size() + 1);
+                        	for (int extruder : *entity_overrides)
+                        		printing_extruders.emplace_back(extruder >= 0 ? 
+                        			// at least one copy is overridden to use this extruder
+                        			extruder : 
+                        			// at least one copy would normally be printed with this extruder (see get_extruder_overrides function for explanation)
+                        			static_cast<unsigned int>(- extruder - 1));
+                        }
+                        if (! layer_tools.has_extruder(correct_extruder_id)) {
+							// this entity is not overridden, but its extruder is not in layer_tools - we'll print it
+                            // by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools)
+                        	printing_extruders.emplace_back(layer_tools.extruders.back());
+                        }
+                        Slic3r::sort_remove_duplicates(printing_extruders);
+                        if (printing_extruders.size() == 1 && printing_extruders.front() == correct_extruder_id)
+                        	entity_overrides = nullptr;
 
                         // Now we must add this extrusion into the by_extruder map, once for each extruder that will print it:
-                        for (unsigned int extruder : layer_tools.extruders)
+                        for (unsigned int extruder : printing_extruders)
                         {
-                            // Init by_extruder item only if we actually use the extruder:
-                            if (std::find(entity_overrides->begin(), entity_overrides->end(), extruder) != entity_overrides->end() ||      // at least one copy is overridden to use this extruder
-                                std::find(entity_overrides->begin(), entity_overrides->end(), -extruder-1) != entity_overrides->end() ||   // at least one copy would normally be printed with this extruder (see get_extruder_overrides function for explanation)
-                                (std::find(layer_tools.extruders.begin(), layer_tools.extruders.end(), correct_extruder_id) == layer_tools.extruders.end() && extruder == layer_tools.extruders.back())) // this entity is not overridden, but its extruder is not in layer_tools - we'll print it
-                                                                                                                                            //by last extruder on this layer (could happen e.g. when a wiping object is taller than others - dontcare extruders are eradicated from layer_tools)
-                            {
-                                std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
-                                    by_extruder,
-                                    extruder,
-                                    &layer_to_print - layers.data(),
-                                    layers.size(), n_slices+1);
-                                for (size_t i = 0; i <= n_slices; ++ i) {
-									bool   last = i == n_slices;
-                                	size_t island_idx = last ? n_slices : slices_test_order[i];
-                                    if (// fill->first_point does not fit inside any slice
-										last ||
-                                        // fill->first_point fits inside ith slice
-                                        point_inside_surface(island_idx, fill->first_point())) {
-                                        if (islands[island_idx].by_region.empty())
-                                            islands[island_idx].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
-                                        islands[island_idx].by_region[region_id].append(entity_type, fill, entity_overrides, layer_to_print.object()->copies().size());
-                                        break;
-                                    }
+                            std::vector<ObjectByExtruder::Island> &islands = object_islands_by_extruder(
+                                by_extruder,
+                                extruder,
+                                &layer_to_print - layers.data(),
+                                layers.size(), n_slices+1);
+                            for (size_t i = 0; i <= n_slices; ++ i) {
+								bool   last = i == n_slices;
+                            	size_t island_idx = last ? n_slices : slices_test_order[i];
+                                if (// extrusions->first_point does not fit inside any slice
+									last ||
+                                    // extrusions->first_point fits inside ith slice
+                                    point_inside_surface(island_idx, extrusions->first_point())) {
+                                    if (islands[island_idx].by_region.empty())
+                                        islands[island_idx].by_region.assign(print.regions().size(), ObjectByExtruder::Island::Region());
+                                    islands[island_idx].by_region[region_id].append(entity_type, extrusions, entity_overrides);
+                                    break;
                                 }
                             }
                         }
@@ -2147,6 +2158,7 @@ void GCode::process_layer(
 
         // We are almost ready to print. However, we must go through all the objects twice to print the the overridden extrusions first (infill/perimeter wiping feature):
         bool is_anything_overridden = const_cast<LayerTools&>(layer_tools).wiping_extrusions().is_anything_overridden();
+		std::vector<ObjectByExtruder::Island::Region> by_region_per_copy_cache;
         for (int print_wipe_extrusions = is_anything_overridden; print_wipe_extrusions>=0; --print_wipe_extrusions) {
             if (is_anything_overridden && print_wipe_extrusions == 0)
                 gcode+="; PURGING FINISHED\n";
@@ -2174,8 +2186,8 @@ void GCode::process_layer(
                     m_layer = layers[instance_to_print.layer_id].layer();
                 }
                 for (ObjectByExtruder::Island &island : instance_to_print.object_by_extruder.islands) {
-                    const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(instance_to_print.instance_id, extruder_id, print_wipe_extrusions) : island.by_region;
-
+                    const auto& by_region_specific = is_anything_overridden ? island.by_region_per_copy(by_region_per_copy_cache, instance_to_print.instance_id, extruder_id, print_wipe_extrusions) : island.by_region;
+                	//FIXME the following code prints regions in the order they are defined, the path is not optimized in any way.
                     if (print.config().infill_first) {
                         gcode += this->extrude_infill(print, by_region_specific);
                         gcode += this->extrude_perimeters(print, by_region_specific, lower_layer_edge_grids[instance_to_print.layer_id]);
@@ -3260,59 +3272,97 @@ Point GCode::gcode_to_point(const Vec2d &point) const
 
 // Goes through by_region std::vector and returns reference to a subvector of entities, that are to be printed
 // during infill/perimeter wiping, or normally (depends on wiping_entities parameter)
-// Returns a reference to member to avoid copying.
-const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtruder::Island::by_region_per_copy(unsigned int copy, int extruder, bool wiping_entities)
+// Fills in by_region_per_copy_cache and returns its reference.
+const std::vector<GCode::ObjectByExtruder::Island::Region>& GCode::ObjectByExtruder::Island::by_region_per_copy(std::vector<Region> &by_region_per_copy_cache, unsigned int copy, int extruder, bool wiping_entities) const
 {
+    bool has_overrides = false;
+    for (const auto& reg : by_region)
+    	if (! reg.infills_overrides.empty() || ! reg.perimeters_overrides.empty()) {
+    		has_overrides = true;
+    		break;
+    	}
+    if (! has_overrides)
+    	// Simple case. No need to copy the regions.
+    	return this->by_region;
+
+    // Complex case. Some of the extrusions of some object instances are to be printed first - those are the wiping extrusions.
+    // Some of the extrusions of some object instances are printed later - those are the clean print extrusions.
+    // Filter out the extrusions based on the infill_overrides / perimeter_overrides:
+
+	// Data is cleared, but the memory is not.
     by_region_per_copy_cache.clear();
 
     for (const auto& reg : by_region) {
-        by_region_per_copy_cache.push_back(ObjectByExtruder::Island::Region()); // creates a region in the newly created Island
+        by_region_per_copy_cache.emplace_back(); // creates a region in the newly created Island
 
         // Now we are going to iterate through perimeters and infills and pick ones that are supposed to be printed
         // References are used so that we don't have to repeat the same code
         for (int iter = 0; iter < 2; ++iter) {
-            const ExtrusionEntitiesPtr&         entities     = (iter ? reg.infills.entities : reg.perimeters.entities);
-            ExtrusionEntityCollection&          target_eec   = (iter ? by_region_per_copy_cache.back().infills : by_region_per_copy_cache.back().perimeters);
-            const std::vector<const ExtruderPerCopy*>& overrides   = (iter ? reg.infills_overrides : reg.perimeters_overrides);
+            const ExtrusionEntitiesPtr&         							entities    = (iter ? reg.infills.entities : reg.perimeters.entities);
+            ExtrusionEntityCollection&          							target_eec  = (iter ? by_region_per_copy_cache.back().infills : by_region_per_copy_cache.back().perimeters);
+            const std::vector<const WipingExtrusions::ExtruderPerCopy*>& 	overrides   = (iter ? reg.infills_overrides : reg.perimeters_overrides);
 
             // Now the most important thing - which extrusion should we print.
             // See function ToolOrdering::get_extruder_overrides for details about the negative numbers hack.
-            int this_extruder_mark = wiping_entities ? extruder : -extruder-1;
-
-            for (unsigned int i=0;i<entities.size();++i)
-                if (overrides[i]->at(copy) == this_extruder_mark)   // this copy should be printed with this extruder
-                    target_eec.append((*entities[i]));
+            if (wiping_entities) {
+            	// Apply overrides for this region.
+	            for (unsigned int i = 0; i < overrides.size(); ++ i) {
+            		const WipingExtrusions::ExtruderPerCopy *this_override = overrides[i];
+            		// This copy (aka object instance) should be printed with this extruder, which overrides the default one.
+	                if (this_override != nullptr && (*this_override)[copy] == extruder)
+	                	// Clone the ExtrusionEntity. This is quite expensive.
+	                    target_eec.append((*entities[i]));
+            	}
+	        } else {
+	        	// Apply normal extrusions (non-overrides) for this region.
+				unsigned int i = 0;
+	            for (; i < overrides.size(); ++ i) {
+            		const WipingExtrusions::ExtruderPerCopy *this_override = overrides[i];
+            		// This copy (aka object instance) should be printed with this extruder, which shall be equal to the default one.
+            		if (this_override == nullptr || (*this_override)[copy] == -extruder-1)
+	                	// Clone the ExtrusionEntity. This is quite expensive.
+	                    target_eec.append((*entities[i]));
+	            }
+	            for (; i < overrides.size(); ++ i)
+                	// Clone the ExtrusionEntity. This is quite expensive.
+                    target_eec.append(*entities[i]);
+		    }
         }
     }
     return by_region_per_copy_cache;
 }
 
-
-
 // This function takes the eec and appends its entities to either perimeters or infills of this Region (depending on the first parameter)
 // It also saves pointer to ExtruderPerCopy struct (for each entity), that holds information about which extruders should be used for which copy.
-void GCode::ObjectByExtruder::Island::Region::append(const std::string& type, const ExtrusionEntityCollection* eec, const ExtruderPerCopy* copies_extruder, size_t object_copies_num)
+void GCode::ObjectByExtruder::Island::Region::append(const Type type, const ExtrusionEntityCollection* eec, const WipingExtrusions::ExtruderPerCopy* copies_extruder)
 {
     // We are going to manipulate either perimeters or infills, exactly in the same way. Let's create pointers to the proper structure to not repeat ourselves:
-    ExtrusionEntityCollection* perimeters_or_infills = &infills;
-    std::vector<const ExtruderPerCopy*>* perimeters_or_infills_overrides = &infills_overrides;
+    ExtrusionEntityCollection* 								perimeters_or_infills;
+    std::vector<const WipingExtrusions::ExtruderPerCopy*>* 	perimeters_or_infills_overrides;
 
-    if (type == "perimeters") {
-        perimeters_or_infills = &perimeters;
-        perimeters_or_infills_overrides    = &perimeters_overrides;
+    switch (type) {
+    case PERIMETERS:
+        perimeters_or_infills 			= &perimeters;
+        perimeters_or_infills_overrides = &perimeters_overrides;
+        break;
+    case INFILL:
+    	perimeters_or_infills 			= &infills;
+    	perimeters_or_infills_overrides = &infills_overrides;
+        break;
+    default:
+    	throw std::invalid_argument("Unknown parameter!");
     }
-    else
-        if (type != "infills") {
-            throw std::invalid_argument("Unknown parameter!");
-            return;
-        }
-
 
     // First we append the entities, there are eec->entities.size() of them:
+    size_t old_size = perimeters_or_infills->entities.size();
     perimeters_or_infills->append(eec->entities);
 
-    for (unsigned int i=0;i<eec->entities.size();++i)
-        perimeters_or_infills_overrides->push_back(copies_extruder);
+    if (copies_extruder != nullptr) {
+    	perimeters_or_infills_overrides->reserve(old_size + eec->entities.size());
+    	perimeters_or_infills_overrides->resize(old_size, nullptr);
+	    for (unsigned int i = 0; i < eec->entities.size(); ++ i)
+	        perimeters_or_infills_overrides->emplace_back(copies_extruder);
+	}
 }
 
 }   // namespace Slic3r
diff --git a/src/libslic3r/GCode.hpp b/src/libslic3r/GCode.hpp
index 497dc8c71..934dcaece 100644
--- a/src/libslic3r/GCode.hpp
+++ b/src/libslic3r/GCode.hpp
@@ -239,7 +239,6 @@ protected:
     std::string     extrude_multi_path(ExtrusionMultiPath multipath, std::string description = "", double speed = -1.);
     std::string     extrude_path(ExtrusionPath path, std::string description = "", double speed = -1.);
 
-    typedef std::vector<int> ExtruderPerCopy;
     // Extruding multiple objects with soluble / non-soluble / combined supports
     // on a multi-material printer, trying to minimize tool switches.
     // Following structures sort extrusions by the extruder ID, by an order of objects and object islands.
@@ -256,18 +255,23 @@ protected:
                 ExtrusionEntityCollection perimeters;
                 ExtrusionEntityCollection infills;
 
-                std::vector<const ExtruderPerCopy*> infills_overrides;
-                std::vector<const ExtruderPerCopy*> perimeters_overrides;
+                std::vector<const WipingExtrusions::ExtruderPerCopy*> infills_overrides;
+                std::vector<const WipingExtrusions::ExtruderPerCopy*> perimeters_overrides;
+
+	            enum Type {
+	            	PERIMETERS,
+	            	INFILL,
+	            };
 
                 // Appends perimeter/infill entities and writes don't indices of those that are not to be extruder as part of perimeter/infill wiping
-                void append(const std::string& type, const ExtrusionEntityCollection* eec, const ExtruderPerCopy* copy_extruders, size_t object_copies_num);
+                void append(const Type type, const ExtrusionEntityCollection* eec, const WipingExtrusions::ExtruderPerCopy* copy_extruders);
             };
 
-            std::vector<Region> by_region;                                    // all extrusions for this island, grouped by regions
-            const std::vector<Region>& by_region_per_copy(unsigned int copy, int extruder, bool wiping_entities = false); // returns reference to subvector of by_region
 
-        private:
-            std::vector<Region> by_region_per_copy_cache;   // caches vector generated by function above to avoid copying and recalculating
+            std::vector<Region> by_region;                                    // all extrusions for this island, grouped by regions
+
+            // Fills in by_region_per_copy_cache and returns its reference.
+            const std::vector<Region>& by_region_per_copy(std::vector<Region> &by_region_per_copy_cache, unsigned int copy, int extruder, bool wiping_entities = false) const;
         };
         std::vector<Island>         islands;
     };
@@ -277,7 +281,9 @@ protected:
 		InstanceToPrint(ObjectByExtruder &object_by_extruder, size_t layer_id, const PrintObject &print_object, size_t instance_id) :
 			object_by_extruder(object_by_extruder), layer_id(layer_id), print_object(print_object), instance_id(instance_id) {}
 
-		ObjectByExtruder	&object_by_extruder;
+		// Repository 
+		ObjectByExtruder		&object_by_extruder;
+		// Index into std::vector<LayerToPrint>, which contains Object and Support layers for the current print_z, collected for a single object, or for possibly multiple objects with multiple instances.
 		const size_t       		 layer_id;
 		const PrintObject 		&print_object;
 		// Instance idx of the copy of a print object.
@@ -285,7 +291,8 @@ protected:
 	};
 
 	std::vector<InstanceToPrint> sort_print_object_instances(
-		std::vector<ObjectByExtruder> 			&objects_by_extruder,
+		std::vector<ObjectByExtruder> 					&objects_by_extruder,
+		// Object and Support layers for the current print_z, collected for a single object, or for possibly multiple objects with multiple instances.
 		const std::vector<LayerToPrint> 				&layers,
 		// Ordering must be defined for normal (non-sequential print).
 		const std::vector<std::pair<size_t, size_t>> 	*ordering,
diff --git a/src/libslic3r/GCode/ToolOrdering.cpp b/src/libslic3r/GCode/ToolOrdering.cpp
index bcb65554d..123656e43 100644
--- a/src/libslic3r/GCode/ToolOrdering.cpp
+++ b/src/libslic3r/GCode/ToolOrdering.cpp
@@ -19,7 +19,7 @@ namespace Slic3r {
 // Returns true in case that extruder a comes before b (b does not have to be present). False otherwise.
 bool LayerTools::is_extruder_order(unsigned int a, unsigned int b) const
 {
-    if (a==b)
+    if (a == b)
         return false;
 
     for (auto extruder : extruders) {
@@ -415,10 +415,9 @@ void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, unsi
 {
     something_overridden = true;
 
-    auto entity_map_it = (entity_map.insert(std::make_pair(entity, std::vector<int>()))).first; // (add and) return iterator
-    auto& copies_vector = entity_map_it->second;
-    if (copies_vector.size() < num_of_copies)
-        copies_vector.resize(num_of_copies, -1);
+    auto entity_map_it = (entity_map.emplace(entity, ExtruderPerCopy())).first; // (add and) return iterator
+    ExtruderPerCopy& copies_vector = entity_map_it->second;
+    copies_vector.resize(num_of_copies, -1);
 
     if (copies_vector[copy_id] != -1)
         std::cout << "ERROR: Entity extruder overriden multiple times!!!\n";    // A debugging message - this must never happen.
@@ -426,7 +425,6 @@ void WipingExtrusions::set_extruder_override(const ExtrusionEntity* entity, unsi
     copies_vector[copy_id] = extruder;
 }
 
-
 // Finds first non-soluble extruder on the layer
 int WipingExtrusions::first_nonsoluble_extruder_on_layer(const PrintConfig& print_config) const
 {
@@ -622,31 +620,23 @@ void WipingExtrusions::ensure_perimeters_infills_order(const Print& print)
     }
 }
 
-
-
-
-
-
-
-// Following function is called from process_layer and returns pointer to vector with information about which extruders should be used for given copy of this entity.
-// It first makes sure the pointer is valid (creates the vector if it does not exist) and contains a record for each copy
-// It also modifies the vector in place and changes all -1 to correct_extruder_id (at the time the overrides were created, correct extruders were not known,
-// so -1 was used as "print as usual".
-// The resulting vector has to keep track of which extrusions are the ones that were overridden and which were not. In the extruder is used as overridden,
-// its number is saved as it is (zero-based index). Usual extrusions are saved as -number-1 (unfortunately there is no negative zero).
-const std::vector<int>* WipingExtrusions::get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies)
+// Following function is called from GCode::process_layer and returns pointer to vector with information about which extruders should be used for given copy of this entity.
+// If this extrusion does not have any override, nullptr is returned.
+// Otherwise it modifies the vector in place and changes all -1 to correct_extruder_id (at the time the overrides were created, correct extruders were not known,
+// so -1 was used as "print as usual").
+// The resulting vector therefore keeps track of which extrusions are the ones that were overridden and which were not. If the extruder used is overridden,
+// its number is saved as is (zero-based index). Regular extrusions are saved as -number-1 (unfortunately there is no negative zero).
+const WipingExtrusions::ExtruderPerCopy* WipingExtrusions::get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies)
 {
+	ExtruderPerCopy *overrides = nullptr;
     auto entity_map_it = entity_map.find(entity);
-    if (entity_map_it == entity_map.end())
-        entity_map_it = (entity_map.insert(std::make_pair(entity, std::vector<int>()))).first;
-
-    // Now the entity_map_it should be valid, let's make sure the vector is long enough:
-    entity_map_it->second.resize(num_of_copies, -1);
-
-    // Each -1 now means "print as usual" - we will replace it with actual extruder id (shifted it so we don't lose that information):
-    std::replace(entity_map_it->second.begin(), entity_map_it->second.end(), -1, -correct_extruder_id-1);
-
-    return &(entity_map_it->second);
+    if (entity_map_it != entity_map.end()) {
+        overrides = &entity_map_it->second;
+    	overrides->resize(num_of_copies, -1);
+	    // Each -1 now means "print as usual" - we will replace it with actual extruder id (shifted it so we don't lose that information):
+	    std::replace(overrides->begin(), overrides->end(), -1, -correct_extruder_id-1);
+	}
+    return overrides;
 }
 
 
diff --git a/src/libslic3r/GCode/ToolOrdering.hpp b/src/libslic3r/GCode/ToolOrdering.hpp
index c37c90823..dcb93c021 100644
--- a/src/libslic3r/GCode/ToolOrdering.hpp
+++ b/src/libslic3r/GCode/ToolOrdering.hpp
@@ -7,6 +7,8 @@
 
 #include <utility>
 
+#include <boost/container/small_vector.hpp>
+
 namespace Slic3r {
 
 class Print;
@@ -25,8 +27,19 @@ public:
         return something_overridden;
     }
 
+    // When allocating extruder overrides of an object's ExtrusionEntity, overrides for maximum 3 copies are allocated in place.
+    typedef boost::container::small_vector<int32_t, 3> ExtruderPerCopy;
+
+    class ExtruderOverrides
+    {
+    public:
+    	ExtruderOverrides(const ExtruderPerCopy *overrides, const int correct_extruder_id) : m_overrides(overrides) {}
+    private:
+    	const ExtruderPerCopy *m_overrides;
+    };
+
     // This is called from GCode::process_layer - see implementation for further comments:
-    const std::vector<int>* get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies);
+    const ExtruderPerCopy* get_extruder_overrides(const ExtrusionEntity* entity, int correct_extruder_id, size_t num_of_copies);
 
     // This function goes through all infill entities, decides which ones will be used for wiping and
     // marks them by the extruder id. Returns volume that remains to be wiped on the wipe tower:
@@ -50,7 +63,7 @@ private:
         return (entity_map.find(entity) == entity_map.end() ? false : entity_map.at(entity).at(copy_id) != -1);
     }
 
-    std::map<const ExtrusionEntity*, std::vector<int>> entity_map;  // to keep track of who prints what
+    std::map<const ExtrusionEntity*, ExtruderPerCopy> entity_map;  // to keep track of who prints what
     bool something_overridden = false;
     const LayerTools* m_layer_tools;    // so we know which LayerTools object this belongs to
 };
@@ -74,6 +87,7 @@ public:
     bool operator==(const LayerTools &rhs) const { return print_z == rhs.print_z; }
 
     bool is_extruder_order(unsigned int a, unsigned int b) const;
+    bool has_extruder(unsigned int extruder) const { return std::find(this->extruders.begin(), this->extruders.end(), extruder) != this->extruders.end(); }
 
     coordf_t 					print_z;
     bool 						has_object;
diff --git a/src/libslic3r/pchheader.hpp b/src/libslic3r/pchheader.hpp
index 67b3d3a21..1339368bd 100644
--- a/src/libslic3r/pchheader.hpp
+++ b/src/libslic3r/pchheader.hpp
@@ -63,6 +63,7 @@
 #include <boost/bind.hpp>
 #include <boost/config.hpp>
 #include <boost/config/warning_disable.hpp>
+#include <boost/container/small_vector.hpp>
 #include <boost/date_time/local_time/local_time.hpp>
 #include <boost/date_time/posix_time/posix_time.hpp>
 #include <boost/filesystem.hpp>