@Override
 public NotificationResult findNotificationsAfterEpoch(
     CallingContext context, Long lastEpochSeen) {
   NotificationResult result = new NotificationResult(currentEpoch);
   for (long epoch = lastEpochSeen; epoch < currentEpoch; epoch++) {
     NotificationInfo info = notifications.get(epoch);
     String originKernelId = info.getKernelId();
     // prevent kernel from receiving notifications from itself, which can cause race conditions
     if (originKernelId != null && originKernelId.equals(context.getContext())) {
       continue;
     }
     result.addId(info.getId());
   }
   return result;
 }
 @Override
 public String publishNotification(
     CallingContext context, String referenceId, String content, String contentType) {
   String uuid = IDGenerator.getUUID();
   NotificationInfo info = new NotificationInfo();
   info.setId(uuid);
   info.setWho(context.getUser());
   info.setContent(content);
   info.setReference(referenceId);
   info.setEpoch(currentEpoch);
   info.setWhen(new Date());
   info.setContentType(contentType);
   info.setKernelId(context.getContext());
   currentEpoch++;
   notifications.put(info.getEpoch(), info);
   notificationsById.put(info.getId(), info);
   return uuid;
 }