diff --git a/Assets/Scenes/RiverWorld.unity b/Assets/Scenes/RiverWorld.unity
index a633ddf7a9272cb656f3b8f2cc02ff1314337d73..a44f23726bc6aff29bdbae85b8a5c600df9bd0dd 100644
--- a/Assets/Scenes/RiverWorld.unity
+++ b/Assets/Scenes/RiverWorld.unity
@@ -14372,8 +14372,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: ca8bc7e0b1ca4384192fec35c8699cd9, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
-  snapZoneTop: {fileID: 0}
-  snapZoneBottom: {fileID: 0}
+  minimalSolutionHight: 6
 --- !u!1001 &645585536
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -15844,24 +15843,6 @@ Transform:
     type: 3}
   m_PrefabInstance: {fileID: 704600771}
   m_PrefabAsset: {fileID: 0}
---- !u!1 &707042057 stripped
-GameObject:
-  m_CorrespondingSourceObject: {fileID: 7000045644623408183, guid: 8590393c51194934a95cdc2075fc4dec,
-    type: 3}
-  m_PrefabInstance: {fileID: 6999573641241424516}
-  m_PrefabAsset: {fileID: 0}
---- !u!114 &707042060
-MonoBehaviour:
-  m_ObjectHideFlags: 0
-  m_CorrespondingSourceObject: {fileID: 0}
-  m_PrefabInstance: {fileID: 0}
-  m_PrefabAsset: {fileID: 0}
-  m_GameObject: {fileID: 707042057}
-  m_Enabled: 1
-  m_EditorHideFlags: 0
-  m_Script: {fileID: 11500000, guid: 4298702f3af5da54c9f8d43308ecb160, type: 3}
-  m_Name: 
-  m_EditorClassIdentifier: 
 --- !u!1001 &715240475
 PrefabInstance:
   m_ObjectHideFlags: 0
@@ -59575,6 +59556,11 @@ PrefabInstance:
       propertyPath: m_AnchoredPosition.y
       value: 75
       objectReference: {fileID: 0}
+    - target: {fileID: 293934904593747527, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_IsActive
+      value: 1
+      objectReference: {fileID: 0}
     - target: {fileID: 293934904814280933, guid: b996060e27da25c498842defc1996d84,
         type: 3}
       propertyPath: preferredStartScrollName
@@ -59585,10 +59571,20 @@ PrefabInstance:
       propertyPath: m_AnchoredPosition.y
       value: 400
       objectReference: {fileID: 0}
+    - target: {fileID: 293934905101627528, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_MethodName
+      value: LevelReset
+      objectReference: {fileID: 0}
+    - target: {fileID: 293934905101627528, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_OnClick.m_PersistentCalls.m_Calls.Array.data[0].m_TargetAssemblyTypeName
+      value: Restart, Assembly-CSharp
+      objectReference: {fileID: 0}
     - target: {fileID: 293934905101627533, guid: b996060e27da25c498842defc1996d84,
         type: 3}
       propertyPath: m_IsActive
-      value: 0
+      value: 1
       objectReference: {fileID: 0}
     - target: {fileID: 293934905461160920, guid: b996060e27da25c498842defc1996d84,
         type: 3}
@@ -59735,6 +59731,31 @@ PrefabInstance:
       propertyPath: m_Name
       value: FrameITUI
       objectReference: {fileID: 0}
+    - target: {fileID: 293934906265310054, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_text
+      value: Restart Level
+      objectReference: {fileID: 0}
+    - target: {fileID: 293934906265310054, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_textAlignment
+      value: 65535
+      objectReference: {fileID: 0}
+    - target: {fileID: 293934906265310054, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_TextStyleHashCode
+      value: -1183493901
+      objectReference: {fileID: 0}
+    - target: {fileID: 293934906265310054, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_VerticalAlignment
+      value: 512
+      objectReference: {fileID: 0}
+    - target: {fileID: 293934906265310054, guid: b996060e27da25c498842defc1996d84,
+        type: 3}
+      propertyPath: m_HorizontalAlignment
+      value: 2
+      objectReference: {fileID: 0}
     - target: {fileID: 293934906431221846, guid: b996060e27da25c498842defc1996d84,
         type: 3}
       propertyPath: m_AnchorMax.x
diff --git a/Assets/Scripts/HideUI.cs b/Assets/Scripts/HideUI.cs
index d75c46ffd555b47bf83a305f5e6a4da07179ddee..3b3c4dfb4ce56d744a8cb1d12982a2b11715afda 100644
--- a/Assets/Scripts/HideUI.cs
+++ b/Assets/Scripts/HideUI.cs
@@ -55,11 +55,11 @@ void Update()
         else if (Input.GetButton(modifier))
         {
             if (Input.GetButtonDown(modundo))
-                Facts.undo();
+                LevelFacts.undo();
             else if (Input.GetButtonDown(modredo))
-                Facts.redo();
+                LevelFacts.redo();
             else if (Input.GetButtonDown(modreset))
-                Facts.softreset();
+                LevelFacts.softreset();
         }
         
         /*
diff --git a/Assets/Scripts/InteractionEngine/Character_Animations/TaskCharakterAnimation.cs b/Assets/Scripts/InteractionEngine/Character_Animations/TaskCharakterAnimation.cs
index 1352120d04d7d4c2565a9221ade0832f14a09205..95100e226e4fced509ec37b55daffaba57a90949 100644
--- a/Assets/Scripts/InteractionEngine/Character_Animations/TaskCharakterAnimation.cs
+++ b/Assets/Scripts/InteractionEngine/Character_Animations/TaskCharakterAnimation.cs
@@ -26,7 +26,7 @@ public class TaskCharakterAnimation : MonoBehaviour
     private float rotationTime = 2;
     private bool happy = false;
 
-    private bool happyAnimationDone = false;
+    private bool LelvelVerifiedSolved = false;
     private float happyTimer = 0;
     private float happyTime = 7.5f;
 
@@ -72,10 +72,10 @@ void Update()
             //Face walkAroundObject to Player (but only on y-Axis, so ignore x-and z-axis)
             currentTransform.LookAt(new Vector3(player.transform.position.x, currentTransform.position.y, player.transform.position.z));
 
-            if(checkGameSolved() && taskCharacterAddressed && !happyAnimationDone)
+            if(taskCharacterAddressed && !LelvelVerifiedSolved && checkGameSolved())
             {
                 startHappy();
-                happyAnimationDone = true;
+                //LelvelVerifiedSolved = true;
             }
 
             return;
diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
index 3cba5f0c5f7e0faf3b0a505cb3d0284fa934c507..b114c50134a041bb5b51f12d757724d3a60db7e8 100644
--- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
@@ -5,44 +5,21 @@
 
 public static class CommunicationEvents
 {
-    public class HitEvent : UnityEvent<RaycastHit>
-    {
+    public class HitEvent : UnityEvent<RaycastHit> { }
 
-    }
-    public class FactEvent : UnityEvent<Fact>
-    {
+    public class FactEvent : UnityEvent<Fact> { }
 
-    }
+    public class MouseOverFactEvent : UnityEvent<Transform> { }
 
-    public class MouseOverFactEvent : UnityEvent<Transform>
-    {
+    public class ToolModeEvent : UnityEvent<int> { }
 
-    }
-    public class ToolModeEvent : UnityEvent<int> {
+    public class ShinyEvent : UnityEvent<Fact> { }
 
-    }
+    public class SignalEvent : UnityEvent { }
 
-    public class ShinyEvent : UnityEvent<Fact> {
+    public class AnimationEvent : UnityEvent<GameObject, string> { }
 
-    }
-
-    public class SignalEvent : UnityEvent {
-
-    }
-
-    public class AnimationEvent : UnityEvent<GameObject, String> {
-
-    }
-
-    public class AnimationEventWithUri : UnityEvent<String>
-    {
-
-    }
-
-    public class AnimationEventWithUris : UnityEvent<List<string>>
-    {
-
-    }
+    public class AnimationEventWithUris : UnityEvent<List<string>> { }
 
 
 
@@ -52,7 +29,7 @@ public class AnimationEventWithUris : UnityEvent<List<string>>
     public static ToolModeEvent ToolModeChangedEvent = new ToolModeEvent();
     public static FactEvent AddFactEvent = new FactEvent();
     public static FactEvent RemoveFactEvent = new FactEvent();
-    
+
     public static ShinyEvent PushoutFactEvent = new ShinyEvent();
     public static ShinyEvent PushoutFactEndEvent = new ShinyEvent();
     public static ShinyEvent PushoutFactFailEvent = new ShinyEvent();
@@ -60,12 +37,8 @@ public class AnimationEventWithUris : UnityEvent<List<string>>
     public static SignalEvent gameSucceededEvent = new SignalEvent();
     public static SignalEvent gameNotSucceededEvent = new SignalEvent();
     public static SignalEvent LevelReset = new SignalEvent();
-
     public static SignalEvent NewAssignmentEvent = new SignalEvent();
 
-    //TODO: Remove this event after CompletionsDemo isn't necessary anymore
-    public static AnimationEventWithUri parameterDisplayHint = new AnimationEventWithUri();
-
     public static AnimationEvent ScrollFactHintEvent = new AnimationEvent();
     public static FactEvent AnimateExistingFactEvent = new FactEvent();
     public static FactEvent AnimateNonExistingFactEvent = new FactEvent();
@@ -76,8 +49,10 @@ public class AnimationEventWithUris : UnityEvent<List<string>>
     //-------------------------------Global Variables-------------------------------------
 
     //Global Level-List of Facts
-    public static FactOrganizer Facts = new FactOrganizer();
-
+    public static FactOrganizer LevelFacts = new FactOrganizer(true);
+    public static FactOrganizer SolutionManager = new FactOrganizer(false);
+    //TODO? List<[HashSet<string>, FactComparer]>
+    public static List<Fact> Solution = new List<Fact>();
 
     public static bool ServerRunning = true;
     public static string ServerAdress = "localhost:8085";
diff --git a/Assets/Scripts/InteractionEngine/Fact.cs b/Assets/Scripts/InteractionEngine/Fact.cs
index e7709422845922222a2b9db4f7db27aa92245689..f9481f1732253ad4df4945515c094dab45497dc9 100644
--- a/Assets/Scripts/InteractionEngine/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/Fact.cs
@@ -59,6 +59,7 @@ public static AddFactResponse sendAdd(string path, string body)
     }
 }
 
+[Serializable]
 public abstract class Fact
 {
     public GameObject Representation;
@@ -67,8 +68,14 @@ public abstract class Fact
     protected string _URI;
     public string Label;
 
+    protected FactOrganizer _Facts;
+
     private static int LabelId = 0;
 
+    protected Fact(FactOrganizer organizer)
+    {
+        this._Facts = organizer;
+    }
 
     public void rename(string newLabel)
     {
@@ -117,6 +124,8 @@ public int GetFirstEmptyID()
 
 public abstract class FactWrappedCRTP<T>: Fact where T: FactWrappedCRTP<T>
 {
+    protected FactWrappedCRTP(FactOrganizer organizer) : base(organizer) { }
+
     public override bool Equivalent(Fact f2)
     {
         return Equivalent(this, f2);
@@ -124,7 +133,7 @@ public override bool Equivalent(Fact f2)
 
     public override bool Equivalent(Fact f1, Fact f2)
     {
-        return EquivalentWrapped((T)f1, (T)f2);
+        return f1.GetType() == f2.GetType() && EquivalentWrapped((T)f1, (T)f2);
     }
 
     protected abstract bool EquivalentWrapped(T f1, T f2);
@@ -141,12 +150,12 @@ public abstract class AbstractLineFact: FactWrappedCRTP<AbstractLineFact>
     //only for temporary Use of LineFacts.
     //public AbstractLineFact() { }
 
-    public AbstractLineFact(string pid1, string pid2)
+    public AbstractLineFact(string pid1, string pid2, FactOrganizer organizer): base(organizer)
     {
         set_public_members(pid1, pid2);
     }
 
-    public AbstractLineFact(string pid1, string pid2, string backendURI)
+    public AbstractLineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(organizer)
     {
         set_public_members(pid1, pid2);
         this._URI = backendURI;
@@ -157,8 +166,8 @@ private void set_public_members(string pid1, string pid2)
         this.Pid1 = pid1;
         this.Pid2 = pid2;
         this.Label = generateLabel();
-        PointFact pf1 = Facts[pid1] as PointFact;
-        PointFact pf2 = Facts[pid2] as PointFact;
+        PointFact pf1 = _Facts[pid1] as PointFact;
+        PointFact pf2 = _Facts[pid2] as PointFact;
         this.Dir = (pf2.Point - pf1.Point).normalized;
     }
 
@@ -183,9 +192,9 @@ public abstract class AbstractLineFactWrappedCRTP<T>: AbstractLineFact where T:
     //only for temporary Use of LineFacts.
     //public AbstractLineFactWrappedCRTP() { }
 
-    public AbstractLineFactWrappedCRTP (string pid1, string pid2) : base(pid1, pid2) { }
+    public AbstractLineFactWrappedCRTP (string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer) { }
 
-    public AbstractLineFactWrappedCRTP (string pid1, string pid2, string backendURI) : base(pid1, pid2, backendURI) { }
+    public AbstractLineFactWrappedCRTP (string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) { }
 
     protected override bool EquivalentWrapped(AbstractLineFact f1, AbstractLineFact f2)
     {
@@ -203,7 +212,7 @@ public class PointFact : FactWrappedCRTP<PointFact>
     public Vector3 Normal;
 
 
-    public PointFact(Vector3 P, Vector3 N)
+    public PointFact(Vector3 P, Vector3 N, FactOrganizer organizer) : base(organizer)
     {
         this.Point = P;
         this.Normal = N;
@@ -229,7 +238,7 @@ public PointFact(Vector3 P, Vector3 N)
         Debug.Log(this.URI);
     }
 
-    public PointFact(float a, float b, float c, string uri)
+    public PointFact(float a, float b, float c, string uri, FactOrganizer organizer) : base(organizer)
     {
         this.Point = new Vector3(a, b, c);
         this.Normal = new Vector3(0, 1, 0);
@@ -245,7 +254,7 @@ public static PointFact parseFact(Scroll.ScrollFact fact) {
             float a = (float)((OMF)df.arguments[0]).f;
             float b = (float)((OMF)df.arguments[1]).f;
             float c = (float)((OMF)df.arguments[2]).f;
-            return new PointFact(a, b, c, uri);
+            return new PointFact(a, b, c, uri, LevelFacts);
         }
         else {
             return null;
@@ -286,12 +295,19 @@ protected override bool EquivalentWrapped(PointFact f1, PointFact f2)
 
 public class LineFact : AbstractLineFactWrappedCRTP<LineFact>
 {
-    public LineFact(string pid1, string pid2, string backendURI) : base(pid1, pid2, backendURI) { }
+    public float Distance;
+
+    public LineFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer)
+    {
+        SetDistance();
+    }
 
-    public LineFact(string pid1, string pid2) : base(pid1, pid2)
+    public LineFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
     {
-        PointFact pf1 = Facts[pid1] as PointFact;
-        PointFact pf2 = Facts[pid2] as PointFact;
+        SetDistance();
+
+        PointFact pf1 = _Facts[pid1] as PointFact;
+        PointFact pf2 = _Facts[pid2] as PointFact;
 
         string p1URI = pf1.URI;
         string p2URI = pf2.URI;
@@ -323,9 +339,9 @@ public static LineFact parseFact(Scroll.ScrollFact fact)
         string pointAUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[0]).uri;
         string pointBUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[1]).uri;
 
-        if (Facts.ContainsKey(pointAUri)
-         && Facts.ContainsKey(pointBUri))
-            return new LineFact(pointAUri, pointBUri, uri);
+        if (LevelFacts.ContainsKey(pointAUri)
+         && LevelFacts.ContainsKey(pointBUri))
+            return new LineFact(pointAUri, pointBUri, uri, LevelFacts);
 
         //If dependent facts do not exist return null
         else {
@@ -334,14 +350,14 @@ public static LineFact parseFact(Scroll.ScrollFact fact)
     }
     protected override string generateLabel()
     {
-        return "[" + Facts[Pid1].Label + Facts[Pid2].Label + "]";
+        return "[" + _Facts[Pid1].Label + _Facts[Pid2].Label + "]";
     }
 
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid2].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid2].Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
@@ -352,24 +368,29 @@ protected override bool EquivalentWrapped(LineFact f1, LineFact f2)
             //(f1.Pid1 == f2.Pid2 && f1.Pid2 == f2.Pid1))
             return true;
 
-        PointFact p1f1 = (PointFact)Facts[f1.Pid1];
-        PointFact p2f1 = (PointFact)Facts[f1.Pid2];
-        PointFact p1f2 = (PointFact)Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)Facts[f2.Pid2];
+        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
+        PointFact p2f1 = (PointFact)_Facts[f1.Pid2];
+        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
+        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
 
         return (p1f1.Equivalent(p1f2) && p2f1.Equivalent(p2f2))
             ;//|| (p1f1.Equivalent(p2f2) && p2f1.Equivalent(p1f2));
     }
+
+    private void SetDistance()
+    {
+        this.Distance = Vector3.Distance(((PointFact)_Facts[Pid1]).Point, ((PointFact)_Facts[Pid2]).Point);
+    }
 }
 
 public class RayFact : AbstractLineFactWrappedCRTP<RayFact>
 {
-    public RayFact(string pid1, string pid2, string backendURI) : base(pid1, pid2, backendURI) { }
+    public RayFact(string pid1, string pid2, string backendURI, FactOrganizer organizer) : base(pid1, pid2, backendURI, organizer) { }
 
-    public RayFact(string pid1, string pid2) : base(pid1, pid2)
+    public RayFact(string pid1, string pid2, FactOrganizer organizer) : base(pid1, pid2, organizer)
     {
-        PointFact pf1 = Facts[pid1] as PointFact;
-        PointFact pf2 = Facts[pid2] as PointFact;
+        PointFact pf1 = _Facts[pid1] as PointFact;
+        PointFact pf2 = _Facts[pid2] as PointFact;
 
         string p1URI = pf1.URI;
         string p2URI = pf2.URI;
@@ -401,9 +422,9 @@ public static RayFact parseFact(Scroll.ScrollFact fact)
             string pointAUri = ((OMS)((OMA)((Scroll.ScrollSymbolFact)fact).df).arguments[0]).uri;
             string pointBUri = ((OMS)((OMA)((Scroll.ScrollSymbolFact)fact).df).arguments[1]).uri;
 
-            if (Facts.ContainsKey(pointAUri)
-             && Facts.ContainsKey(pointBUri))
-                return new RayFact(pointAUri, pointBUri, uri);
+            if (LevelFacts.ContainsKey(pointAUri)
+             && LevelFacts.ContainsKey(pointBUri))
+                return new RayFact(pointAUri, pointBUri, uri, LevelFacts);
 
             //If dependent facts do not exist return null
         }
@@ -412,7 +433,7 @@ public static RayFact parseFact(Scroll.ScrollFact fact)
 
     protected override string generateLabel()
     {
-        return "–" + Facts[Pid1].Label + Facts[Pid2].Label + "–";
+        return "–" + _Facts[Pid1].Label + _Facts[Pid2].Label + "–";
     }
 
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform) {
@@ -428,9 +449,9 @@ protected override bool EquivalentWrapped(RayFact f1, RayFact f2)
         if (!Math3d.IsApproximatelyParallel(f1.Dir, f2.Dir))
             return false;
 
-        PointFact p1f1 = (PointFact)Facts[f1.Pid1];
-        PointFact p1f2 = (PointFact)Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)Facts[f2.Pid2];
+        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
+        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
+        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
 
         return Math3d.IsPointApproximatelyOnLine(p1f1.Point, f1.Dir, p1f2.Point)
             && Math3d.IsPointApproximatelyOnLine(p1f1.Point, f1.Dir, p2f2.Point);
@@ -442,14 +463,14 @@ public class OnLineFact : FactWrappedCRTP<OnLineFact>
     //Id's of the Point and the Line it's on
     public string Pid, Rid;
 
-    public OnLineFact(string pid, string rid)
+    public OnLineFact(string pid, string rid, FactOrganizer organizer) : base(organizer)
     {
         this.Pid = pid;
         this.Rid = rid;
         this.Label = generateLabel();
 
-        PointFact pf = Facts[pid] as PointFact;
-        RayFact rf = Facts[rid] as RayFact;
+        PointFact pf = _Facts[pid] as PointFact;
+        RayFact rf = _Facts[rid] as RayFact;
         string pURI = pf.URI;
         string rURI = rf.URI;
 
@@ -477,7 +498,7 @@ public OnLineFact(string pid, string rid)
         Debug.Log(this.URI);
     }
 
-    public OnLineFact(string pid, string rid, string uri)
+    public OnLineFact(string pid, string rid, string uri, FactOrganizer organizer) : base(organizer)
     {
         this.Pid = pid;
         this.Rid = rid;
@@ -491,9 +512,9 @@ public static OnLineFact parseFact(Scroll.ScrollFact fact)
         string lineUri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[0]).uri;
         string pointUri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).uri;
 
-        if (Facts.ContainsKey(pointUri)
-         && Facts.ContainsKey(lineUri))
-            return new OnLineFact(pointUri, lineUri, uri);
+        if (LevelFacts.ContainsKey(pointUri)
+         && LevelFacts.ContainsKey(lineUri))
+            return new OnLineFact(pointUri, lineUri, uri, LevelFacts);
 
         //If dependent facts do not exist return null
         else
@@ -501,7 +522,7 @@ public static OnLineFact parseFact(Scroll.ScrollFact fact)
     }
     protected override string generateLabel()
     {
-        return Facts[Pid].Label + "∈" + Facts[Rid].Label;
+        return _Facts[Pid].Label + "∈" + _Facts[Rid].Label;
     }
 
     public override Boolean hasDependentFacts()
@@ -517,8 +538,8 @@ public override string[] getDependentFactIds()
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform)
     {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Rid].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid].Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Rid].Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
@@ -533,10 +554,10 @@ protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
         if (f1.Pid == f2.Pid && f1.Rid == f2.Rid)
             return true;
 
-        PointFact pf1 = (PointFact)Facts[f1.Pid];
-        RayFact rf1 = (RayFact)Facts[f1.Rid];
-        PointFact pf2 = (PointFact)Facts[f2.Pid];
-        RayFact rf2 = (RayFact)Facts[f2.Rid];
+        PointFact pf1 = (PointFact)_Facts[f1.Pid];
+        RayFact rf1 = (RayFact)_Facts[f1.Rid];
+        PointFact pf2 = (PointFact)_Facts[f2.Pid];
+        RayFact rf2 = (RayFact)_Facts[f2.Rid];
 
         return pf1.Equivalent(pf2) && rf1.Equivalent(rf2);
     }
@@ -548,15 +569,15 @@ public class AngleFact : FactWrappedCRTP<AngleFact>
     public string Pid1, Pid2, Pid3;
     public bool is_right_angle;
 
-    public AngleFact(string pid1, string pid2, string pid3)
+    public AngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(organizer)
     {
         this.Pid1 = pid1;
         this.Pid2 = pid2;
         this.Pid3 = pid3;
 
-        PointFact pf1 = Facts[pid1] as PointFact;
-        PointFact pf2 = Facts[pid2] as PointFact;
-        PointFact pf3 = Facts[pid3] as PointFact;
+        PointFact pf1 = _Facts[pid1] as PointFact;
+        PointFact pf2 = _Facts[pid2] as PointFact;
+        PointFact pf3 = _Facts[pid3] as PointFact;
 
         float v = GetAngle(); // sets is_right_angle
         this.Label = generateLabel(); //needs is_right_angle
@@ -580,7 +601,7 @@ public AngleFact(string pid1, string pid2, string pid3)
         Debug.Log(this.URI);
     }
 
-    public AngleFact(string Pid1, string Pid2, string Pid3, string backendURI)
+    public AngleFact(string Pid1, string Pid2, string Pid3, string backendURI, FactOrganizer organizer) : base(organizer)
     {
         this.Pid1 = Pid1;
         this.Pid2 = Pid2;
@@ -614,11 +635,11 @@ public static AngleFact parseFact(Scroll.ScrollFact fact)
             pointCUri = ((OMS)((OMA)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).arguments[2]).uri;
         }
 
-        if (Facts.ContainsKey(pointAUri)
-         && Facts.ContainsKey(pointBUri)
-         && Facts.ContainsKey(pointCUri))
+        if (LevelFacts.ContainsKey(pointAUri)
+         && LevelFacts.ContainsKey(pointBUri)
+         && LevelFacts.ContainsKey(pointCUri))
 
-            return new AngleFact(pointAUri, pointBUri, pointCUri, uri);
+            return new AngleFact(pointAUri, pointBUri, pointCUri, uri, LevelFacts);
 
         else    //If dependent facts do not exist return null
             return null;
@@ -626,14 +647,14 @@ public static AngleFact parseFact(Scroll.ScrollFact fact)
 
     protected override string generateLabel()
     {
-        return (is_right_angle ? "⊾" : "∠") + Facts[Pid1].Label + Facts[Pid2].Label + Facts[Pid2].Label;
+        return (is_right_angle ? "⊾" : "∠") + _Facts[Pid1].Label + _Facts[Pid2].Label + _Facts[Pid3].Label;
     }
 
     private float GetAngle()
     {
-        PointFact pf1 = Facts[Pid1] as PointFact;
-        PointFact pf2 = Facts[Pid2] as PointFact;
-        PointFact pf3 = Facts[Pid3] as PointFact;
+        PointFact pf1 = _Facts[Pid1] as PointFact;
+        PointFact pf2 = _Facts[Pid2] as PointFact;
+        PointFact pf3 = _Facts[Pid3] as PointFact;
 
         float v = Vector3.Angle((pf1.Point - pf2.Point), (pf3.Point - pf2.Point));
         this.is_right_angle = Mathf.Abs(v - 90.0f) < 0.01;
@@ -695,9 +716,9 @@ public override string[] getDependentFactIds()
 
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform) {
         var obj = GameObject.Instantiate(prefab, Vector3.zero, Quaternion.identity, transform);
-        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid1].Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid2].Label;
-        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Facts[this.Pid3].Label;
+        obj.transform.GetChild(0).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid1].Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid2].Label;
+        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = _Facts[this.Pid3].Label;
         obj.GetComponent<FactWrapper>().fact = this;
         return obj;
     }
@@ -713,12 +734,12 @@ protected override bool EquivalentWrapped(AngleFact f1, AngleFact f2)
             //(f1.Pid1 == f2.Pid3 && f1.Pid2 == f2.Pid2 && f1.Pid3 == f2.Pid1))
             return true;
 
-        PointFact p1f1 = (PointFact)Facts[f1.Pid1];
-        PointFact p2f1 = (PointFact)Facts[f1.Pid2];
-        PointFact p3f1 = (PointFact)Facts[f1.Pid3];
-        PointFact p1f2 = (PointFact)Facts[f2.Pid1];
-        PointFact p2f2 = (PointFact)Facts[f2.Pid2];
-        PointFact p3f2 = (PointFact)Facts[f2.Pid3];
+        PointFact p1f1 = (PointFact)_Facts[f1.Pid1];
+        PointFact p2f1 = (PointFact)_Facts[f1.Pid2];
+        PointFact p3f1 = (PointFact)_Facts[f1.Pid3];
+        PointFact p1f2 = (PointFact)_Facts[f2.Pid1];
+        PointFact p2f2 = (PointFact)_Facts[f2.Pid2];
+        PointFact p3f2 = (PointFact)_Facts[f2.Pid3];
 
         return (p1f1.Equivalent(p1f2) && p2f1.Equivalent(p2f2) && p3f1.Equivalent(p3f2))
             ;//|| (p1f1.Equivalent(p3f2) && p2f1.Equivalent(p2f2) && p1f1.Equivalent(p3f2));
diff --git a/Assets/Scripts/InteractionEngine/FactComparer.cs b/Assets/Scripts/InteractionEngine/FactComparer.cs
new file mode 100644
index 0000000000000000000000000000000000000000..7259946f0fbd04e5daf53ba80f828a215498cd40
--- /dev/null
+++ b/Assets/Scripts/InteractionEngine/FactComparer.cs
@@ -0,0 +1,50 @@
+using System.Collections;
+using System.Collections.Generic;
+using UnityEngine;
+
+public abstract class FactComparer : EqualityComparer<Fact>
+{
+    protected bool search_righthanded;
+
+    protected abstract bool Compare (Fact search, Fact fact);
+
+    public FactComparer SetSearchRight()
+    {
+        search_righthanded = true;
+        return this;
+    }
+    public FactComparer SetSearchLeft()
+    {
+        search_righthanded = false;
+        return this;
+    }
+
+    public override bool Equals(Fact left, Fact right)
+    {
+        return search_righthanded ? Compare(left, right) : Compare(right, left);
+    }
+
+    public override int GetHashCode(Fact obj)
+    {
+        return 0; //obj.GetHashCode();
+    }
+}
+
+public class FactEquivalentsComparer : FactComparer
+{
+    protected override bool Compare (Fact search, Fact fact)
+    {
+        return search.Equivalent(fact);
+    }
+}
+
+class LineFactHightDirectionComparer : FactComparer
+{
+    protected override bool Compare (Fact search, Fact fact)
+    {
+        return fact is LineFact && search is LineFact
+            && Math3d.IsApproximatelyParallel(((LineFact) fact).Dir, ((LineFact) search).Dir)
+            && ((LineFact) fact).Distance > ((LineFact) search).Distance + Math3d.vectorPrecission;
+        // && Mathf.Approximately(((LineFact) x).Distance, ((LineFact) y).Distance);
+    }
+}
diff --git a/Assets/Scripts/InteractionEngine/FactComparer.cs.meta b/Assets/Scripts/InteractionEngine/FactComparer.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..a6b2fb0a967f0679396dc6fbe07665c58f90203e
--- /dev/null
+++ b/Assets/Scripts/InteractionEngine/FactComparer.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 5d7d3beaa8cf49a4d81780b5264532c1
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/InteractionEngine/FactManager.cs b/Assets/Scripts/InteractionEngine/FactManager.cs
index 89a6cc7dfb5fa894d9356e5bddff71c7c8b17999..26bb2b66879dfa02abca925557d67f120c15cbbb 100644
--- a/Assets/Scripts/InteractionEngine/FactManager.cs
+++ b/Assets/Scripts/InteractionEngine/FactManager.cs
@@ -10,38 +10,38 @@ public class FactManager : MonoBehaviour
     //TODO! communicate success/ failure
     public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep)
     {
-        return Facts[Facts.Add(fact, out exists, samestep)];
+        return LevelFacts[LevelFacts.Add(fact, out exists, samestep)];
     }
 
     public PointFact AddPointFact(RaycastHit hit, bool samestep = false)
     {
-        return (PointFact) AddFactIfNotFound(new PointFact(hit.point, hit.normal), out bool obsolete, samestep);
+        return (PointFact) AddFactIfNotFound(new PointFact(hit.point, hit.normal, LevelFacts), out bool obsolete, samestep);
     }
 
     public PointFact AddPointFact(Vector3 point, Vector3 normal, bool samestep = false)
     {
-        return (PointFact) AddFactIfNotFound(new PointFact(point, normal), out bool obsolete, samestep);
+        return (PointFact) AddFactIfNotFound(new PointFact(point, normal, LevelFacts), out bool obsolete, samestep);
     }
 
     public OnLineFact AddOnLineFact(string pid, string lid, bool samestep = false)
     {
-        return (OnLineFact)AddFactIfNotFound(new OnLineFact(pid, lid), out bool obsolete, samestep);
+        return (OnLineFact)AddFactIfNotFound(new OnLineFact(pid, lid, LevelFacts), out bool obsolete, samestep);
     }
 
     public LineFact AddLineFact(string pid1, string pid2, bool samestep = false)
     {
-        return (LineFact)AddFactIfNotFound(new LineFact(pid1, pid2), out bool obsolete, samestep);
+        return (LineFact)AddFactIfNotFound(new LineFact(pid1, pid2, LevelFacts), out bool obsolete, samestep);
     }
 
     public RayFact AddRayFact(string pid1, string pid2, bool samestep = false)
     {
-        RayFact rayFact = (RayFact)AddFactIfNotFound(new RayFact(pid1, pid2), out bool exists, samestep);
+        RayFact rayFact = (RayFact)AddFactIfNotFound(new RayFact(pid1, pid2, LevelFacts), out bool exists, samestep);
         if (exists)
             return rayFact;
 
         //Add all PointFacts on Ray as OnLineFacts
-        PointFact rayP1 = (PointFact)Facts[rayFact.Pid1];
-        PointFact rayP2 = (PointFact)Facts[rayFact.Pid2];
+        PointFact rayP1 = (PointFact)LevelFacts[rayFact.Pid1];
+        PointFact rayP2 = (PointFact)LevelFacts[rayFact.Pid2];
         int layerMask = LayerMask.GetMask("Point");
         RaycastHit[] hitsA = Physics.RaycastAll(rayP1.Point,  rayFact.Dir, Mathf.Infinity, layerMask);
         RaycastHit[] hitsB = Physics.RaycastAll(rayP2.Point, -rayFact.Dir, Mathf.Infinity, layerMask);
@@ -69,7 +69,7 @@ void AddHitIfOnLine(RaycastHit hit)
 
     public AngleFact AddAngleFact(string pid1, string pid2, string pid3, bool samestep = false)
     {
-        return (AngleFact)AddFactIfNotFound(new AngleFact(pid1, pid2, pid3), out bool obsolete, samestep);
+        return (AngleFact)AddFactIfNotFound(new AngleFact(pid1, pid2, pid3, LevelFacts), out bool obsolete, samestep);
     }
 
 }
diff --git a/Assets/Scripts/InteractionEngine/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactOrganizer.cs
index f263b041201b7b460f53dab880f10bdcaee7ebc0..dbe47e92e744019ba9c13199e84237ac3a53feea 100644
--- a/Assets/Scripts/InteractionEngine/FactOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactOrganizer.cs
@@ -7,12 +7,15 @@
 //TODO? hide base dict
 //TODO: MMT: move some functionality there
 //TODO: consequent!= samestep != dependent
-//TODO! use URI as key
 
-//PERF: avoid string as key (hash -> colission? -> strcmp[!])
+//PERF: avoid string as key (general: allocations & dict: hash -> colission? -> strcmp[!])
 
+[System.Serializable]
 public class FactOrganizer: Dictionary<string, Fact>
 {
+    // InvokeEvents?
+    private bool invoke;
+
     private Dictionary<string, meta> MetaInf = new Dictionary<string, meta>();
     private List<stepnote> Workflow = new List<stepnote>();
     // notes position in Workflow for un-/redo; the pointed to element is non-acitve
@@ -21,7 +24,7 @@ public class FactOrganizer: Dictionary<string, Fact>
     private int worksteps = 0;
     private int backlog = 0;
     // set if recently been resetted
-    private bool resetted = false;
+    private bool soft_resetted = false;
 
     private struct stepnote
     {
@@ -71,36 +74,33 @@ public meta(int workflow_id, bool active = true)
         }
     }
 
-    public FactOrganizer() : base() { }
-
-    public FactOrganizer(IDictionary<string, Fact> dictionary) : base(dictionary) { }
-
-
-    //TODO: PERF: better way than string search? -> use string as key!
-    public bool searchURI(string uri, out string found)
+    public FactOrganizer(bool invoke = false) : base()
     {
-        foreach(var element in this)
-            if (element.Value.URI.Equals(uri))
-            {
-                found = element.Key;
-                return true;
-            }
+        this.invoke = invoke;
+    }
 
-        found = null;
-        return false;
+    public FactOrganizer(IDictionary<string, Fact> dictionary, bool invoke = false) : base(dictionary)
+    {
+        this.invoke = invoke;
     }
 
+
     //TODO? MMT? PERF: O(n), every Fact-insertion
-    private bool FindEquivalent(Fact search, out Fact found)
+    private bool FindEquivalent(Fact search, out string found, out bool exact)
     // Looks for existent facts (found) which are very similar to prposed fact (search)
     // does not check active state
     {
+        if (exact = this.ContainsKey(search.URI))
+        {
+            found = search.URI;
+            return true;
+        }
+
         foreach (var entry in this)
         {
-            if (entry.Value.GetType() == search.GetType() &&
-                entry.Value.Equivalent(search))
+            if (entry.Value.Equivalent(search))
             {
-                found = entry.Value;
+                found = entry.Key;
                 return true;
             }
         }
@@ -110,7 +110,7 @@ private bool FindEquivalent(Fact search, out Fact found)
     }
 
     private void WorkflowAdd(stepnote note)
-    // prunes & adds Workflow; updates meta struct; Invokes Events
+    // prunes & adds Workflow; Invokes Events
     {
         PruneWorkflow();
 
@@ -127,18 +127,16 @@ private void WorkflowAdd(stepnote note)
         Workflow.Add(note);
         marker = Workflow.Count;
 
-        // update active info
-        meta info = MetaInf[note.Id];
-        info.active = note.creation;
-        MetaInf[note.Id] = info;
-
         InvokeFactEvent(note.creation, note.Id);
     }
 
     private void PruneWorkflow()
     // set current (displayed) state in stone; resets un-redo parameters
     {
-        if (backlog > 0)
+        if (soft_resetted)
+            this.hardreset(false);
+
+        else if (backlog > 0)
         {
             worksteps -= backlog;
             backlog = 0;
@@ -155,13 +153,6 @@ private void PruneWorkflow()
                     base.Remove(last.Id);
                     MetaInf.Remove(last.Id);
                 }
-                else
-                // update active status
-                {
-                    meta inf = MetaInf[last.Id];
-                    inf.active = !last.creation;
-                    MetaInf[last.Id] = inf;
-                }
             }
 
             // prune Worklfow down to marker
@@ -172,29 +163,35 @@ private void PruneWorkflow()
     public new void Add(string key, Fact value)
     // hide
     {
-        this.Add(value, out bool obsolete);
+        this.Add(value, out _);
     }
 
     public string Add(Fact value, out bool exists, bool samestep = false)
     // also checks for duplicates and active state
     // returns key of actual Fact
     {
-        if (resetted)
-            this.hardreset(false);
-
         string key;
-        if (exists = FindEquivalent(value, out Fact found))
-        {
-            //TODO: MMT: del 'fact' (value) in MMT (alt.: s.TODO in addFact)
 
-            key = found.URI;
-            if (MetaInf[key].active)
+        if (exists = FindEquivalent(value, out key, out bool exact))
+        {
+            if (!exact)
+                // no longer needed
+                value.delete();
+
+            if (MetaInf[key].workflow_id >= marker)
+            // check for zombie-status
+                // protect zombie from beeing pruned
+                MetaInf[key] = new meta(marker, true);
+
+            // zombies are undead!
+            else if (MetaInf[key].active)
+                // desired outcome already achieved
                 return key;
+
         }
         else
+        // brand new Fact
         {
-            //TODO: MMT: alt: insert in MMT if needed here/ on Invoke() (see WorkflowAdd)
-
             key = value.URI;
             base.Add(key, value);
             MetaInf.Add(key, new meta(marker, true));
@@ -212,11 +209,7 @@ public string Add(Fact value, out bool exists, bool samestep = false)
 
     public bool Remove(Fact value, bool samestep = false)
     {
-        if (!this.ContainsKey(value.URI))
-            return false;
-
-        this.Remove(value.URI, samestep);
-        return true;
+        return this.Remove(value.URI, samestep);
     }
 
     public bool Remove(string key, bool samestep = false)
@@ -250,20 +243,10 @@ public bool safe_dependencies(string key, out List<string> dependencies)
         int pos = MetaInf[key].workflow_id;
         dependencies.Add(key);
 
-        /* consequent != samestep != dependent
-        // get steproot
-        if (Workflow[pos].samestep)
-            pos = Workflow[pos].steplink;
-
-        // add entire step
-        for (int i = pos; i < Workflow[pos].steplink; i++)
-            dependencies.Add(Workflow[i].Id);
-        pos = Workflow[pos].steplink;
-        */
-
         // accumulate facts that are dependent of dependencies
         for (int i = pos; i < marker; i++)
         {
+            // TODO: consequent != samestep != dependent (want !consequent)
             if (!Workflow[i].creation)
             {
                 // just try
@@ -295,20 +278,23 @@ private void reversestep(int pos, bool samestep = false)
     {
         pos--;
 
-        // check for valid step (implicit reset check)
         if (pos >= marker)
+        // check for valid step (implicit reset check)
             return;
         
         for (int i = pos, stop = Workflow[pos].samestep ? Workflow[pos].steplink : pos;
             i >= stop; i--, samestep = true)
         {
-            WorkflowAdd(new stepnote(Workflow[i].Id, samestep, !Workflow[i].creation, this));
+            if (Workflow[i].creation)
+                Remove(Workflow[i].Id, samestep);
+            else
+                WorkflowAdd(new stepnote(Workflow[i].Id, samestep, true, this));
         }
     }
 
     public void undo()
     {
-        if (resetted)
+        if (soft_resetted)
             fastforward(); // revert softreset
 
         else if (backlog < worksteps) {
@@ -328,7 +314,7 @@ public void undo()
 
     public void redo()
     {
-        resetted = false;
+        soft_resetted = false;
 
         if (backlog > 0)
         {
@@ -350,18 +336,19 @@ public void redo()
     // Does not Invoke RemoveFactEvent(s)!
     {
         base.Clear();
+        MetaInf.Clear();
         Workflow.Clear();
         marker = 0;
         worksteps = 0;
         backlog = 0;
-        resetted = false;
+        soft_resetted = false;
     }
 
     public void hardreset(bool invoke_event = true)
     {
         foreach(var entry in this)
         {
-            if (invoke_event) //TODO? check if removed
+            if (invoke_event && invoke && MetaInf[entry.Key].active)
                 CommunicationEvents.RemoveFactEvent.Invoke(entry.Value);
             entry.Value.delete();
         }
@@ -370,7 +357,7 @@ public void hardreset(bool invoke_event = true)
 
     public void softreset()
     {
-        if (resetted)
+        if (soft_resetted)
         {
             fastforward();
             return;
@@ -381,7 +368,7 @@ public void softreset()
         while (marker > 0)
             undo();
 
-        resetted = true;
+        soft_resetted = true;
     }
 
     public void fastforward()
@@ -394,19 +381,65 @@ public void fastforward()
     public void store()
     {
         // TODO: save state of all of this?
+        // probably nothing:
+        //      safe class instance somewhere
     }
 
-    public void load()
+    public void load(bool draw_all = true)
+    // call this after assigning a stored instance in an empty world
     {
         // TODO: see issue #58
+
+        foreach (var mett in MetaInf)
+        {
+            // update active info if needed
+            if (mett.Value.active)
+            {
+                meta info = mett.Value;
+                info.active = false;
+                MetaInf[mett.Key] = info;
+            }
+        }
+
+        marker = 0;
+        var stop = backlog;
+        backlog = worksteps;
+
+        if(draw_all)
+            while(backlog > stop)
+                redo();
     }
 
     private void InvokeFactEvent(bool creation, string Id)
     {
-        if (creation)
-            CommunicationEvents.AddFactEvent.Invoke(this[Id]);
-        else
-            CommunicationEvents.RemoveFactEvent.Invoke(this[Id]);
+        // update meta struct
+        meta info = MetaInf[Id];
+        info.active = creation;
+        MetaInf[Id] = info;
+
+        if (invoke)
+            if (creation)
+                CommunicationEvents.AddFactEvent.Invoke(this[Id]);
+            else
+                CommunicationEvents.RemoveFactEvent.Invoke(this[Id]);
+    }
+
+    public bool StaticlySovled(List<Fact> StaticSolution, out List<Fact> MissingElements)
+    // QoL for simple Levels
+    {
+        return DynamiclySolved(StaticSolution, out MissingElements, out _, new FactEquivalentsComparer());
+    }
+
+    //TODO: PERF: see CommunicationEvents.Solution
+    public bool DynamiclySolved(List<Fact> MinimalSolution, out List<Fact> MissingElements, out List<Fact> Solutions, FactComparer FactComparer)
+    {
+        Solutions = this.Values.Where(f => MetaInf[f.URI].active)
+            .Where(active => MinimalSolution.Contains(active, FactComparer.SetSearchRight()))
+            .ToList();
+
+        MissingElements = MinimalSolution.Except(Solutions, FactComparer.SetSearchLeft()).ToList();
+
+        return MissingElements.Count == 0;
     }
 
 }
\ No newline at end of file
diff --git a/Assets/Scripts/InteractionEngine/FactSpawner.cs b/Assets/Scripts/InteractionEngine/FactSpawner.cs
index 9874aef3b20413fab3d5183935851e976ff156b5..0500cac89b3599026e8b6b36448ff86171c30f49 100644
--- a/Assets/Scripts/InteractionEngine/FactSpawner.cs
+++ b/Assets/Scripts/InteractionEngine/FactSpawner.cs
@@ -65,8 +65,8 @@ public Fact SpawnLine(Fact fact)
     {
         LineFact lineFact = ((LineFact)fact);
 
-        PointFact pointFact1 = (Facts[lineFact.Pid1] as PointFact);
-        PointFact pointFact2 = (Facts[lineFact.Pid2] as PointFact);
+        PointFact pointFact1 = (LevelFacts[lineFact.Pid1] as PointFact);
+        PointFact pointFact2 = (LevelFacts[lineFact.Pid2] as PointFact);
         Vector3 point1 = pointFact1.Point;
         Vector3 point2 = pointFact2.Point;
         //Change FactRepresentation to Line
@@ -102,8 +102,8 @@ public Fact SpawnRay(Fact fact)
     {
         RayFact rayFact = ((RayFact)fact);
 
-        PointFact pointFact1 = (Facts[rayFact.Pid1] as PointFact);
-        PointFact pointFact2 = (Facts[rayFact.Pid2] as PointFact);
+        PointFact pointFact1 = (LevelFacts[rayFact.Pid1] as PointFact);
+        PointFact pointFact2 = (LevelFacts[rayFact.Pid2] as PointFact);
 
  
         Vector3 point1 = pointFact1.Point;
@@ -145,9 +145,9 @@ public Fact SpawnAngle(Fact fact)
     {
         AngleFact angleFact = (AngleFact)fact;
 
-        Vector3 point1 = (Facts[angleFact.Pid1] as PointFact).Point;
-        Vector3 point2 = (Facts[angleFact.Pid2] as PointFact).Point;
-        Vector3 point3 = (Facts[angleFact.Pid3] as PointFact).Point;
+        Vector3 point1 = (LevelFacts[angleFact.Pid1] as PointFact).Point;
+        Vector3 point2 = (LevelFacts[angleFact.Pid2] as PointFact).Point;
+        Vector3 point3 = (LevelFacts[angleFact.Pid3] as PointFact).Point;
 
         //Length of the Angle relative to the Length of the shortest of the two lines (point2->point1) and (point2->point3)
         float lengthFactor = 0.3f;
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs
index ce595794e6f78ba13ee4dd80c70195a496deb323..be18d2d330253b1ce1d4dff14b853fb0c5bbae94 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/AngleTool.cs
@@ -49,7 +49,7 @@ public override void OnHit(RaycastHit hit)
         if (!this.isActiveAndEnabled) return;
         if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
         {
-            PointFact tempFact = (PointFact)Facts[hit.transform.GetComponent<FactObject>().URI];
+            PointFact tempFact = (PointFact)LevelFacts[hit.transform.GetComponent<FactObject>().URI];
 
             //If two points were already selected and now the third point got selected
             if (this.angleModeIsFirstPointSelected && this.angleModeIsSecondPointSelected)
@@ -138,7 +138,7 @@ public void UpdateCurveDrawing(Vector3 currentPosition)
         //TODO! PERF O(n)
         //Find the nearest of all potential third points
         PointFact nearestPoint = null;
-        foreach (var entry in Facts)
+        foreach (var entry in LevelFacts)
         {
             Fact fact = entry.Value;
             if (fact is PointFact && fact.URI != angleModeFirstPointSelected.URI && fact.URI != angleModeSecondPointSelected.URI && nearestPoint == null)
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs
index f125fbb601540006179b91ab31a1ba303531bc50..e3449d9347a8f28472c3822c6bbda7cebf21adec 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/LineTool.cs
@@ -40,7 +40,7 @@ public override void OnHit(RaycastHit hit)
         if (!this.isActiveAndEnabled) return;
         if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
         {
-            Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().URI];
+            Fact tempFact = LevelFacts[hit.transform.GetComponent<FactObject>().URI];
 
             //If first point was already selected AND second point != first point
             if (this.LineModeIsFirstPointSelected && this.LineModeFirstPointSelected.URI != tempFact.URI)
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
index 8b8095d84aa6f0cba0e5b830d84794eb9ddaa7ae..b77f0e6f455cc0db04547b5a6f7f8c8f68d578c2 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
@@ -72,7 +72,7 @@ void CreateRayAndAngles(string pidIntersectionPoint, string pidLotPoint, bool sa
         //If baseline already selected and point selected
         else if (this.LotModeIsLineSelected && !this.LotModeIsPointSelected && hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
         {
-            PointFact tempFact = Facts[hit.transform.GetComponent<FactObject>().URI] as PointFact;
+            PointFact tempFact = LevelFacts[hit.transform.GetComponent<FactObject>().URI] as PointFact;
 
             Vector3 intersectionPoint = Math3d.ProjectPointOnLine(this.LotModeLinePointA.Point, this.LotModeLineSelected.Dir, tempFact.Point);
 
@@ -99,12 +99,12 @@ void CreateRayAndAngles(string pidIntersectionPoint, string pidLotPoint, bool sa
             && (hit.transform.gameObject.layer == LayerMask.NameToLayer("Ray")
             || hit.transform.gameObject.layer == LayerMask.NameToLayer("Line")))
         {
-            Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().URI];
+            Fact tempFact = LevelFacts[hit.transform.GetComponent<FactObject>().URI];
 
             //Activate LineDrawing for preview
             this.LotModeIsLineSelected = true;
             this.LotModeLineSelected = tempFact as AbstractLineFact;
-            this.LotModeLinePointA = (PointFact) Facts[this.LotModeLineSelected.Pid1];
+            this.LotModeLinePointA = (PointFact) LevelFacts[this.LotModeLineSelected.Pid1];
             this.LotModeLineHit = hit;
             this.ActivateLineDrawing();
         }
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs b/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs
index 7be05aed12822de0315a733b3d38386303124b4b..135f598c4ea82e1e9efea788d583deb9e4e27514 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/Pendulum.cs
@@ -45,7 +45,7 @@ public override void OnHit(RaycastHit hit)
 
         if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
         {
-            PointFact tempFact = Facts[hit.transform.GetComponent<FactObject>().URI] as PointFact;
+            PointFact tempFact = LevelFacts[hit.transform.GetComponent<FactObject>().URI] as PointFact;
 
             //Raycast downwoard
             RaycastHit ground;
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs b/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs
index 7b626909dbe94321708242d84ba950719246d07a..6b64d8bcada8ccc008717affeee73b4186c84769 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/Remover.cs
@@ -32,7 +32,7 @@ public override void OnHit(RaycastHit hit)
 
         // TODO: ask/warn user to cascade
         var hid = hit.transform.GetComponent<FactObject>().URI;
-        Facts.Remove(hid);
+        LevelFacts.Remove(hid);
     }
   
 }
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs b/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs
index c31d81e9811e2802ed5ad78eaa69c2530460e284..6b24581e5d61fcc53581705aae177a1f86626b1a 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/Tape.cs
@@ -5,6 +5,8 @@
 
 public class Tape : Gadget
 {
+    public float maxHeight = 2.5f;
+
     //Variables for TapeMode distinction
     private bool TapeModeIsFirstPointSelected = false;
     private Fact TapeModeFirstPointSelected = null;
@@ -40,10 +42,10 @@ public override void OnHit(RaycastHit hit)
         if (!this.isActiveAndEnabled) return;
         if (hit.transform.gameObject.layer == LayerMask.NameToLayer("Point"))
         {
-            Fact tempFact = Facts[hit.transform.GetComponent<FactObject>().URI];
+            Fact tempFact = LevelFacts[hit.transform.GetComponent<FactObject>().URI];
 
             //we can only reach points that are lower than that with the measuring tape
-            if (/*ActiveToolMode == ToolMode.CreateLineMode && */tempFact.Representation.transform.position.y > 2.5f)
+            if (/*ActiveToolMode == ToolMode.CreateLineMode && */tempFact.Representation.transform.position.y > maxHeight)
                 return;
 
             //If first point was already selected AND second point != first point
diff --git a/Assets/Scripts/InteractionEngine/ShinyThings.cs b/Assets/Scripts/InteractionEngine/ShinyThings.cs
index e9eeaf64a7d41e959e9e5fc41e134db6e2cac38b..0ff9960a4866477ed21cfd0681ed7ba8bee77d42 100644
--- a/Assets/Scripts/InteractionEngine/ShinyThings.cs
+++ b/Assets/Scripts/InteractionEngine/ShinyThings.cs
@@ -38,10 +38,16 @@ public class ShinyThings : MonoBehaviour
     // Start is called before the first frame update
     public void Start()
     {
-        if (Cursor == null) Cursor = GetComponent<WorldCursor>();
-        if (directionalLight == null) directionalLight = FindObjectOfType<Light>().gameObject;
-        CommunicationEvents.PushoutFactEvent.AddListener(StartPushoutFactHighlighting);
+        if (Cursor == null) 
+            Cursor = GetComponent<WorldCursor>();
+
+        if (directionalLight == null)
+            directionalLight = FindObjectOfType<Light>().gameObject;
+
+        CommunicationEvents.PushoutFactEvent.AddListener(HighlightFact);
         CommunicationEvents.PushoutFactFailEvent.AddListener(StartPushoutFactFailHighlighting);
+        CommunicationEvents.AnimateExistingFactEvent.AddListener(HighlightWithFireworks);
+
         speedSlowDown = timerDurationEnd * 10;
         lightColor = directionalLight.GetComponent<Light>().color;
 
@@ -181,9 +187,18 @@ public void OnMouseOverFactEnd(Transform selection)
         }
     }
 
-    public void StartPushoutFactHighlighting(Fact startFact) {
-
+    public void HighlightWithFireworks(Fact fact)
+    {
         GameObject fireworksRepresentation = (GameObject)Resources.Load("Prefabs/Fireworks_Animation", typeof(GameObject));
+
+        this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
+        this.extraHighlight.transform.position = fact.Representation.transform.position;
+
+        HighlightFact(fact);
+    }
+
+    public void HighlightFact(Fact startFact) {
+
         highlightedPushoutFact = startFact;
 
         if (typeof(PointFact).IsInstanceOfType(highlightedPushoutFact))
@@ -191,23 +206,17 @@ public void StartPushoutFactHighlighting(Fact startFact) {
             PointFact fact = (PointFact)highlightedPushoutFact;
             tempMaterial = fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material;
             fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material = pushoutMaterial;
-            this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
-            this.extraHighlight.transform.position = fact.Representation.transform.position;
         }
         else if (typeof(LineFact).IsInstanceOfType(highlightedPushoutFact))
         {
             LineFact fact = (LineFact)highlightedPushoutFact;
             tempMaterial = fact.Representation.transform.GetChild(0).GetChild(1).GetComponent<MeshRenderer>().material;
             fact.Representation.transform.GetChild(0).GetChild(1).GetComponent<MeshRenderer>().material = pushoutMaterial;
-            this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
-            this.extraHighlight.transform.position = fact.Representation.transform.position;
         }
         else if (typeof(AngleFact).IsInstanceOfType(highlightedPushoutFact)) {
             AngleFact fact = (AngleFact)highlightedPushoutFact;
             tempMaterial = fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material;
             fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material = pushoutMaterial;
-            this.extraHighlight = GameObject.Instantiate(fireworksRepresentation);
-            this.extraHighlight.transform.position = fact.Representation.transform.position;
         }
 
         //Activate Timer
@@ -216,7 +225,7 @@ public void StartPushoutFactHighlighting(Fact startFact) {
         this.timerActive = true;
     }
 
-    public void StopPushoutFactHighlighting() {
+    public void StopHighlighting() {
 
         if (typeof(PointFact).IsInstanceOfType(highlightedPushoutFact))
         {
@@ -234,8 +243,11 @@ public void StopPushoutFactHighlighting() {
             fact.Representation.transform.GetChild(0).GetComponent<MeshRenderer>().material = tempMaterial;
         }
 
-        GameObject.Destroy(this.extraHighlight);
-        this.extraHighlight = null;
+        if (this.extraHighlight != null)
+        {
+            GameObject.Destroy(this.extraHighlight);
+            this.extraHighlight = null;
+        }
 
         //Event for the happy Task-Charakter
         CommunicationEvents.PushoutFactEndEvent.Invoke(null);
@@ -261,7 +273,7 @@ public void CheckPushoutHighlighting() {
                 {
                     this.timerActive = false;
                     this.timer = 0;
-                    StopPushoutFactHighlighting();
+                    StopHighlighting();
                 }
                 //After this.timerDuration: Slow Down Fireworks
                 else
diff --git a/Assets/Scripts/InteractionEngine/SmartMenu.cs b/Assets/Scripts/InteractionEngine/SmartMenu.cs
index 42a882c6c2fdf16f99b210fb769c9cc3bfec3074..da13a5667f850c37574768e340e4dbdbc3333a1c 100644
--- a/Assets/Scripts/InteractionEngine/SmartMenu.cs
+++ b/Assets/Scripts/InteractionEngine/SmartMenu.cs
@@ -7,7 +7,7 @@ public class SmartMenu : MonoBehaviour
 
     public void DestroyObject()
     {
-        CommunicationEvents.Facts.Remove(CommunicationEvents.Facts[transform.parent.GetComponent<FactObject>().URI]);
+        CommunicationEvents.LevelFacts.Remove(CommunicationEvents.LevelFacts[transform.parent.GetComponent<FactObject>().URI]);
     }
 
 
diff --git a/Assets/Scripts/InteractionEngine/WorldCursor.cs b/Assets/Scripts/InteractionEngine/WorldCursor.cs
index 3109f3f061f2a59cd65c0771ab8c026a644ba6fa..b69ae6bf11985ccce1a3181927d481c907d271d9 100644
--- a/Assets/Scripts/InteractionEngine/WorldCursor.cs
+++ b/Assets/Scripts/InteractionEngine/WorldCursor.cs
@@ -89,8 +89,8 @@ void Update()
                     || Hit.collider.gameObject.layer == LayerMask.NameToLayer("Line"))
                 {
                     var id = Hit.collider.gameObject.GetComponent<FactObject>().URI;
-                    AbstractLineFact lineFact = CommunicationEvents.Facts[id] as AbstractLineFact;
-                    PointFact p1 =  CommunicationEvents.Facts[lineFact.Pid1] as PointFact;
+                    AbstractLineFact lineFact = CommunicationEvents.LevelFacts[id] as AbstractLineFact;
+                    PointFact p1 =  CommunicationEvents.LevelFacts[lineFact.Pid1] as PointFact;
 
                     Hit.point = Math3d.ProjectPointOnLine(p1.Point, lineFact.Dir, Hit.point);
                     CheckMouseButtons(true,true);
diff --git a/Assets/Scripts/InventoryStuff/DisplayFacts.cs b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
index 2141e6e56bf22d2df97c4b174f0af936f58ba539..926b2fb85b92693b6bb97edb3430e18500237570 100644
--- a/Assets/Scripts/InventoryStuff/DisplayFacts.cs
+++ b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
@@ -55,6 +55,14 @@ public void RemoveFact(Fact fact)
     {
         GameObject.Destroy(displayedFacts[fact.URI]);
         displayedFacts.Remove(fact.URI);
+        UpdatePositions();
+    }
+
+    public void UpdatePositions()
+    {
+        int i = 0;
+        foreach (var element in displayedFacts)
+            element.Value.GetComponent<RectTransform>().localPosition = GetPosition(i++);
     }
 
     public void AnimateFact(Fact fact) {
@@ -62,10 +70,6 @@ public void AnimateFact(Fact fact) {
         factIcon.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
     }
 
-    string getLetter(int Id) {
-        return ((Char)(64 + Id + 1)).ToString();
-    }
-
     private GameObject CreateDisplay(Transform transform, Fact fact)
     {
         return fact.instantiateDisplay(prefabDictionary[fact.GetType()], transform);
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index ba0fb8d3bbf60dcfc0be8a34389df2ca652d90c9..b3b44d81ef6c8dded826d86e64f370c6c6040331 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -32,7 +32,6 @@ void Start()
     {
         if (cursor == null) cursor = GameObject.FindObjectOfType<WorldCursor>();
 
-        parameterDisplayHint.AddListener(animateScrollParameter);
         ScrollFactHintEvent.AddListener(animateHint);
         NewAssignmentEvent.AddListener(newAssignmentTrigger);
     }
@@ -168,9 +167,7 @@ private void readPushout(List<Scroll.ScrollFact> pushoutFacts)
             Fact newFact = ParsingDictionary.parseFactDictionary[pushoutFacts[i].getType()].Invoke(pushoutFacts[i]);
             if (newFact != null)
             {
-                FactManager.AddFactIfNotFound(newFact, out bool exists, samestep);
-                if(!exists)
-                    PushoutFactEvent.Invoke(newFact);
+                PushoutFactEvent.Invoke(FactManager.AddFactIfNotFound(newFact, out bool exists, samestep));
             }
             else {
                 Debug.Log("Parsing on pushout-fact returned null -> One of the dependent facts does not exist");
@@ -236,9 +233,9 @@ public void animateHint(GameObject scrollParameter, string scrollParameterUri) {
 
         if (suitableCompletion != null)
         {
-            if (Facts.ContainsKey(suitableCompletion.assignment.uri))
+            if (LevelFacts.ContainsKey(suitableCompletion.assignment.uri))
             {
-                fact = Facts[suitableCompletion.assignment.uri];
+                fact = LevelFacts[suitableCompletion.assignment.uri];
                 //Animate ScrollParameter
                 scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
                 //Animate Fact in FactPanel
@@ -253,9 +250,9 @@ public void animateHint(GameObject scrollParameter, string scrollParameterUri) {
             var factId = fact.URI;
 
             //If there is an equal existing fact -> Animate that fact AND ScrollParameter
-            if (Facts.ContainsKey(factId))
+            if (LevelFacts.ContainsKey(factId))
             {
-                Fact existingFact = Facts[factId];
+                Fact existingFact = LevelFacts[factId];
 
                 //Animate ScrollParameter
                 scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
diff --git a/Assets/Scripts/Level.cs b/Assets/Scripts/Level.cs
index a65344b1702760760a9b101b71d5699bcd4660ce..8832fabc94fa1aad5d49df804ad492b5732f2256 100644
--- a/Assets/Scripts/Level.cs
+++ b/Assets/Scripts/Level.cs
@@ -1,4 +1,5 @@
-using UnityEngine;
+using System.Collections.Generic;
+using UnityEngine;
 using static CommunicationEvents;
 
 //TODO: think about having one Level class and then different subclasses like TreeLevel, Tangenslevel?
@@ -6,46 +7,35 @@ public class Level : MonoBehaviour
 {
 
     //Solving game parameters
-    public GameObject snapZoneTop;
-    public GameObject snapZoneBottom;
-    public static Vector3 solutionVector;
+    public int minimalSolutionHight;
+
     public static bool solved = false;
-    // Start is called before the first frame update
+
+
     void Start()
+    // Start is called before the first frame update
     {
-        solutionVector = snapZoneTop.transform.position - snapZoneBottom.transform.position;
-    }
+        PointFact
+            buttom = new PointFact(Vector3.zero, Vector3.up, SolutionManager),
+            top = new PointFact(Vector3.zero + Vector3.up * minimalSolutionHight, Vector3.up, SolutionManager);
+
+        SolutionManager.Add(buttom, out _);
+        SolutionManager.Add(top, out _, true);
 
+        LineFact target = new LineFact(buttom.URI, top.URI, SolutionManager);
+        Solution.Add(SolutionManager[SolutionManager.Add(target, out _, true)]);
+    }
 
     public static bool gameSolved()
     {
+        solved =
+            LevelFacts.DynamiclySolved(Solution, out _, out List<Fact> hits, new LineFactHightDirectionComparer());
 
-        Vector3 tempDir1 = new Vector3(0, 0, 0);
-        Vector3 tempDir2 = new Vector3(0, 0, 0);
-
-        if (solved == true)
-            return true;
-        else
-        {
-            //Look for solutionFact in global factList
-            foreach (var entry in Facts)
-            {
-                Fact fact = entry.Value;
-                if (typeof(LineFact).IsInstanceOfType(fact))
-                {
-                    tempDir1 = ((PointFact) Facts[((LineFact) fact).Pid1]).Point
-                             - ((PointFact) Facts[((LineFact) fact).Pid2]).Point;
-                    tempDir2 = ((PointFact) Facts[((LineFact) fact).Pid2]).Point
-                             - ((PointFact) Facts[((LineFact) fact).Pid1]).Point;
-
-                    if (solutionVector == tempDir1 || solutionVector == tempDir2)
-                    {
-                        solved = true;
-                        return true;
-                    }
-                }
-            }
-            return false;
-        }
+        if (solved)
+            foreach (var hit in hits)
+                AnimateExistingFactEvent.Invoke(hit);
+
+        return solved;
     }
+
 }
diff --git a/Assets/Scripts/Restart.cs b/Assets/Scripts/Restart.cs
index cf20ce143c751cca4393404951f573c515e88fd2..47e919b45b077349bb4d2836a84856621f9dcfaa 100644
--- a/Assets/Scripts/Restart.cs
+++ b/Assets/Scripts/Restart.cs
@@ -1,19 +1,24 @@
 using UnityEngine;
-using static StartServer;
+using UnityEngine.SceneManagement;
 
 public class Restart : MonoBehaviour
 {
+    public void LevelReset()
+    {
+        CommunicationEvents.LevelReset.Invoke(); // currently unused
+        Level.solved = false; // needed?
+        CommunicationEvents.LevelFacts.hardreset(false); // delete Facts at Server
+        SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().buildIndex);
+    }
+
     public void LoadStartScreen()
     {
-        process.Kill();
-        Level.solved = false;
-        //TODO: CommunicationEvents.Facts.Clear();
-        CommunicationEvents.Facts.hardreset();
-        UnityEngine.SceneManagement.SceneManager.LoadScene(0);
+        StartServer.process.Kill();  // null reference exception if Server started manually
+        SceneManager.LoadScene(0);
     }
 
     public void OnApplicationQuit()
     {
-        process.Kill();
+        StartServer.process.Kill();
     }
 }