diff --git a/src/algorithms.hpp b/src/algorithms.hpp
index 40b6e9cc79afbd6dacec475e5d52fd622ae3eed0..5d609b1effe57f12d3998e10d856b659c042120e 100644
--- a/src/algorithms.hpp
+++ b/src/algorithms.hpp
@@ -244,8 +244,9 @@ std::vector<typename C::value_type> make_parent_index(
         "integral type required"
     );
 
-    if (parent_index.empty() && branch_index.empty())
+    if (parent_index.empty() && branch_index.empty()) {
         return {};
+    }
 
     EXPECTS(parent_index.size() == branch_index.back());
     EXPECTS(has_contiguous_segments(parent_index));
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/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));
 }
-