/// <summary>
        /// Get the last known location and calculate speed. Then Publish back to the MQTT Broker.
        /// </summary>
        /// <param name="mqttClient">The MQTT Client</param>
        /// <param name="topic">The most recent topic</param>
        /// <returns>A Task which performs the operation</returns>
        public async Task Work(IManagedMqttClient mqttClient, CarCoordinates topic)
        {
            try
            {
                // Get lastCoordinate from key
                var carInformation = _carCache.Read(topic.CarIndex);

                // Get Geo coordinate
                var lastGeoCoordinate    = new GeoCoordinate(carInformation.LastLocation.Latitude, carInformation.LastLocation.Longitude);
                var currentGeoCoordinate = new GeoCoordinate(topic.Location.Latitude, topic.Location.Longitude);

                // Calculate the distance and the speed
                var distance = lastGeoCoordinate.GetDistanceTo(currentGeoCoordinate);
                var speed    = Speedometer.CalculateSpeedMph(distance, carInformation.LastRecordedTimestamp,
                                                             topic.TimeStamp);

                // using the total distance driven
                var carValues = _carCache.Values().ToList();
                var position  = carValues.OrderByDescending(x => x.TotalDistanceTraveled)
                                .Select(x => x.CarIndex).ToList().IndexOf(topic.CarIndex) + 1;

                //  has the car position changed
                if (position != carInformation.Position)
                {
                    //  who is now in that position?
                    var carInPreviousPos = carValues.FirstOrDefault(x => x.Position == position);

                    if (carInPreviousPos != null)
                    {
                        var eventStatus = new EventMessage()
                        {
                            Timestamp = topic.TimeStamp,
                            Text      =
                                $"Car {carInPreviousPos.CarIndex} races ahead of Car {carInformation.CarIndex} in a dramatic overtake."
                        };
                        var messageEvent = MessageBuilder.CreateMessage(eventStatus);

                        //  send event for the overtake
                        await mqttClient.PublishAsync(messageEvent);
                    }
                }

                // Set information car information
                carInformation.TotalDistanceTraveled += distance;
                carInformation.LastRecordedTimestamp  = topic.TimeStamp;
                carInformation.LastLocation           = topic.Location;
                carInformation.Position = position;
                _carCache.AddOrUpdate(topic.CarIndex, carInformation);

                // The response
                var messageSpeed    = MessageBuilder.CreateMessage(CarStatus.SpeedStatus(topic, speed));
                var messagePosition = MessageBuilder.CreateMessage(CarStatus.PositionStatus(topic, position));

                await mqttClient.PublishAsync(messageSpeed);

                await mqttClient.PublishAsync(messagePosition);
            }
            catch (KeyNotFoundException)
            {
                // Must be first time round, add topic to dictionary
                var carInformation = new CarInformation()
                {
                    LastLocation          = topic.Location,
                    LastRecordedTimestamp = topic.TimeStamp,
                    Position = 0,
                    TotalDistanceTraveled = 0,
                    CarIndex = topic.CarIndex
                };

                _carCache.AddOrUpdate(topic.CarIndex, carInformation);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
            }
        }