diff --git a/CMakeLists.txt b/CMakeLists.txt
index 72ac867917e76a6b92ffe0a2073d0fd6d4f72b0a..f91e332eecdd77b327846951ed9271d740e926df 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,27 +20,29 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
 
 # TBB support
-set( WITH_TBB OFF CACHE BOOL "use TBB for on-node threading" )
-if(${WITH_TBB})
+set(WITH_TBB OFF CACHE BOOL "use TBB for on-node threading" )
+if(WITH_TBB)
     find_package(TBB REQUIRED)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_TBB ${TBB_DEFINITIONS}")
-    link_directories(${TBB_LIBRARY})
 endif()
 
 # MPI support
-# relies on the user specifying an MPI-aware compiler wrapper
-set( WITH_MPI OFF CACHE BOOL "use MPI for distrubuted parallelism" )
-if(${WITH_MPI})
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWITH_MPI")
+set(WITH_MPI OFF CACHE BOOL "use MPI for distrubuted parallelism")
+if(WITH_MPI)
+    find_package(MPI REQUIRED)
+    include_directories(SYSTEM ${MPI_C_INCLUDE_PATH})
+    add_definitions(-DWITH_MPI)
+    # unfortunate workaround for C++ detection in system mpi.h
+    add_definitions(-DMPICH_SKIP_MPICXX=1 -DOMPI_SKIP_MPICXX=1)
+    set_property(DIRECTORY APPEND_STRING PROPERTY COMPILE_OPTIONS "${MPI_C_COMPILE_FLAGS}")
 endif()
 
 # Cray systems
-set( SYSTEM_CRAY OFF CACHE BOOL "add flags for compilation on Cray systems" )
-if( ${SYSTEM_CRAY} )
+set(SYSTEM_CRAY OFF CACHE BOOL "add flags for compilation on Cray systems")
+if(SYSTEM_CRAY)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -dynamic")
 endif()
 
-
 # targets for extermal dependencies
 include(ExternalProject)
 externalproject_add(modparser
diff --git a/external/vector b/external/vector
index 193df3683a3eaa2bf203bbcfa935d7e7019b1719..8284611f05b0fbe21a1f84630e2726015cb1d96d 160000
--- a/external/vector
+++ b/external/vector
@@ -1 +1 @@
-Subproject commit 193df3683a3eaa2bf203bbcfa935d7e7019b1719
+Subproject commit 8284611f05b0fbe21a1f84630e2726015cb1d96d
diff --git a/miniapp/CMakeLists.txt b/miniapp/CMakeLists.txt
index 883905caa9a5ffe2ebd6c244ac0565e620ed6a81..a5b9561198875a6515b4e8a69f7685ea75c19803 100644
--- a/miniapp/CMakeLists.txt
+++ b/miniapp/CMakeLists.txt
@@ -11,6 +11,11 @@ add_executable(miniapp.exe ${MINIAPP_SOURCES} ${HEADERS})
 target_link_libraries(miniapp.exe LINK_PUBLIC cellalgo)
 target_link_libraries(miniapp.exe LINK_PUBLIC ${TBB_LIBRARIES})
 
+if(WITH_MPI)
+    target_link_libraries(miniapp.exe LINK_PUBLIC ${MPI_C_LIBRARIES})
+    set_property(TARGET miniapp.exe APPEND_STRING PROPERTY LINK_FLAGS "${MPI_C_LINK_FLAGS}")
+endif()
+
 set_target_properties(miniapp.exe
    PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/miniapp"
diff --git a/src/algorithms.hpp b/src/algorithms.hpp
index 83eeaf8dd7e32f776384d0c47fec5e5d0b43d1a8..738f163fa8381363b099c981d57df36923bc921d 100644
--- a/src/algorithms.hpp
+++ b/src/algorithms.hpp
@@ -19,230 +19,302 @@
 
 namespace nest {
 namespace mc {
-namespace algorithms{
-
-    template <typename C>
-    typename C::value_type
-    sum(C const& c)
-    {
-        using value_type = typename C::value_type;
-        return std::accumulate(c.begin(), c.end(), value_type{0});
-    }
-
-    template <typename C>
-    typename C::value_type
-    mean(C const& c)
-    {
-        return sum(c)/c.size();
+namespace algorithms {
+
+template <typename C>
+typename C::value_type
+sum(C const& c)
+{
+    using value_type = typename C::value_type;
+    return std::accumulate(c.begin(), c.end(), value_type{0});
+}
+
+template <typename C>
+typename C::value_type
+mean(C const& c)
+{
+    return sum(c)/c.size();
+}
+
+template <typename C>
+C make_index(C const& c)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "make_index only applies to integral types"
+    );
+
+    C out(c.size()+1);
+    out[0] = 0;
+    std::partial_sum(c.begin(), c.end(), out.begin()+1);
+    return out;
+}
+
+/// works like std::is_sorted(), but with stronger condition that succesive
+/// elements must be greater than those before them
+template <typename C>
+bool is_strictly_monotonic_increasing(C const& c)
+{
+    using value_type = typename C::value_type;
+    return std::is_sorted(
+        c.begin(),
+        c.end(),
+        [] (value_type const& lhs, value_type const& rhs) {
+            return lhs <= rhs;
+        }
+    );
+}
+
+template <typename C>
+bool is_strictly_monotonic_decreasing(C const& c)
+{
+    using value_type = typename C::value_type;
+    return std::is_sorted(
+        c.begin(),
+        c.end(),
+        [] (value_type const& lhs, value_type const& rhs) {
+            return lhs >= rhs;
+        }
+    );
+}
+
+template <
+    typename C,
+    typename = typename std::enable_if<std::is_integral<typename C::value_type>::value>
+>
+bool is_minimal_degree(C const& c)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "is_minimal_degree only applies to integral types"
+    );
+
+    if(c.size()==0u) {
+        return true;
     }
 
-    template <typename C>
-    C make_index(C const& c)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "make_index only applies to integral types"
-        );
-
-        C out(c.size()+1);
-        out[0] = 0;
-        std::partial_sum(c.begin(), c.end(), out.begin()+1);
-        return out;
+    using value_type = typename C::value_type;
+    if(c[0] != value_type(0)) {
+        return false;
     }
-
-    /// works like std::is_sorted(), but with stronger condition that succesive
-    /// elements must be greater than those before them
-    template <typename C>
-    bool is_strictly_monotonic_increasing(C const& c)
-    {
-        using value_type = typename C::value_type;
-        return std::is_sorted(
-            c.begin(),
-            c.end(),
-            [] (value_type const& lhs, value_type const& rhs) {
-                return lhs <= rhs;
-            }
-        );
+    auto i = value_type(1);
+    auto it = std::find_if(
+        c.begin()+1, c.end(), [&i](value_type v) { return v>=(i++); }
+    );
+    return it==c.end();
+}
+
+template <typename C>
+bool is_positive(C const& c)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "is_positive only applies to integral types"
+    );
+    for(auto v : c) {
+        if(v<1) {
+            return false;
+        }
     }
-
-    template <typename C>
-    bool is_strictly_monotonic_decreasing(C const& c)
-    {
-        using value_type = typename C::value_type;
-        return std::is_sorted(
-            c.begin(),
-            c.end(),
-            [] (value_type const& lhs, value_type const& rhs) {
-                return lhs >= rhs;
-            }
-        );
+    return true;
+}
+
+template<typename C>
+bool has_contiguous_segments(const C &parent_index)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "integral type required"
+    );
+
+    if (!is_minimal_degree(parent_index)) {
+        return false;
     }
 
-    template <
-        typename C,
-        typename = typename std::enable_if<std::is_integral<typename C::value_type>::value>
-    >
-    bool is_minimal_degree(C const& c)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "is_minimal_degree only applies to integral types"
-        );
-
-        if(c.size()==0u) {
-            return true;
-        }
+    int n = parent_index.size();
+    std::vector<bool> is_leaf(n, false);
 
-        using value_type = typename C::value_type;
-        if(c[0] != value_type(0)) {
+    for(auto i=1; i<n; ++i) {
+        auto p = parent_index[i];
+        if(is_leaf[p]) {
             return false;
         }
-        auto i = value_type(1);
-        auto it = std::find_if(
-            c.begin()+1, c.end(), [&i](value_type v) { return v>=(i++); }
-        );
-        return it==c.end();
-    }
 
-    template <typename C>
-    bool is_positive(C const& c)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "is_positive only applies to integral types"
-        );
-        for(auto v : c) {
-            if(v<1) {
-                return false;
-            }
+        if(p != i-1) {
+            // we have a branch and i-1 is a leaf node
+            is_leaf[i-1] = true;
         }
-        return true;
     }
 
-    template<typename C>
-    bool has_contiguous_segments(const C &parent_index)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "integral type required"
-        );
+    return true;
+}
 
-        if (!is_minimal_degree(parent_index)) {
-            return false;
-        }
+template<typename C>
+std::vector<typename C::value_type> child_count(const C &parent_index)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "integral type required"
+    );
 
-        int n = parent_index.size();
-        std::vector<bool> is_leaf(n, false);
+    std::vector<typename C::value_type> count(parent_index.size(), 0);
+    for (std::size_t i = 1; i < parent_index.size(); ++i) {
+        ++count[parent_index[i]];
+    }
 
-        for(auto i=1; i<n; ++i) {
-            auto p = parent_index[i];
-            if(is_leaf[p]) {
-                return false;
-            }
+    return count;
+}
 
-            if(p != i-1) {
-                // we have a branch and i-1 is a leaf node
-                is_leaf[i-1] = true;
-            }
-        }
+template<typename C>
+std::vector<typename C::value_type> branches(const C& parent_index)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "integral type required"
+    );
 
-        return true;
+    EXPECTS(has_contiguous_segments(parent_index));
+
+    std::vector<typename C::value_type> branch_index;
+    if (parent_index.empty()) {
+        return branch_index;
     }
 
-    template<typename C>
-    std::vector<typename C::value_type> child_count(const C &parent_index)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "integral type required"
-        );
-
-        std::vector<typename C::value_type> count(parent_index.size(), 0);
-        for (std::size_t i = 1; i < parent_index.size(); ++i) {
-            ++count[parent_index[i]];
+    auto num_child = child_count(parent_index);
+    branch_index.push_back(0);
+    for (std::size_t i = 1; i < parent_index.size(); ++i) {
+        auto p = parent_index[i];
+        if (num_child[p] > 1 || parent_index[p] == p) {
+            // parent_index[p] == p -> parent_index[i] is the soma
+            branch_index.push_back(i);
         }
-
-        return count;
     }
 
-    template<typename C>
-    std::vector<typename C::value_type> branches(const C &parent_index)
-    {
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "integral type required"
-        );
-
-        EXPECTS(has_contiguous_segments(parent_index));
-
-        auto num_child = child_count(parent_index);
-        std::vector<typename C::value_type> branch_runs(
-            parent_index.size(), 0
-        );
-
-        std::size_t num_branches = (num_child[0] == 1) ? 1 : 0;
-        for (std::size_t i = 1; i < parent_index.size(); ++i) {
-            auto p = parent_index[i];
-            if (num_child[p] > 1) {
-                ++num_branches;
-            }
-
-            branch_runs[i] = num_branches;
-        }
+    branch_index.push_back(parent_index.size());
+    return branch_index;
+}
+
 
-        return branch_runs;
+template<typename C>
+std::vector<typename C::value_type> expand_branches(const C& branch_index)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "integral type required"
+    );
+
+    if (branch_index.empty())
+        return {};
+
+    std::vector<typename C::value_type> expanded(branch_index.back());
+    for (std::size_t i = 0; i < branch_index.size()-1; ++i) {
+        for (auto j = branch_index[i]; j < branch_index[i+1]; ++j) {
+            expanded[j] = i;
+        }
     }
 
-    template<typename C>
-    bool is_sorted(const C& c)
-    {
-        return std::is_sorted(c.begin(), c.end());
+    return expanded;
+}
+
+template<typename C>
+typename C::value_type find_branch(const C& branch_index,
+                                   typename C::value_type nid)
+{
+    using value_type = typename C::value_type;
+    static_assert(
+        std::is_integral<value_type>::value,
+        "integral type required"
+    );
+
+    auto it =  std::find_if(
+        branch_index.begin(), branch_index.end(),
+        [nid](const value_type &v) { return v > nid; }
+    );
+
+    return it - branch_index.begin() - 1;
+}
+
+
+template<typename C>
+std::vector<typename C::value_type> make_parent_index(
+    const C& parent_index, const C& branch_index)
+{
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "integral type required"
+    );
+
+    if (parent_index.empty() && branch_index.empty()) {
+        return {};
     }
 
-    template<typename C>
-    bool is_unique(const C& c)
-    {
-        return std::adjacent_find(c.begin(), c.end()) == c.end();
+    EXPECTS(parent_index.size() == branch_index.back());
+    EXPECTS(has_contiguous_segments(parent_index));
+    EXPECTS(is_strictly_monotonic_increasing(branch_index));
+
+    // expand the branch index
+    auto expanded_branch = expand_branches(branch_index);
+
+    std::vector<typename C::value_type> new_parent_index;
+    for (std::size_t i = 0; i < branch_index.size()-1; ++i) {
+        auto p = parent_index[branch_index[i]];
+        new_parent_index.push_back(expanded_branch[p]);
     }
 
-    /// Return and index that maps entries in sub to their corresponding
-    /// values in super, where sub is a subset of super.
-    ///
-    /// Both sets are sorted and have unique entries.
-    /// Complexity is O(n), where n is size of super
-    template<typename C>
-    // C::iterator models forward_iterator
-    // C::value_type is_integral
-    C index_into(const C& super, const C& sub)
-    {
-        //EXPECTS {s \in super : \forall s \in sub};
-        EXPECTS(is_unique(super) && is_unique(sub));
-        EXPECTS(is_sorted(super) && is_sorted(sub));
-        EXPECTS(sub.size() <= super.size());
-
-        static_assert(
-            std::is_integral<typename C::value_type>::value,
-            "index_into only applies to integral types"
-        );
-
-        C out(sub.size()); // out will have one entry for each index in sub
-
-        auto sub_it=sub.begin();
-        auto super_it=super.begin();
-        auto sub_idx=0u, super_idx = 0u;
-
-        while(sub_it!=sub.end() && super_it!=super.end()) {
-            if(*sub_it==*super_it) {
-                out[sub_idx] = super_idx;
-                ++sub_it; ++sub_idx;
-            }
-            ++super_it; ++super_idx;
+    return new_parent_index;
+}
+
+
+template<typename C>
+bool is_sorted(const C& c)
+{
+    return std::is_sorted(c.begin(), c.end());
+}
+
+template<typename C>
+bool is_unique(const C& c)
+{
+    return std::adjacent_find(c.begin(), c.end()) == c.end();
+}
+
+/// Return and index that maps entries in sub to their corresponding
+/// values in super, where sub is a subset of super.
+///
+/// Both sets are sorted and have unique entries.
+/// Complexity is O(n), where n is size of super
+template<typename C>
+// C::iterator models forward_iterator
+// C::value_type is_integral
+C index_into(const C& super, const C& sub)
+{
+    //EXPECTS {s \in super : \forall s \in sub};
+    EXPECTS(is_unique(super) && is_unique(sub));
+    EXPECTS(is_sorted(super) && is_sorted(sub));
+    EXPECTS(sub.size() <= super.size());
+
+    static_assert(
+        std::is_integral<typename C::value_type>::value,
+        "index_into only applies to integral types"
+    );
+
+    C out(sub.size()); // out will have one entry for each index in sub
+
+    auto sub_it=sub.begin();
+    auto super_it=super.begin();
+    auto sub_idx=0u, super_idx = 0u;
+
+    while(sub_it!=sub.end() && super_it!=super.end()) {
+        if(*sub_it==*super_it) {
+            out[sub_idx] = super_idx;
+            ++sub_it; ++sub_idx;
         }
+        ++super_it; ++super_idx;
+    }
 
-        EXPECTS(sub_idx==sub.size());
+    EXPECTS(sub_idx==sub.size());
 
-        return out;
-    }
+    return out;
+}
 
 } // namespace algorithms
 } // namespace mc
diff --git a/src/cell_tree.hpp b/src/cell_tree.hpp
index 1e04fc2c3bcc4e0fe887c7048997afd272fa4bff..4d9f70b1a934ab3b5bdb840d6bb0bd1b8419dfec 100644
--- a/src/cell_tree.hpp
+++ b/src/cell_tree.hpp
@@ -32,7 +32,7 @@ class cell_tree {
 public :
     // use a signed 16-bit integer for storage of indexes, which is reasonable given
     // that typical cells have at most 1000-2000 segments
-    using int_type        = int16_t;
+    using int_type        = int;
     using index_type      = memory::HostVector<int_type>;
     using view_type       = index_type::view_type;
     using const_view_type = index_type::const_view_type;
@@ -298,4 +298,3 @@ private :
 
 } // namespace mc
 } // namespace nest
-
diff --git a/src/swcio.cpp b/src/swcio.cpp
index 792d0fc7bdb3b4898b575dae552d0347efd85e9c..203f69eb1bdca8905145edb4edbe86d564682e9b 100644
--- a/src/swcio.cpp
+++ b/src/swcio.cpp
@@ -1,4 +1,5 @@
 #include <algorithm>
+#include <functional>
 #include <iomanip>
 #include <map>
 #include <sstream>
@@ -230,88 +231,60 @@ swc_record_range_clean::swc_record_range_clean(std::istream &is)
     }
 }
 
-//
-// Convenience functions for returning the radii and the coordinates of a series
-// of swc records
-//
-static std::vector<swc_record::coord_type>
-swc_radii(const std::vector<swc_record> &records)
-{
-    std::vector<swc_record::coord_type> radii;
-    for (const auto &r : records) {
-        radii.push_back(r.radius());
-    }
-
-    return radii;
-}
-
-static std::vector<nest::mc::point<swc_record::coord_type> >
-swc_points(const std::vector<swc_record> &records)
-{
-    std::vector<nest::mc::point<swc_record::coord_type> > points;
-    for (const auto &r : records) {
-        points.push_back(r.coord());
-    }
-
-    return points;
-}
-
-static void make_cable(cell &cell,
-                       const std::vector<swc_record::id_type> &branch_index,
-                       const std::vector<swc_record> &branch_run)
-{
-    auto new_parent = branch_index[branch_run.back().id()] - 1;
-    cell.add_cable(new_parent, nest::mc::segmentKind::dendrite,
-                   swc_radii(branch_run), swc_points(branch_run));
-}
-
 cell swc_read_cell(std::istream &is)
 {
+    using namespace nest::mc;
+
     cell newcell;
-    std::vector<swc_record::id_type> parent_list;
+    std::vector<swc_record::id_type> parent_index;
     std::vector<swc_record> swc_records;
     for (const auto &r : swc_get_records<swc_io_clean>(is)) {
         swc_records.push_back(r);
-        parent_list.push_back(r.parent());
+        parent_index.push_back(r.parent());
     }
 
-    // The parent of soma must be 0
-    if (!parent_list.empty()) {
-        parent_list[0] = 0;
+    if (parent_index.empty()) {
+        return newcell;
     }
 
-    auto branch_index = nest::mc::algorithms::branches(parent_list);
-    std::vector<swc_record> branch_run;
-
-    branch_run.reserve(parent_list.size());
-    auto last_branch_point = branch_index[0];
-    for (auto i = 0u; i < swc_records.size(); ++i) {
-        if (branch_index[i] != last_branch_point) {
-            // New branch encountered; add to cell the current one
-            const auto &p = branch_run.back();
-            if (p.parent() == -1) {
-                // This is a soma
-                newcell.add_soma(p.radius(), p.coord());
-                last_branch_point = i;
-            } else {
-                last_branch_point = i - 1;
-                make_cable(newcell, branch_index, branch_run);
-            }
-
-            // Reset the branch run
-            branch_run.clear();
-            if (p.parent() != -1) {
-                // Add parent of the current cell to the branch,
-                // if not branching from soma
-                branch_run.push_back(swc_records[parent_list[i]]);
-            }
+    // The parent of soma must be 0, while in SWC files is -1
+    parent_index[0] = 0;
+    auto branch_index     = algorithms::branches(parent_index);
+    auto new_parent_index = algorithms::make_parent_index(parent_index,
+                                                          branch_index);
+
+    // sanity check
+    EXPECTS(new_parent_index.size() == branch_index.size() - 1);
+
+    // Add the soma first; then the segments
+    newcell.add_soma(swc_records[0].radius(), swc_records[0].coord());
+    for (std::size_t i = 1; i < new_parent_index.size(); ++i) {
+        auto b_start = std::next(swc_records.begin(), branch_index[i]);
+        auto b_end   = std::next(swc_records.begin(), branch_index[i+1]);
+
+        std::vector<swc_record::coord_type> radii;
+        std::vector<nest::mc::point<swc_record::coord_type>> points;
+        if (new_parent_index[i] != 0) {
+            // include the parent of current record if not branching from soma
+            auto p = parent_index[branch_index[i]];
+            radii.push_back(swc_records[p].radius());
+            points.push_back(swc_records[p].coord());
         }
 
-        branch_run.push_back(swc_records[i]);
-    }
+        // extract the radii and the points
+        std::for_each(b_start, b_end,
+                      [&radii](const swc_record& r) {
+                          radii.push_back(r.radius());
+                      });
+
+        std::for_each(b_start, b_end,
+                      [&points](const swc_record& r) {
+                          points.push_back(r.coord());
+                      });
 
-    if (!branch_run.empty()) {
-        make_cable(newcell, branch_index, branch_run);
+        // add the new cable
+        newcell.add_cable(new_parent_index[i],
+                          nest::mc::segmentKind::dendrite, radii, points);
     }
 
     return newcell;
diff --git a/src/tree.hpp b/src/tree.hpp
index 3d76a9dc1e8171f62026320a98f71078e91f1dc5..98ff9aa43656f9d68b879297a6ffd5399348b6f0 100644
--- a/src/tree.hpp
+++ b/src/tree.hpp
@@ -17,7 +17,7 @@ class tree {
 
     public :
 
-    using int_type = int16_t;
+    using int_type = int;
 
     using index_type = memory::HostVector<int_type>;
     using view_type  = index_type::view_type;
@@ -62,92 +62,22 @@ class tree {
             );
         }
 
-        // n = number of compartment in cell
-        auto n = parent_index.size();
+        auto new_parent_index = algorithms::make_parent_index(
+            parent_index, algorithms::branches(parent_index));
 
-        // On completion of this loop child_count[i] is the number of children
-        // of compartment i compensate count for compartment 0, which has itself
-        // as its own parent
-        index_type child_count(n, 0);
-        child_count[0] = -1;
-        for(auto i : parent_index) {
-            ++child_count[i];
-        }
+        init(new_parent_index.size());
+        parents_(memory::all) = new_parent_index;
+        parents_[0] = -1;
 
-        // Find the number of branches by summing the number of children of all
-        // compartments with more than 1 child.
-        auto nbranches = 1 + child_count[0]; // children of the root node are counted differently
-        for(auto i : range(1,n)) {
-            if(child_count[i]>1) {
-                nbranches += child_count[i];
-            }
-        }
+        child_index_(memory::all) =
+            algorithms::make_index(algorithms::child_count(parents_));
 
-        // allocate memory for storing the tree
-        init(nbranches);
-
-        // index of the branch for each compartment
-        std::vector<I> branch_index(n);
-
-        // Mark the parent of the root node as -1.
-        // This simplifies the implementation of some algorithms on the tree
-        parents_[0]=-1;
-
-        // bcount records how many branches have been created in the loop
-        auto bcount=0;
-
-        for(auto i : range(1,n)) {
-            // the branch index of the parent of compartment i
-            auto parent_node = parent_index[i];
-            // index of the parent of compartment i
-            auto parent_branch = branch_index[parent_node];
-
-            // if this compartments's parent
-            //  - has more than one child
-            //  - or is the root branch
-            // this is the first compartment in a branch, so mark it as such
-            if(child_count[parent_node]>1 || parent_node==0) {
-                bcount++;
-                branch_index[i] = bcount;
-                parents_[bcount] = parent_branch;
-            }
-            // not the first compartment in a branch,
-            // so inherit the parent's branch number
-            else {
-                branch_index[i] = parent_branch;
-            }
-        }
-
-        child_index_(memory::all) = 0;
-        // the root node has to be handled separately: all of its children must
-        // be counted
-        child_index_[1] = child_count[0];
-        for(auto i : range(1, n)) {
-            if(child_count[i]>1) {
-                child_index_[branch_index[i]+1] = child_count[i];
-            }
-        }
-        std::partial_sum(child_index_.begin(), child_index_.end(), child_index_.begin());
-
-        // Fill in the list of children of each branch.
-        // Requires some additional book keeping to keep track of how many
-        // children have already been filled in for each branch.
-        for(auto i : range(1, nbranches)) {
-            // parents_[i] is the parent of branch i, for which i must be added
-            // as a child, and child_index_[p] is the index into which the next
-            // child of p is to be stored
+        std::vector<int> pos(parents_.size(), 0);
+        for (auto i = 1u; i < parents_.size(); ++i) {
             auto p = parents_[i];
-            children_[child_index_[p]] = i;
-            ++child_index_[p];
-        }
-
-        // The child index has already been calculated as a side-effect of the
-        // loop above, but is shifted one value to the left, so perform a
-        // rotation to the right.
-        for(auto i=nbranches-1; i>=00; --i) {
-            child_index_[i+1] = child_index_[i];
+            children_[child_index_[p] + pos[p]] = i;
+            ++pos[p];
         }
-        child_index_[0] = 0;
     }
 
     size_t num_children() const {
diff --git a/src/util/meta.hpp b/src/util/meta.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..2e22e31ceda0ff83588625486ec7a36161569733
--- /dev/null
+++ b/src/util/meta.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+/* Type utilities and convenience expressions.  */
+
+#include <type_traits>
+
+namespace nest {
+namespace mc {
+namespace util {
+
+// Until C++14 ...
+
+template <typename T>
+using result_of_t = typename std::result_of<T>::type;
+
+template <bool V>
+using enable_if_t = typename std::enable_if<V>::type;
+
+// Convenience short cuts
+
+template <typename T>
+using enable_if_copy_constructible_t =
+    enable_if_t<std::is_copy_constructible<T>::value>;
+
+template <typename T>
+using enable_if_move_constructible_t =
+    enable_if_t<std::is_move_constructible<T>::value>;
+
+template <typename... T>
+using enable_if_constructible_t =
+    enable_if_t<std::is_constructible<T...>::value>;
+
+
+} // namespace util
+} // namespace mc
+} // namespace nest
diff --git a/src/util/optional.hpp b/src/util/optional.hpp
index a3c2da998d468c8564894f2db61b0340c056c70c..0d71c4a5d564b4a85db457a930f803388ee0861b 100644
--- a/src/util/optional.hpp
+++ b/src/util/optional.hpp
@@ -1,25 +1,25 @@
 #pragma once
 
-/*! \file optional.h
- *  \brief An option class with a monadic interface.
+/* An option class with a monadic interface.
  *
- *  The std::option<T> class was proposed for inclusion into C++14, but was
- *  ultimately rejected. (See N3672 proposal for details.) This class offers
- *  similar functionality, namely a class that can represent a value (or
- *  reference), or nothing at all.
+ * The std::option<T> class was proposed for inclusion into C++14, but was
+ * ultimately rejected. (See N3672 proposal for details.) This class offers
+ * similar functionality, namely a class that can represent a value (or
+ * reference), or nothing at all.
  *
- *  In addition, this class offers monadic and monoidal bindings, allowing
- *  the chaining of operations any one of which might represent failure with
- *  an unset optional value.
+ * In addition, this class offers monadic and monoidal bindings, allowing
+ * the chaining of operations any one of which might represent failure with
+ * an unset optional value.
  *
- *  One point of difference between the proposal N3672 and this implementation
- *  is the lack of constexpr versions of the methods and constructors.
+ * One point of difference between the proposal N3672 and this implementation
+ * is the lack of constexpr versions of the methods and constructors.
  */
 
 #include <type_traits>
 #include <stdexcept>
 #include <utility>
 
+#include "util/meta.hpp"
 #include "util/uninitialized.hpp"
 
 namespace nest {
@@ -29,135 +29,208 @@ namespace util {
 template <typename X> struct optional;
 
 struct optional_unset_error: std::runtime_error {
-    explicit optional_unset_error(const std::string &what_str): std::runtime_error(what_str) {}
-    optional_unset_error(): std::runtime_error("optional value unset") {}
+    explicit optional_unset_error(const std::string &what_str)
+        : std::runtime_error(what_str)
+    {}
+
+    optional_unset_error()
+        : std::runtime_error("optional value unset")
+    {}
 };
 
 struct optional_invalid_dereference: std::runtime_error {
-    explicit optional_invalid_dereference(const std::string &what_str): std::runtime_error(what_str) {}
-    optional_invalid_dereference(): std::runtime_error("derefernce of optional<void> value") {}
+    explicit optional_invalid_dereference(const std::string &what_str)
+        : std::runtime_error(what_str)
+    {}
+
+    optional_invalid_dereference()
+        : std::runtime_error("derefernce of optional<void> value")
+    {}
 };
 
 struct nothing_t {};
 constexpr nothing_t nothing{};
 
 namespace detail {
-    template <typename Y> struct lift_type { using type=optional<Y>; };
-    template <typename Y> struct lift_type<optional<Y>> { using type=optional<Y>; };
+    template <typename Y>
+    struct lift_type {
+        using type = optional<Y>;
+    };
+
+    template <typename Y>
+    struct lift_type<optional<Y>> {
+        using type = optional<Y>;
+    };
+
+    template <typename Y>
+    using lift_type_t = typename lift_type<Y>::type;
 
     struct optional_tag {};
 
-    template <typename X> struct is_optional {
-        enum {value=std::is_base_of<optional_tag,typename std::decay<X>::type>::value };
+    template <typename X>
+    using is_optional = std::is_base_of<optional_tag, typename std::decay<X>::type>;
+
+    template <typename D,typename X>
+    struct wrapped_type_impl {
+        using type = X;
     };
 
-    template <typename D,typename X> struct wrapped_type_ { using type=X; };
-    template <typename D,typename X> struct wrapped_type_<optional<D>,X> { using type=D; };
+    template <typename D,typename X>
+    struct wrapped_type_impl<optional<D>,X> {
+        using type = D;
+    };
 
-    template <typename X> struct wrapped_type { using type=typename wrapped_type_<typename std::decay<X>::type,X>::type; };
+    template <typename X>
+    struct wrapped_type {
+       using type = typename wrapped_type_impl<typename std::decay<X>::type,X>::type;
+    };
+
+    template <typename X>
+    using wrapped_type_t = typename wrapped_type<X>::type;
 
     template <typename X>
     struct optional_base: detail::optional_tag {
         template <typename Y> friend struct optional;
 
     protected:
-        using D=util::uninitialized<X>;
+        using data_type = util::uninitialized<X>;
 
     public:
-        using reference_type=typename D::reference_type;
-        using const_reference_type=typename D::const_reference_type;
-        using pointer_type=typename D::pointer_type;
-        using const_pointer_type=typename D::const_pointer_type;
+        using reference_type = typename data_type::reference_type;
+        using const_reference_type = typename data_type::const_reference_type;
+        using pointer_type = typename data_type::pointer_type;
+        using const_pointer_type = typename data_type::const_pointer_type;
 
     protected:
         bool set;
-        D data;
+        data_type data;
 
-        optional_base(): set(false) {}
+        optional_base() : set(false) {}
 
         template <typename T>
-        optional_base(bool set_,T&& init): set(set_) { if (set) data.construct(std::forward<T>(init)); }
+        optional_base(bool set_, T&& init) : set(set_) {
+            if (set) {
+                data.construct(std::forward<T>(init));
+            }
+        }
 
-        reference_type ref() { return data.ref(); }
+        reference_type       ref()       { return data.ref(); }
         const_reference_type ref() const { return data.cref(); }
 
     public:
-        ~optional_base() { if (set) data.destruct(); }
+        ~optional_base() {
+            if (set) {
+                data.destruct();
+            }
+        }
 
         const_pointer_type operator->() const { return data.ptr(); }
-        pointer_type operator->() { return data.ptr(); }
-            
+        pointer_type       operator->()       { return data.ptr(); }
+
         const_reference_type operator*() const { return ref(); }
-        reference_type operator*() { return ref(); }
-            
+        reference_type       operator*()       { return ref(); }
+
         reference_type get() {
-            if (set) return ref();
-            else throw optional_unset_error();
+            if (set) {
+                return ref();
+            }
+            else {
+                throw optional_unset_error();
+            }
         }
 
         const_reference_type get() const {
-            if (set) return ref();
-            else throw optional_unset_error();
+            if (set) {
+                return ref();
+            }
+            else {
+                throw optional_unset_error();
+            }
         }
 
         explicit operator bool() const { return set; }
 
         template <typename Y>
-        bool operator==(const Y &y) const { return set && ref()==y; }
+        bool operator==(const Y& y) const {
+            return set && ref()==y;
+        }
 
         template <typename Y>
-        bool operator==(const optional<Y> &o) const {
+        bool operator==(const optional<Y>& o) const {
             return (set && o.set && ref()==o.ref()) || (!set && !o.set);
         }
 
         void reset() {
-            if (set) data.destruct();
-            set=false;
+            if (set) {
+                data.destruct();
+            }
+            set = false;
         }
 
         template <typename F>
-        auto bind(F &&f) -> typename lift_type<decltype(data.apply(std::forward<F>(f)))>::type {
-            using F_result_type=decltype(data.apply(std::forward<F>(f)));
-            using result_type=typename lift_type<F_result_type>::type;
+        auto bind(F&& f) -> lift_type_t<decltype(data.apply(std::forward<F>(f)))> {
+            using F_result_type = decltype(data.apply(std::forward<F>(f)));
+            using result_type = lift_type_t<F_result_type>;
+
+            if (!set) {
+                return result_type();
+            }
 
-            if (!set) return result_type();
-            else return bind_impl<result_type,std::is_same<F_result_type,void>::value>::bind(data,std::forward<F>(f));
+            return bind_impl<result_type, std::is_void<F_result_type>::value>::
+                       bind(data, std::forward<F>(f));
         }
 
         template <typename F>
-        auto bind(F &&f) const -> typename lift_type<decltype(data.apply(std::forward<F>(f)))>::type {
-            using F_result_type=decltype(data.apply(std::forward<F>(f)));
-            using result_type=typename lift_type<F_result_type>::type;
+        auto bind(F&& f) const -> lift_type_t<decltype(data.apply(std::forward<F>(f)))> {
+            using F_result_type = decltype(data.apply(std::forward<F>(f)));
+            using result_type = lift_type_t<F_result_type>;
 
-            if (!set) return result_type();
-            else return bind_impl<result_type,std::is_same<F_result_type,void>::value>::bind(data,std::forward<F>(f));
+            if (!set) {
+                return result_type();
+            }
+
+            return bind_impl<result_type, std::is_void<F_result_type>::value>::
+                       bind(data, std::forward<F>(f));
         }
 
         template <typename F>
-        auto operator>>(F &&f) -> decltype(this->bind(std::forward<F>(f))) { return bind(std::forward<F>(f)); }
+        auto operator>>(F&& f) -> decltype(this->bind(std::forward<F>(f))) {
+            return bind(std::forward<F>(f));
+        }
 
         template <typename F>
-        auto operator>>(F &&f) const -> decltype(this->bind(std::forward<F>(f))) { return bind(std::forward<F>(f)); }
+        auto operator>>(F&& f) const -> decltype(this->bind(std::forward<F>(f))) {
+            return bind(std::forward<F>(f));
+        }
 
     private:
-        template <typename R,bool F_void_return>
+        template <typename R, bool F_void_return>
         struct bind_impl {
             template <typename DT,typename F>
-            static R bind(DT &d,F &&f) { return R(d.apply(std::forward<F>(f))); }
+            static R bind(DT& d,F&& f) {
+                return R(d.apply(std::forward<F>(f)));
+            }
         };
 
         template <typename R>
         struct bind_impl<R,true> {
             template <typename DT,typename F>
-            static R bind(DT &d,F &&f) { d.apply(std::forward<F>(f)); return R(true); }
+            static R bind(DT& d,F&& f) {
+                d.apply(std::forward<F>(f));
+                return R(true);
+            }
         };
-        
     };
-}
+
+    // type utilities
+    template <typename T>
+    using enable_unless_optional_t = enable_if_t<!is_optional<T>::value>;
+
+} // namespace detail
 
 template <typename X>
 struct optional: detail::optional_base<X> {
-    using base=detail::optional_base<X>;
+    using base = detail::optional_base<X>;
     using base::set;
     using base::ref;
     using base::reset;
@@ -166,85 +239,109 @@ struct optional: detail::optional_base<X> {
     optional(): base() {}
     optional(nothing_t): base() {}
 
-    template <typename Y=X,typename = typename std::enable_if<std::is_copy_constructible<Y>::value>::type>
-    optional(const X &x): base(true,x) {}
+    template <
+        typename Y = X,
+        typename = enable_if_copy_constructible_t<Y>
+    >
+    optional(const X& x): base(true, x) {}
 
-    template <typename Y=X,typename = typename std::enable_if<std::is_move_constructible<Y>::value>::type>
-    optional(X &&x): base(true,std::move(x)) {}
+    template <
+        typename Y = X,
+        typename = enable_if_move_constructible_t<Y>
+    >
+    optional(X&& x): base(true, std::move(x)) {}
 
-    optional(const optional &ot): base(ot.set,ot.ref()) {}
+    optional(const optional& ot): base(ot.set, ot.ref()) {}
 
     template <typename T>
-    optional(const optional<T> &ot): base(ot.set,ot.ref()) {}
+    optional(const optional<T>& ot): base(ot.set, ot.ref()) {}
 
-    optional(optional &&ot): base(ot.set,std::move(ot.ref())) {}
+    optional(optional&& ot): base(ot.set, std::move(ot.ref())) {}
 
     template <typename T>
-    optional(optional<T> &&ot): base(ot.set,std::move(ot.ref())) {}
+    optional(optional<T>&& ot): base(ot.set, std::move(ot.ref())) {}
 
-    template <typename Y,typename = typename std::enable_if<!detail::is_optional<Y>::value>::type>
-    optional &operator=(Y &&y) {
-        if (set) ref()=std::forward<Y>(y);
+    template <
+        typename Y,
+        typename = detail::enable_unless_optional_t<Y>
+    >
+    optional& operator=(Y&& y) {
+        if (set) {
+            ref() = std::forward<Y>(y);
+        }
         else {
-            set=true;
+            set = true;
             data.construct(std::forward<Y>(y));
         }
         return *this;
     }
 
-    optional &operator=(const optional &o) {
+    optional& operator=(const optional& o) {
         if (set) {
-            if (o.set) ref()=o.ref();
-            else reset();
+            if (o.set) {
+                ref() = o.ref();
+            }
+            else {
+                reset();
+            }
         }
         else {
-            set=o.set;
-            if (set) data.construct(o.ref());
+            set = o.set;
+            if (set) {
+                data.construct(o.ref());
+            }
         }
         return *this;
     }
 
-    template <typename Y=X, typename =typename std::enable_if<
-        std::is_move_assignable<Y>::value &&
-        std::is_move_constructible<Y>::value
-    >::type>
-    optional &operator=(optional &&o) {
+    template <
+        typename Y = X,
+        typename = typename std::enable_if<
+            std::is_move_assignable<Y>::value &&
+            std::is_move_constructible<Y>::value
+        >::type
+    >
+    optional& operator=(optional&& o) {
         if (set) {
-            if (o.set) ref()=std::move(o.ref());
+            if (o.set) {
+                ref() = std::move(o.ref());
+            }
             else reset();
         }
         else {
-            set=o.set;
-            if (set) data.construct(std::move(o.ref()));
+            set = o.set;
+            if (set) {
+                data.construct(std::move(o.ref()));
+            }
         }
         return *this;
     }
 };
 
 template <typename X>
-struct optional<X &>: detail::optional_base<X &> {
-    using base=detail::optional_base<X &>;
+struct optional<X&>: detail::optional_base<X&> {
+    using base=detail::optional_base<X&>;
     using base::set;
     using base::ref;
     using base::data;
 
     optional(): base() {}
     optional(nothing_t): base() {}
-    optional(X &x): base(true,x) {}
+    optional(X&x): base(true,x) {}
 
     template <typename T>
-    optional(optional<T &> &ot): base(ot.set,ot.ref()) {}
+    optional(optional<T&>& ot): base(ot.set,ot.ref()) {}
 
-    template <typename Y,typename = typename std::enable_if<!detail::is_optional<Y>::value>::type>
-    optional &operator=(Y &y) {
-        set=true;
-        ref()=y;
+    template <typename Y,typename = typename std::enable_if<!detail::is_optional<Y>()>::type>
+    optional& operator=(Y& y) {
+        set = true;
+        ref() = y;
         return *this;
     }
 
     template <typename Y>
-    optional &operator=(optional<Y &> &o) {
-        set=o.set;
+    optional& operator=(optional<Y&>& o) {
+        set = o.set;
         data.construct(o);
         return *this;
     }
@@ -256,7 +353,7 @@ struct optional<X &>: detail::optional_base<X &> {
 
 template <>
 struct optional<void>: detail::optional_base<void> {
-    using base=detail::optional_base<void>;
+    using base = detail::optional_base<void>;
     using base::set;
 
     optional(): base() {}
@@ -265,19 +362,24 @@ struct optional<void>: detail::optional_base<void> {
     optional(T): base(true,true) {}
 
     template <typename T>
-    optional(const optional<T> &o): base(o.set,true) {}
+    optional(const optional<T>& o): base(o.set,true) {}
     
     template <typename T>
-    optional &operator=(T) { set=true; return *this; }
+    optional& operator=(T) {
+        set = true;
+        return *this;
+    }
 
     template <typename T>
-    optional &operator=(const optional<T> &o) { set=o.set; return *this; }
+    optional& operator=(const optional<T>& o) {
+        set = o.set;
+        return *this;
+    }
 
-    // override equality operators
     template <typename Y>
-    bool operator==(const Y &y) const { return false; }
+    bool operator==(const Y& y) const { return false; }
 
-    bool operator==(const optional<void> &o) const {
+    bool operator==(const optional<void>& o) const {
         return (set && o.set) || (!set && !o.set);
     }
 };
@@ -286,25 +388,36 @@ struct optional<void>: detail::optional_base<void> {
 template <typename A,typename B>
 typename std::enable_if<
     detail::is_optional<A>::value || detail::is_optional<B>::value,
-    optional<typename std::common_type<typename detail::wrapped_type<A>::type,typename detail::wrapped_type<B>::type>::type>
+    optional<
+        typename std::common_type<
+            detail::wrapped_type_t<A>,
+            detail::wrapped_type_t<B>
+        >::type
+    >
 >::type
-operator|(A &&a,B &&b) {
-    return a?a:b;
+operator|(A&& a,B&& b) {
+    return a ? a : b;
 }
 
 template <typename A,typename B>
 typename std::enable_if<
     detail::is_optional<A>::value || detail::is_optional<B>::value,
-    optional<typename detail::wrapped_type<B>::type>
+    optional<detail::wrapped_type_t<B>>
 >::type
-operator&(A &&a,B &&b) {
-    using result_type=optional<typename detail::wrapped_type<B>::type>;
-    return a?b:result_type();
+operator&(A&& a,B&& b) {
+    using result_type = optional<detail::wrapped_type_t<B>>;
+    return a ? b: result_type();
 }
 
-inline optional<void> provided(bool condition) { return condition?optional<void>(true):optional<void>(); }
+inline optional<void> provided(bool condition) {
+    return condition ? optional<void>(true) : optional<void>();
+}
 
 template <typename X>
-optional<X> just(X &&x) { return optional<X>(std::forward<X>(x)); }
+optional<X> just(X&& x) {
+    return optional<X>(std::forward<X>(x));
+}
 
-}}} // namespace nest::mc::util
+} // namespace util
+} // namespace mc
+} // namespace nest
diff --git a/src/util/uninitialized.hpp b/src/util/uninitialized.hpp
index 26ebcf90ef2c94ea0645ccb7d3a94f6a01fb2510..846e46d5a2451fe1535f026ee4b801e5303a6f0c 100644
--- a/src/util/uninitialized.hpp
+++ b/src/util/uninitialized.hpp
@@ -5,10 +5,15 @@
  * The uninitialized<X> structure holds space for an item of
  * type X, leaving its construction or destruction to the user.
  * 
- * Specialisations for reference types X & and for the void type
+ * Specialisations for reference types X& and for the void type
  * allow for the handling of non-value types in a uniform manner.
  */
 
+#include <type_traits>
+#include <utility>
+
+#include "util/meta.hpp"
+
 namespace nest {
 namespace mc {
 namespace util {
@@ -19,39 +24,47 @@ namespace util {
 template <typename X>
 struct uninitialized {
 private:
-    typename std::aligned_storage<sizeof(X),alignof(X)>::type data;
+    typename std::aligned_storage<sizeof(X), alignof(X)>::type data;
 
 public:
-    using pointer_type=X *;
-    using const_pointer_type=const X *;
-    using reference_type=X &;
-    using const_reference_type=const X &;
+    using pointer_type = X*;
+    using const_pointer_type = const X*;
+    using reference_type = X&;
+    using const_reference_type = const X&;
 
-    pointer_type ptr() { return reinterpret_cast<X *>(&data); }
-    const_pointer_type cptr() const { return reinterpret_cast<const X *>(&data); }
+    pointer_type ptr() { return reinterpret_cast<X*>(&data); }
+    const_pointer_type cptr() const { return reinterpret_cast<const X*>(&data); }
 
-    reference_type ref() { return *reinterpret_cast<X *>(&data); }
-    const_reference_type cref() const { return *reinterpret_cast<const X *>(&data); }
+    reference_type ref() { return *reinterpret_cast<X*>(&data); }
+    const_reference_type cref() const { return *reinterpret_cast<const X*>(&data); }
 
     // Copy construct the value.
-    template <typename Y=X,
-              typename =typename std::enable_if<std::is_copy_constructible<Y>::value>::type>
-    void construct(const X &x) { new(&data) X(x); }
+    template <
+        typename Y = X,
+        typename = enable_if_copy_constructible_t<Y>
+    >
+    void construct(const X& x) {
+        new(&data) X(x);
+    }
 
     // General constructor for X, forwarding arguments.
-    template <typename... Y,
-              typename =typename std::enable_if<std::is_constructible<X,Y...>::value>::type>
-    void construct(Y&& ...args) { new(&data) X(std::forward<Y>(args)...); }
+    template <
+        typename... Y,
+        typename = enable_if_constructible_t<X, Y...>
+    >
+    void construct(Y&& ...args) {
+        new(&data) X(std::forward<Y>(args)...);
+    }
 
     void destruct() { ptr()->~X(); }
 
     // Apply the one-parameter functor F to the value by reference.
     template <typename F>
-    typename std::result_of<F(reference_type)>::type apply(F &&f) { return f(ref()); }
+    result_of_t<F(reference_type)> apply(F&& f) { return f(ref()); }
 
     // Apply the one-parameter functor F to the value by const reference.
     template <typename F>
-    typename std::result_of<F(const_reference_type)>::type apply(F &&f) const { return f(cref()); }
+    result_of_t<F(const_reference_type)> apply(F&& f) const { return f(cref()); }
 };
 
 /* Maintains storage for a pointer of type X, representing
@@ -63,10 +76,10 @@ private:
     X *data;
 
 public:
-    using pointer_type=X *;
-    using const_pointer_type=const X *;
-    using reference_type=X &;
-    using const_reference_type=const X &;
+    using pointer_type = X*;
+    using const_pointer_type = const X*;
+    using reference_type = X&;
+    using const_reference_type = const X&;
 
     pointer_type ptr() { return data; }
     const_pointer_type cptr() const { return data; }
@@ -74,15 +87,20 @@ public:
     reference_type ref() { return *data; }
     const_reference_type cref() const { return *data; }
 
-    void construct(X &x) { data=&x; }
+    void construct(X& x) { data = &x; }
     void destruct() {}
 
     // Apply the one-parameter functor F to the value by reference.
     template <typename F>
-    typename std::result_of<F(reference_type)>::type apply(F &&f) { return f(ref()); }
+    result_of_t<F(reference_type)> apply(F&& f) {
+        return f(ref());
+    }
+
     // Apply the one-parameter functor F to the value by const reference.
     template <typename F>
-    typename std::result_of<F(const_reference_type)>::type apply(F &&f) const { return f(cref()); }
+    result_of_t<F(const_reference_type)> apply(F&& f) const {
+        return f(cref());
+    }
 };
 
 /* Wrap a void type in an uninitialized template.
@@ -91,10 +109,10 @@ public:
  */
 template <>
 struct uninitialized<void> {
-    using pointer_type=void *;
-    using const_pointer_type=const void *;
-    using reference_type=void;
-    using const_reference_type=void;
+    using pointer_type = void*;
+    using const_pointer_type = const void*;
+    using reference_type = void;
+    using const_reference_type = void;
 
     pointer_type ptr() { return nullptr; }
     const_pointer_type cptr() const { return nullptr; }
@@ -109,20 +127,9 @@ struct uninitialized<void> {
 
     // Equivalent to f()
     template <typename F>
-    typename std::result_of<F()>::type apply(F &&f) const { return f(); }
+    result_of_t<F()> apply(F&& f) const { return f(); }
 };
 
-template <typename...>
-struct uninitialized_can_construct: std::false_type {};
-
-template <typename X,typename... Y>
-struct uninitialized_can_construct<X,Y...>: std::integral_constant<bool,std::is_constructible<X,Y...>::value> {};
-
-template <typename X,typename Y>
-struct uninitialized_can_construct<X &,Y>: std::integral_constant<bool,std::is_convertible<X &,Y>::value> {};
-
-template <typename... Y>
-struct uninitialized_can_construct<void,Y...>: std::true_type {};
-
-}}} // namespace nest::mc::util
-
+} // namespace util
+} // namespace mc
+} // namespace nest
diff --git a/tests/test_algorithms.cpp b/tests/test_algorithms.cpp
index 584bdf8ad10db170b44604d3db8f8047d3c29860..ec25bd42c0941b8324fbea3288ed5b4f1d1f7a59 100644
--- a/tests/test_algorithms.cpp
+++ b/tests/test_algorithms.cpp
@@ -369,11 +369,11 @@ TEST(algorithms, branches)
 
     {
         //
-        //        0
-        //       /|\.
-        //      1 4 6
-        //     /  |  \.
-        //    2   5   7
+        //        0                        0
+        //       /|\.                     /|\.
+        //      1 4 6                    1 2 3
+        //     /  |  \.           =>        / \.
+        //    2   5   7                    4   5
         //   /         \.
         //  3           8
         //             / \.
@@ -386,58 +386,100 @@ TEST(algorithms, branches)
         std::vector<int> parent_index =
             { 0, 0, 1, 2, 0, 4, 0, 6, 7, 8, 9, 8, 11, 12 };
         std::vector<int> expected_branches =
-            { 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5 };
+            { 0, 1, 4, 6, 9, 11, 14 };
+        std::vector<int> expected_parent_index =
+            { 0, 0, 0, 0, 3, 3 };
 
         auto actual_branches = algorithms::branches(parent_index);
         EXPECT_EQ(expected_branches, actual_branches);
+
+        auto actual_parent_index =
+            algorithms::make_parent_index(parent_index, actual_branches);
+        EXPECT_EQ(expected_parent_index, actual_parent_index);
+
+        // Check find_branch
+        EXPECT_EQ(0, algorithms::find_branch(actual_branches,  0));
+        EXPECT_EQ(1, algorithms::find_branch(actual_branches,  1));
+        EXPECT_EQ(1, algorithms::find_branch(actual_branches,  2));
+        EXPECT_EQ(1, algorithms::find_branch(actual_branches,  3));
+        EXPECT_EQ(2, algorithms::find_branch(actual_branches,  4));
+        EXPECT_EQ(2, algorithms::find_branch(actual_branches,  5));
+        EXPECT_EQ(3, algorithms::find_branch(actual_branches,  6));
+        EXPECT_EQ(3, algorithms::find_branch(actual_branches,  7));
+        EXPECT_EQ(3, algorithms::find_branch(actual_branches,  8));
+        EXPECT_EQ(4, algorithms::find_branch(actual_branches,  9));
+        EXPECT_EQ(4, algorithms::find_branch(actual_branches, 10));
+        EXPECT_EQ(5, algorithms::find_branch(actual_branches, 11));
+        EXPECT_EQ(5, algorithms::find_branch(actual_branches, 12));
+        EXPECT_EQ(5, algorithms::find_branch(actual_branches, 13));
+        EXPECT_EQ(6, algorithms::find_branch(actual_branches, 55));
+
+        // Check expand_branches
+        auto expanded = algorithms::expand_branches(actual_branches);
+        EXPECT_EQ(parent_index.size(), expanded.size());
+        for (std::size_t i = 0; i < parent_index.size(); ++i) {
+            EXPECT_EQ(algorithms::find_branch(actual_branches, i),
+                      expanded[i]);
+        }
     }
 
     {
         //
-        //    0
-        //    |
-        //    1
+        //    0      0
+        //    |      |
+        //    1  =>  1
         //    |
         //    2
         //    |
         //    3
         //
-        std::vector<int> parent_index =
-            { 0, 0, 1, 2 };
-        std::vector<int> expected_branches =
-            { 0, 1, 1, 1 };
+        std::vector<int> parent_index          = { 0, 0, 1, 2 };
+        std::vector<int> expected_branches     = { 0, 1, 4 };
+        std::vector<int> expected_parent_index = { 0, 0 };
 
         auto actual_branches = algorithms::branches(parent_index);
         EXPECT_EQ(expected_branches, actual_branches);
+
+        auto actual_parent_index =
+            algorithms::make_parent_index(parent_index, actual_branches);
+        EXPECT_EQ(expected_parent_index, actual_parent_index);
     }
 
     {
         //
-        //    0
-        //    |
-        //    1
-        //    |
-        //    2
+        //    0           0
+        //    |           |
+        //    1     =>    1
+        //    |          / \.
+        //    2         2   3
         //   / \.
         //  3   4
         //       \.
         //        5
         //
-        std::vector<int> parent_index =
-            { 0, 0, 1, 2, 2, 4 };
-        std::vector<int> expected_branches =
-            { 0, 1, 1, 2, 3, 3 };
+        std::vector<int> parent_index          = { 0, 0, 1, 2, 2, 4 };
+        std::vector<int> expected_branches     = { 0, 1, 3, 4, 6 };
+        std::vector<int> expected_parent_index = { 0, 0, 1, 1 };
 
         auto actual_branches = algorithms::branches(parent_index);
         EXPECT_EQ(expected_branches, actual_branches);
+
+        auto actual_parent_index =
+            algorithms::make_parent_index(parent_index, actual_branches);
+        EXPECT_EQ(expected_parent_index, actual_parent_index);
     }
 
     {
-        std::vector<int> parent_index = { 0 };
-        std::vector<int> expected_branches = { 0 };
+        std::vector<int> parent_index          = { 0 };
+        std::vector<int> expected_branches     = { 0, 1 };
+        std::vector<int> expected_parent_index = { 0 };
 
         auto actual_branches = algorithms::branches(parent_index);
         EXPECT_EQ(expected_branches, actual_branches);
+
+        auto actual_parent_index =
+            algorithms::make_parent_index(parent_index, actual_branches);
+        EXPECT_EQ(expected_parent_index, actual_parent_index);
     }
 }
 
diff --git a/tests/test_swcio.cpp b/tests/test_swcio.cpp
index 62c52b099e6142f9bc409ca461568dbce7ffa4d7..5ba0b991a865dfb397e5c1dbbb1e8813e71b628c 100644
--- a/tests/test_swcio.cpp
+++ b/tests/test_swcio.cpp
@@ -521,4 +521,3 @@ TEST(swc_parser, from_file_ball_and_stick)
 
     EXPECT_TRUE(nest::mc::cell_basic_equality(local_cell, cell));
 }
-
diff --git a/tests/test_tree.cpp b/tests/test_tree.cpp
index 1e06b3a90fdf92f96e43e2c93036d37788c3efa6..ca9c6d73b1d9e4bde0bb90fc9061ff34f69f0503 100644
--- a/tests/test_tree.cpp
+++ b/tests/test_tree.cpp
@@ -142,20 +142,27 @@ TEST(cell_tree, from_parent_index) {
     {
         //
         //              0
-        //             / \.
-        //            1   2
+        //             /|\.
+        //            1 4 5
         //           / \.
-        //          3   4
-        std::vector<int> parent_index = {0,0,0,1,1};
+        //          2   3
+        std::vector<int> parent_index = {0,0,1,1,0,0};
         cell_tree tree(parent_index);
 
-        EXPECT_EQ(tree.num_segments(), 5u);
+        EXPECT_EQ(tree.num_segments(), 6u);
 
-        EXPECT_EQ(tree.num_children(0), 2u);
+        EXPECT_EQ(tree.num_children(0), 3u);
         EXPECT_EQ(tree.num_children(1), 2u);
         EXPECT_EQ(tree.num_children(2), 0u);
         EXPECT_EQ(tree.num_children(3), 0u);
         EXPECT_EQ(tree.num_children(4), 0u);
+
+        // Check children
+        EXPECT_EQ(1, tree.children(0)[0]);
+        EXPECT_EQ(4, tree.children(0)[1]);
+        EXPECT_EQ(5, tree.children(0)[2]);
+        EXPECT_EQ(2, tree.children(1)[0]);
+        EXPECT_EQ(3, tree.children(1)[1]);
     }
     {
         //              0