/// <summary>
        /// Calculates for how long the sensor stayed in each state during the hour.
        /// </summary>
        /// <param name="clientsHistory">The clients states changes history for the given hour (can be empty).</param>
        /// <param name="sensorsHistory">The sensors states changes history for the give hour (can be empty).</param>
        /// <param name="previousClientHistory">The most recent client state change prior to the hour we calculating for (can be null).</param>
        /// <param name="previousSensorHistory">The most recent sensor state change prior to the hour we calculating for (can be null).</param>
        /// <returns>Dictionary where is the key is a state and the value is for how long in ms the sensor stayed in this state</returns>
        private Dictionary<int, long> calculateHourlyStats(
            List<ClientStateHistory> clientsHistory,
            List<SensorStateHistory> sensorsHistory,
            ClientStateHistory previousClientHistory,
            SensorStateHistory previousSensorHistory)
        {
            IDictionary<ClientStateHistory, List<SensorStateHistory>> sensorStatesByClient = new SortedDictionary<ClientStateHistory, List<SensorStateHistory>>();

            var result = new Dictionary<int, long>() { { (int)StatState.Offline, 0 }, { (int)StatState.Available, 0 }, { (int)StatState.Occupied, 0 } };

            if (clientsHistory.Count == 0 && previousClientHistory == null)
            {
                result[(int)StatState.Offline] = ((long)TimeSpan.FromHours(1).TotalMilliseconds);
                return result;
            }

            //No Data on current hour, take previous stats and set for full hour 
            if (clientsHistory.Count == 0 && sensorsHistory.Count == 0)
            {
                if (previousClientHistory == null || previousClientHistory.IsOnline == false)
                {
                    result[-1] = ((long)TimeSpan.FromHours(1).TotalMilliseconds);
                }

                if (previousClientHistory != null && previousClientHistory.IsOnline && previousSensorHistory != null)
                {
                    result[previousSensorHistory.State] = ((long)TimeSpan.FromHours(1).TotalMilliseconds);
                }
                return result;
            }

            //Set previous and set to beginging of current hour
            if (previousClientHistory != null)
            {
                previousClientHistory.StateChangedTimestamp = getStartingHour(clientsHistory, sensorsHistory);
                sensorStatesByClient.Add(previousClientHistory, new List<SensorStateHistory>());

                if (previousSensorHistory != null)
                {
                    previousSensorHistory.StateChangedTimestamp = previousClientHistory.StateChangedTimestamp;
                    sensorStatesByClient[previousClientHistory].Add(previousSensorHistory);
                }
            }

            //clients list to dictionary keys
            foreach (var clientHistoryRecord in clientsHistory)
            {
                sensorStatesByClient.Add(clientHistoryRecord, new List<SensorStateHistory>());
            }

            //triage sensors to relevant client records
            foreach (var sensorHistRecord in sensorsHistory)
            {
                //going backwards.
                var key = sensorStatesByClient.Keys.OrderByDescending(c => c.StateChangedTimestamp).FirstOrDefault(c => c.StateChangedTimestamp <= sensorHistRecord.StateChangedTimestamp);
                if (key != null)//otherwise we ignore.. we have sensorChangeState before first ever Client State change!!
                {
                    sensorStatesByClient[key].Add(sensorHistRecord);
                }

            }

            //for each client set a dummy first sensor record (with time equal to  begining of the range..)
            foreach (var client in sensorStatesByClient)
            {
                if (client.Key.IsOnline)
                {
                    var closest = FindClosestSensorHistory(client.Key.StateChangedTimestamp, sensorsHistory) ?? previousSensorHistory ?? new SensorStateHistory() { State = (int)StatState.Available, StateChangedTimestamp = client.Key.StateChangedTimestamp };
                    if (!client.Value.Any() || client.Value.First().StateChangedTimestamp != client.Key.StateChangedTimestamp)
                    {
                        client.Value.Insert(0, new SensorStateHistory() { StateChangedTimestamp = client.Key.StateChangedTimestamp, State = closest.State });
                    }
                }
            }

            //calc offline
            var orderedKeys = sensorStatesByClient.Keys.OrderBy(c => c.StateChangedTimestamp);
            DateTime from = orderedKeys.First().StateChangedTimestamp.ToRoundHourBottom();

            foreach (var key in orderedKeys)
            {
                if (key.IsOnline == true)
                {
                    result[-1] += ((long)(key.StateChangedTimestamp - from).TotalMilliseconds);
                }
                from = key.StateChangedTimestamp;
            }
            //add the rest
            if (!orderedKeys.Last().IsOnline)
            {
                result[-1] += orderedKeys.Last().StateChangedTimestamp.MsTillTheEndOfHour();
            }


            //calc available/occupied for each online range
            DateTime to = orderedKeys.First().StateChangedTimestamp.ToRoundHourUpper();

            foreach (var key in orderedKeys.Reverse())
            {
                if (key.IsOnline == true)
                {
                    for (int i = sensorStatesByClient[key].Count - 1; i >= 0; i--)
                    {
                        var sensorState = sensorStatesByClient[key][i];
                        result[sensorState.State] += ((long)(to - sensorStatesByClient[key][i].StateChangedTimestamp).TotalMilliseconds);
                        to = sensorState.StateChangedTimestamp;
                    }
                }
                to = key.StateChangedTimestamp;
            }

            return result;


        }
 private Dictionary<int, long> invokeCalculateHourlyStats(
             List<ClientStateHistory> clientsHistory,
             List<SensorStateHistory> sensorsHistory,
             ClientStateHistory previousClientHistory,
             SensorStateHistory previousSensorHistory)
 {
     var result = _testedMethod.Invoke(_processor, parameters: new object[] {
         clientsHistory, sensorsHistory, previousClientHistory, previousSensorHistory });
     return result as Dictionary<int, long>;
 }