diff --git a/core/data/CbmEvent.cxx b/core/data/CbmEvent.cxx
index c34f22f3b3109a8ffb09e496a7ec00d074359d05..3f4117d41b1f7eeaaab6b47fc80b7fcb401e7300 100644
--- a/core/data/CbmEvent.cxx
+++ b/core/data/CbmEvent.cxx
@@ -55,6 +55,18 @@ void CbmEvent::SetVertex(Double_t x, Double_t y, Double_t z, Double_t chi2, Int_
 }
 // -------------------------------------------------------------------------
 
+// -----    Swap two events
+void CbmEvent::Swap(CbmEvent& e)
+{
+  std::swap(fNumber, e.fNumber);
+  std::swap(fTimeStart, e.fTimeStart);
+  std::swap(fTimeEnd, e.fTimeEnd);
+  std::swap(fNofData, e.fNofData);
+  std::swap(fVertex, e.fVertex);
+  std::swap(fMatch, e.fMatch);
+  std::swap(fIndexMap, e.fIndexMap);
+}
+
 
 // -----   String output   -------------------------------------------------
 std::string CbmEvent::ToString() const
diff --git a/core/data/CbmEvent.h b/core/data/CbmEvent.h
index e8c9aad81f7223ad6be0751b4c6c45c98c4093bd..00208ba5712320fd3c4a32bae624f2f91f3e5fa5 100644
--- a/core/data/CbmEvent.h
+++ b/core/data/CbmEvent.h
@@ -135,6 +135,10 @@ public:
 		 **/
   Double_t GetStartTime() const { return fTimeStart; }
 
+  /** Set event number
+		 ** @value Event number
+		 **/
+  void SetNumber(Int_t number) { fNumber = number; }
 
   /** Set end time
 		 ** @param endTime  End time of event [ns]
@@ -189,6 +193,8 @@ public:
 		 **/
   CbmVertex* GetVertex() { return &fVertex; }
 
+  /** Swap two events **/
+  void Swap(CbmEvent& e);
 
 private:
   /** Event meta data **/
diff --git a/reco/eventbuilder/digis/CbmBuildEventsIdeal.cxx b/reco/eventbuilder/digis/CbmBuildEventsIdeal.cxx
index 895a2757484245ebc3afed139e0e35dbfd7ec4cb..6b9290ee7c7d4090972c861246f592ebb654422c 100644
--- a/reco/eventbuilder/digis/CbmBuildEventsIdeal.cxx
+++ b/reco/eventbuilder/digis/CbmBuildEventsIdeal.cxx
@@ -38,24 +38,20 @@ CbmBuildEventsIdeal::~CbmBuildEventsIdeal() {}
 
 
 // =====   Number if different pairs (input,event) in a match object   =======
-UInt_t CbmBuildEventsIdeal::EventsInMatch(const CbmMatch* match)
+CbmMatch CbmBuildEventsIdeal::EventsInMatch(const CbmMatch* match)
 {
+  // --- Collect links from different events
 
-  // --- No or empty match object
-  if (match == nullptr) return 0;
-  if (!match->GetNofLinks()) return 0;
+  CbmMatch eventMatch;
+  Int_t nLinks = (match != nullptr) ? match->GetNofLinks() : 0;
 
-  // --- Only one link
-  if (match->GetNofLinks() == 1) return 1;
-
-  // --- More than one link: check whether they are from different events
-  CbmMatch testMatch;
-  for (Int_t iLink = 0; iLink < match->GetNofLinks(); iLink++) {
-    Int_t input = match->GetLink(iLink).GetFile();
-    Int_t event = match->GetLink(iLink).GetEntry();
-    testMatch.AddLink(1., 0, event, input);
+  for (Int_t iLink = 0; iLink < nLinks; iLink++) {
+    Int_t mcInput = match->GetLink(iLink).GetFile();
+    Int_t mcEvent = match->GetLink(iLink).GetEntry();
+    if (mcInput < 0 || mcEvent < 0) { continue; }
+    eventMatch.AddLink(1., 0, mcEvent, mcInput);
   }
-  return testMatch.GetNofLinks();
+  return eventMatch;
 }
 // ===========================================================================
 
@@ -85,54 +81,58 @@ void CbmBuildEventsIdeal::Exec(Option_t*)
     if (!fDigiMan->IsPresent(system)) continue;
     if (!fDigiMan->IsMatchPresent(system)) continue;
 
+    ECbmDataType digiType = ECbmDataType::kUnknown;
+
+    // --- Find the digi type
+    switch (system) {
+      case ECbmModuleId::kMvd: digiType = ECbmDataType::kMvdDigi; break;
+      case ECbmModuleId::kSts: digiType = ECbmDataType::kStsDigi; break;
+      case ECbmModuleId::kRich: digiType = ECbmDataType::kRichDigi; break;
+      case ECbmModuleId::kMuch: digiType = ECbmDataType::kMuchDigi; break;
+      case ECbmModuleId::kTrd: digiType = ECbmDataType::kTrdDigi; break;
+      case ECbmModuleId::kTof: digiType = ECbmDataType::kTofDigi; break;
+      case ECbmModuleId::kPsd: digiType = ECbmDataType::kPsdDigi; break;
+      default: break;
+    }  //? detector
+
+    if (digiType == ECbmDataType::kUnknown) {
+      LOG(fatal) << "unknown type of the module";
+      assert(0);
+      continue;  // in case assert(..) macro is switched off
+    }
+
     // --- Loop over digis for the current system
     Int_t nDigis  = fDigiMan->GetNofDigis(system);
     UInt_t nNoise = 0;
     UInt_t nAmbig = 0;
     for (Int_t iDigi = 0; iDigi < nDigis; iDigi++) {
 
-      // --- Get the MC input and event number through the match object
-      const CbmMatch* match = fDigiMan->GetMatch(system, iDigi);
-      assert(match);
-      Int_t mcInput = -1;
-      Int_t mcEvent = -1;
-      if (match->GetNofLinks()) {
-        mcInput = match->GetMatchedLink().GetFile();
-        mcEvent = match->GetMatchedLink().GetEntry();
-      }
+      // --- Get the MC input and event numbers through the match object
+
+      CbmMatch digiEvents = EventsInMatch(fDigiMan->GetMatch(system, iDigi));
+
+      for (Int_t iLink = 0; iLink < digiEvents.GetNofLinks(); iLink++) {
+        const auto& link = digiEvents.GetLink(iLink);
+        auto eventID     = make_pair(link.GetFile(), link.GetEntry());
+
+        // --- Get event pointer. If event is not yet present, create it.
+        CbmEvent* event = nullptr;
+        auto it         = eventMap.find(eventID);
+        if (it == eventMap.end()) {
+          event             = new CbmEvent();
+          eventMap[eventID] = event;
+        }
+        else {
+          event = it->second;
+        }
+        event->AddData(digiType, iDigi);
+      }  //# links
 
       // --- Empty match objects or negative event numbers signal noise
-      if (mcInput < 0 || mcEvent < 0) {
-        nNoise++;
-        continue;
-      }
+      if (!digiEvents.GetNofLinks() == 0) { nNoise++; }
 
       // --- Count occurrences of multiple MC events in match
-      if (EventsInMatch(match) > 1) nAmbig++;
-
-      // --- Get event pointer. If event is not yet present, create it.
-      CbmEvent* event = nullptr;
-      auto it         = eventMap.find(make_pair(mcInput, mcEvent));
-      if (it == eventMap.end()) {
-        assert(nEvents == fEvents->GetEntriesFast());
-        event                                 = new ((*fEvents)[nEvents]) CbmEvent(nEvents);
-        eventMap[make_pair(mcInput, mcEvent)] = event;
-        nEvents++;
-      }
-      else
-        event = it->second;
-
-      // --- Fill digi index into event
-      switch (system) {
-        case ECbmModuleId::kMvd: event->AddData(ECbmDataType::kMvdDigi, iDigi); break;
-        case ECbmModuleId::kSts: event->AddData(ECbmDataType::kStsDigi, iDigi); break;
-        case ECbmModuleId::kRich: event->AddData(ECbmDataType::kRichDigi, iDigi); break;
-        case ECbmModuleId::kMuch: event->AddData(ECbmDataType::kMuchDigi, iDigi); break;
-        case ECbmModuleId::kTrd: event->AddData(ECbmDataType::kTrdDigi, iDigi); break;
-        case ECbmModuleId::kTof: event->AddData(ECbmDataType::kTofDigi, iDigi); break;
-        case ECbmModuleId::kPsd: event->AddData(ECbmDataType::kPsdDigi, iDigi); break;
-        default: break;
-      }  //? detector
+      if (digiEvents.GetNofLinks() > 1) { nAmbig++; }
 
     }  //# digis
     LOG(debug) << GetName() << ": Detector " << CbmModuleList::GetModuleNameCaps(system) << ", digis " << nDigis << " ("
@@ -143,7 +143,15 @@ void CbmBuildEventsIdeal::Exec(Option_t*)
 
   }  //# detector systems
 
-  assert(nEvents == fEvents->GetEntriesFast());
+  // events are already ordered in the map, create CbmEvents in the same order
+  for (auto it = eventMap.begin(); it != eventMap.end(); it++) {
+    assert(nEvents == fEvents->GetEntriesFast());
+    CbmEvent* store = new ((*fEvents)[nEvents]) CbmEvent();
+    store->Swap(*(it->second));
+    store->SetNumber(nEvents++);
+    delete it->second;
+    it->second = nullptr;  // for a case
+  }
 
   // --- Timeslice log and statistics
   timer.Stop();
diff --git a/reco/eventbuilder/digis/CbmBuildEventsIdeal.h b/reco/eventbuilder/digis/CbmBuildEventsIdeal.h
index b855c0606ab49aabf21ef84281acc77f8264bc13..16f4d1dd8bb5a3f80eb35abdaa57a020c8d7c004 100644
--- a/reco/eventbuilder/digis/CbmBuildEventsIdeal.h
+++ b/reco/eventbuilder/digis/CbmBuildEventsIdeal.h
@@ -13,6 +13,7 @@
 
 
 #include "CbmDefs.h"
+#include "CbmMatch.h"
 
 #include <FairTask.h>
 
@@ -65,7 +66,7 @@ private:  // methods
 
 
   /** @brief Number of different MC events in a match object **/
-  UInt_t EventsInMatch(const CbmMatch* match);
+  CbmMatch EventsInMatch(const CbmMatch* match);
 
 
 private:                                  // members