public static BestLap AsModel(this BestLapViewModel lapViewModel, VehicleViewModel vehicle, bool isMetricUnits, bool isPublic, string userName, long trackId, IEnumerable <TrackSectorViewModel> sectors) { DateTimeOffset utcLapTimestamp = lapViewModel.Timestamp.ToUniversalTime(); var hashAlgorithm = new HMACSHA256(Convert.FromBase64String(Constants.APP_LAPVERIFICATION_HASHKEY)); string verificationText = string.Format("{0}{1}{2}{3}{4}{5}", Constants.APP_LAPVERIFICATION_PREFIX, trackId, vehicle.Key.ToString().ToUpperInvariant(), lapViewModel.LapTime.Ticks, utcLapTimestamp.ToString("yyyy-MM-ddTHH:mm:ss.fffK"), userName); string verificationCode = Convert.ToBase64String(hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(verificationText))); var model = new BestLap { LapTimeTicks = lapViewModel.LapTime.Ticks, Timestamp = utcLapTimestamp, VehicleId = vehicle.Id, VehicleClass = (int)vehicle.Class, Vehicle = vehicle.AsModel(), VerificationCode = verificationCode, TrackId = trackId, IsPublic = isPublic, UserName = userName, IsUnofficial = lapViewModel.IsUnofficial, GpsDeviceName = lapViewModel.GpsDeviceName, WeatherCondition = lapViewModel.WeatherCondition, AmbientTemperature = lapViewModel.AmbientTemperature }; var dataPoints = new List <LapDataPoint>(); var geographicDataPoints = lapViewModel.DataPoints.Where(dp => dp != null && dp.Latitude.HasValue && dp.Longitude.HasValue); foreach (var sector in sectors) { LapDataPointViewModel lastDataPoint = null; LapDataPointViewModel previousDataPoint = null; foreach (var dataPoint in geographicDataPoints.SkipWhile(dp => dp.SectorNumber != sector.SectorNumber)) { if (dataPoint.SectorNumber != sector.SectorNumber) { break; } lastDataPoint = dataPoint; if (previousDataPoint != null && (dataPoint.ElapsedTime - previousDataPoint.ElapsedTime < TimeSpan.FromMilliseconds(900d))) { continue; } previousDataPoint = dataPoint; dataPoints.Add(dataPoint.AsBestLapDataPoint(isMetricUnits)); } // Last data point used for split times dataPoints.Add(lastDataPoint.AsBestLapDataPoint(isMetricUnits)); } model.DataPoints = dataPoints; return(model); }