public void Update(ScanResult result)
		{
			foreach (var tuple in result.ConvertAreaToPositions())
			{
				UpdatePosition(tuple.Item1, tuple.Item2);
			}

			UpdatePosition(result.StairsDown, (uint) TileFlags.STAIR_DOWN);
			UpdatePosition(result.StairsUp, (uint) TileFlags.STAIR_UP);
		}
		public void Update(ScanResult result)
		{
			if (result.Updates != null)
			{
				var charUpdate = result.Updates
									   .Where(x => x.Character != null)
									   .LastOrDefault(x => x.Character.Id == Id);
				if (charUpdate != null)
				{
					Update(charUpdate.Character);
				}

				var inventoryUpdate = result.Updates.LastOrDefault(x => x.Inventory != null);
				if (inventoryUpdate != null) Inventory = inventoryUpdate.Inventory;
			}


			XPos = result.XPos;
			YPos = result.YPos;
			CurrentMap = result.Map;

			_visibleItems = result.Items;
			_visibleEntities = result.Entities;
			_visibleArea = result.ConvertAreaToPositions().Select(x => x.Item1);
		}
		private void AddUpdateMessages(ScanResult result)
		{
			if (result.Updates == null) return;
			foreach (var update in result.Updates.Where(x => x.Message != null))
			{
				AddMessage(update.Message);
			}
		}
		private Character UpdatePlayer(string playerId, ScanResult result)
		{
			var player = GetPlayer(playerId);
			player.Update(result);
			return player;
		}
		private void StoreDamageStatistics(ScanResult result, string playerId)
		{
			if (result.Updates == null) return;
			var player = GetPlayer(playerId);

			try
			{
				foreach (var update in result.Updates)
				{
					if (update.Message == null) continue;
					var match = Regex.Match(update.Message, "\\[" + playerId + "\\]\\sscored\\sa\\shit\\s\\[damage\\s(?<damage>\\d+)\\]");
					if (!match.Success) continue;
					var damage = Int32.Parse(match.Groups["damage"].Captures[0].Value);
					var stats = new DamageStatistics(player.WieldedWeaponName, damage, player.Strength, player.Level);
					_damageStorage.Store(stats);
				}
			}
			catch (Exception ex)
			{
				AddMessage(ex.Message);
			}
		}
		private void Update(string playerId, ScanResult scanResult)
		{
			if (scanResult.Error != null)
			{
				if (scanResult.Error == "Unable to find character object" ||
					scanResult.Error == "could not find a character by that id")
				{
					if (_currentParty.ContainsKey(playerId))
					{
						_currentParty.Remove(playerId);
					}

					return;
				}

				AddMessage(scanResult.Error);
				return;
			}

			var player = UpdatePlayer(playerId, scanResult);

			var map = GetOrAddMap(scanResult.Map);
			map.Update(scanResult);

			if (map.HasChanges())
			{
				_mapStorage.Store(map);
			}

			StoreDamageStatistics(scanResult, playerId);
			AddUpdateMessages(scanResult);

			if (player.Position.Equals(GetGoalForPlayer(playerId)))
			{
				RemoveGoalForPlayer(playerId);
			}

			if (player.Position.Equals(GetTempGoalForPlayer(playerId)))
			{
				RemoveTempGoalForPlayer(playerId);
			}

			if (PlayerHasAttackMode(playerId) || PlayerHasPvPMode(playerId))
			{
				if (player.HitPoints < (player.MaxHitPoints/2))
				{
					QuickQuaff(playerId, x => x.IsHealingPotion);
				}

				// Just some temporary ai stuff for the player...
				//------------------------------------------------
				var numberOfItems = player.Inventory.Length;
				if (numberOfItems < 10)
				{
					var potion = player.VisibleItems
					                   .Where(item => Equals(item.Position, player.Position))
					                   .Select(item => GetInfoFor(item.Id))
					                   .Where(item => item.IsPotion)
					                   .FirstOrDefault(item => !item.IsGaseousPotion);
					if (potion != null)
					{
						PickUpItem(playerId);
						numberOfItems++;
					}
				}

				var monsterPositions = GetMonsters(player)
					.OrderBy(x => x.Position.Distance(player.Position))
					.Select(x => x.Position);

				var enemyPositions = GetEnemyCharacters(player)
					.OrderBy(x => x.Position.Distance(player.Position))
					.Select(x => x.Position);

				var potionPositions = player.VisibleItems
				                      .Where(item => GetInfoFor(item.Id).IsPotion)
				                      .Where(item => !GetInfoFor(item.Id).IsGaseousPotion)
				                      .OrderBy(item => item.Position.Distance(player.Position))
				                      .Select(x => x.Position);

				Position potionPos = null;
				Position enemyPos = null;
				Position monsterPos = null;

				if (numberOfItems < 10)
				{
					potionPos = potionPositions.FirstOrDefault();
				}

				if (PlayerHasAttackMode(playerId))
				{
					monsterPos = monsterPositions.FirstOrDefault();
				}

				if (PlayerHasPvPMode(playerId))
				{
					enemyPos = enemyPositions.FirstOrDefault();
				}

				var nextPos = new[]{potionPos,monsterPos,enemyPos}
					.Where(pos => pos != null)
					.OrderBy(pos => pos.Distance(player.Position))
					.FirstOrDefault();

				if (nextPos != null)
				{
					SetTempGoalForPlayer(playerId, nextPos);
				}
				else
				{
					RemoveTempGoalForPlayer(playerId);
				}

				//------------------------------------------------

			}

			if (player.HitPoints <= 0)
			{
				AddMessage(string.Format("{0} [{1}] is dead!!! AAArrrghhh!!!", player.Name, player.Id));
				DeleteCharacter(playerId);
			}
		}