diff --git a/src/fvm_multicell.hpp b/src/fvm_multicell.hpp
index 67324155ccb32157bec224d50638cf111bd3e265..709273adfac72a0f485162318757703f51d9a522 100644
--- a/src/fvm_multicell.hpp
+++ b/src/fvm_multicell.hpp
@@ -224,6 +224,9 @@ void fvm_multicell<T, I>::compute_cv_area_unnormalized_capacitance(
     const segment& seg,
     index_vector &parent)
 {
+    using util::left;
+    using util::right;
+
     // precondition: group_parent_index[j] holds the correct value for
     // j in [base_comp, base_comp+segment.num_compartments()].
 
@@ -316,16 +319,23 @@ void fvm_multicell<T, I>::initialize(
     current_    = vector_type{ncomp, T{0}};
     voltage_    = vector_type{ncomp, T{0}};
 
+    // create maps for mechanism initialization.
+    std::map<std::string, std::pair<size_type, size_type>> mech_map;
+    std::vector<std::vector<cell_lid_type>> syn_mech_map;
+    std::map<std::string, std::size_t> syn_mech_indices;
+
+    // initialize vector used for matrix creation.
     index_vector group_parent_index{ncomp, 0};
 
+    auto target_hi = target_handles.begin();
     for (size_type i = 0; i<ncell; ++i) {
         const auto& c = cells[i];
         auto comps = cell_comp_part[i];
 
-        auto parent_index = c.model().parent_index;
+        auto graph = c.model();
 
         for (auto k: make_span(comps)) {
-            group_parent_index[k] = parent_index[k-comps.first]+comps.first;
+            group_parent_index[k] = graph.parent_index[k-comps.first]+comps.first;
         }
 
         auto seg_num_compartments =
@@ -336,7 +346,37 @@ void fvm_multicell<T, I>::initialize(
         auto seg_comp_part = make_partition(seg_comp_bounds, seg_num_compartments, comps.first);
 
         for (size_type j = 0; j<nseg; ++j) {
-            compute_cv_area_unnormalized_capacitance(seg_comp_part[j], c.segment(j), group_parent_index);
+            const auto& seg = c.segment(j);
+            const auto& seg_comps = seg_comp_part[j];
+
+            compute_cv_area_unnormalized_capacitance(seg_comps, seg, group_parent_index);
+
+            for (const auto& mech: seg->mechanisms()) {
+                if (mech.name()!="membrane") {
+                    mech_map[mech_name().push_back(seg_comps)];
+                }
+            }
+        }
+
+        for (const auto& syn: c.synapses()) {
+            const auto& name = syn.mechanism.name();
+            std::size_t index = 0;
+            if (syn_mech_indices.count(name)==0) {
+                index = syn_mech_map.size();
+                syn_mech_indices[name] = index;
+                syn_mech_map.push_back(std::vector<size_type>{});
+            }
+            else {
+                index = syn_mech_indices[name];
+            }
+
+            size_type syn_comp = comps.first+find_compartment_index(syn.location, graph);
+
+            EXPECTS(targets_total < c.targets.size());
+            *target_hi++ = target_handle{index, syn_mech_map[index].size()};
+            ++targets_total;
+
+            syn_mech_map[index].push_back(syn_comp);
         }
 
         // normalize capacitance across cell
@@ -344,12 +384,7 @@ void fvm_multicell<T, I>::initialize(
             cv_capacitance_[k] /= cv_areas_[k];
         }
 
-        // add mechanisms to look up table for instantiation below
-
-        // TODO: move mech_map, syn_map insertions here etc.
-
         detectors_total += c.detectors().size();
-        targets_total += c.synapses().size();
         probess_total += c.probes.size();
     }
 
@@ -361,90 +396,32 @@ void fvm_multicell<T, I>::initialize(
     // initalize matrix
     matrix_ = matrix_type(group_parent_index);
 
-    using util::left;
-    using util::right;
-
-    // create mechanisms
-
-    // for each mechanism in the cell record the indexes of the segments that
-    // contain the mechanism
-    std::map<std::string, std::vector<unsigned>> mech_map;
-
-    for (unsigned i=0; i<cell.num_segments(); ++i) {
-        for (const auto& mech : cell.segment(i)->mechanisms()) {
-            // FIXME : Membrane has to be a proper mechanism,
-            //         because it is exposed via the public interface.
-            //         This if statement is bad
-            if(mech.name() != "membrane") {
-                mech_map[mech.name()].push_back(i);
-            }
-        }
-    }
-
-    // Create the mechanism implementations with the state for each mechanism
-    // instance.
-    // TODO : this works well for density mechanisms (e.g. ion channels), but
-    // does it work for point processes (e.g. synapses)?
-    for (auto& mech : mech_map) {
-        // calculate the number of compartments that contain the mechanism
-        auto num_comp = 0u;
-        for (auto seg : mech.second) {
-            num_comp += segment_index_[seg+1] - segment_index_[seg];
-        }
+    // create density mechanisms
+    std::vector<size_type> mech_comp_indices;
+    mech_comp_indices.reserve(ncomp);
 
-        // build a vector of the indexes of the compartments that contain
-        // the mechanism
-        index_type compartment_index(num_comp);
-        auto pos = 0u;
-        for (auto seg : mech.second) {
-            auto seg_size = segment_index_[seg+1] - segment_index_[seg];
-            std::iota(
-                compartment_index.data() + pos,
-                compartment_index.data() + pos + seg_size,
-                segment_index_[seg]
-            );
-            pos += seg_size;
+    for (auto& mech: mech_map) {
+        mech_comp_indices.clear();
+        for (auto comp_ival: mech.second) {
+            util::append(mech_comp_indices, make_span(comp_ival));
         }
 
-        // instantiate the mechanism
         mechanisms_.push_back(
-            mechanism_catalogue::make(mech.first, voltage_, current_, compartment_index)
+            mechanism_catalogue::make(mech.first, voltage_, current_, mech_comp_indices)
         );
     }
 
+    // create point (synapse) mechanisms
     synapse_base_ = mechanisms_.size();
-
-    // Create the synapse mechanism implementations together with the target handles
-    std::vector<std::vector<cell_lid_type>> syn_mech_map;
-    std::map<std::string, std::size_t> syn_mech_indices;
-    auto target_hi = target_handles.begin();
-
-    for (const auto& syn : cell.synapses()) {
-        const auto& name = syn.mechanism.name();
-        std::size_t index = 0;
-        if (syn_mech_indices.count(name)==0) {
-            index = syn_mech_map.size();
-            syn_mech_indices[name] = index;
-            syn_mech_map.push_back(std::vector<cell_lid_type>{});
-        }
-        else {
-            index = syn_mech_indices[name];
-        }
-
-        size_type comp = find_compartment_index(syn.location, graph);
-        *target_hi++ = target_handle{index, syn_mech_map[index].size()};
-        syn_mech_map[index].push_back(comp);
-    }
-
-    for (const auto& syni : syn_mech_indices) {
+    for (const auto& syni: syn_mech_indices) {
         const auto& mech_name = syni.first;
 
-        index_type compartment_index(syn_mech_map[syni.second]);
-        auto mech = mechanism_catalogue::make(mech_name, voltage_, current_, compartment_index);
+        auto mech = mechanism_catalogue::make(mech_name, voltage_, current_, syn_mech_map[syni.second]);
         mech->set_areas(cv_areas_);
         mechanisms_.push_back(std::move(mech));
     }
 
+    // TODO: FROM HERE...
 
     /////////////////////////////////////////////
     // build the ion species
diff --git a/src/util/range.hpp b/src/util/range.hpp
index 7777444d0f65d7feebc03f8f3e988a234462cdf6..590bdb45d14433cd5642e9042b8adaeb4feb76f2 100644
--- a/src/util/range.hpp
+++ b/src/util/range.hpp
@@ -327,6 +327,15 @@ range<const T*> singleton_view(const T& item) {
     return {&item, &item+1};
 }
 
+/*
+ * Range/container utility functions
+ */
+
+template <typename Container, typename Seq>
+void append(Container &c, const Seq& seq) {
+    c.insert(c.end(), seq.begin(), seq.end());
+}
+
 } // namespace util
 } // namespace mc
 } // namespace nest