diff --git a/miniapp/miniapp.cpp b/miniapp/miniapp.cpp
index 00adf7e5723a35f0b009e07e43d29ae49d38c4f0..898e478c67ff4ed0c76712b79e5604a25dc27236 100644
--- a/miniapp/miniapp.cpp
+++ b/miniapp/miniapp.cpp
@@ -6,7 +6,7 @@
 
 #include <json/src/json.hpp>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <cell_group.hpp>
 #include <fvm_cell.hpp>
diff --git a/miniapp/trace_sampler.hpp b/miniapp/trace_sampler.hpp
index 96ad269afed90551f710fe57c3651b58db3304fd..1e20bea2e3bd0a260e5cd829adb77d935f7797d5 100644
--- a/miniapp/trace_sampler.hpp
+++ b/miniapp/trace_sampler.hpp
@@ -3,7 +3,7 @@
 #include <cstdlib>
 #include <vector>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <util/optional.hpp>
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6b6de968388dafa466a57c65e960044c36b34625..8e0db8876fadf3d030b65ccac9a653eedc1c8d37 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -2,7 +2,7 @@ set(HEADERS
     swcio.hpp
 )
 set(BASE_SOURCES
-    catypes_io.cpp
+    common_types_io.cpp
     cell.cpp
     parameter_list.cpp
     profiling/profiler.cpp
diff --git a/src/cell.hpp b/src/cell.hpp
index effdf9254a22b1a5db20673544274a0784db9fce..746549289f1b718433388e92f5f1ca9d13d433c1 100644
--- a/src/cell.hpp
+++ b/src/cell.hpp
@@ -5,7 +5,7 @@
 #include <thread>
 #include <vector>
 
-#include "catypes.hpp"
+#include "common_types.hpp"
 #include "cell_tree.hpp"
 #include "segment.hpp"
 #include "stimulus.hpp"
diff --git a/src/cell_group.hpp b/src/cell_group.hpp
index 69a94a98fa3de23890b735a3d52a1c381c70322d..e70d4b0bb5826b6ccde449f63a7fad6dab29c783 100644
--- a/src/cell_group.hpp
+++ b/src/cell_group.hpp
@@ -4,8 +4,8 @@
 #include <functional>
 #include <vector>
 
-#include <catypes.hpp>
 #include <cell.hpp>
+#include <common_types.hpp>
 #include <event_queue.hpp>
 #include <spike.hpp>
 #include <spike_source.hpp>
@@ -40,9 +40,15 @@ public:
     {
         initialize_cells();
 
-        source_id_type source_id={gid_base_,0};
+        // Create spike detectors and associate them with globally unique source ids,
+        // as specified by cell gid and cell-local zero-based index.
+
+        cell_gid_type source_gid = gid_base_;
+        cell_lid_type source_lid = 0u;
+
         for (auto& d : c.detectors()) {
-            ++source_id.index;
+            cell_member_type source_id{source_gid, source_lid++};
+
             spike_sources_.push_back({
                 source_id, spike_detector_type(cell_, d.location, d.threshold, 0.f)
             });
diff --git a/src/cell_tree.hpp b/src/cell_tree.hpp
index 3bbcb3ef4816ea61dcd8702b1587069f342645be..ce06d69a8b8ac7427b991e7e54ac2bc764a052e7 100644
--- a/src/cell_tree.hpp
+++ b/src/cell_tree.hpp
@@ -11,7 +11,7 @@
 
 #include <vector/include/Vector.hpp>
 
-#include "catypes.hpp"
+#include "common_types.hpp"
 #include "tree.hpp"
 #include "util.hpp"
 
diff --git a/src/catypes.hpp b/src/common_types.hpp
similarity index 57%
rename from src/catypes.hpp
rename to src/common_types.hpp
index e2e9799be3dbb7d4a91a75e01c8adf2eaa5a565e..da81ed5d65368af60095d8b9dab40aeede29467a 100644
--- a/src/catypes.hpp
+++ b/src/common_types.hpp
@@ -13,18 +13,35 @@
 namespace nest {
 namespace mc {
 
-// for identifying cells globally
+// For identifying cells globally.
+
 using cell_gid_type = std::uint32_t;
 
-// for sizes of collections of cells
+// For sizes of collections of cells.
+
 using cell_size_type = typename std::make_unsigned<cell_gid_type>::type;
 
-// for indexes into cell-local data
+// For indexes into cell-local data.
+// 
+// Local indices for items within a particular cell-local collection should be
+// zero-based and numbered contiguously.
+
 using cell_lid_type = std::uint32_t;
 
-// for counts of cell-local data
+// For counts of cell-local data.
+
 using cell_local_size_type = typename std::make_unsigned<cell_lid_type>::type;
 
+// For global identification of an item of cell local data.
+//
+// Items of cell_member_type must:
+//
+//  * be associated with a unique cell, identified by the member `gid`
+//    (see: cell_gid_type);
+//
+//  * identify an item within a cell-local collection by the member `index`
+//    (see: cell_lid_type).
+
 struct cell_member_type {
     cell_gid_type gid;
     cell_lid_type index;
diff --git a/src/catypes_io.cpp b/src/common_types_io.cpp
similarity index 83%
rename from src/catypes_io.cpp
rename to src/common_types_io.cpp
index 4c9d185f0bf68a2cd1c9ba8cbe67df26f614631d..ad6ca540b80e1ce296c8ba2f4eceb52cd9ebfd63 100644
--- a/src/catypes_io.cpp
+++ b/src/common_types_io.cpp
@@ -1,6 +1,6 @@
 #include <iostream>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 
 std::ostream& operator<<(std::ostream& O, nest::mc::cell_member_type m) {
     return O << m.gid << ':' << m.index;
diff --git a/src/communication/communicator.hpp b/src/communication/communicator.hpp
index cefffd4cfd381c7d2350a2efd1c178d534b1ce1a..9336daebc2cda6f179a2ad59211d7b9927c38a38 100644
--- a/src/communication/communicator.hpp
+++ b/src/communication/communicator.hpp
@@ -5,12 +5,12 @@
 #include <vector>
 #include <random>
 
-#include <spike.hpp>
-#include <threading/threading.hpp>
 #include <algorithms.hpp>
+#include <connection.hpp>
 #include <event_queue.hpp>
-
-#include "connection.hpp"
+#include <spike.hpp>
+#include <threading/threading.hpp>
+#include <util/debug.hpp>
 
 namespace nest {
 namespace mc {
diff --git a/src/communication/mpi_global_policy.hpp b/src/communication/mpi_global_policy.hpp
index 54ded32cc059e2bff221a880edbd3ee68c4f272b..0e9ec33370695990e2e2fa0d8d03d4a1e8b26c26 100644
--- a/src/communication/mpi_global_policy.hpp
+++ b/src/communication/mpi_global_policy.hpp
@@ -9,7 +9,7 @@
 #include <vector>
 
 #include <algorithms.hpp>
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <communication/mpi.hpp>
 #include <spike.hpp>
 
diff --git a/src/compartment.hpp b/src/compartment.hpp
index c69f622f16ece3638e32d8b95155fa1c31f33a65..da6bbcf57298593a60f7510822832060c7a89846 100644
--- a/src/compartment.hpp
+++ b/src/compartment.hpp
@@ -3,7 +3,7 @@
 #include <iterator>
 #include <utility>
 
-#include "catypes.hpp"
+#include "common_types.hpp"
 
 namespace nest {
 namespace mc {
diff --git a/src/connection.hpp b/src/connection.hpp
index 3ef99a9c28e1007c88835b9e1df1be4765bc32f5..b9e40fb5baeb83ad69c87c219f65d9f98acc4456 100644
--- a/src/connection.hpp
+++ b/src/connection.hpp
@@ -2,7 +2,7 @@
 
 #include <cstdint>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <event_queue.hpp>
 #include <spike.hpp>
 
diff --git a/src/event_queue.hpp b/src/event_queue.hpp
index b78cc0ca821aa2d393c64280164adad50f355e74..31f6a5a10cf6b0c9ff9c0ff049909b801cd25b34 100644
--- a/src/event_queue.hpp
+++ b/src/event_queue.hpp
@@ -4,7 +4,7 @@
 #include <ostream>
 #include <queue>
 
-#include "catypes.hpp"
+#include "common_types.hpp"
 #include "util/optional.hpp"
 
 namespace nest {
diff --git a/src/model.hpp b/src/model.hpp
index e819ff8b180beea18d5c0e745793bba1ef6aa8a5..3b773823d867983db54b5aa1ca86cac9513bfccb 100644
--- a/src/model.hpp
+++ b/src/model.hpp
@@ -1,7 +1,7 @@
 #include <cstdlib>
 #include <vector>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <cell_group.hpp>
 #include <communication/communicator.hpp>
diff --git a/src/segment.hpp b/src/segment.hpp
index a7600da948dfec79dfc600d9099b421accfd1aae..248306a6c3a976d123b9d412b93c09156305086d 100644
--- a/src/segment.hpp
+++ b/src/segment.hpp
@@ -4,7 +4,7 @@
 #include <vector>
 
 #include "algorithms.hpp"
-#include "catypes.hpp"
+#include "common_types.hpp"
 #include "compartment.hpp"
 #include "math.hpp"
 #include "parameter_list.hpp"
diff --git a/tests/unit/test_cell_group.cpp b/tests/unit/test_cell_group.cpp
index 050974f0bda553a04cff3b932afa7269d3393034..3aed222029f4535a85d9713849cff184a3684531 100644
--- a/tests/unit/test_cell_group.cpp
+++ b/tests/unit/test_cell_group.cpp
@@ -1,6 +1,6 @@
 #include "gtest.h"
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <fvm_cell.hpp>
 #include <cell_group.hpp>
 
@@ -20,10 +20,8 @@ nest::mc::cell make_cell() {
 
     dendrite->mechanism("membrane").set("r_L", 100);
 
-    // add stimulus
-    cell.add_stimulus({1,1}, {5., 80., 0.3});
-
-    cell.add_detector({0,0}, 0);
+    cell.add_detector({0, 0}, 0);
+    cell.add_stimulus({1, 1}, {5., 80., 0.3});
 
     return cell;
 }
@@ -41,3 +39,36 @@ TEST(cell_group, test)
     EXPECT_EQ(group.spikes().size(), 4u);
 }
 
+TEST(cell_group, sources)
+{
+    using namespace nest::mc;
+
+    // TODO: extend to multi-cell cell groups when the time comes
+
+    using cell_group_type = cell_group<fvm::fvm_cell<double, cell_local_size_type>>;
+
+    auto cell = make_cell();
+    EXPECT_EQ(cell.detectors().size(), 1u);
+    // add another detector on the cell to make things more interesting
+    cell.add_detector({1, 0.3}, 2.3);
+
+    cell_gid_type first_gid = 37u;
+    auto group = cell_group_type{first_gid, cell};
+
+    // expect group sources to be lexicographically sorted by source id
+    // with gids in cell group's range and indices starting from zero
+
+    const auto& sources = group.spike_sources();
+    for (unsigned i = 0; i<sources.size(); ++i) {
+        auto id = sources[i].source_id;
+        if (i==0) {
+            EXPECT_EQ(id.gid, first_gid);
+            EXPECT_EQ(id.index, 0u);
+        }
+        else {
+            auto prev = sources[i-1].source_id;
+            EXPECT_GT(id, prev);
+            EXPECT_EQ(id.index, id.gid==prev.gid? prev.index+1: 0u);
+        }
+    }
+}
diff --git a/tests/unit/test_fvm.cpp b/tests/unit/test_fvm.cpp
index ea8cd7dae4f1b2cc17af3c39cfd3422169180dca..c0ed438f20841d40a9f2653e38424aeeba4a64ea 100644
--- a/tests/unit/test_fvm.cpp
+++ b/tests/unit/test_fvm.cpp
@@ -2,7 +2,7 @@
 
 #include "gtest.h"
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <fvm_cell.hpp>
 
diff --git a/tests/unit/test_lexcmp.cpp b/tests/unit/test_lexcmp.cpp
index a02ac0765823f61d54e8acee3cf38611552d9dd7..e2b5c476d7983f7726349953d15e34509aab031c 100644
--- a/tests/unit/test_lexcmp.cpp
+++ b/tests/unit/test_lexcmp.cpp
@@ -62,8 +62,8 @@ class lexcmp_test_refmemfn {
 public:
     explicit lexcmp_test_refmemfn(int foo): foo_(foo) {}
 
-    const int &foo() const { return foo_; }
-    int &foo() { return foo_; }
+    const int& foo() const { return foo_; }
+    int& foo() { return foo_; }
 
 private:
     int foo_;
diff --git a/tests/unit/test_probe.cpp b/tests/unit/test_probe.cpp
index 888e710eec377143b6ac6684e41cc222d0b0c107..5af744d2cc5f7f9b8a403b991b22d260c9ec74d4 100644
--- a/tests/unit/test_probe.cpp
+++ b/tests/unit/test_probe.cpp
@@ -1,6 +1,6 @@
 #include "gtest.h"
 
-#include "catypes.hpp"
+#include "common_types.hpp"
 #include "cell.hpp"
 #include "fvm_cell.hpp"
 
diff --git a/tests/validation/validate_ball_and_stick.cpp b/tests/validation/validate_ball_and_stick.cpp
index a819173e937419a87471a79f1644a243b20e7ac0..62d06b4dac85885f935dd88855223551cc33fcce 100644
--- a/tests/validation/validate_ball_and_stick.cpp
+++ b/tests/validation/validate_ball_and_stick.cpp
@@ -1,7 +1,7 @@
 #include <fstream>
 #include <json/src/json.hpp>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <fvm_cell.hpp>
 
diff --git a/tests/validation/validate_soma.cpp b/tests/validation/validate_soma.cpp
index 203967014117ca539564aadb35da98ceb1b60054..24a0c1c59f0db24bc6f9c7832909f9f52af7beb7 100644
--- a/tests/validation/validate_soma.cpp
+++ b/tests/validation/validate_soma.cpp
@@ -1,7 +1,7 @@
 #include <fstream>
 #include <json/src/json.hpp>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <fvm_cell.hpp>
 
diff --git a/tests/validation/validate_synapses.cpp b/tests/validation/validate_synapses.cpp
index 9bc67172879d14e8aea1aed21311c344fcb9f64a..876b24eb55c9cad0e08c17cef9cdf16595f5bd90 100644
--- a/tests/validation/validate_synapses.cpp
+++ b/tests/validation/validate_synapses.cpp
@@ -3,7 +3,7 @@
 
 #include <json/src/json.hpp>
 
-#include <catypes.hpp>
+#include <common_types.hpp>
 #include <cell.hpp>
 #include <cell_group.hpp>
 #include <fvm_cell.hpp>