public TickerResponse Tick(TickerRequest tickRequest)
 {
     TickerResponse response = new TickerResponse();
     var validationResult = Validation.Validate<TickerRequest>(tickRequest);
     try
     {
         Traveler traveler = _repository.FindBy<Traveler>(t => t.TravelerID == _currentTravelerId);
         if (validationResult.IsValid)
         {
             LocationService locationSvc = new LocationService(_locationDeterminator, _repository, _geoCoder);
             locationSvc.UpdateTravelerCoordinates(traveler, tickRequest.IPAddress);
             response.City = traveler.City;
             response.Country = traveler.Country;
             response.Latitude = traveler.Latitude;
             response.Longtitude = traveler.Longtitude;
         }
         response.NewMessagesCount = traveler.Messages.Count(m => m.IsRead == false && m.FolderID == (int)FolderType.Inbox);
         response.MarkSuccess();
     }
     catch (Exception ex)
     {
         ReportError(ex, response);
     }
     return response;
 }
        public SearchResponse Search(bool includeOfflineTravelers, int index, int count, string ipAddress = null, double lat = 0, double lon = 0)
        {
            SearchResponse response = new SearchResponse();
            LocationService locSvc = new LocationService(_locationDeterminator, _repository, _geoCoder);
            APIKeyService apiKeySvc = new APIKeyService(_repository, _apiKeyGen);
            //TODO: split up method to separate methods
            try
            {
                Traveler currentTraveler = _repository.FindBy<Traveler>(t => t.TravelerID == _currentTravelerId);
                if (!String.IsNullOrEmpty(ipAddress) || (lat != 0 && lon != 0))
                {
                    //This part is optional. It will happen only if the client will explicitly the location, either by IP address or coordinates
                    //otherwise the IP address of the client who made the request will be used to determine the location

                    GeoCoordinates coords = new GeoCoordinates { Latitude = lat, Longtitude = lon };

                    if (!String.IsNullOrEmpty(ipAddress))
                    {
                        locSvc.UpdateTravelerCoordinates(currentTraveler, ipAddress);
                    }
                    else if (currentTraveler.IsLocationChanged(coords))
                    {
                        currentTraveler.Latitude = coords.Latitude;
                        currentTraveler.Longtitude = coords.Longtitude;
                        //TODO: obtain city and country by given coords otherwise coords.City and coords.Country are always null
                        currentTraveler.City = coords.City;
                        currentTraveler.Country = coords.Country;
                    }
                }
                else
                {
                    //Normally this will happen
                    locSvc.UpdateTravelerCoordinates(currentTraveler, APIKeyService.CurrentTravelerIPAddress);
                }
                //Updating traveler's location
                _repository.Save<Traveler>(currentTraveler);
                _repository.Commit();

                //All online travelers in the system
                IEnumerable<Guid> allOnlineTravelersFromCache = apiKeySvc.GetCurrentlyActiveTravelers();

                //Raw results of travelers around - including offline users
                PagedList<Traveler> travelersAroundRawResults = locSvc.GetListOfTravelersWithin(RADIUS, index, count, currentTraveler);

                if (!includeOfflineTravelers)
                {
                    //Gets only travelers around who are online at this moment out of the 10 rows from the DB
                    var onlineTravelersAround = travelersAroundRawResults.Entities.Where(t => allOnlineTravelersFromCache.Contains(t.TravelerID));

                    //if we have another page from the DB (10 more travelers) and the maximum rows for the page hasn't been reached then loop until
                    //all the rows for the page are full or until the last page has reached
                    while (travelersAroundRawResults.HasNext && onlineTravelersAround.Count() < count)
                    {
                        index = index + count; //index for the next page
                        //get next page from the DB
                        travelersAroundRawResults = locSvc.GetListOfTravelersWithin(RADIUS, index, count, currentTraveler);
                        //take only as many as needed to fill up the page
                        var onlineTravelersFromNextPage = travelersAroundRawResults.Entities.Where(t => allOnlineTravelersFromCache.Contains(t.TravelerID)).Take(count - onlineTravelersAround.Count());
                        //pile up the results
                        onlineTravelersAround = onlineTravelersAround.Concat(onlineTravelersFromNextPage);

                    }
                    travelersAroundRawResults = onlineTravelersAround.ToPagedList(index, count);
                }

                //Marks which travelers are online
                for (int i = 0; i < travelersAroundRawResults.Entities.Count; i++)
                {
                    if (allOnlineTravelersFromCache.Contains(travelersAroundRawResults.Entities[i].TravelerID))
                    {
                        travelersAroundRawResults.Entities[i].IsOnline = true;
                    }
                }

                //Converts to the suitable data contract for serialization
                response.Travelers = travelersAroundRawResults.ConvertToTravelerViewList();
                response.MarkSuccess();
            }
            catch (Exception ex)
            {
                ReportError(ex, response);
            }
            return response;
        }