protected virtual async Task OnNewInitiative(InitiativeCreatedEventArgs e, CancellationToken token)
        {
            var initiative = e.Initiative;
            var owner      = e.Owner;

            using (LogContext.PushProperty("InitiativeId", initiative.Id))
            {
                _logger.Information("Begin OnNewInitiative for initiative {InitiativeId}", initiative.Id);
                Stopwatch watch = new Stopwatch();
                watch.Start();

                PersonData personData;
                try
                {
                    personData = await GetPersonData(owner.GetEmail());
                }
                catch (Exception err)
                {
                    _logger.Error(err, "Unable to get PersonData for {InitiativeId} from {EmailAddress}: {ErrorMessage}", initiative.Id, owner.GetEmail(), err.Message);
                    throw;
                }

                string workOrderId;
                try
                {
                    workOrderId = await CreateWorkOrder(initiative, personData);
                }
                catch (Exception err)
                {
                    _logger.Error(err, "Unable to get create a workOrder for initiative {InitiativeId} from {EmailAddress}: {ErrorMessage}", initiative.Id, owner.GetEmail(), err.Message);
                    throw;
                }

                DateTime?eta;
                try
                {
                    _initiativeStatusEtaService.Authenticate(e.Owner);
                    eta = await _initiativeStatusEtaService.GetStatusEtaFromNowUtcAsync(InitiativeStatus.Submit);
                }
                catch (Exception err)
                {
                    _logger.Error(err, "Unable to get ETA for Submitted status");
                    throw;
                }

                await SendWorkOrderCreatedMessage(initiative, owner, workOrderId, eta, e.SkipEmailNotification);

                _logger.Information("Processed OnNewInitiative for initiative {InitiativeId} in {ElapsedMilliseconds}ms", initiative.Id, watch.ElapsedMilliseconds);
            }
        }
        protected virtual async Task <WorkOrderUpdatedEventArgs> TryProcessWorkItemChanged(
            OutputMapping1GetListValues workItem)
        {
            // we need to convert the Assignee 3+3 to an email so Octava can use it
            // from manual inspection in looks like this field is the "assignee 3+3":
            string assignee3and3 = workItem.ASLOGID;

            PersonData assignee = null;

            if (string.IsNullOrWhiteSpace(assignee3and3))
            {
                _logger.Information("Assignee is empty");
            }
            else
            {
                _logger.Information("Looking up assignee with 3+3 {User3and3}", assignee3and3);
                try { assignee = await _peopleService.GetPersonAsync(assignee3and3); }
                catch (Exception err) { _logger.Warning(err, "Unable to get email for Remedy Work Order Assignee {User3and3}: {ErrorMessage}", assignee3and3, err.Message); }
            }

            InitiativeStatus?newInitiativeStatus = GetInitiativeStatusForRemedyStatus(workItem.Status);

            if (newInitiativeStatus == null)
            {
                _logger.Information("Abondining updated work item because an appropriate InitiativeStatus could not be determined from the Remedy Status {WorkItemStatus}", workItem.Status);
                return(null);
            }

            DateTime?etaUtc = null;

            try
            {
                etaUtc = await _initiativeStatusEtaService.GetStatusEtaFromNowUtcAsync(newInitiativeStatus.Value);
            }
            catch (Exception err) { _logger.Warning(err, "Unable to get an updated ETA for initiative status {InitiativeStatus}: {ErrorMessage}", newInitiativeStatus.Value, err.Message); }

            try
            {
                // Note the ToUniversalTime on the Last_Modified_Date:
                // this works because this service runs in the same time zone as Remedy.
                var args = new WorkOrderUpdatedEventArgs()
                {
                    WorkOrderId         = workItem.InstanceId,
                    UpdatedDateUtc      = workItem.Last_Modified_Date.ToUniversalTime(),
                    RemedyStatus        = workItem.Status.ToString(),
                    UpdatedStatus       = newInitiativeStatus.Value.ToString(),
                    AssigneeEmail       = assignee?.Email,
                    AssigneeDisplayName = assignee?.DisplayName,
                    EtaUtc = etaUtc
                };
                await _initiativeMessageSender.SendWorkOrderUpdatedAsync(args);

                return(args);
            }
            catch (Exception e)
            {
                Guid correlationId = Guid.NewGuid();
                _logger.Error(e, $"Unable to process work item changed (correlationId {correlationId}): {e.Message}");
                _logger.Debug($"Work item change that caused processing error (correlationId {correlationId}): { workItem }");
                throw;
            }
        }