public async Task TrackAsync(ClientUsageRecord record)
        {
            Guard.ArgumentNotNull(nameof(record), record);
            Guard.ArgumentNotNull(nameof(record.ClientId), record.ClientId);
            Guard.ArgumentNotNull(nameof(record.GrantType), record.GrantType);
            Guard.ArgumentNotNull(nameof(record.DateTime), record.DateTime);
            Guard.ArgumentNotNull(nameof(record.EndPointKey), record.EndPointKey);

            DateTime dateTimeUtcCurrentDay =
                new DateTime(record.DateTime.Year, record.DateTime.Month, record.DateTime.Day);
            DateTime dateTimeUtcNextDay = dateTimeUtcCurrentDay.AddDays(1);

            lock (ClientRecords)
            {
                var query = from item in ClientRecords
                            let c = item as IAggregatedClientUsageRecordWrite
                                    where (c.ClientId == record.ClientId) &&
                                    (c.GrantType == record.GrantType) &&
                                    (c.EndPointKey == record.EndPointKey) &&
                                    (dateTimeUtcCurrentDay == c.DateRange.Item1 && dateTimeUtcNextDay == c.DateRange.Item2)
                                    select item;
                IAggregatedClientUsageRecordReadWrite currentAggregatedClientUsageRecord = query.FirstOrDefault();
                if (currentAggregatedClientUsageRecord == null)
                {
                    currentAggregatedClientUsageRecord = new AggregatedClientUsageRecord()
                    {
                        ClientId    = record.ClientId,
                        EndPointKey = record.EndPointKey,
                        GrantType   = record.GrantType,
                        DateRange   = (dateTimeUtcCurrentDay, dateTimeUtcNextDay)
                    };
                    ClientRecords.Add(currentAggregatedClientUsageRecord);
                }

                IAggregatedClientUsageRecordWrite writer = currentAggregatedClientUsageRecord;

                writer.Count += 1;
            }
        }
        public async Task <IRequestTrackerResult> PostEvaluateAsync(IdentityServerRequestRecord requestRecord, bool error)
        {
            if (requestRecord.Client == null)
            {
                // not for us
                return(null);
            }
            if (error)
            {
                return(null);
            }

            var clientId    = requestRecord.Client.ClientId;
            var endpointKey = requestRecord.EndpointKey;
            var context     = requestRecord.HttpContext;
            var grantType   = "";

            if (HttpMethods.IsPost(context.Request.Method))
            {
                if (context.Request.HasFormContentType)
                {
                    var values = context.Request.Form.AsNameValueCollection();
                    grantType = values.Get("grant_type");
                }
            }

            var record = new ClientUsageRecord()
            {
                ClientId    = clientId,
                DateTime    = DateTime.UtcNow,
                EndPointKey = endpointKey,
                GrantType   = grantType
            };
            await _clientUsageStore.TrackAsync(record);

            return(null);
        }