/// <summary>
		/// Activate the necromancer. First he detects and then moves.
		/// </summary>
		/// <param name="gameState">Game state.</param>
		/// <param name="detectedHero">Force this hero to be detected.</param>
		/// <param name="roll">Force the necromancer roll.</param>
		/// <param name="heroesToIgnore">Heroes that are ignored due to Elusive Spirit or Blinding Black</param>
		public NecromancerActivationResult Activate (GameState gameState, 
		                                             Hero detectedHero = null,
		                                             int? roll = null, 
		                                             int[] heroesToIgnore = null)
		{
			var result = new NecromancerActivationResult ();
			result.NecromancerRoll = roll.HasValue ? roll.Value : _d6GeneratorService.RollDemBones ();
			result.OldLocationId = gameState.Necromancer.LocationId;

			result.DarknessIncrease = 1 + gameState.Locations.SelectMany (x => x.Blights).Count (x => x.Name == "Desecration");
			if (gameState.Heroes.ShieldOfRadianceActive && result.NecromancerRoll == 6) {
				result.DarknessIncrease--;
				result.Notes += "Shield of Radiance triggered" + Environment.NewLine;
			}

			gameState.Darkness += result.DarknessIncrease;
				
			//detect
			if (detectedHero == null)
				result.DetectedHero = Detect (gameState, result.NecromancerRoll, heroesToIgnore);
			else
				result.DetectedHero = detectedHero;

			//move
			var newLocation = Move (gameState, detectedHero, result.NecromancerRoll);
			result.NewLocationId = newLocation.Id;

			//spawn
			var spawnResult = Spawn(gameState, newLocation, result.NecromancerRoll);
			result.NewBlights = spawnResult.NewBlights;
			result.SpawnQuest = spawnResult.SpawnQuest;

			return result;
		}
		public void Initialise (Hero detectedHero, int necromancerRoll, int [] heroesToIgnore = null)
		{
			Task.Run (() => {
				_pendingGameState = Application.CurrentGame.Clone ();
				SetResult (_necromancerService.Activate (_pendingGameState, detectedHero, necromancerRoll, heroesToIgnore));
				IsLoading = false;
			});
		}
		private void OnHeroUpdated(HeroViewModel sender, Hero hero){
			HeroRows.SingleOrDefault (x => x.Hero.Id == hero.Id).Updated ();
		}
		public HeroSummaryViewModel (Hero hero)
		{
			Hero = hero;
		}
		public AcolyteViewModel (Hero hero)
			: base(hero)
		{
		}
		/// <summary>
		/// Moves the necromancer in the detected hero's direction or via the die roll if no hero passed in.
		/// Return the Location that the necromancer moved to.
		/// </summary>
		/// <param name="gameState">Game state.</param>
		/// <param name="detectedHero">Detected hero.</param>
		/// <param name="roll">Roll.</param>
		public Location Move (GameState gameState, Hero detectedHero, int roll)
		{
			var currentLocation = gameState.Locations.Single (x => x.Id == gameState.Necromancer.LocationId);
			Location newLocation = null;

			if (detectedHero != null) {
				var heroLocation = gameState.Locations.Single (x => x.Id == detectedHero.LocationId);
				var necromancerLocation = gameState.Locations.First (x => x.Id == gameState.Necromancer.LocationId);
				//if the necromancer can reach the hero go directly to them
				if (necromancerLocation.Pathways.Contains (heroLocation.Id) || gameState.GatesActive)
					newLocation = heroLocation;
				else {
					//the common locations between the hero and necromancer are the ones that the necro should move along
					var commonLocationIds = necromancerLocation.Pathways.Intersect (heroLocation.Pathways).ToArray ();
					var index = new Random ().Next (0, commonLocationIds.Length - 1);
					newLocation = gameState.Locations.Single (x => x.Id == commonLocationIds [index]);
				}
			} else
				newLocation = gameState.Locations.Single (x => x.Id == currentLocation.Pathways [roll - 1]);

			if (gameState.Heroes.InvisibleBarrierLocationId.HasValue
				&& gameState.Heroes.InvisibleBarrierLocationId == newLocation.Id) 
			{
				newLocation = currentLocation;
				gameState.Heroes.InvisibleBarrierLocationId = null;
				//result.Notes += string.Format ("Invisible Barrier deactivated and cancelled the Necromancer's movement. {0}", Environment.NewLine);
			}

			gameState.Necromancer.LocationId = newLocation.Id;

			return newLocation;
		}
		public HeroViewModel (Hero hero)
		{
			_hero = hero;
		}
		public static HeroViewModel Create (Hero hero)
		{
			if (hero is Seer)
				return new SeerViewModel (hero as Seer);
			else if (hero is Acolyte)
				return new AcolyteViewModel (hero as Acolyte);
			else if (hero is Paragon)
				return new ParagonViewModel (hero as Paragon);
			else if (hero is Ranger)
				return new RangerViewModel (hero as Ranger);
			else if (hero is Scholar)
				return new ScholarViewModel (hero as Scholar);
			else if (hero is Shaman)
				return new ShamanViewModel (hero as Shaman);
			else if (hero is Valkyrie)
				return new ValkyrieViewModel (hero as Valkyrie);
			else if (hero is Wayfarer)
				return new WayfarerViewModel (hero as Wayfarer);
			else if (hero is Wizard)
				return new WizardViewModel (hero as Wizard);
			else if (hero is Conjurer)
				return new ConjurerViewModel (hero as Conjurer);
			else if (hero is Tamer)
				return new TamerViewModel (hero as Tamer);
			else
				return new HeroViewModel (hero);
		}