diff --git a/src/communication/communicator.hpp b/src/communication/communicator.hpp
index e59e15f5b2bf5ab7482ad9ce0c11fb0ea1359638..0289fc3192e268bd5e647d659747635509914ef8 100644
--- a/src/communication/communicator.hpp
+++ b/src/communication/communicator.hpp
@@ -92,20 +92,19 @@ public:
     /// events in each queue are all events that must be delivered to targets in that cell
     /// group as a result of the global spike exchange.
     std::vector<event_queue> exchange(const std::vector<spike_type>& local_spikes,
-        std::function<void (const std::vector<spike_type>&)> export_function) //const std::vector<spike_type>&
+        std::function<void (const std::vector<spike_type>&)> do_export_rank,
+        std::function<void(const std::vector<spike_type>&)> do_export_single)
     {
         // global all-to-all to gather a local copy of the global spike list on each node.
         
 
-        bool file_per_rank = true;
-        if (file_per_rank) {
-            export_function(local_spikes); //local_spikes
-        }
-
+        do_export_rank(local_spikes); 
 
         auto global_spikes = communication_policy_.gather_spikes( local_spikes );
         num_spikes_ += global_spikes.size();
 
+        do_export_single(global_spikes);
+
         // check each global spike in turn to see it generates local events.
         // if so, make the events and insert them into the appropriate event list.
         auto queues = std::vector<event_queue>(num_groups_local());
diff --git a/src/communication/export_manager.hpp b/src/communication/export_manager.hpp
index ccef9c1c86538a75ca38f855509c409ff647474d..ed4997282ac6d2f71894b8aa987d8ac80250d8db 100644
--- a/src/communication/export_manager.hpp
+++ b/src/communication/export_manager.hpp
@@ -1,27 +1,82 @@
-//#pragma once
-//
-//#include <algorithm>
-//#include <iostream>
-//#include <fstream>
-//#include <vector>
-//#include <random>
-//
-//#include <spike.hpp>
-//
-//#include "exporter_interface.hpp"
-//
-//namespace nest {
-//namespace mc {
-//namespace communication {
-//
-//class export_manager {
-//
-//
-//
-//};
-//
-//
-//
-//} //communication
-//} // namespace mc
-//} // namespace nest
\ No newline at end of file
+#pragma once
+
+#include <algorithm>
+#include <iostream>
+
+#include <vector>
+#include <memory>
+#include <utility>
+
+#include <spike.hpp>
+#include <util.hpp>
+#include <common_types.hpp>
+#include "exporter_interface.hpp"
+#include "exporter_spike_file.hpp"
+#include "exporter_spike_single_file.hpp"
+
+namespace nest {
+namespace mc {
+namespace communication {
+
+template <typename Time, typename CommunicationPolicy>
+class export_manager {
+public:
+    using time_type = Time;
+    using spike_type = spike<cell_member_type, time_type>;
+    export_manager() 
+    {
+
+        if (true) { // single file per rank
+
+            rank_exporters_.push_back(
+                nest::mc::util::make_unique<
+                    nest::mc::communication::exporter_spike_file<Time, CommunicationPolicy> >(
+                        "rank", "./", "gdf"));
+
+
+        }
+
+
+        if (true) { // single file per simulation
+            single_exporters_.push_back(
+                nest::mc::util::make_unique<
+                    nest::mc::communication::exporter_spike_single_file<Time, CommunicationPolicy> >(
+                    "single", "./", "gdf"));
+        }
+    }
+
+    void do_export_rank(const std::vector<spike_type>& spikes)
+    {
+        for (auto &exporter : rank_exporters_)
+        {
+            exporter->add_and_export(spikes);
+        }
+    }
+
+    void do_export_single(const std::vector<spike_type>& spikes)
+    {
+        if (!communication_policy_.id() == 0) {
+            return;
+        }
+
+        for (auto &exporter : single_exporters_)
+        {
+            exporter->add_and_export(spikes);
+        }
+    }
+
+private:
+    // 
+    std::vector<std::unique_ptr<exporter_interface<Time, CommunicationPolicy> > > rank_exporters_;
+
+    std::vector<std::unique_ptr<exporter_interface<Time, CommunicationPolicy> > > single_exporters_;
+
+
+    CommunicationPolicy communication_policy_;
+};
+
+
+
+} //communication
+} // namespace mc
+} // namespace nest
\ No newline at end of file
diff --git a/src/communication/exporter_spike_single_file.hpp b/src/communication/exporter_spike_single_file.hpp
index b22d77c011ef21d31195b290c4d5566d93817f11..249e7583b28b6043e20b719ba8d1d9facfb8c339 100644
--- a/src/communication/exporter_spike_single_file.hpp
+++ b/src/communication/exporter_spike_single_file.hpp
@@ -72,10 +72,6 @@ public:
     // Does not throw
     void do_export() override
     {        
-        if (!communication_policy_.id() == 0) {
-            return;
-        }
-
         for (auto spike : spikes_) {
             *file_handle_ << spike.source.gid << " " << spike.time << std::endl;
         }
@@ -90,9 +86,6 @@ public:
     // Does not do the actual export  
     void add_data(std::vector<spike_type>spikes) override
     {
-        if (!communication_policy_.id() == 0) {
-            return;
-        }
 
         spikes_.insert(std::end(spikes_), 
                        std::begin(spikes), std::end(spikes));       
@@ -101,10 +94,6 @@ public:
     // Add and export data to file in a single function
     void add_and_export(const std::vector<spike_type>& spikes) override
     {
-        if (!communication_policy_.id() == 0) {
-            return;
-        }
-
         add_data(spikes);
         do_export();
     }
@@ -114,9 +103,6 @@ public:
     // We need a way to assertain the status of the stream
     bool ok() const override
     {
-        if (!communication_policy_.id() == 0) {
-            return true;
-        }
 
         return ok_ && file_handle_->good();
     }
diff --git a/src/model.hpp b/src/model.hpp
index f7e22d28c939c6fb1f81bd41e7a127d6f5a6d3cd..d84396c7ca2bed6a3223f1cf24bff1de6724d30e 100644
--- a/src/model.hpp
+++ b/src/model.hpp
@@ -12,9 +12,7 @@
 #include <thread_private_spike_store.hpp>
 #include <communication/communicator.hpp>
 #include <communication/global_policy.hpp>
-#include <communication/exporter_interface.hpp>
-#include <communication/exporter_spike_single_file.hpp>
-#include <communication/exporter_spike_file.hpp>
+#include <communication/export_manager.hpp>
 #include <profiling/profiler.hpp>
 
 #include "trace_sampler.hpp"
@@ -74,8 +72,7 @@ public:
 
         bool single_file = true;
         if (single_file == true) {
-            exporter_ = nest::mc::util::make_unique<exporter_spike_single_file_type>(
-                "file_name", "./","gdf");
+            exporter_ = nest::mc::util::make_unique<exporter_manager_type>();
         }
 
         // Allocate an empty queue buffer for each cell group
@@ -139,7 +136,8 @@ public:
                 PE("stepping", "exchange");
                 auto local_spikes = previous_spikes().gather();
                 future_events() = communicator_.exchange(local_spikes,
-                [&] (const std::vector<spike_type>& spikes){ exporter_->add_and_export(spikes); });
+                    [&](const std::vector<spike_type>& spikes) { exporter_->do_export_rank(spikes); },
+                [&] (const std::vector<spike_type>& spikes){ exporter_->do_export_single(spikes); });
                 PL(2);
             };
 
@@ -194,10 +192,9 @@ private:
     using local_spike_store_type = thread_private_spike_store<time_type>;
     util::double_buffer< local_spike_store_type > local_spikes_;
 
-    using exporter_interface_type = nest::mc::communication::exporter_interface<time_type, communication::global_policy>;
-    using exporter_spike_single_file_type = nest::mc::communication::exporter_spike_file<time_type, communication::global_policy>;
+    using exporter_manager_type = nest::mc::communication::export_manager<time_type, communication::global_policy>;
 
-    std::unique_ptr<exporter_interface_type> exporter_;
+    std::unique_ptr<exporter_manager_type> exporter_;
     // Convenience functions that map the spike buffers and event queues onto
     // the appropriate integration interval.
     //