/// <summary>
 /// Publish a new text-only notification
 /// </summary>
 /// <param name="topic"></param>
 /// <param name="severity"></param>
 /// <param name="message"></param>
 public void Publish(Notification.Topic topic, Notification.Severity severity, string message)
 {
     Publish(topic, severity, message, element =>
     {
         var textElement  = new TextElement();
         textElement.text = message;
         element.Add(textElement);
     });
 }
 internal NotificationBuilder(long id, DateTime publishedOn, Notification.Topic topic, Notification.Severity severity,
                              string rawMessage, Notification.PopulateNotificationMessage populateNotificationMessage)
 {
     this.id          = id;
     this.publishedOn = publishedOn;
     this.topic       = topic;
     this.severity    = severity;
     this.rawMessage  = rawMessage;
     this.populateNotificationMessage = populateNotificationMessage;
 }
        /// <summary>
        /// Publish a new notification
        /// </summary>
        /// <param name="topic"></param>
        /// <param name="severity"></param>
        /// <param name="rawMessage"></param>
        /// <param name="populateNotificationMessage"></param>
        /// <param name="avoidDuplicates"></param>
        public void Publish(Notification.Topic topic, Notification.Severity severity, string rawMessage, Notification.PopulateNotificationMessage populateNotificationMessage, bool avoidDuplicates = true)
        {
            var publishedOn = DateTime.Now.ToUniversalTime();

            foreach (var existingNotificationBuilder in m_NotificationBuilders)
            {
                if (existingNotificationBuilder.topic == topic &&
                    existingNotificationBuilder.severity == severity &&
                    existingNotificationBuilder.rawMessage == rawMessage &&
                    (avoidDuplicates || (publishedOn - existingNotificationBuilder.publishedOn) <= TimeSpan.FromMilliseconds(k_DuplicateNotificationMillisecondsThreshold))
                    )
                {
                    //Duplicate messages should at least be a minimum amount of time apart and specifically requested. We don't want spam.
                    return;
                }
            }

            var notificationBuilder = new NotificationBuilder(GetNextNotificationId(), publishedOn, topic, severity, rawMessage, populateNotificationMessage);

            //TODO eventually: add analytics to keep track of this notification
            //TODO eventually: if we want to add auto-dismissal, a notification should either be listening on events or another system needs to keep track of auto-dismiss notifications
            //Chances are the new notification is actually the most recent, so add it as the last element, then sort by desc date if required,
            //but most likely won't do anything and won't take too much time
            m_NotificationBuilders.Add(notificationBuilder);
            m_NotificationBuilders.Sort((notification1, notification2) => notification2.publishedOn.CompareTo(notification1.publishedOn));
            foreach (var subscriber in m_SubscribersByTopic[topic])
            {
                try
                {
                    //We can be vulnerable here since subscribers could crash and prevent other subscribers to receive the notification
                    //Hopefully each Subscriber will be robust enough that it won't happen. But worst case, we will output the error.
                    subscriber.ReceiveNotification(notificationBuilder.BuildNotification());
                }
                catch (Exception ex)
                {
                    Debug.LogException(ex);
                }
            }
        }