diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactComparer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactComparer.cs
index d3e5a304b44befa2c02ebd2a8d7eb848561cf1a0..3f4fadd7688071f1463b3d0bb8fae1569088a703 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactComparer.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactComparer.cs
@@ -151,7 +151,7 @@ protected override bool Compare(Fact solution, Fact fact)
         // get positions of anker points
         var point_pos =
             factLine.getDependentFactIds()
-            .Select(id => StageStatic.stage.factState[id].Representation.transform.position)
+            .Select(id => FactOrganizer.AllFacts[id].Representation.transform.position)
             .ToArray();
 
         // check anker points *not within* RiverWall
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
index 1b91647fc9cdff5035de426bfb64ee9859dedb9d..b72e976a783737ef95346c155d0807923994ef38 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactManager.cs
@@ -26,7 +26,7 @@ public static Fact AddFactIfNotFound(Fact fact, out bool exists, bool samestep,
             return AddParsedAngleFactIfNotFound((AngleFact)fact, out exists, samestep, null, scroll_label);
 
         else
-            return StageStatic.stage.factState[
+            return FactOrganizer.AllFacts[
             StageStatic.stage.factState.Add(
                 fact, out exists, samestep
                 , gadget ?? (scroll_label == null ? GadgetBehaviour.ActiveGadget : null)
@@ -63,9 +63,9 @@ public static OnLineFact AddOnLineFact(string pid, string lid, bool samestep = f
     {
         if (!is_certain)
         {
-            AbstractLineFact line = (AbstractLineFact)StageStatic.stage.factState[lid];
-            PointFact line_point = (PointFact)StageStatic.stage.factState[line.Pid1];
-            PointFact point = (PointFact)StageStatic.stage.factState[pid];
+            AbstractLineFact line = (AbstractLineFact)FactOrganizer.AllFacts[lid];
+            PointFact line_point = (PointFact)FactOrganizer.AllFacts[line.Pid1];
+            PointFact point = (PointFact)FactOrganizer.AllFacts[pid];
 
             if (!Math3d.IsPointApproximatelyOnLine(line_point.Point, line.Dir, point.Point))
                 return null;
@@ -104,8 +104,8 @@ public static RayFact AddRayFact(string pid1, string pid2, bool samestep = false
             return rayFact;
 
         //Add all PointFacts on Ray as OnLineFacts
-        PointFact rayP1 = (PointFact)StageStatic.stage.factState[rayFact.Pid1];
-        PointFact rayP2 = (PointFact)StageStatic.stage.factState[rayFact.Pid2];
+        PointFact rayP1 = (PointFact)FactOrganizer.AllFacts[rayFact.Pid1];
+        PointFact rayP2 = (PointFact)FactOrganizer.AllFacts[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);
@@ -179,7 +179,7 @@ public static Fact AddParsedAngleCircleLineFactIfNotFound(AngleCircleLineFact fa
                 , out _, samestep, gadget, scroll_label);
         }
 
-        return StageStatic.stage.factState[
+        return FactOrganizer.AllFacts[
             StageStatic.stage.factState.Add(
                 fact, out exists, samestep
                 , gadget ?? (scroll_label == null ? GadgetBehaviour.ActiveGadget : null)
@@ -193,7 +193,7 @@ public static Fact AddParsedAngleFactIfNotFound(AngleFact fact, out bool exists,
                 new RightAngleFact(fact.Pid1, fact.Pid2, fact.Pid3, StageStatic.stage.factState)
                 , out _, samestep, gadget, scroll_label);
 
-        return StageStatic.stage.factState[
+        return FactOrganizer.AllFacts[
             StageStatic.stage.factState.Add(
                 fact, out exists, samestep
                 , gadget ?? (scroll_label == null ? GadgetBehaviour.ActiveGadget : null)
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs
index c644ce061ce4e1d97756875573224de0a1fba005..7842c2fb351e194b5cb16fa5bb31fc518bcf37db 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactSpawner.cs
@@ -2,6 +2,7 @@
 using System.Collections;
 using TMPro;
 using UnityEngine;
+using UnityEngine.UIElements;
 using UnityStandardAssets.Vehicles.Car;
 using static CommunicationEvents;
 using static GlobalBehaviour;
@@ -32,9 +33,8 @@ public void SpawnFactRepresentation(Fact fact)
                 SpawnPoint(PointFact); break;
             case LineFact LineFact:
                 SpawnLine(LineFact); break;
-            case RightAngleFact RightAngleFact: //needed for Hint System
-                SpawnAngle(RightAngleFact); break;
-            case AngleFact AngleFact:
+            //case RightAngleFact AngleFact: //needed for Hint System
+            case AbstractAngleFact AngleFact:
                 SpawnAngle(AngleFact); break;
             case RayFact RayFact:
                 SpawnRay(RayFact); break;
@@ -102,27 +102,11 @@ public void SpawnRay(RayFact fact)
     }
 
     //Spawn an angle: point with id = angleFact.Pid2 is the point where the angle gets applied
-    public void SpawnAngle(Fact fact)
+    public void SpawnAngle(AbstractAngleFact fact)
     {
-        Vector3 Psotion;
-        Quaternion Rotation;
-        float angleValue;
-
-        // TODO: just use simple inheritence or similar!!
-        if (fact is RightAngleFact rightangleFact)
-        {
-            Psotion = rightangleFact.Position;
-            Rotation = rightangleFact.Rotation;
-            angleValue = 90f;
-        }
-        else if (fact is AngleFact angleFact)
-        {
-            Psotion = angleFact.Position;
-            Rotation = angleFact.Rotation;
-            angleValue = angleFact.angle;
-        }
-        else
-            throw new Exception("Invalid Type:" + fact.GetType().ToString());
+        Vector3 Psotion = fact.Position;
+        Quaternion Rotation = fact.Rotation;
+        float angleValue = fact.angle;
 
         //Change FactRepresentation to Angle
         GameObject angle = GameObject.Instantiate(Angle);
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs
new file mode 100644
index 0000000000000000000000000000000000000000..b1c2c1e9e82970f37a917620d3ece79fa95bfbc7
--- /dev/null
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs
@@ -0,0 +1,350 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using static SOMDocManager;
+using TMPro;
+using UnityEngine;
+using UnityEngine.UIElements;
+
+public abstract class AbstractAngleFact : FactWrappedCRTP<AbstractAngleFact>
+{
+    /// @{ <summary>
+    /// One <see cref="Fact.Id">Id</see> of three <see cref="PointFact">PointFacts</see> defining Angle [<see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>].
+    /// </summary>
+    public string Pid1, Pid2, Pid3;
+    /// @}
+
+    [JsonIgnore]
+    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
+    [JsonIgnore]
+    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
+    [JsonIgnore]
+    public PointFact Point3 { get => (PointFact)FactOrganizer.AllFacts[Pid3]; }
+
+    /// <summary> <see langword="true"/>, if AngleFact is approximately 90° or 270°</summary>
+    virtual public bool is_right_angle { get; set; } = false;
+
+    /// <summary>
+    /// Smallets angle in Degrees between [< see cref = "Pid1" />, < see cref = "Pid2" />] and[< see cref = "Pid2" />, < see cref = "Pid3" />]
+    /// </summary>
+    [JsonIgnore]
+    virtual public float angle { get; set; } = -0f;
+
+    /// <summary>\copydoc Fact.Fact</summary>
+    protected AbstractAngleFact() : base()
+    {
+        this.Pid1 = null;
+        this.Pid2 = null;
+        this.Pid3 = null;
+    }
+
+    /// <summary>\copydoc AbstractAngleFact.AbstractAngleFact(AbstractAngleFact, Dictionary{string, string}, FactOrganizer)</summary>
+    protected AbstractAngleFact(AbstractAngleFact fact, Dictionary<string, string> old_to_new, FactOrganizer organizer)
+        : this(old_to_new[fact.Pid1], old_to_new[fact.Pid2], old_to_new[fact.Pid3], organizer) { }
+
+    /// <summary>\copydoc AbstractAngleFact.AbstractAngleFact(string, string, FactOrganizer)</summary>
+    protected AbstractAngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(organizer)
+    {
+        this.Pid1 = pid1;
+        this.Pid2 = pid2;
+        this.Pid3 = pid3;
+
+        RecalulateTransform();
+    }
+
+    /// <summary>\copydoc AbstractAngleFact.AbstractAngleFact(string, string, string, FactOrganizer)</summary>
+    protected AbstractAngleFact(string pid1, string pid2, string pid3, float angle, string backendURI, FactOrganizer organizer)
+        : this(pid1, pid2, pid3, organizer)
+    {
+        this.angle = angle;
+        this._URI = backendURI;
+    }
+
+    /// \copydoc Fact.hasDependentFacts
+    public override Boolean hasDependentFacts()
+        => true;
+
+    /// \copydoc Fact.getDependentFactIds
+    public override string[] getDependentFactIds()
+        => new string[] { Pid1, Pid2, Pid3 };
+
+    protected override void RecalulateTransform()
+    {
+        Position = Point2.Position;
+        { //Rotation
+            Vector3 from = (Point1.Position - Position).normalized;
+            Vector3 to = (Point3.Position - Position).normalized;
+
+            Vector3 up = Vector3.Cross(from, to);
+            Vector3 forwoard = (from + to).normalized;
+
+            if (up.sqrMagnitude < Math3d.vectorPrecission)
+            { //Angle is 180° (or 0°)
+                Vector3 from_arbitary = from.normalized == Vector3.forward ? Vector3.right : Vector3.forward;
+                up = Vector3.Cross(from_arbitary, to);
+                forwoard = Vector3.Cross(up, to);
+            }
+
+            Rotation = Quaternion.LookRotation(forwoard, up);
+        }
+    }
+}
+
+public abstract class AbstractAngleFactWrappedCRTP<T> : AbstractAngleFact where T : AbstractAngleFactWrappedCRTP<T>
+{
+    /// <summary>\copydoc Fact.Fact</summary>
+    protected AbstractAngleFactWrappedCRTP() : base() { }
+
+    /// <summary>\copydoc AbstractAngleFactWrappedCRTP.AbstractAngleFactWrappedCRTP(AbstractAngleFactWrappedCRTP, Dictionary{string, string}, FactOrganizer)</summary>
+    protected AbstractAngleFactWrappedCRTP(AbstractAngleFactWrappedCRTP<T> fact, Dictionary<string, string> old_to_new, FactOrganizer organizer) : base(fact, old_to_new, organizer) { }
+
+    /// <summary>\copydoc AbstractAngleFactWrappedCRTP.AbstractAngleFactWrappedCRTP(string, string, FactOrganizer)</summary>
+    protected AbstractAngleFactWrappedCRTP(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(pid1, pid2, pid3, organizer) { }
+
+    /// <summary>\copydoc AbstractAngleFactWrappedCRTP.AbstractAngleFactWrappedCRTP(string, string, string, FactOrganizer)</summary>
+    protected AbstractAngleFactWrappedCRTP(string pid1, string pid2, string pid3, float angle, string backendURI, FactOrganizer organizer) : base(pid1, pid2, pid3, angle, backendURI, organizer) { }
+
+    /// \copydoc Fact.Equivalent(Fact, Fact)
+    protected override bool EquivalentWrapped(AbstractAngleFact f1, AbstractAngleFact f2)
+        => EquivalentWrapped((T)f1, (T)f2);
+
+    /// <summary>CRTP step of <see cref="EquivalentWrapped(AbstractAngleFact, AbstractAngleFact)"/></summary>
+    protected abstract bool EquivalentWrapped(T f1, T f2);
+}
+
+/// <summary>
+/// Angle comprised of three <see cref="PointFact">PointFacts</see> [A,B,C]
+/// </summary>
+public class AngleFact : AbstractAngleFactWrappedCRTP<AngleFact>
+{
+    /// <summary> \copydoc Fact.Fact </summary>
+    public AngleFact() : base() { }
+
+    /// <summary>
+    /// Copies <paramref name="fact"/> by initiating new MMT %Fact.
+    /// </summary>
+    /// <param name="fact">Fact to be copied</param>
+    /// <param name="old_to_new"><c>Dictionary</c> mapping <paramref name="fact"/>.<see cref="getDependentFactIds"/> in <paramref name="fact"/>.<see cref="Fact._Facts"/> to corresponding <see cref="Fact.Id"/> in <paramref name="organizer"/> </param>
+    /// <param name="organizer">sets <see cref="_Facts"/></param>
+    public AngleFact(AngleFact fact, Dictionary<string, string> old_to_new, FactOrganizer organizer)
+        : this(old_to_new[fact.Pid1], old_to_new[fact.Pid2], old_to_new[fact.Pid3], organizer) { }
+
+    /// <summary>
+    /// Standard Constructor:
+    /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>, <see cref="is_right_angle"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
+    /// </summary>
+    /// <param name="pid1">sets <see cref="Pid1"/></param>
+    /// <param name="pid2">sets <see cref="Pid2"/></param>
+    /// <param name="pid3">sets <see cref="Pid3"/></param>
+    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
+    public AngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(pid1, pid2, pid3, organizer)
+    {
+        angle = Vector3.Angle((Point1.Point - Point2.Point), (Point3.Point - Point2.Point));
+
+        this.is_right_angle = Mathf.Abs(angle - 90.0f) < Math3d.vectorPrecission;
+
+        angle = is_right_angle ? 90f : angle;
+
+        MMTDeclaration mmtDecl = MakeMMTDeclaration(angle, pid1, pid2, pid3);
+        AddFactResponse.sendAdd(mmtDecl, out this._URI);
+    }
+
+    /// <summary>
+    /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
+    /// </summary>
+    /// <param name="Pid1">sets <see cref="Pid1"/></param>
+    /// <param name="Pid2">sets <see cref="Pid2"/></param>
+    /// <param name="Pid3">sets <see cref="Pid3"/></param>
+    /// <param name="backendURI">MMT URI</param>
+    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
+    public AngleFact(string Pid1, string Pid2, string Pid3, float angle, string backendURI, FactOrganizer organizer) 
+        : base(Pid1, Pid2, Pid3, angle, backendURI, organizer) { }
+
+    /// <summary>
+    /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
+    /// </summary>
+    /// <param name="val">Angle != 90f, _not checked_</param>
+    /// <param name="p1URI"><see cref="Pid1"/></param>
+    /// <param name="p2URI"><see cref="Pid2"/></param>
+    /// <param name="p3URI"><see cref="Pid3"/></param>
+    /// <returns>struct for <see cref="AddFactResponse"/></returns>
+    private MMTDeclaration MakeMMTDeclaration(float val, string p1URI, string p2URI, string p3URI)
+    {
+        SOMDoc lhs =
+            new OMA(
+                new OMS(MMT_OMS_URI.Angle),
+                new List<SOMDoc> {
+                    new OMS(p1URI),
+                    new OMS(p2URI),
+                    new OMS(p3URI)
+                }
+            );
+
+        SOMDoc valueTp = new OMS(MMT_OMS_URI.RealLit);
+        SOMDoc value = new OMF(val);
+
+        return new MMTValueDeclaration(this.Label, lhs, valueTp, value);
+    }
+
+    /// \copydoc Fact.parseFact(Scroll.ScrollFact)
+    public new static AngleFact parseFact(Scroll.ScrollFact fact)
+    {
+        if (fact is not Scroll.ScrollValueFact value_fact) //If angle is a 90Degree-Angle
+            throw new ArgumentException("Angle 90 degrees parsed. This shouldn't happen anymore");
+
+        if (value_fact.lhs is not OMA df)
+            return null;
+
+        float angle = value_fact.value == null
+            ? 0f
+            : ((OMF)value_fact.value).f;
+
+        string pointAUri = ((OMS)df.arguments[0]).uri;
+        string pointBUri = ((OMS)df.arguments[1]).uri;
+        string pointCUri = ((OMS)df.arguments[2]).uri;
+
+        if (!StageStatic.stage.factState.ContainsKey(pointAUri)
+         || !StageStatic.stage.factState.ContainsKey(pointBUri)
+         || !StageStatic.stage.factState.ContainsKey(pointCUri))
+            return null; //If dependent facts do not exist return null
+
+        return new AngleFact(pointAUri, pointBUri, pointCUri, angle, fact.@ref.uri, StageStatic.stage.factState);
+    }
+
+    /// \copydoc Fact.generateLabel
+    protected override string generateLabel()
+        => (is_right_angle ? "⊾" : "∠") + Point1.Label + Point2.Label + Point3.Label;
+
+    /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
+    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 = Point1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
+        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
+        obj.GetComponent<FactWrapper>().fact = this;
+        return obj;
+    }
+
+    /// \copydoc Fact.Equivalent(Fact, Fact)
+    protected override bool EquivalentWrapped(AngleFact f1, AngleFact f2)
+        => DependentFactsEquivalent(f1, f2);
+}
+
+/// <summary>
+/// A RightAngleFact defined by 3  <see cref="PointFact">Pointfact</see> 
+/// </summary>
+public class RightAngleFact : AbstractAngleFactWrappedCRTP<RightAngleFact>
+{
+    override public bool is_right_angle { get => true; }
+    override public float angle {get => 90f;}
+
+    /// <summary> \copydoc Fact.Fact </summary>
+    public RightAngleFact() : base() { }
+
+    /// <summary>
+    /// Copies <paramref name="fact"/> by initiating new MMT %Fact.
+    /// </summary>
+    /// <param name="fact">Fact to be copied</param>
+    /// <param name="old_to_new"><c>Dictionary</c> mapping <paramref name="fact"/>.<see cref="getDependentFactIds"/> in <paramref name="fact"/>.<see cref="Fact._Facts"/> to corresponding <see cref="Fact.Id"/> in <paramref name="organizer"/> </param>
+    /// <param name="organizer">sets <see cref="_Facts"/></param>
+    public RightAngleFact(RightAngleFact fact, Dictionary<string, string> old_to_new, FactOrganizer organizer)
+        : this(old_to_new[fact.Pid1], old_to_new[fact.Pid2], old_to_new[fact.Pid3], organizer) { }
+
+    /// <summary>
+    /// Standard Constructor:
+    /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>, <see cref="is_right_angle"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
+    /// </summary>
+    /// <param name="pid1">sets <see cref="Pid1"/></param>
+    /// <param name="pid2">sets <see cref="Pid2"/></param>
+    /// <param name="pid3">sets <see cref="Pid3"/></param>
+    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
+    public RightAngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(pid1, pid2, pid3, organizer)
+    {
+        angle = 90f;
+
+        MMTDeclaration mmtDecl = MakeMMTDeclaration(pid1, pid2, pid3);
+        AddFactResponse.sendAdd(mmtDecl, out this._URI);
+    }
+
+    /// <summary>
+    /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
+    /// </summary>
+    /// <param name="Pid1">sets <see cref="Pid1"/></param>
+    /// <param name="Pid2">sets <see cref="Pid2"/></param>
+    /// <param name="Pid3">sets <see cref="Pid3"/></param>
+    /// <param name="backendURI">MMT URI</param>
+    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
+    public RightAngleFact(string Pid1, string Pid2, string Pid3, string backendURI, FactOrganizer organizer)
+        : base(Pid1, Pid2, Pid3, 90f, backendURI, organizer) { }
+
+    /// <summary>
+    /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/>
+    /// </summary>
+    /// <param name="p1URI"> Uri for <see cref="Pid1"/></param>
+    /// <param name="p2URI"> Uri for <see cref="Pid2"/></param>
+    /// <param name="p3URI"> Uri for <see cref="Pid3"/></param>
+    /// <returns>struct for <see cref="AddFactResponse"/></returns>
+    private MMTDeclaration MakeMMTDeclaration(string p1URI, string p2URI, string p3URI)
+    {
+        SOMDoc tp =
+            new OMA(
+                new OMS(MMT_OMS_URI.Ded),
+                new List<SOMDoc> {
+                    new OMA(
+                        new OMS(MMT_OMS_URI.RightAngle),
+                        new List<SOMDoc> {
+                            new OMS(p1URI),
+                            new OMS(p2URI),
+                            new OMS(p3URI),
+        }),});
+
+        SOMDoc df = null;
+
+        return new MMTSymbolDeclaration(this.Label, tp, df);
+    }
+
+    /// \copydoc Fact.parseFact(Scroll.ScrollFact)
+    public new static RightAngleFact parseFact(Scroll.ScrollFact fact)
+    {
+        if (((Scroll.ScrollSymbolFact)fact).tp
+                is not OMA proof_OMA // proof DED
+            || proof_OMA.arguments[0]
+                is not OMA rightAngleOMA // rightAngle OMA
+            || rightAngleOMA.arguments[0]
+                is not OMS // rightAngle Arg0
+        )
+            return null;
+
+        string Point1Uri = ((OMS)rightAngleOMA.arguments[0]).uri;
+        string Point2Uri = ((OMS)rightAngleOMA.arguments[1]).uri;
+        string Point3Uri = ((OMS)rightAngleOMA.arguments[2]).uri;
+
+        if (!StageStatic.stage.factState.ContainsKey(Point1Uri)
+         || !StageStatic.stage.factState.ContainsKey(Point2Uri)
+         || !StageStatic.stage.factState.ContainsKey(Point3Uri))
+            return null; //If dependent facts do not exist return null
+
+        return new RightAngleFact(Point1Uri, Point2Uri, Point3Uri, fact.@ref.uri, StageStatic.stage.factState);
+    }
+
+    /// \copydoc Fact.generateLabel
+    protected override string generateLabel()
+        => Point1.Label + Point2.Label + Point3.Label + "⊥";
+
+    /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
+    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 = Point1.Label;
+        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
+        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
+
+        obj.GetComponent<FactWrapper>().fact = this;
+        return obj;
+    }
+
+    /// \copydoc Fact.Equivalent(Fact, Fact)
+    protected override bool EquivalentWrapped(RightAngleFact f1, RightAngleFact f2)
+        => DependentFactsEquivalent(f1, f2);
+}
\ No newline at end of file
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs.meta b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs.meta
new file mode 100644
index 0000000000000000000000000000000000000000..dffff378d6eb12cde3e65d110bc94a0d960ea7c2
--- /dev/null
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/AbstractAngleFact.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 344f76a2aeeeae349b21386bc4230f70
+MonoImporter:
+  externalObjects: {}
+  serializedVersion: 2
+  defaultReferences: []
+  executionOrder: 0
+  icon: {instanceID: 0}
+  userData: 
+  assetBundleName: 
+  assetBundleVariant: 
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
index f15d885aeb62c267582c1eb75313ddf7828e8952..4a83b23d3c47ec909c800be8e588697c41dc402b 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/Facts/Fact.cs
@@ -715,459 +715,6 @@ protected override bool EquivalentWrapped(OnLineFact f1, OnLineFact f2)
         => DependentFactsEquivalent(f1, f2);
 }
 
-/// <summary>
-/// Angle comprised of three <see cref="PointFact">PointFacts</see> [A,B,C]
-/// </summary>
-public class AngleFact : FactWrappedCRTP<AngleFact>
-{
-    /// @{ <summary>
-    /// One <see cref="Fact.Id">Id</see> of three <see cref="PointFact">PointFacts</see> defining Angle [<see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>].
-    /// </summary>
-    public string Pid1, Pid2, Pid3;
-    /// @}
-
-    [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
-    [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
-    [JsonIgnore]
-    public PointFact Point3 { get => (PointFact)FactOrganizer.AllFacts[Pid3]; }
-
-    /// <summary> <see langword="true"/>, if AngleFact is approximately 90° or 270°</summary>
-    public bool is_right_angle;
-    [JsonIgnore]
-    public float angle;
-
-    /// <summary> \copydoc Fact.Fact </summary>
-    public AngleFact() : base()
-    {
-        this.Pid1 = null;
-        this.Pid2 = null;
-        this.Pid3 = null;
-        this.is_right_angle = false;
-    }
-
-    /// <summary>
-    /// Copies <paramref name="fact"/> by initiating new MMT %Fact.
-    /// </summary>
-    /// <param name="fact">Fact to be copied</param>
-    /// <param name="old_to_new"><c>Dictionary</c> mapping <paramref name="fact"/>.<see cref="getDependentFactIds"/> in <paramref name="fact"/>.<see cref="Fact._Facts"/> to corresponding <see cref="Fact.Id"/> in <paramref name="organizer"/> </param>
-    /// <param name="organizer">sets <see cref="_Facts"/></param>
-    public AngleFact(AngleFact fact, Dictionary<string, string> old_to_new, FactOrganizer organizer) : base(fact, organizer)
-        => init(old_to_new[fact.Pid1], old_to_new[fact.Pid2], old_to_new[fact.Pid3]);
-
-    /// <summary>
-    /// Standard Constructor
-    /// </summary>
-    /// <param name="pid1">sets <see cref="Pid1"/></param>
-    /// <param name="pid2">sets <see cref="Pid2"/></param>
-    /// <param name="pid3">sets <see cref="Pid3"/></param>
-    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
-    public AngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(organizer)
-        => init(pid1, pid2, pid3);
-
-    /// <summary>
-    /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>, <see cref="is_right_angle"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
-    /// </summary>
-    /// <param name="pid1">sets <see cref="Pid1"/></param>
-    /// <param name="pid2">sets <see cref="Pid2"/></param>
-    /// <param name="pid3">sets <see cref="Pid3"/></param>
-    private void init(string pid1, string pid2, string pid3)
-    {
-        this.Pid1 = pid1;
-        this.Pid2 = pid2;
-        this.Pid3 = pid3;
-
-        ComputeAngle(); // sets is_right_angle, angle
-        RecalulateTransform();
-
-        MMTDeclaration mmtDecl = generateNot90DegreeAngleDeclaration(angle, pid1, pid2, pid3);
-        AddFactResponse.sendAdd(mmtDecl, out this._URI);
-    }
-
-    protected override void RecalulateTransform()
-    {
-        Position = Point2.Position;
-        { //Rotation
-            Vector3 from = (Point1.Position - Position).normalized;
-            Vector3 to = (Point3.Position - Position).normalized;
-
-            Vector3 up = Vector3.Cross(to, from);
-            Vector3 forwoard = (from + to).normalized;
-
-            if (up.sqrMagnitude < Math3d.vectorPrecission)
-            { //Angle is 180° (or 0°)
-                Vector3 arbitary = up.normalized == Vector3.forward ? Vector3.right : Vector3.forward;
-                up = Vector3.Cross(arbitary, to);
-                forwoard = Vector3.Cross(up, to);
-            }
-
-            Rotation = Quaternion.LookRotation(forwoard, up);
-        }
-    }
-
-    /// <summary>
-    /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
-    /// </summary>
-    /// <param name="Pid1">sets <see cref="Pid1"/></param>
-    /// <param name="Pid2">sets <see cref="Pid2"/></param>
-    /// <param name="Pid3">sets <see cref="Pid3"/></param>
-    /// <param name="backendURI">MMT URI</param>
-    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
-    public AngleFact(string Pid1, string Pid2, string Pid3, string backendURI, FactOrganizer organizer) : base(organizer)
-    {
-        this.Pid1 = Pid1;
-        this.Pid2 = Pid2;
-        this.Pid3 = Pid3;
-
-        ComputeAngle();
-        this._URI = backendURI;
-        _ = this.Label;
-
-        RecalulateTransform();
-    }
-
-    public AngleFact(string Pid1, string Pid2, string Pid3, float angle, string backendURI, FactOrganizer organizer) : base(organizer)
-    {
-        this.Pid1 = Pid1;
-        this.Pid2 = Pid2;
-        this.Pid3 = Pid3;
-        this.angle = angle;
-
-        this._URI = backendURI;
-        _ = this.Label;
-
-        RecalulateTransform();
-    }
-
-    /// \copydoc Fact.parseFact(Scroll.ScrollFact)
-    public new static AngleFact parseFact(Scroll.ScrollFact fact)
-    {
-        string uri = fact.@ref.uri;
-        string
-            pointAUri,
-            pointBUri,
-            pointCUri;
-
-        float angle = 0.0f;
-        //If angle is not a 90Degree-Angle
-        if (fact.GetType().Equals(typeof(Scroll.ScrollValueFact)))
-        {
-            OMA df = (OMA)((Scroll.ScrollValueFact)fact).lhs;
-            if (df == null)
-                return null;
-
-            if (((Scroll.ScrollValueFact)fact).value != null)
-                angle = ((OMF)(((Scroll.ScrollValueFact)fact).value)).f;
-
-            pointAUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[0]).uri;
-            pointBUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[1]).uri;
-            pointCUri = ((OMS)((OMA)((Scroll.ScrollValueFact)fact).lhs).arguments[2]).uri;
-        }
-        // this should never happen anymore
-        //If angle is a 90Degree-Angle
-        else
-        {
-            Debug.LogError("Angle 90 degrees parsed. This shouldn't happen anymore");
-
-            pointAUri = ((OMS)((OMA)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).arguments[0]).uri;
-            pointBUri = ((OMS)((OMA)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).arguments[1]).uri;
-            pointCUri = ((OMS)((OMA)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).arguments[2]).uri;
-        }
-
-        if (StageStatic.stage.factState.ContainsKey(pointAUri)
-         && StageStatic.stage.factState.ContainsKey(pointBUri)
-         && StageStatic.stage.factState.ContainsKey(pointCUri))
-            return new AngleFact(pointAUri, pointBUri, pointCUri, angle, uri, StageStatic.stage.factState);
-        else
-            return null; //If dependent facts do not exist return null
-    }
-
-    /// \copydoc Fact.generateLabel
-    protected override string generateLabel()
-        => (is_right_angle ? "⊾" : "∠") + Point1.Label + Point2.Label + Point3.Label;
-
-    /// <summary>
-    /// Computes smallest angle and sets <see cref="is_right_angle"/>
-    /// </summary>
-    /// <returns>Smallets angle between [<see cref="Pid1"/>, <see cref="Pid2"/>] and [<see cref="Pid2"/>, <see cref="Pid3"/>]</returns>
-    private float ComputeAngle()
-    {
-        angle = Vector3.Angle((Point1.Point - Point2.Point), (Point3.Point - Point2.Point));
-        this.is_right_angle = Mathf.Abs(angle - 90.0f) < 0.01;
-
-        return is_right_angle ? 90f : angle;
-    }
-
-    /// <summary>
-    /// Constructs struct for right-angled MMT %Fact <see cref="AddFactResponse"/>
-    /// </summary>
-    /// <param name="val">Angle == 90f, _not checked_</param>
-    /// <param name="p1URI"><see cref="Pid1"/></param>
-    /// <param name="p2URI"><see cref="Pid2"/></param>
-    /// <param name="p3URI"><see cref="Pid3"/></param>
-    /// <returns>struct for <see cref="AddFactResponse"/></returns>
-    private MMTDeclaration generate90DegreeAngleDeclaration(float val, string p1URI, string p2URI, string p3URI)
-    {
-        SOMDoc argument = new OMA(
-            new OMS(MMT_OMS_URI.Eq),
-            new List<SOMDoc> {
-                new OMS(MMT_OMS_URI.RealLit),
-                new OMA(
-                    new OMS(MMT_OMS_URI.Angle),
-                    new List<SOMDoc> {
-                        new OMS(p1URI),
-                        new OMS(p2URI),
-                        new OMS(p3URI)
-                    }
-                ),
-                new OMF(val) // 90f
-            }
-        );
-
-        SOMDoc tp = new OMA(new OMS(MMT_OMS_URI.Ded), new List<SOMDoc> { argument });
-        SOMDoc df = null;
-
-        return new MMTSymbolDeclaration(this.Label, tp, df);
-    }
-
-    /// <summary>
-    /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
-    /// </summary>
-    /// <param name="val">Angle != 90f, _not checked_</param>
-    /// <param name="p1URI"><see cref="Pid1"/></param>
-    /// <param name="p2URI"><see cref="Pid2"/></param>
-    /// <param name="p3URI"><see cref="Pid3"/></param>
-    /// <returns>struct for <see cref="AddFactResponse"/></returns>
-    private MMTDeclaration generateNot90DegreeAngleDeclaration(float val, string p1URI, string p2URI, string p3URI)
-    {
-        SOMDoc lhs =
-            new OMA(
-                new OMS(MMT_OMS_URI.Angle),
-                new List<SOMDoc> {
-                    new OMS(p1URI),
-                    new OMS(p2URI),
-                    new OMS(p3URI)
-                }
-            );
-
-        SOMDoc valueTp = new OMS(MMT_OMS_URI.RealLit);
-        SOMDoc value = new OMF(val);
-
-        return new MMTValueDeclaration(this.Label, lhs, valueTp, value);
-    }
-
-    /// \copydoc Fact.hasDependentFacts
-    public override Boolean hasDependentFacts()
-        => true;
-
-    /// \copydoc Fact.getDependentFactIds
-    public override string[] getDependentFactIds()
-        => new string[] { Pid1, Pid2, Pid3 };
-
-    /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
-    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 = Point1.Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
-        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
-        obj.GetComponent<FactWrapper>().fact = this;
-        return obj;
-    }
-
-    /// \copydoc Fact.Equivalent(Fact, Fact)
-    protected override bool EquivalentWrapped(AngleFact f1, AngleFact f2) 
-        => DependentFactsEquivalent(f1, f2);
-}
-
-/// <summary>
-/// A RightAngleFact defined by 3  <see cref="PointFact">Pointfact</see> 
-/// </summary>
-public class RightAngleFact : FactWrappedCRTP<RightAngleFact>
-{
-    ///  <summary> three <see cref="PointFact">Pointfacts</see> defining the right angle </summary>
-    public string Pid1, Pid2, Pid3;
-
-    [JsonIgnore]
-    public PointFact Point1 { get => (PointFact)FactOrganizer.AllFacts[Pid1]; }
-    [JsonIgnore]
-    public PointFact Point2 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
-    [JsonIgnore]
-    public PointFact Point3 { get => (PointFact)FactOrganizer.AllFacts[Pid2]; }
-
-    /// <summary> \copydoc Fact.Fact </summary>
-    public RightAngleFact() : base()
-    {
-        this.Pid1 = null;
-        this.Pid2 = null;
-        this.Pid3 = null;
-    }
-
-    /// <summary>
-    /// Copies <paramref name="fact"/> by initiating new MMT %Fact.
-    /// </summary>
-    /// <param name="fact">Fact to be copied</param>
-    /// <param name="old_to_new"><c>Dictionary</c> mapping <paramref name="fact"/>.<see cref="getDependentFactIds"/> in <paramref name="fact"/>.<see cref="Fact._Facts"/> to corresponding <see cref="Fact.Id"/> in <paramref name="organizer"/> </param>
-    /// <param name="organizer">sets <see cref="_Facts"/></param>
-    public RightAngleFact(RightAngleFact fact, Dictionary<string, string> old_to_new, FactOrganizer organizer) : base(fact, organizer)
-        => init(old_to_new[fact.Pid1], old_to_new[fact.Pid2], old_to_new[fact.Pid3]);
-
-    /// <summary>
-    /// Standard Constructor
-    /// </summary>
-    /// <param name="pid1">sets <see cref="Pid1"/></param>
-    /// <param name="pid2">sets <see cref="Pid2"/></param>
-    /// <param name="pid3">sets <see cref="Pid3"/></param>
-    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
-    public RightAngleFact(string pid1, string pid2, string pid3, FactOrganizer organizer) : base(organizer)
-        => init(pid1, pid2, pid3);
-
-    /// <summary>
-    /// Initiates <see cref="Pid1"/>, <see cref="Pid2"/>, <see cref="Pid3"/>, <see cref="is_right_angle"/>, <see cref="Fact._URI"/> and creates MMT %Fact Server-Side
-    /// </summary>
-    /// <param name="pid1">sets <see cref="Pid1"/></param>
-    /// <param name="pid2">sets <see cref="Pid2"/></param>
-    /// <param name="pid3">sets <see cref="Pid3"/></param>
-    private void init(string pid1, string pid2, string pid3)
-    {
-        this.Pid1 = pid1;
-        this.Pid2 = pid2;
-        this.Pid3 = pid3;
-
-        RecalulateTransform();
-
-        AddFactResponse.sendAdd(generateMMTDeclaration(pid1, pid2, pid3), out this._URI);
-    }
-
-    protected override void RecalulateTransform()
-    {
-        Position = Point2.Position;
-        { //Rotation
-            Vector3 from = (Point1.Position - Position).normalized;
-            Vector3 to = (Point3.Position - Position).normalized;
-
-            Vector3 up = Vector3.Cross(to, from);
-            Vector3 forwoard = (from + to).normalized;
-
-            if (up.sqrMagnitude < Math3d.vectorPrecission)
-            { //Angle is 180° (or 0°)
-                Vector3 arbitary = up.normalized == Vector3.forward ? Vector3.right : Vector3.forward;
-                up = Vector3.Cross(arbitary, to);
-                forwoard = Vector3.Cross(up, to);
-            }
-
-            Rotation = Quaternion.LookRotation(forwoard, up);
-        }
-    }
-
-    /// <summary>
-    /// Bypasses initialization of new MMT %Fact by using existend URI, _which is not checked for existence_.
-    /// </summary>
-    /// <param name="Pid1">sets <see cref="Pid1"/></param>
-    /// <param name="Pid2">sets <see cref="Pid2"/></param>
-    /// <param name="Pid3">sets <see cref="Pid3"/></param>
-    /// <param name="backendURI">MMT URI</param>
-    /// <param name="organizer">sets <see cref="Fact._Facts"/></param>
-    public RightAngleFact(string Pid1, string Pid2, string Pid3, string backendURI, FactOrganizer organizer) : base(organizer)
-    {
-        this.Pid1 = Pid1;
-        this.Pid2 = Pid2;
-        this.Pid3 = Pid3;
-
-        this._URI = backendURI;
-        _ = this.Label;
-
-        RecalulateTransform();
-    }
-
-    /// \copydoc Fact.parseFact(Scroll.ScrollFact)
-    public new static RightAngleFact parseFact(Scroll.ScrollFact fact)
-    {
-        OMA tp = (OMA)((Scroll.ScrollSymbolFact)fact).tp;
-        if (tp == null)
-            return null;
-
-        string Point1Uri = "";
-        string Point2Uri = "";
-        string Point3Uri = "";
-
-        string uri = fact.@ref.uri;
-        OMA proof_OMA = (OMA)((Scroll.ScrollSymbolFact)fact).tp; // proof DED
-        OMA rightAngleOMA = (OMA)proof_OMA.arguments[0]; // rightAngle OMA
-
-        if (rightAngleOMA.arguments[0] is OMS)
-        {
-            Point1Uri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[0]).uri;
-            Point2Uri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[1]).uri;
-            Point3Uri = ((OMS)((OMA)((OMA)((Scroll.ScrollSymbolFact)fact).tp).arguments[0]).arguments[2]).uri;
-        }
-
-        if (StageStatic.stage.factState.ContainsKey(Point1Uri)
-         && StageStatic.stage.factState.ContainsKey(Point2Uri)
-         && StageStatic.stage.factState.ContainsKey(Point3Uri))
-
-            return new RightAngleFact(Point1Uri, Point2Uri, Point3Uri, uri, StageStatic.stage.factState);
-
-        else    //If dependent facts do not exist return null
-            return null;
-    }
-
-    /// \copydoc Fact.generateLabel
-    protected override string generateLabel()
-        => Point1.Label + Point2.Label + Point3.Label + "⊥";
-
-    /// <summary>
-    /// Constructs struct for not-right-angled MMT %Fact <see cref="AddFactResponse"/>
-    /// </summary>
-    /// <param name="p1URI"> Uri for <see cref="Pid1"/></param>
-    /// <param name="p2URI"> Uri for <see cref="Pid2"/></param>
-    /// <param name="p3URI"> Uri for <see cref="Pid3"/></param>
-    /// <returns>struct for <see cref="AddFactResponse"/></returns>
-    private MMTDeclaration generateMMTDeclaration(string p1URI, string p2URI, string p3URI)
-    {
-        SOMDoc tp =
-            new OMA(
-                new OMS(MMT_OMS_URI.Ded),
-                new List<SOMDoc> {
-                    new OMA(
-                        new OMS(MMT_OMS_URI.RightAngle),
-                        new List<SOMDoc> {
-                            new OMS(p1URI),
-                            new OMS(p2URI),
-                            new OMS(p3URI),
-        }),});
-
-        SOMDoc df = null;
-
-        return new MMTSymbolDeclaration(this.Label, tp, df);
-    }
-
-    /// \copydoc Fact.hasDependentFacts
-    public override bool hasDependentFacts()
-        => true;
-
-    /// \copydoc Fact.getDependentFactIds
-    public override string[] getDependentFactIds()
-        => new string[] { Pid1, Pid2, Pid3 };
-
-    /// \copydoc Fact.instantiateDisplay(GameObject, Transform)
-    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 = Point1.Label;
-        obj.transform.GetChild(1).gameObject.GetComponent<TextMeshProUGUI>().text = Point2.Label;
-        obj.transform.GetChild(2).gameObject.GetComponent<TextMeshProUGUI>().text = Point3.Label;
-
-        obj.GetComponent<FactWrapper>().fact = this;
-        return obj;
-    }
-
-    /// \copydoc Fact.Equivalent(Fact, Fact)
-    protected override bool EquivalentWrapped(RightAngleFact f1, RightAngleFact f2)
-        => DependentFactsEquivalent(f1, f2);
-}
-
 /// <summary>
 /// Two parallel Lines comprised of two <see cref="LineFact">LineFacts</see> 
 /// </summary>
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/EqualCircleGadget.cs b/Assets/Scripts/InteractionEngine/Gadgets/EqualCircleGadget.cs
index 75c5973b39b0d5da46ad81fd8c0e1d8ee4f59c7e..1e28f2231af3736f2f5c8a912cd5c83b3e53b1c7 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/EqualCircleGadget.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/EqualCircleGadget.cs
@@ -34,8 +34,8 @@ public override void _Hit(RaycastHit[] hit)
                 //Debug.Log("hit it");
                 //Debug.Log("data: radius dif" + Mathf.Abs(this.FirstCircle.radius - tempFact.radius) +" ids: 1. "+ this.FirstCircle.Id+", 2."+ tempFact.Id);
 
-                CircleFact tempFact = (CircleFact)StageStatic.stage.factState[Workflow[0]];
-                CircleFact FirstCircle = (CircleFact)StageStatic.stage.factState[tempFactId];
+                CircleFact tempFact = (CircleFact)FactOrganizer.AllFacts[Workflow[0]];
+                CircleFact FirstCircle = (CircleFact)FactOrganizer.AllFacts[tempFactId];
 
                 if (Mathf.Approximately(FirstCircle.radius, tempFact.radius))
                     FactManager.AddEqualCirclesFact  (Workflow[0], tempFactId);
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
index f643e57e9fca55146e685a6ccaf17e4147b1896c..8622940d9a4101b8c340810e8f0b654e5f7118d4 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/LotTool.cs
@@ -38,7 +38,7 @@ void CreateRayAndAngles(string IntersectionId, string LotPointId, bool samestep)
            || Workflow.Contains(tempFactId = obj.URI)))
             return;
 
-        Fact tempFact = tempFactId == null ? null : StageStatic.stage.factState[tempFactId];
+        Fact tempFact = tempFactId == null ? null : FactOrganizer.AllFacts[tempFactId];
         switch (Workflow.Count)
         {
             case 0: // select basline
@@ -47,7 +47,7 @@ void CreateRayAndAngles(string IntersectionId, string LotPointId, bool samestep)
                 Workflow.Add(tempFactId);
 
                 BaseLine = (AbstractLineFact) tempFact;
-                BaseLineRoot = ((PointFact) StageStatic.stage.factState[BaseLine.Pid1]).Point;
+                BaseLineRoot = ((PointFact)FactOrganizer.AllFacts[BaseLine.Pid1]).Point;
 
                 BaseLineHit = hit[0].point;
                 ActivateLineDrawing();
diff --git a/Assets/Scripts/InteractionEngine/Gadgets/TestMiddlePoint.cs b/Assets/Scripts/InteractionEngine/Gadgets/TestMiddlePoint.cs
index 12672bbfa21135055e72d7588cc98ca422361a7b..00bc83ca137157d75102165d14519e61a3cbb5ea 100644
--- a/Assets/Scripts/InteractionEngine/Gadgets/TestMiddlePoint.cs
+++ b/Assets/Scripts/InteractionEngine/Gadgets/TestMiddlePoint.cs
@@ -31,8 +31,8 @@ public override void _Hit(RaycastHit[] hit)
             case 2:
 
                 //Insert point in the middle
-                PointFact p1 = (PointFact)StageStatic.stage.factState[Workflow[0]];
-                PointFact p2 = (PointFact)StageStatic.stage.factState[Workflow[1]];
+                PointFact p1 = (PointFact)FactOrganizer.AllFacts[Workflow[0]];
+                PointFact p2 = (PointFact)FactOrganizer.AllFacts[Workflow[1]];
 
                 Vector3 middle = p1.Point + (p2.Point - p1.Point) * 0.5f;
 
diff --git a/Assets/Scripts/InteractionEngine/WorldCursor.cs b/Assets/Scripts/InteractionEngine/WorldCursor.cs
index 187bca1f4dd103e23e3118953246c9aba3ebfde3..d5ef2abb6df31730297d31d2c2fa31682f076be3 100644
--- a/Assets/Scripts/InteractionEngine/WorldCursor.cs
+++ b/Assets/Scripts/InteractionEngine/WorldCursor.cs
@@ -121,16 +121,16 @@ void Update()
             if (!((multipleHits[i].collider.transform.CompareTag("SnapZone") || multipleHits[i].collider.transform.CompareTag("Selectable"))
                 && (!deactSnapKey)))
                 continue;
-    
+
             //TODO see whether the conditions needs to be adjusted
             //if (Hit.transform.TryGetComponent<FactObject>(out var obj)
-            //        && StageStatic.stage.factState[obj.URI] is AbstractLineFact lineFact)
+            //        && FactOrganizer.AllFacts[obj.URI] is AbstractLineFact lineFact)
 
             if (multipleHits[i].collider.gameObject.layer == LayerMask.NameToLayer("Ray")
                 || multipleHits[i].collider.gameObject.layer == LayerMask.NameToLayer("Line"))
             {
                 var id = multipleHits[i].collider.gameObject.GetComponent<FactObject>().URI;
-                AbstractLineFact lineFact = StageStatic.stage.factState[id] as AbstractLineFact;
+                AbstractLineFact lineFact = FactOrganizer.AllFacts[id] as AbstractLineFact;
                 PointFact p1 = lineFact.Point1;
 
                 multipleHits[i].point = Math3d.ProjectPointOnLine(p1.Point, lineFact.Dir, multipleHits[i].point);
@@ -139,9 +139,9 @@ void Update()
             {
                 #region Ring
                 var id = multipleHits[i].transform.GetComponent<FactObject>().URI;
-                CircleFact circleFact = StageStatic.stage.factState[id] as CircleFact;
-                Vector3 middlePoint = ((PointFact)StageStatic.stage.factState[circleFact.Pid1]).Point;
-                Vector3 edgePoint = ((PointFact)StageStatic.stage.factState[circleFact.Pid2]).Point;
+                CircleFact circleFact = FactOrganizer.AllFacts[id] as CircleFact;
+                Vector3 middlePoint = ((PointFact)FactOrganizer.AllFacts[circleFact.Pid1]).Point;
+                Vector3 edgePoint = ((PointFact)FactOrganizer.AllFacts[circleFact.Pid2]).Point;
                 var normal = circleFact.normal;
                 var radius = circleFact.radius;
 
@@ -177,9 +177,9 @@ void Update()
             {
                 #region Circle
                 var id = multipleHits[i].transform.GetComponent<FactObject>().URI;
-                CircleFact circleFact = StageStatic.stage.factState[id] as CircleFact;
-                Vector3 middlePoint = ((PointFact)StageStatic.stage.factState[circleFact.Pid1]).Point;
-                Vector3 edgePoint = ((PointFact)StageStatic.stage.factState[circleFact.Pid2]).Point;
+                CircleFact circleFact = FactOrganizer.AllFacts[id] as CircleFact;
+                Vector3 middlePoint = ((PointFact)FactOrganizer.AllFacts[circleFact.Pid1]).Point;
+                Vector3 edgePoint = ((PointFact)FactOrganizer.AllFacts[circleFact.Pid2]).Point;
                 var normal = circleFact.normal;
                 var radius = circleFact.radius;
 
@@ -220,8 +220,8 @@ void Update()
                 var id = multipleHits[i].collider.gameObject.GetComponent<FactObject>().URI;
 
                 // get the two corresponding line facts
-                AbstractLineFact lineFactLine0 = StageStatic.stage.factState[idLine0] as AbstractLineFact;
-                AbstractLineFact lineFact = StageStatic.stage.factState[id] as AbstractLineFact;
+                AbstractLineFact lineFactLine0 = FactOrganizer.AllFacts[idLine0] as AbstractLineFact;
+                AbstractLineFact lineFact = FactOrganizer.AllFacts[id] as AbstractLineFact;
 
                 // get a point on the line 
                 PointFact p1Line0 = lineFactLine0.Point1;
diff --git a/Assets/Scripts/InteractionEngine/WorldFactInteraction.cs b/Assets/Scripts/InteractionEngine/WorldFactInteraction.cs
index 305d0c0beb379db1cc7e71173221d6b784c94cfb..c5bd69b78c00bc93bc6a2dab5325edd6602a099f 100644
--- a/Assets/Scripts/InteractionEngine/WorldFactInteraction.cs
+++ b/Assets/Scripts/InteractionEngine/WorldFactInteraction.cs
@@ -73,7 +73,7 @@ private void InstantiateNewDisplay(FactObject factObj)
     {
         if (currentDisplay)
             Destroy(currentDisplay);
-        Fact fact = StageStatic.stage.factState[factObj.URI];
+        Fact fact = FactOrganizer.AllFacts[factObj.URI];
         // TODO: this link to DisplayFacts is not ideal: maybe refactor to SciptableObject or such
         currentDisplay = fact.instantiateDisplay(DisplayFacts.PrefabDictionary[fact.GetType()], HidingCanvas);
     }
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index d72e6bb11c9f025af6bccc1722186201f56b3700..dd9d1fa6c694d6ab65de4f4a54f4340d261811cb 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -278,7 +278,7 @@ public void animateHint(GameObject scrollParameter, string scrollParameterUri) {
         {
             if (StageStatic.stage.factState.ContainsKey(suitableCompletion.assignment.uri))
             {
-                fact = StageStatic.stage.factState[suitableCompletion.assignment.uri];
+                fact = FactOrganizer.AllFacts[suitableCompletion.assignment.uri];
                 //Animate ScrollParameter
                 scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
                 //Animate Fact in FactPanel
@@ -293,7 +293,7 @@ public void animateHint(GameObject scrollParameter, string scrollParameterUri) {
             //If there is an equal existing fact -> Animate that fact AND ScrollParameter
             if (StageStatic.stage.factState.ContainsKey(factId))
             {
-                Fact existingFact = StageStatic.stage.factState[factId];
+                Fact existingFact = FactOrganizer.AllFacts[factId];
 
                 //Animate ScrollParameter
                 scrollParameter.GetComponentInChildren<ImageHintAnimation>().AnimationTrigger();
diff --git a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
index 0ccd1fc0ab0eea7f149e161d4a6779c4372046be..78ea5ab520df9ab601cd5e8177631909a267fa76 100644
--- a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
+++ b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
@@ -52,12 +52,12 @@ public void Initialize(Fact fact, Vector3 factPosition)
     private List<Fact> GetParentFacts()
     {   
         _ = StageStatic.stage.factState.safe_dependencies(mainFact.Id, out var parentFactIds);
-        return parentFactIds.Distinct().Select(factId => StageStatic.stage.factState[factId]).Where(f => f != mainFact).ToList();
+        return parentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).Where(f => f != mainFact).ToList();
     }
 
     private List<Fact> GetChildFacts()
     {
-        return mainFact.getDependentFactIds().Distinct().Select(factId => StageStatic.stage.factState[factId]).ToList();
+        return mainFact.getDependentFactIds().Distinct().Select(factId => FactOrganizer.AllFacts[factId]).ToList();
     }
 
     private void UpdateFactExplorerUI()