code: void processEvent(Event e) {
      assert !_processed;
      // Event e = _events[idx];
      if (e.isSend()) {
        _sends.put(e, new ArrayList<TimelineSnapshot.Event>());
        for (Event otherE : _events) {
          if ((otherE != null) && (otherE != e) && (!otherE.equals(e)) && otherE._blocked
            && otherE.match(e)) {
            _edges.put(otherE, e);
            _sends.get(e).add(otherE);
            otherE._blocked = false;
          }
        }
      } else { // look for matching send, otherwise set _blocked
        assert !_edges.containsKey(e);
        int senderIdx = e.packH2O().index();
        if (senderIdx < 0) { // binary search did not find member, should not happen?
          // no possible sender - return and do not block
          Log.warn("no sender found! port = " + e.portPack() + ", ip = " + e.addrPack().toString());
          return;
        }
        Event senderCnd = _events[senderIdx];
        if (senderCnd != null) {
          if (isSenderRecvPair(senderCnd, e)) {
            _edges.put(e, senderCnd.clone());
            _sends.get(senderCnd).add(e);
            return;
          }
          senderCnd = senderCnd.clone();
          while (senderCnd.prev()) {
            if (isSenderRecvPair(senderCnd, e)) {
              _edges.put(e, senderCnd);
              _sends.get(senderCnd).add(e);
              return;
            }
          }
        }
        e._blocked = true;
      }
      assert (e == null) || (e._eventIdx < TimeLine.MAX_EVENTS);
    }
docs: Process new event. For sender, check if there are any blocked receives
  waiting for this send. For receiver, try to find matching sender, otherwise
  block.
  
  @param e