diff --git a/Framework/Parallel/CMakeLists.txt b/Framework/Parallel/CMakeLists.txt
index 4c78ef283fe0f86092dc889ce0a0c2768afc9f63..faeda7ba64d758c12ab9f9839854d03c36543c78 100644
--- a/Framework/Parallel/CMakeLists.txt
+++ b/Framework/Parallel/CMakeLists.txt
@@ -3,6 +3,7 @@ set ( SRC_FILES
 	src/ExecutionMode.cpp
 	src/IO/Chunker.cpp
 	src/IO/EventLoader.cpp
+	src/IO/EventParser.cpp
 	src/Request.cpp
 	src/StorageMode.cpp
 	src/ThreadingBackend.cpp
diff --git a/Framework/Parallel/inc/MantidParallel/IO/EventParser.h b/Framework/Parallel/inc/MantidParallel/IO/EventParser.h
index 0c28a8baeac863f7ed3ab32c0074fd60e1bd409f..dcd5bde8d02773f6aef2a6061b0a7fc2c66486ef 100644
--- a/Framework/Parallel/inc/MantidParallel/IO/EventParser.h
+++ b/Framework/Parallel/inc/MantidParallel/IO/EventParser.h
@@ -55,6 +55,20 @@ template <class TimeOffsetType> struct Event {
   TimeOffsetType tof;
   Types::Core::DateAndTime pulseTime;
 };
+
+void MANTID_PARALLEL_DLL eventIdToGlobalSpectrumIndex(int32_t *event_id_start,
+                                                      size_t count,
+                                                      const int32_t bankOffset);
+
+template <class TimeOffsetType>
+void redistributeDataMPI(
+    Communicator &comm, std::vector<Event<TimeOffsetType>> &result,
+    const std::vector<std::vector<Event<TimeOffsetType>>> &data);
+
+template <class TimeOffsetType>
+void populateEventLists(
+    const std::vector<Event<TimeOffsetType>> &events,
+    std::vector<std::vector<Types::Event::TofEvent> *> &eventLists);
 }
 
 template <class IndexType, class TimeZeroType, class TimeOffsetType>
@@ -79,15 +93,6 @@ public:
                              const TimeOffsetType *eventTimeOffset,
                              const Chunker::LoadRange &range);
 
-  void eventIdToGlobalSpectrumIndex(int32_t *event_id_start, size_t count,
-                                    size_t bankIndex) const;
-
-  void populateEventList(const std::vector<Event> &events);
-
-  const std::vector<std::vector<Event>> &rankData() const {
-    return m_allRankData;
-  }
-
   void wait() const;
 
 private:
@@ -142,24 +147,6 @@ void EventParser<IndexType, TimeZeroType, TimeOffsetType>::setPulseInformation(
       event_time_zero_offset);
 }
 
-/** Transform event IDs to global spectrum numbers using the bankOffsets stored
- * at object creation.
- *
- * The transformation is in-place to save memory bandwidth and modifies the
- * range pointed to by `event_id_start`.
- * @param event_id_start Starting position of chunk of data containing event
- * IDs.
- * @param count Number of items in data chunk
- * @param bankIndex Index into the list of bank offsets.
- */
-template <class IndexType, class TimeZeroType, class TimeOffsetType>
-void EventParser<IndexType, TimeZeroType, TimeOffsetType>::
-    eventIdToGlobalSpectrumIndex(int32_t *event_id_start, size_t count,
-                                 size_t bankIndex) const {
-  for (size_t i = 0; i < count; ++i)
-    event_id_start[i] -= m_bankOffsets[bankIndex];
-}
-
 /** Extracts event information from the list of time offsets and global spectrum
  * indices using the event_index and event_time_offset tables provided from
  * file. These events are separated according to MPI ranks.
@@ -191,6 +178,7 @@ void EventParser<IndexType, TimeZeroType, TimeOffsetType>::
   }
 }
 
+namespace detail {
 /** Uses MPI calls to redistribute chunks which must be processed on certain
  * ranks.
  * @param comm MPI communicator.
@@ -200,9 +188,9 @@ void EventParser<IndexType, TimeZeroType, TimeOffsetType>::
  */
 template <class TimeOffsetType>
 void redistributeDataMPI(
-    Communicator &comm, std::vector<detail::Event<TimeOffsetType>> &result,
-    const std::vector<std::vector<detail::Event<TimeOffsetType>>> &data) {
-  using Event = detail::Event<TimeOffsetType>;
+    Communicator &comm, std::vector<Event<TimeOffsetType>> &result,
+    const std::vector<std::vector<Event<TimeOffsetType>>> &data) {
+  using Event = Event<TimeOffsetType>;
   if (comm.size() == 1) {
     result = data.front();
     return;
@@ -248,20 +236,21 @@ void redistributeDataMPI(
 /** Fills the workspace EventList with extracted events
  * @param events Events extracted from file according to mpi rank.
  */
-template <class IndexType, class TimeZeroType, class TimeOffsetType>
-void EventParser<IndexType, TimeZeroType, TimeOffsetType>::populateEventList(
-    const std::vector<Event> &events) {
+template <class TimeOffsetType>
+void populateEventLists(
+    const std::vector<Event<TimeOffsetType>> &events,
+    std::vector<std::vector<Types::Event::TofEvent> *> &eventLists) {
   for (const auto &event : events) {
-    m_eventLists[event.index]->emplace_back(event.tof, event.pulseTime);
+    eventLists[event.index]->emplace_back(event.tof, event.pulseTime);
     // In general `index` is random so this loop suffers from frequent cache
     // misses (probably because the hardware prefetchers cannot keep up with the
     // number of different memory locations that are getting accessed). We
     // manually prefetch into L2 cache to reduce the amount of misses.
-    _mm_prefetch(
-        reinterpret_cast<char *>(&m_eventLists[event.index]->back() + 1),
-        _MM_HINT_T1);
+    _mm_prefetch(reinterpret_cast<char *>(&eventLists[event.index]->back() + 1),
+                 _MM_HINT_T1);
   }
 }
+}
 
 /** Accepts raw data from file which has been pre-treated and sorted into chunks
  * for parsing. The parser extracts event data from the provided buffers,
@@ -292,16 +281,16 @@ void EventParser<IndexType, TimeZeroType, TimeOffsetType>::doParsing(
     int32_t *event_id_start, const TimeOffsetType *event_time_offset_start,
     const Chunker::LoadRange &range) {
   // change event_id_start in place
-  eventIdToGlobalSpectrumIndex(event_id_start, range.eventCount,
-                               range.bankIndex);
+  detail::eventIdToGlobalSpectrumIndex(event_id_start, range.eventCount,
+                                       m_bankOffsets[range.bankIndex]);
 
   // event_id_start now contains globalSpectrumIndex
   extractEventsForRanks(m_allRankData, event_id_start, event_time_offset_start,
                         range);
 
-  redistributeDataMPI(m_comm, m_thisRankData, m_allRankData);
+  detail::redistributeDataMPI(m_comm, m_thisRankData, m_allRankData);
   // TODO: accept something which translates from global to local spectrum index
-  populateEventList(m_thisRankData);
+  populateEventLists(m_thisRankData, m_eventLists);
 }
 
 template <class IndexType, class TimeZeroType, class TimeOffsetType>
diff --git a/Framework/Parallel/src/IO/EventParser.cpp b/Framework/Parallel/src/IO/EventParser.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70f00e1f5657edb6fb0e87a620fb0a2e888a6496
--- /dev/null
+++ b/Framework/Parallel/src/IO/EventParser.cpp
@@ -0,0 +1,27 @@
+#include "MantidParallel/IO/EventParser.h"
+
+namespace Mantid {
+namespace Parallel {
+namespace IO {
+namespace detail {
+
+/** Transform event IDs to global spectrum numbers using the bankOffsets stored
+ * at object creation.
+ *
+ * The transformation is in-place to save memory bandwidth and modifies the
+ * range pointed to by `event_id_start`.
+ * @param event_id_start Starting position of chunk of data containing event
+ * IDs.
+ * @param count Number of items in data chunk
+ * @param bankOffset Offset to subtract from the array `event_id_start`.
+ */
+void eventIdToGlobalSpectrumIndex(int32_t *event_id_start, size_t count,
+                                  const int32_t bankOffset) {
+  for (size_t i = 0; i < count; ++i)
+    event_id_start[i] -= bankOffset;
+}
+
+} // namespace detail
+} // namespace IO
+} // namespace Parallel
+} // namespace Mantid
diff --git a/Framework/Parallel/test/EventParserTest.h b/Framework/Parallel/test/EventParserTest.h
index e51a47ef2d082d1082dd27e0cff10e74dd108ecd..1825ee53b4f4e3be3f637b976a6cd8dbf105c548 100644
--- a/Framework/Parallel/test/EventParserTest.h
+++ b/Framework/Parallel/test/EventParserTest.h
@@ -152,17 +152,11 @@ public:
   }
 
   void testConvertEventIDToGlobalSpectrumIndex() {
-    std::vector<std::vector<int>> rankGroups;
     std::vector<int32_t> bankOffsets{1000};
-    std::vector<std::vector<TofEvent> *> eventLists(10);
-
-    Parallel::Communicator comm;
-    EventParser<int64_t, int64_t, double> parser(comm, rankGroups, bankOffsets,
-                                                 eventLists);
-
     std::vector<int32_t> eventId{1001, 1002, 1004, 1004};
     auto eventIdCopy = eventId;
-    parser.eventIdToGlobalSpectrumIndex(eventId.data(), eventId.size(), 0);
+    detail::eventIdToGlobalSpectrumIndex(eventId.data(), eventId.size(),
+                                         bankOffsets[0]);
 
     TS_ASSERT_EQUALS(eventId[0], eventIdCopy[0] - bankOffsets[0]);
     TS_ASSERT_EQUALS(eventId[1], eventIdCopy[1] - bankOffsets[0]);
@@ -178,8 +172,8 @@ public:
     auto event_time_offset = gen.eventTimeOffset(0);
     auto range = gen.generateBasicRange(0);
 
-    parser->eventIdToGlobalSpectrumIndex(event_id.data() + range.eventOffset,
-                                         range.eventCount, range.bankIndex);
+    detail::eventIdToGlobalSpectrumIndex(event_id.data() + range.eventOffset,
+                                         range.eventCount, 1000);
     std::vector<std::vector<EventParser<int32_t, int64_t, int64_t>::Event>>
         rankData;
     // event_id now contains spectrum indices
@@ -201,8 +195,8 @@ public:
     auto event_time_offset = gen.eventTimeOffset(0);
     auto range = Chunker::LoadRange{0, 5, 100};
 
-    parser->eventIdToGlobalSpectrumIndex(event_id.data() + range.eventOffset,
-                                         range.eventCount, range.bankIndex);
+    detail::eventIdToGlobalSpectrumIndex(event_id.data() + range.eventOffset,
+                                         range.eventCount, 1000);
     std::vector<std::vector<EventParser<int32_t, int64_t, int64_t>::Event>>
         rankData;
     // event_id now contains spectrum indices
@@ -355,6 +349,8 @@ public:
     }
 
     parser = gen.generateTestParser();
+    for (auto &eventList : m_eventLists)
+      m_eventListPtrs.emplace_back(&eventList);
   }
 
   void testCompletePerformance() {
@@ -373,8 +369,8 @@ public:
                                     gen.generateBasicRange(bank));
   }
 
-  void testPopulateEventListPerformance() {
-    parser->populateEventList(rankData[0]);
+  void testPopulateEventListsPerformance() {
+    detail::populateEventLists(rankData[0], m_eventListPtrs);
   }
 
 private:
@@ -385,5 +381,7 @@ private:
   boost::shared_ptr<EventParser<int32_t, int64_t, double>> parser;
   std::vector<std::vector<EventParser<int32_t, int64_t, double>::Event>>
       rankData;
+  std::vector<std::vector<TofEvent>> m_eventLists{NUM_BANKS * 1000};
+  std::vector<std::vector<TofEvent> *> m_eventListPtrs;
 };
 #endif /* MANTID_PARALLEL_COLLECTIVESTEST_H_ */