void IUserSaver.UpdateLastVisitedHotZone(Guid userId, Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.LastVisitedHotZoneId = hotZoneId;
                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.UpdateBaseLine(Guid userId, int maxAttackPower, int maxEnergy)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.BaseLineAttackPower = maxAttackPower;
                userDto.BaseLineEnergy = maxEnergy;
                dataContext.SubmitChanges();
            }
        }
        void IUserCountsSaver.AddHotZonesDestroyed(Guid userId, int hotzoneCount)
        {
            AddCountIfNeeded(userId);
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserCountDto userCountDto = GetUserCount(undeadEarthDataContext, userId);

                userCountDto.HotZonesDestroyed += hotzoneCount;
                undeadEarthDataContext.SubmitChanges();
            }
        }
        void IUserSaver.AddMoney(Guid userId, int amount)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.Money = userDto.Money + amount;
                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.UpdateUserInventorySlot(Guid userId, int newInventorySlotAmount)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                if (userDto == null)
                {
                    throw new InvalidOperationException("User does not exist.");
                }

                userDto.PossibleItemAmount = newInventorySlotAmount;

                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.UpdateCurrentBaseAttack(Guid userId, int attackpower)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.CurrentBaseAttack = attackpower;
                dataContext.SubmitChanges();
            }
        }
        void ISafeHouseItemSaver.SaveItemInSafeHouse(Guid safeHouseId, Guid itemId, Guid userId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.SafeHouseItemDtos
                    .InsertOnSubmit(new SafeHouseItemDto
                                        {
                                            Id = Guid.NewGuid(),
                                            ItemId = itemId,
                                            SafeHouseId = safeHouseId,
                                            UserId = userId
                                        });

                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.SetUserLevel(Guid userId, int level)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                if (userDto == null)
                {
                    throw new InvalidOperationException("User does not exist.");
                }

                userDto.Level = level;

                dataContext.SubmitChanges();
            }
        }
        private void AddCountIfNeeded(Guid userId)
        {
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                undeadEarthDataContext.ReadUncommited();

                if (undeadEarthDataContext.UserCountsDtos.Any(u => u.UserId == userId) == false)
                {
                    UserCountDto userCountDto = new UserCountDto
                    {
                        Id = Guid.NewGuid(),
                        UserId = userId,
                        Miles = 0,
                        HotZonesDestroyed = 0,
                        PeakAttack = 0,
                        ZombiesKilled = 0
                    };

                    undeadEarthDataContext.UserCountsDtos.InsertOnSubmit(userCountDto);
                    undeadEarthDataContext.SubmitChanges();
                }
            }
        }
        void IUserItemSaver.SaveUserItem(Guid userId, Guid itemId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.UserItemDtos.InsertOnSubmit(new UserItemDto
                                                        {
                                                            UserItemId = Guid.NewGuid(),
                                                            ItemId = itemId,
                                                            UserId = userId
                                                        });

                dataContext.SubmitChanges();
            }
        }
        void IUserCountsSaver.AddMoney(Guid userId, int money)
        {
            AddCountIfNeeded(userId);
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserCountDto userCountDto = GetUserCount(dataContext, userId);

                userCountDto.AccumulatedMoney += money;
                dataContext.SubmitChanges();
            }
        }
        void IUserCountsSaver.AddZombiePacksDestroyed(Guid userId, int zombiePacksDestroyed)
        {
            AddCountIfNeeded(userId);
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserCountDto userCountDto = GetUserCount(undeadEarthDataContext, userId);

                userCountDto.ZombiePacksDestroyed += zombiePacksDestroyed;
                undeadEarthDataContext.SubmitChanges();
            }
        }
        void IUserCountsSaver.RecordPeakZombiesDestroyed(Guid userId, int attackPower)
        {
            AddCountIfNeeded(userId);
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserCountDto userCountDto = GetUserCount(undeadEarthDataContext, userId);

                if (userCountDto.PeakAttack < attackPower)
                {
                    userCountDto.PeakAttack = attackPower;
                    undeadEarthDataContext.SubmitChanges();
                }
            }
        }
        void IUserSaver.SetCurrentBaseSightRadius(Guid userId, int userBaseSightRadius)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.BaseSightRadius = userBaseSightRadius;
                dataContext.SubmitChanges();
            }
        }
        void ISafeHouseItemSaver.RemoveSafeHouseItem(Guid safeHouseUserItemId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.SafeHouseItemDtos.DeleteAllOnSubmit(
                                    dataContext.SafeHouseItemDtos.Where(c => c.Id == safeHouseUserItemId));

                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.SaveLastSightRadius(Guid userId, int sightRadius, DateTime time)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.LastSightRadius = sightRadius;
                userDto.LastSightRadiusDate = time;
                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.UpdateUserLocation(Guid userId, double lattitude, double longitude)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto userDto = dataContext.GetUserById(userId);

                HotZoneDto hotZone = dataContext.HotZoneDtos.SingleOrDefault(c => c.Latitude == (decimal)lattitude && c.Longitude == (decimal)longitude);

                if (userDto != null)
                {
                    userDto.Latitude = (decimal)lattitude;
                    userDto.Longitude = (decimal)longitude;
                    userDto.ZoneId = hotZone != null ? hotZone.Id : userDto.ZoneId;
                    dataContext.SubmitChanges();
                }
            }
        }
        void IUserSaver.UpdateAttackForDifficultyCalculation(Guid userId, int newBaseAttack)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                if (userDto == null)
                {
                    throw new InvalidOperationException("User does not exist.");
                }

                userDto.BaseLineAttackPower = newBaseAttack;

                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.UpdateZone(Guid userId, Guid hotZoneId)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                dataContext.ReadUncommited();

                UserDto userDto = dataContext.GetUserById(userId);

                if (userDto != null)
                {
                    userDto.ZoneId = hotZoneId;

                    dataContext.SubmitChanges();
                }
            }
        }
        void IUserSaver.UpdateCurrentBaseEnergy(Guid userId, int energy)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.CurrentBaseEnergy = energy;
                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.SaveLastEnergy(Guid userId, int energy, DateTime time)
        {
            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserById(userId);

                userDto.LastEnergy = energy;
                userDto.LastEnergyDate = time;
                dataContext.SubmitChanges();
            }
        }
        void IUserSaver.InsertUser(Guid userId, long facebookUserId, string name, Guid startingLocation, int baseAttackPower, int baseEnergy)
        {
            if(facebookUserId == 0)
            {
                throw new InvalidOperationException("Facebook UserId cannot be 0.");
            }

            using (UndeadEarthDataContext dataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserDto userDto = dataContext.GetUserByFacebookUserId(facebookUserId);
                if(userDto != null)
                {
                    throw new InvalidOperationException("User already exists.");
                }

                userDto = new UserDto
                {
                    Id = userId,
                    FacebookUserId = facebookUserId,
                    ZoneId = startingLocation,
                    CurrentBaseAttack = baseAttackPower,
                    CurrentBaseEnergy = baseEnergy,
                    LastVisitedHotZoneId = startingLocation,
                    BaseLineAttackPower = baseAttackPower,
                    BaseLineEnergy = baseEnergy,
                    DisplayName = name,
                    Level = 1,
                    Email = string.Empty,
                    LocationId = startingLocation,
                    Money = 0,
                    PossibleItemAmount = 5
                };

                dataContext.UserDtos.InsertOnSubmit(userDto);
                dataContext.SubmitChanges();
            }
        }
        void IUserCountsSaver.AddMiles(Guid userId, int miles)
        {
            AddCountIfNeeded(userId);
            using (UndeadEarthDataContext undeadEarthDataContext = new UndeadEarthDataContext(_connectionString))
            {
                UserCountDto userCountDto = GetUserCount(undeadEarthDataContext, userId);

                userCountDto.Miles += miles;
                undeadEarthDataContext.SubmitChanges();
            }
        }