diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index 424098fcb047b0f464229ba6bd21ac4a1ec86fb9..f0983d0514f6eeddff2778aef45e4e0b78b5f9f1 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -28,7 +28,8 @@
 using namespace nest::mc;
 
 using global_policy = communication::global_policy;
-using lowered_cell = fvm::fvm_multicell<double, cell_local_size_type>;
+//using lowered_cell = fvm::fvm_multicell<double, cell_local_size_type>;
+using lowered_cell = fvm::fvm_cell<double, cell_local_size_type>;
 using model_type = model<lowered_cell>;
 using time_type = model_type::time_type;
 using sample_trace_type = sample_trace<time_type, model_type::value_type>;
diff --git a/src/compartment.hpp b/src/compartment.hpp
index 326563ad4261bd6d3e5ce0b516c3aa8808c893a9..083155ffb7c5a3ea0d9d089740b6d7a3345ae234 100644
--- a/src/compartment.hpp
+++ b/src/compartment.hpp
@@ -37,134 +37,6 @@ struct compartment {
     value_type length;
 };
 
-
-/// The simplest type of compartment iterator :
-///     - divide a segment into n compartments of equal length
-///     - assume that the radius varies linearly from one end of the segment
-///       to the other
-class compartment_iterator :
-    public std::iterator<std::forward_iterator_tag, compartment>
-{
-
-    public:
-
-    using base = std::iterator<std::forward_iterator_tag, compartment>;
-    using size_type = base::value_type::size_type;
-    using real_type = base::value_type::value_type;
-
-    compartment_iterator() = delete;
-
-    compartment_iterator(
-        size_type idx,
-        real_type len,
-        real_type rad,
-        real_type delta_rad
-    )
-    :   index_(idx),
-        radius_(rad),
-        delta_radius_(delta_rad),
-        length_(len)
-    { }
-
-    compartment_iterator(compartment_iterator const& other) = default;
-
-    compartment_iterator& operator++()
-    {
-        index_++;
-        radius_ += delta_radius_;
-        return *this;
-    }
-
-    compartment_iterator operator++(int)
-    {
-        compartment_iterator ret(*this);
-        operator++();
-        return ret;
-    }
-
-    compartment operator*() const
-    {
-        return
-            compartment(
-                index_, length_, radius_, radius_ + delta_radius_
-            );
-    }
-
-    bool operator==(compartment_iterator const& other) const
-    {
-        return other.index_ == index_;
-    }
-
-    bool operator!=(compartment_iterator const& other) const
-    {
-        return !operator==(other);
-    }
-
-    private :
-
-    size_type index_;
-    real_type radius_;
-    const real_type delta_radius_;
-    const real_type length_;
-};
-
-class compartment_range {
-public:
-    using size_type = compartment_iterator::size_type;
-    using real_type = compartment_iterator::real_type;
-
-    compartment_range(
-        size_type num_compartments,
-        real_type radius_L,
-        real_type radius_R,
-        real_type length
-    )
-    :   num_compartments_(num_compartments),
-        radius_L_(radius_L),
-        radius_R_(radius_R),
-        length_(length)
-    {}
-
-    compartment_iterator begin() const
-    {
-        return {0, compartment_length(), radius_L_, delta_radius()};
-    }
-
-    compartment_iterator cbegin() const
-    {
-        return begin();
-    }
-
-    /// With 0-based indexing compartment number "num_compartments_" is
-    /// one past the end
-    compartment_iterator end() const
-    {
-        return {num_compartments_, 0, 0, 0};
-    }
-
-    compartment_iterator cend() const
-    {
-        return end();
-    }
-
-    real_type delta_radius() const
-    {
-        return (radius_R_ - radius_L_) / num_compartments_;
-    }
-
-    real_type compartment_length() const
-    {
-        return length_ / num_compartments_;
-    }
-
-    private:
-
-    size_type num_compartments_;
-    real_type radius_L_;
-    real_type radius_R_;
-    real_type length_;
-};
-
 // (NB: auto type deduction and lambda in C++14 will simplify the following)
 
 template <typename size_type, typename real_type>
@@ -187,11 +59,16 @@ private:
 };
 
 template <typename size_type, typename real_type>
-using compartment_iterator_bis =
+using compartment_iterator =
     util::transform_iterator<util::counter<size_type>, compartment_maker<size_type, real_type>>;
 
 template <typename size_type, typename real_type>
-util::range<compartment_iterator_bis<size_type, real_type>> make_compartment_range(
+using compartment_range =
+    util::range<compartment_iterator<size_type, real_type>>;
+
+
+template <typename size_type, typename real_type>
+compartment_range<size_type, real_type> make_compartment_range(
     size_type num_compartments,
     real_type radius_L,
     real_type radius_R,
diff --git a/src/fvm_multicell.hpp b/src/fvm_multicell.hpp
index 8239c7e5070401cd9973a3b0cb4e7db5a9d8173a..9100a8fb56789be83fb950f7ff666e8dc6c0ffa8 100644
--- a/src/fvm_multicell.hpp
+++ b/src/fvm_multicell.hpp
@@ -20,6 +20,8 @@
 #include <stimulus.hpp>
 #include <util.hpp>
 #include <util/meta.hpp>
+#include <util/partition.hpp>
+#include <util/span.hpp>
 
 #include <vector/include/Vector.hpp>
 
@@ -202,7 +204,7 @@ private:
     /// the ion species
     std::map<mechanisms::ionKind, ion_type> ions_;
 
-    std::vector<std::pair<uint32_t, i_clamp>> stimulii_;
+    std::vector<std::pair<uint32_t, i_clamp>> stimuli_;
 
     std::vector<std::pair<const vector_type fvm_multicell::*, uint32_t>> probes_;
 
@@ -211,7 +213,7 @@ private:
 
     // perform area and capacitance calculation on initialization
     void compute_cv_area_unnormalized_capacitance(
-        std::pair<size_type, size_type> comps, const segment& seg, index_type &parent);
+        std::pair<size_type, size_type> comps, const segment* seg, index_type &parent);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -221,7 +223,7 @@ private:
 template <typename T, typename I>
 void fvm_multicell<T, I>::compute_cv_area_unnormalized_capacitance(
     std::pair<size_type, size_type> comps,
-    const segment& seg,
+    const segment* seg,
     index_type &parent)
 {
     using util::left;
@@ -230,9 +232,11 @@ void fvm_multicell<T, I>::compute_cv_area_unnormalized_capacitance(
     // precondition: group_parent_index[j] holds the correct value for
     // j in [base_comp, base_comp+segment.num_compartments()].
 
-    if (auto soma = seg.as_soma()) {
+    auto ncomp = comps.second-comps.first;
+
+    if (auto soma = seg->as_soma()) {
         // confirm assumption that there is one compartment in soma
-        if (comps.size()!=1)
+        if (ncomp!=1) {
             throw std::logic_error("soma allocated more than one compartment");
         }
         auto i = comps.first;
@@ -241,7 +245,7 @@ void fvm_multicell<T, I>::compute_cv_area_unnormalized_capacitance(
         cv_areas_[i] += area;
         cv_capacitance_[i] += area * soma->mechanism("membrane").get("c_m").value;
     }
-    else if (auto cable = s.as_cable()) {
+    else if (auto cable = seg->as_cable()) {
         // loop over each compartment in the cable
         // each compartment has the face between two CVs at its centre
         // the centers of the CVs are the end points of the compartment
@@ -261,10 +265,10 @@ void fvm_multicell<T, I>::compute_cv_area_unnormalized_capacitance(
         auto r_L = cable->mechanism("membrane").get("r_L").value;
         const auto& compartments = cable->compartments();
 
-        EXPECTS(util::size(compartments)==comps.second-comps.first);
+        EXPECTS(util::size(compartments)==ncomp);
 
         for (auto i: util::make_span(comps)) {
-            const auto c& = compartments[i-comps.first];
+            const auto& c = compartments[i-comps.first];
             auto j = parent[i];
 
             auto radius_center = math::mean(c.radius);
@@ -302,10 +306,10 @@ void fvm_multicell<T, I>::initialize(
     // count total detectors, targets and probes for validation of handle container sizes
     size_type detectors_count = 0u;
     size_type targets_count = 0u;
-    size_type probess_count = 0u;
+    size_type probes_count = 0u;
     size_type detectors_size = util::size(detector_handles);
-    size_type targets_size = util::size(targets_handles);
-    size_type probes_size = util::size(probes_handles);
+    size_type targets_size = util::size(target_handles);
+    size_type probes_size = util::size(probe_handles);
 
     auto ncell = util::size(cells);
     auto cell_num_compartments =
@@ -323,12 +327,12 @@ void fvm_multicell<T, I>::initialize(
     voltage_    = vector_type{ncomp, T{0}};
 
     // create maps for mechanism initialization.
-    std::map<std::string, std::pair<size_type, size_type>> mech_map;
+    std::map<std::string, std::vector<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};
+    index_type group_parent_index{ncomp, 0};
 
     // create each cell:
     auto target_hi = target_handles.begin();
@@ -346,7 +350,7 @@ void fvm_multicell<T, I>::initialize(
         }
 
         auto seg_num_compartments =
-            transform_view(c.segments(), [](const segment& s) { return s.num_compartments(); });
+            transform_view(c.segments(), [](const segment_ptr& s) { return s->num_compartments(); });
         auto nseg = seg_num_compartments.size();
 
         std::vector<cell_lid_type> seg_comp_bounds;
@@ -360,7 +364,7 @@ void fvm_multicell<T, I>::initialize(
 
             for (const auto& mech: seg->mechanisms()) {
                 if (mech.name()!="membrane") {
-                    mech_map[mech_name().push_back(seg_comps)];
+                    mech_map[mech.name()].push_back(seg_comps);
                 }
             }
         }
@@ -391,7 +395,7 @@ void fvm_multicell<T, I>::initialize(
             cv_capacitance_[k] /= cv_areas_[k];
         }
 
-        // add the stimulii
+        // add the stimuli
         for (const auto& stim: c.stimuli()) {
             auto idx = comps.first+find_compartment_index(stim.location, graph);
             stimuli_.push_back({idx, stim.clamp});
@@ -578,8 +582,8 @@ void fvm_multicell<T, I>::advance(T dt) {
         PL();
     }
 
-    // add current contributions from stimulii
-    for (auto& stim : stimulii_) {
+    // add current contributions from stimuli
+    for (auto& stim : stimuli_) {
         auto ie = stim.second.amplitude(t_); // [nA]
         auto loc = stim.first;
 
diff --git a/src/mechanism_catalogue.hpp b/src/mechanism_catalogue.hpp
index c9d3e6de2771a1b18fa05f104dd257b8c7fe6dd9..aecea5ce18bba05b9e28fcff6dcf123c3bddfc91 100644
--- a/src/mechanism_catalogue.hpp
+++ b/src/mechanism_catalogue.hpp
@@ -19,18 +19,19 @@ struct catalogue {
     using view_type = typename mechanism<T, I>::view_type;
     using index_view = typename mechanism<T, I>::index_view;
 
+    template <typename Indices>
     static mechanism_ptr<T, I> make(
         const std::string& name,
         view_type vec_v,
         view_type vec_i,
-        index_view node_indices)
+        Indices node_indices)
     {
         auto entry = mech_map.find(name);
         if (entry==mech_map.end()) {
             throw std::out_of_range("no such mechanism");
         }
 
-        return entry->second(vec_v, vec_i, node_indices);
+        return entry->second(vec_v, vec_i, index_view{node_indices});
     }
 
     static bool has(const std::string& name) {
diff --git a/src/parameter_list.cpp b/src/parameter_list.cpp
index 86c641aa809e6efe1c8f03247cc64f9f1b3a01f0..2ca508175f58a402165fd0d56b744148cdb2b267 100644
--- a/src/parameter_list.cpp
+++ b/src/parameter_list.cpp
@@ -6,88 +6,92 @@
 namespace nest {
 namespace mc {
 
-    bool parameter_list::add_parameter(parameter p)
-    {
-        if(has_parameter(p.name)) {
-            return false;
-        }
+bool parameter_list::add_parameter(parameter p) {
+    if (has_parameter(p.name)) {
+        return false;
+    }
 
-        parameters_.push_back(std::move(p));
+    parameters_.push_back(std::move(p));
 
-        return true;
-    }
+    return true;
+}
 
-    bool parameter_list::has_parameter(std::string const& n) const
-    {
-        return find_by_name(n) != parameters_.end();
-    }
+bool parameter_list::has_parameter(std::string const& n) const {
+    return find_by_name(n) != parameters_.end();
+}
 
-    int parameter_list::num_parameters() const
-    {
-        return parameters_.size();
-    }
+int parameter_list::num_parameters() const {
+    return parameters_.size();
+}
 
-    // returns true if parameter was succesfully updated
-    // returns false if parameter was not updated, i.e. if
-    //  - no parameter with name n exists
-    //  - value is not in the valid range
-    bool parameter_list::set(std::string const& n, parameter_list::value_type v)
-    {
-        auto p = find_by_name(n);
-        if(p!=parameters_.end()) {
-            if(p->is_in_range(v)) {
-                p->value = v;
-                return true;
-            }
+// returns true if parameter was succesfully updated
+// returns false if parameter was not updated, i.e. if
+//  - no parameter with name n exists
+//  - value is not in the valid range
+bool parameter_list::set(std::string const& n, parameter_list::value_type v) {
+    auto p = find_by_name(n);
+    if(p!=parameters_.end()) {
+        if(p->is_in_range(v)) {
+            p->value = v;
+            return true;
         }
-        return false;
     }
+    return false;
+}
 
-    parameter& parameter_list::get(std::string const& n)
-    {
-        auto it = find_by_name(n);
-        if(it==parameters_.end()) {
-            throw std::domain_error(
-                "parameter list does not contain parameter"
-            );
-        }
-        return *it;
+parameter& parameter_list::get(std::string const& n) {
+    auto it = find_by_name(n);
+    if (it==parameters_.end()) {
+        throw std::domain_error(
+            "parameter list does not contain parameter"
+        );
     }
+    return *it;
+}
 
-    std::string const& parameter_list::name() const {
-        return mechanism_name_;
+const parameter& parameter_list::get(std::string const& n) const {
+    auto it = find_by_name(n);
+    if (it==parameters_.end()) {
+        throw std::domain_error(
+            "parameter list does not contain parameter"
+        );
     }
+    return *it;
+}
 
-    std::vector<parameter> const& parameter_list::parameters() const
-    {
-        return parameters_;
-    }
+std::string const& parameter_list::name() const {
+    return mechanism_name_;
+}
 
-    auto parameter_list::find_by_name(std::string const& n)
-        -> decltype(parameters_.begin())
-    {
-        return
-            std::find_if(
-                parameters_.begin(), parameters_.end(),
-                [&n](parameter const& p) {return p.name == n;}
-            );
-    }
+std::vector<parameter> const& parameter_list::parameters() const {
+    return parameters_;
+}
+
+auto parameter_list::find_by_name(std::string const& n)
+    -> decltype(parameters_.begin())
+{
+    return
+        std::find_if(
+            parameters_.begin(), parameters_.end(),
+            [&n](parameter const& p) {return p.name == n;}
+        );
+}
+
+auto parameter_list::find_by_name(std::string const& n) const
+    -> decltype(parameters_.begin())
+{
+    return
+        std::find_if(
+            parameters_.begin(), parameters_.end(),
+            [&n](parameter const& p) {return p.name == n;}
+        );
+}
 
-    auto parameter_list::find_by_name(std::string const& n) const
-        -> decltype(parameters_.begin())
-    {
-        return
-            std::find_if(
-                parameters_.begin(), parameters_.end(),
-                [&n](parameter const& p) {return p.name == n;}
-            );
-    }
 } // namespace mc
 } // namespace nest
 
 std::ostream&
-operator<<(std::ostream& o, nest::mc::parameter const& p)
-{
+operator<<(std::ostream& o, nest::mc::parameter const& p) {
     return o
         << "parameter("
         << "name " << p.name
@@ -97,8 +101,7 @@ operator<<(std::ostream& o, nest::mc::parameter const& p)
 }
 
 std::ostream&
-operator<<(std::ostream& o, nest::mc::parameter_list const& l)
-{
+operator<<(std::ostream& o, nest::mc::parameter_list const& l) {
     o << "parameters \"" << l.name() << "\" :\n";
     for(nest::mc::parameter const& p : l.parameters()) {
         o << " " << p << "\n";
diff --git a/src/parameter_list.hpp b/src/parameter_list.hpp
index 0c06988756a077fdbb860fc8f42043b178b1b7e7..eb3ee8fe2f3c3ce1018bb113c966cb556e12916e 100644
--- a/src/parameter_list.hpp
+++ b/src/parameter_list.hpp
@@ -102,6 +102,7 @@ namespace mc {
         //  - value is not in the valid range
         bool set(std::string const& n, value_type v);
         parameter& get(std::string const& n);
+        const parameter& get(std::string const& n) const;
 
         std::string const& name() const;
 
diff --git a/src/segment.hpp b/src/segment.hpp
index 248306a6c3a976d123b9d412b93c09156305086d..5a9782b9ce41d8748bb5af6234ab9640c349f360 100644
--- a/src/segment.hpp
+++ b/src/segment.hpp
@@ -418,9 +418,9 @@ public:
     }
 
     /// iterable range type for simple compartment representation
-    compartment_range compartments() const
+    compartment_range<size_type, value_type> compartments() const
     {
-        return {num_compartments(), radii_.front(), radii_.back(), length()};
+        return make_compartment_range(num_compartments(), radii_.front(), radii_.back(), length());
     }
 
 private:
diff --git a/src/util/transform.hpp b/src/util/transform.hpp
index f7d9fed04c721f09611757c84c54e5f13cd15942..d20b006102984e8dc40adb528cd5b4388aab21c5 100644
--- a/src/util/transform.hpp
+++ b/src/util/transform.hpp
@@ -33,12 +33,12 @@ class transform_iterator: public iterator_adaptor<transform_iterator<I, F>, I> {
 
 public:
     using typename base::difference_type;
-    using value_type = decltype(f_(*inner_));
+    using value_type = typename std::result_of<F (inner_value_type)>::type;
     using pointer = const value_type*;
     using reference = const value_type&;
 
     template <typename J, typename G>
-    transform_iterator(J&& c, G&& g): inner_{std::forward<J>(c)}, f_{std::forward<G>(g)} {}
+    transform_iterator(J&& c, G&& g): inner_(std::forward<J>(c)), f_(std::forward<G>(g)) {}
 
     transform_iterator(const transform_iterator&) = default;
     transform_iterator(transform_iterator&&) = default;
diff --git a/tests/unit/test_compartments.cpp b/tests/unit/test_compartments.cpp
index 176bf18177d2379d2c42d3fc31199f904f22bc52..8bc034ade553675ac8f85ce19bc8bfccf5d14d5d 100644
--- a/tests/unit/test_compartments.cpp
+++ b/tests/unit/test_compartments.cpp
@@ -2,8 +2,8 @@
 
 #include "gtest.h"
 
-#include "../src/compartment.hpp"
-#include "../src/util.hpp"
+#include <compartment.hpp>
+#include <util.hpp>
 
 using nest::mc::util::left;
 using nest::mc::util::right;
@@ -12,7 +12,6 @@ using nest::mc::util::right;
 // are correctly stored in members
 TEST(compartments, compartment)
 {
-
     {
         nest::mc::compartment c(100, 1.2, 2.1, 2.2);
         EXPECT_EQ(c.index, 100u);
@@ -36,102 +35,6 @@ TEST(compartments, compartment)
     }
 }
 
-TEST(compartments, compartment_iterator)
-{
-    // iterator with arguments
-    //  idx = 0
-    //  len = 2.5
-    //  rad = 1
-    //  delta_rad = 2
-    nest::mc::compartment_iterator it(0, 2.5, 1, 2);
-
-    // so each time the iterator is incremented
-    //   idx is incremented by 1
-    //   len is unchanged
-    //   rad is incremented by 2
-
-    // check the prefix increment
-    ++it;
-    {
-        auto c = *it;
-        EXPECT_EQ(c.index, 1u);
-        EXPECT_EQ(left(c.radius), 3.0);
-        EXPECT_EQ(right(c.radius), 5.0);
-        EXPECT_EQ(c.length, 2.5);
-    }
-
-    // check postfix increment
-
-    // returned iterator should be unchanged
-    {
-        auto c = *(it++);
-        EXPECT_EQ(c.index, 1u);
-        EXPECT_EQ(left(c.radius), 3.0);
-        EXPECT_EQ(right(c.radius), 5.0);
-        EXPECT_EQ(c.length, 2.5);
-    }
-    // while the iterator itself was updated
-    {
-        auto c = *it;
-        EXPECT_EQ(c.index, 2u);
-        EXPECT_EQ(left(c.radius), 5.0);
-        EXPECT_EQ(right(c.radius), 7.0);
-        EXPECT_EQ(c.length, 2.5);
-    }
-
-    // check that it can be copied and compared
-    {
-        // copy iterator
-        auto it2 = it;
-        auto c = *it2;
-        EXPECT_EQ(c.index, 2u);
-        EXPECT_EQ(left(c.radius), 5.0);
-        EXPECT_EQ(right(c.radius), 7.0);
-        EXPECT_EQ(c.length, 2.5);
-
-        // comparison
-        EXPECT_EQ(it2, it);
-        it2++;
-        EXPECT_NE(it2, it);
-
-        // check the copy has updated correctly when incremented
-        c= *it2;
-        EXPECT_EQ(c.index, 3u);
-        EXPECT_EQ(left(c.radius), 7.0);
-        EXPECT_EQ(right(c.radius), 9.0);
-        EXPECT_EQ(c.length, 2.5);
-    }
-}
-
-TEST(compartments, compartment_range)
-{
-    {
-        nest::mc::compartment_range rng(10, 1.0, 2.0, 10.);
-
-        EXPECT_EQ((*rng.begin()).index, 0u);
-        EXPECT_EQ((*rng.end()).index, 10u);
-        EXPECT_NE(rng.begin(), rng.end());
-
-        unsigned count = 0;
-        for(auto c : rng) {
-            EXPECT_EQ(c.index, count);
-            auto er = 1.0 + double(count)/10.;
-            EXPECT_TRUE(std::fabs(left(c.radius)-er)<1e-15);
-            EXPECT_TRUE(std::fabs(right(c.radius)-(er+0.1))<1e-15);
-            EXPECT_EQ(c.length, 1.0);
-            ++count;
-        }
-        EXPECT_EQ(count, 10u);
-    }
-
-    // test case of zero length range
-    {
-        nest::mc::compartment_range rng(0, 1.0, 1.0, 0.);
-
-        EXPECT_EQ(rng.begin(), rng.end());
-    }
-}
-
 TEST(compartments, make_compartment_range)
 {
     using namespace nest::mc;