public IEnumerator CheckForPossibleTransitionAndDoIt(Action<bool> setIsRunningBool, float waitForSeconds, HPlayerModel model, params FactQuery[] queries)
		{
			if ((currStoryElement == null) || (currStoryElement.neighborStateID.Count == 0)) yield break;
			setIsRunningBool(true);
			foreach (uint nextStateID in currStoryElement.neighborStateID)
			{
				// take the next possible story state
				StoryElement se = StoryElement.GetByID(nextStateID);

				// and each criteria in it
				int criteriaCount = se.transitionToCriteria.Count;
				foreach(KeyValuePair<uint, StoryElement.CriteriaValue> c in se.transitionToCriteria)
				{
					// check HPlayerModel
					HPlayerModel.Trait t = HPlayerModel.Trait.TryGetTrait(c.Key);
					if (t != null)
					{
						if (c.Value.compareTo(c.Value.value, (int)model.GetNodeValue(t)))
							criteriaCount--;
					}
					else
					{
						// if criteria is not in a HPlayerModel
						// check against all queries
						foreach (FactQuery q in queries)						
						{
							int value = 0;
							// try get the concept value from player/world/... facts
							FactQuery.Concept concept = (FactQuery.Concept)c.Key;
							//Debug.Log (concept);
							if (q.TryGetFactValue(concept, out value))
							{
								// if it matches with the laws criteria, continue
								if (c.Value.compareTo(value, c.Value.value))
									criteriaCount--;
								// query doesn't contain the corresponding fact value, move to next query
								else
									continue;
							}
						}
					}
					// return in 3 seconds and resume work
					yield return new WaitForSeconds(3);
					
					// if matching law with the most criteria was found
					if (criteriaCount == 0)
					{
						se.ApplyToGameplay();
						Messenger.Broadcast("A slight change in the story is coming right up!");
						StoryManager.currStoryElement = se;
                        goto BreakForTimeX;                     // I'm going to hell for his. I just know it. Please forgive me!
					}
				}
			}
        BreakForTimeX:
			yield return new WaitForSeconds(waitForSeconds);
            setIsRunningBool(false);
            yield break;
		}
		public IEnumerator ConvertDataToStoryElements(uint id, Action<StoryElement> setRootCallback)
		{
			string data;
			int count = 0;
			bool rootAssigned = false;

			// Normal StoryElement
			// data = "4:10|2,5:6|1?spawnenemy!0:1,2;";
			// Who: Player, Destroyed_Asteroids > 0 => Spawnasteroids();"
			
			// Add some storyElements for debugging - ToDo: Store in an extra file.
			// Root story element: Players arrives at the asteroid field (ist's a dummy!)
			data = "0:0|0?donothing!0:1,2";
			// First node: Players stats to mine on those asteroids (uint80 == float0.8)
			data += ";10002:80|2?asteroidminingstarted!1:2,3";
			// Second node: Players starts to attack the strange folks
			data += ";10001:80|2?playerattacks!2:3,4,5";
			// Third node: Players destroys asteroid
			data += ";10003:80|2?playerdestroysasteroid!3:2,6";
			// Fourth node: Strange folks attacks the players, if there are less players than strange folks (<3)
			data += ";100:2|1?attackallplayers!4:7,9";
			// Fifth node: Strange folks runs like chicken if there are more players than strange folks (>3)
			data += ";100:2|2?fleefromplayers!5:7";
			// Sixth node: Rebel fleet arrives when there are no asteroids left
			data += ";104:0|0?spawnrebels!6:8,9";
			// Seventh node: Players win the battle against the strange volks
			data += ";105:0|0?gamewon!7:-1";
			// Eigth node: Players win the battle against the rebel fleet
			data += ";106:0|0?gamewon!8:-1";
			// Ninth node: Players loose the battle
			data += ";100:0|0?gameover!9:-1";
			
			Debug.Log("Story Collection contains already " + StoryElement.collection.Count + " elements.");
			
			string[] storyElements = data.Split(';');
			foreach (string sElement in storyElements)
			{
				StoryElement se = new StoryElement();
				count++;

				string[] criteriaResponse = sElement.Split('?');
				string[] criteriaResponseID = criteriaResponse[1].Split('!');
				string[] IDs = criteriaResponseID[1].Split(':');
				se.ID = Convert.ToUInt32(IDs[0]);
				string[] toIDs = IDs[1].Split(',');
				foreach (string toID in toIDs)
				{
					int tmpID = Convert.ToInt32(toID);
					if (tmpID >= 0) se.neighborStateID.Add((uint)tmpID);
				}
				if (!criteriaResponse[1].Contains("null")) se.stateResponse = criteriaResponseID[0];
				string[] criteria = criteriaResponse[0].Split(',');
				foreach (string c in criteria)
				{
					string[] keyValue = c.Split(':');
					string[] valueCompare = keyValue[1].Split('|');
					uint key = uint.MaxValue, compareType = uint.MaxValue;
					int value = int.MaxValue;
					
					key = Convert.ToUInt32(keyValue[0]);
					value = Convert.ToInt32(valueCompare[0]);
					compareType = Convert.ToUInt32(valueCompare[1]);
					
					if ((key == uint.MaxValue) || (value == int.MaxValue) || (compareType == uint.MaxValue))
						Console.WriteLine("ERROR (StoryElement): Input string is not a sequence of digits.");
					
					se.AddTransitionCriteria(key, value, compareType);
				}
				
				if (!rootAssigned)
				{
					setRootCallback(se);
					rootAssigned = true;
				}

				//yield return null;
			}
			
			Debug.Log(count + " new StoryElements added!");
			
			yield break;
		}
		public static StoryElement GetByID(uint ID)
		{
			StoryElement returnSE = new StoryElement(true);
			foreach (StoryElement se in collection)
			{
				if (se.ID == ID) returnSE = se;
			}
			return returnSE;
		}
		public static void LoadAllFromDatabase()
		{
			// This is needed to load all laws from the database at start. (Coroutines can't be static unfortunately)
			StoryElement dummy = new StoryElement(true);
			Coroutiner.StartCoroutine(dummy.ConvertDataToStoryElements(0, result => currStoryElement = result));
		}