diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
index 53045b795ddbdbc885919179bc8c123eafa56728..94bede147666faa83d7ea399a347b354b92525ad 100644
--- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
@@ -4,6 +4,7 @@
 using UnityEngine;
 using UnityEngine.Events;
 using System;
+using static Scroll;
 
 public static class CommunicationEvents
 {
@@ -14,7 +15,8 @@ public static class CommunicationEvents
     public static UnityEvent<Fact> AddFactEvent = new();
     public static UnityEvent<Fact> RemoveFactEvent = new();
 
-    public static UnityEvent<Fact, Scroll.ScrollApplicationInfo> PushoutFactFailEvent = new();
+    public static UnityEvent<ScrollApplicationCheckingError[]> ScrollApplicationCheckingErrorEvent = new();
+    public static UnityEvent PushoutFactFailEvent = new();
 
     public static UnityEvent gameSucceededEvent = new();
     public static UnityEvent gameNotSucceededEvent = new();
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
index 0654b7823d7462d96feeb8ec584f0bca28f1d36b..0fe2e8059c7e78037f3f5de49813f38b896435c5 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactOrganizer.cs
@@ -1060,7 +1060,8 @@ public static bool FindEquivalent(IReadOnlyDictionary<string, Fact> FactSpace, F
 
             foreach (var entry in FactSpace)
             {
-                if (entry.Value.Equivalent(search))
+                if ((allow_exact || entry.Key != search.Id)
+                 && entry.Value.Equivalent(search))
                 {
                     found_key = entry.Key;
                     found_value = entry.Value;
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs
index 79908ec30e7c839c5df0bf150914bf4e91101b9f..cd0ae95831636a700c7952696a1200b7768bc396 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject.cs
@@ -10,7 +10,6 @@
 /// <summary>
 /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.WorldRepresentation"/>
 /// </summary>
-//[DisallowMultipleComponent]
 public abstract class FactObject : FactWrapper, ISerializationCallbackReceiver
 {
     [SerializeField] protected List<TMP_Text> FactText;
@@ -19,7 +18,7 @@ public abstract class FactObject : FactWrapper, ISerializationCallbackReceiver
     [NonSerialized]
     public Material[] Materials;
     protected Material[] MaterialsToChange;
-    [NonSerialized]
+    protected List<FactObject> AllSiblings;
     protected List<FactObject> AllChildren;
 
     #region Unity Serialization
@@ -79,8 +78,10 @@ protected override void _Awake()
     {
         base._Awake();
 
-        AllChildren = transform.GetComponentsInChildren<FactObject>(includeInactive: true).ToList();
-        AllChildren.Remove(this);
+        AllSiblings = GetComponents<FactObject>().ToList();
+        AllChildren = GetComponentsInChildren<FactObject>(includeInactive: true)
+            .Where(fO => !AllSiblings.Contains(fO))
+            .ToList();
 
         FactText ??= new();
         StringLabelFormats ??= new();
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs
index 027670ddbcc40dca4c1b15643a840bdef52a0918..d30f65d070dc34f1a7e492ffcd0a9cec7d59a568 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObject3D.cs
@@ -3,7 +3,6 @@
 using UnityEngine;
 using System.Collections;
 using UnityEditor;
-using static GlobalBehaviour;
 
 /// <summary>
 /// <see cref="Fact.Id"/>/ <c>MonoBehaviour</c> wrapper to be attached to <see cref="Fact.WorldRepresentation"/>
@@ -42,7 +41,7 @@ protected override void _Awake()
     {
         base._Awake();
 
-        MaterialsToChange ??= renderer.SelectMany(r => r.materials).ToArray();
+        MaterialsToChange ??= renderer?.SelectMany(r => r.materials).ToArray();
     }
 
     protected override void _CustomReLabel()
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs
index 592a3a522140f55457410ac6cbad8ae133ff4217..52163edd4601751872f07f6fe4864c6beb55837f 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/FactObjectUI.cs
@@ -1,4 +1,3 @@
-using MoreLinq;
 using System.Linq;
 using UnityEngine.UI;
 
@@ -19,6 +18,8 @@ protected override void _Awake()
     {
         base._Awake();
 
+        Images ??= new Image[0];
+
         if(MaterialsToChange == null)
         {
             MaterialsToChange = new UnityEngine.Material[Images.Length];
diff --git a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs
index be4926cb100392f34b8844de23cd669512032b83..d7bec1639417afb12215b4fbbc6c8f38161c0c45 100644
--- a/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs
+++ b/Assets/Scripts/InteractionEngine/FactHandling/FactWrapper/RenderedScrollFact.cs
@@ -4,7 +4,7 @@
 using UnityEngine.EventSystems;
 using static CommunicationEvents;
 
-public class RenderedScrollFact : FactObjectUI, IDropHandler, IPointerClickHandler
+public class RenderedScrollFact : FactObjectUI, IDropHandler
 {
     #region Serializable
     public TextMeshProUGUI LabelMesh;
@@ -34,6 +34,9 @@ public Scroll Scroll
     }
     private Scroll _Scroll;
 
+    public bool IsSet
+        => ScrollFactURI != URI;
+
     public string ScrollFactURI
         => Scroll.requiredFacts[ID].@ref.uri;
 
@@ -43,7 +46,7 @@ public string ScrollFactLabel
 
     protected override void FactUpdated()
     {
-        Destroy(RenderedFactObject);
+        Destroy(_Payload);
 
         NewAssignmentEvent.Invoke();
 
@@ -89,24 +92,31 @@ public void OnHintAvailable(List<string> uris)
     }
 
     #region DropHandling 
-    private GameObject RenderedFactObject;
+    public FactObjectUI Payload 
+        => _Payload == null ? null : _Payload.GetComponent<FactObjectUI>();
+
+    private GameObject _Payload;
 
     public void OnDrop(PointerEventData eventData)
     {
-        Fact = eventData.pointerDrag.GetComponent<FactObject>().Fact;
+        if (eventData.pointerDrag.TryGetComponent(out FactObjectUI factObject))
+            SetByFactObject(factObject);
+    }
+
+    public void SetByFactObject(FactObjectUI fOUI)
+    {
+        Fact = fOUI.Fact;
 
         if (VerboseURI)
             Debug.Log(Fact.Label + " was dropped on "
                 + gameObject.name + " " + (ID + 1) + "/" +
                 ScrollDetails.ParameterDisplays.Count + " label: " + ScrollFactLabel);
 
-        RenderedFactObject = // has to be: ..., Vector3.zero, Quaternion.identity => SetParent
-            Instantiate(eventData.pointerDrag, Vector3.zero, Quaternion.identity);
+        _Payload = // has to be: ..., Vector3.zero, Quaternion.identity => SetParent
+            Instantiate(fOUI.gameObject, Vector3.zero, Quaternion.identity);
 
-        RenderedFactObject.transform.SetParent(gameObject.transform, worldPositionStays: false);
+        _Payload.transform.SetParent(gameObject.transform, worldPositionStays: false);
+        _Payload.GetComponent<CanvasGroup>().blocksRaycasts = true; // Reverse drag effect
     }
-
-    public void OnPointerClick(PointerEventData eventData)
-        => _DeleteFactEvent(null);
     #endregion DropHandling 
 }
diff --git a/Assets/Scripts/InteractionEngine/ShinyThings.cs b/Assets/Scripts/InteractionEngine/ShinyThings.cs
index 5933e36d4c2b2fbe18d170de44fe2abaefc333f3..8701d50dd72bdaa3f852e355199bdf2a1f4e64b2 100644
--- a/Assets/Scripts/InteractionEngine/ShinyThings.cs
+++ b/Assets/Scripts/InteractionEngine/ShinyThings.cs
@@ -3,6 +3,7 @@
 using System.Linq;
 using UnityEngine;
 using static FactWrapper;
+using static Scroll;
 
 public class ShinyThings : MonoBehaviour
 {
@@ -114,11 +115,11 @@ IEnumerator _BlossomAndDie()
             while (sparks.IsAlive())
                 yield return null;
 
-            GameObject.Destroy(firework);
+            Destroy(firework);
         }
     }
 
-    public void LetItRain(Fact startFact, Scroll.ScrollApplicationInfo _)
+    public void LetItRain()
     {
         // check if couroutine is waiting or finished 
         if (!rain_wait.MoveNext() || !rain.MoveNext())
@@ -126,12 +127,12 @@ public void LetItRain(Fact startFact, Scroll.ScrollApplicationInfo _)
             StopCoroutine(rain);
             StartCoroutine(rain = _BlossomAndDie());
         }
-        rain_wait = 0f.LerpInTime(0, timerDuration); //reset timer
+        rain_wait = IEnumeratorExtensions.ClockForSeconds(timerDuration); //reset timer
 
         IEnumerator _BlossomAndDie()
         {
             Destroy(active_rainwork);
-            active_rainwork = GameObject.Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity);
+            active_rainwork = Instantiate(RainPrefab, new Vector3(0, 40, 0), Quaternion.identity);
 
             Color start = directionalLight.color; // may not be original one
             for (IEnumerator<float> lerper = MathfExtensions.LerpInTime(0, 1, lerpTime)
@@ -151,7 +152,7 @@ IEnumerator _BlossomAndDie()
                 yield return null;
             }
 
-            GameObject.Destroy(active_rainwork);
+            Destroy(active_rainwork);
         }
     }
 }
diff --git a/Assets/Scripts/InventoryStuff/DisplayFacts.cs b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
index fc54a78a47d753aa67716877c671a6e5054e54a6..129aa3b07df0d806abc8a09c34571fed3e576222 100644
--- a/Assets/Scripts/InventoryStuff/DisplayFacts.cs
+++ b/Assets/Scripts/InventoryStuff/DisplayFacts.cs
@@ -128,16 +128,14 @@ public void AddFact(Fact fact)
         );
 
         display.transform.parent.transform.SetSiblingIndex(siblingIdx);
+    }
 
-        return;
-
-        GameObject CreateDisplay(Fact fact, Transform transform)
-        {
-            var spot = Instantiate(FactSpotPrefab, transform);
-            spot.GetComponent<FactWrapper>().Fact = fact;
+    public static GameObject CreateDisplay(Fact fact, Transform transform)
+    {
+        var spot = Instantiate(FactSpotPrefab, transform);
+        spot.GetComponent<FactWrapper>().Fact = fact;
 
-            return InstantiateDisplay(fact, spot.transform);
-        }
+        return InstantiateDisplay(fact, spot.transform);
     }
 
     public static GameObject InstantiateDisplay(Fact fact, Transform transform)
diff --git a/Assets/Scripts/InventoryStuff/ScrollDetails.cs b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
index eedf91dc552fb5df40e16d6abb8ee1482c291d4c..9da20bfbb9c06b29e63b96bfb3e5306bae9ffbb5 100644
--- a/Assets/Scripts/InventoryStuff/ScrollDetails.cs
+++ b/Assets/Scripts/InventoryStuff/ScrollDetails.cs
@@ -7,10 +7,24 @@
 using System.Linq;
 using static CommunicationEvents;
 using static SOMDocManager;
-using static GlobalBehaviour;
+using System;
+using static Scroll;
 
 public class ScrollDetails : MonoBehaviour
 {
+    public static ScrollDetails Instance
+    {
+        get => _Instance;
+        set
+        {
+            if (_Instance == null)
+                _Instance = value;
+            else
+                Destroy(value);
+        }
+    }
+    private static ScrollDetails _Instance;
+
     public WorldCursor cursor;
     public GameObject parameterDisplayPrefab;
     public Scroll ActiveScroll;
@@ -18,7 +32,7 @@ public class ScrollDetails : MonoBehaviour
     private PopupBehavior Popup;
 
     public static List<RenderedScrollFact> ParameterDisplays;
-    private static List<Scroll.ScrollAssignment> LatestCompletions;
+    private static List<ScrollAssignment> LatestCompletions;
     private static List<Fact> LatestRenderedHints;
 
     public string currentMmtAnswer;
@@ -26,14 +40,17 @@ public class ScrollDetails : MonoBehaviour
     public bool DynamicScrollDescriptionsActive = true;
     public bool AutomaticHintGenerationActive = true;
 
+    private bool DynamicScrollDone = true;
 
     void Awake()
     {
+        Instance = this;
+
         if (cursor == null)
             cursor = FindObjectOfType<WorldCursor>();
 
-        (Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>())
-            .hidePopUp();
+        Popup = mmtAnswerPopUp.GetComponent<PopupBehavior>();
+        Popup.gameObject.SetActive(true); // force Awake
     }
 
     private void OnEnable()
@@ -48,6 +65,11 @@ private void OnDisable()
         NewAssignmentEvent.RemoveListener(NewAssignmentTrigger);
     }
 
+    private void OnDestroy()
+    {
+        _Instance = null;
+    }
+
     public void SetScroll(Scroll scroll_to_set)
     {
         ActiveScroll = scroll_to_set;
@@ -84,6 +106,30 @@ public void SetScroll(Scroll scroll_to_set)
         Popup.ParameterDisplays = ParameterDisplays;
     }
 
+    public bool SetNextEmptyTo(FactObjectUI activator)
+    {
+        RenderedScrollFact check = ParameterDisplays
+            .Find(RSF => RSF != null
+                      && RSF.Payload != null
+                      && RSF.Payload.Equals(activator)
+        );
+
+        if (check != null)
+        {
+            check.URI = null;
+            return false;
+        }
+
+        RenderedScrollFact empty = ParameterDisplays
+            .Find(RSF => !RSF.IsSet);
+
+        if (empty == null)
+            return false;
+
+        empty.SetByFactObject(activator);
+        return true;
+    }
+
     /// <summary>
     /// Secretly populates <see cref="Scroll"/>s
     /// </summary>
@@ -106,22 +152,31 @@ public void MagicButtonTrigger()
 
         IEnumerator _MagicButton()
         {
+            while (!DynamicScrollDone)
+                yield return null; // Wait for last assignment
+
+            DynamicScrollDone = false;
             yield return SendView("/scroll/apply");
+            DynamicScrollDone = true;
 
             if (currentMmtAnswer == null)
             {
                 Debug.LogError("Magic FAILED");
-                PushoutFactFailEvent.Invoke(null, null);
+                ScrollApplicationCheckingErrorEvent.Invoke(null);
             }
             else
             {
                 if (VerboseURI)
                     Debug.Log("Magic answers:\n" + currentMmtAnswer);
 
-                Scroll.ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<Scroll.ScrollApplicationInfo>(currentMmtAnswer);
+                ScrollApplicationInfo pushout = JsonConvert.DeserializeObject<ScrollApplicationInfo>(currentMmtAnswer);
 
-                if (pushout.acquiredFacts.Count == 0)
-                    PushoutFactFailEvent.Invoke(null, pushout);
+                if (pushout.acquiredFacts.Count == 0
+                 || pushout.errors.Length > 0)
+                {
+                    ScrollApplicationCheckingErrorEvent.Invoke(pushout.errors);
+                    PushoutFactFailEvent.Invoke();
+                }
 
                 ReadPushout(pushout.acquiredFacts);
             }
@@ -135,8 +190,12 @@ public void NewAssignmentTrigger()
 
         IEnumerator _NewAssignment()
         {
-            //Non blocking wait till sendView() is finished
+            while (!DynamicScrollDone)
+                yield return null; // if we dont wait => server will crash
+
+            DynamicScrollDone = false;
             yield return SendView("/scroll/dynamic");
+            DynamicScrollDone = true;
 
             if (currentMmtAnswer == null)
             {
@@ -144,7 +203,25 @@ IEnumerator _NewAssignment()
             }
             else
             {
-                Scroll.ScrollDynamicInfo scrollDynamicInfo = JsonConvert.DeserializeObject<Scroll.ScrollDynamicInfo>(currentMmtAnswer);
+                ScrollDynamicInfo scrollDynamicInfo;
+                try
+                {
+                    scrollDynamicInfo = JsonConvert.DeserializeObject<ScrollDynamicInfo>(currentMmtAnswer);
+                }
+                catch (JsonSerializationException ex)
+                {
+                    Debug.LogException(ex);
+                    Debug.LogError("Could not Deserialize MMT aswer for /scroll/dynamic\n" + currentMmtAnswer);
+                    yield break;
+                }
+
+                ScrollApplicationCheckingError[] errors = scrollDynamicInfo.errors
+                    .Where(err => err.kind != "nonTotal") // expected
+                    .ToArray();
+
+                if (errors.Length > 0)
+                    ScrollApplicationCheckingErrorEvent.Invoke(errors);
+
                 processScrollDynamicInfo(scrollDynamicInfo);
             }
         }
@@ -181,22 +258,22 @@ private IEnumerator SendView(string endpoint)
 
         string prepareScrollAssignments()
         {
-            List<Scroll.ScrollAssignment> assignmentList = new();
+            List<ScrollAssignment> assignmentList = new();
 
             for (int i = 0; i < ParameterDisplays.Count; i++)
             {
                 Fact tempFact = ParameterDisplays[i].Fact;
                 if (tempFact != null)
-                    assignmentList.Add(new Scroll.ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
+                    assignmentList.Add(new ScrollAssignment(ActiveScroll.requiredFacts[i].@ref.uri, tempFact.Id));
             }
 
-            return JsonConvert.SerializeObject(new Scroll.FilledScroll(ActiveScroll.@ref, assignmentList));
+            return JsonConvert.SerializeObject(new FilledScroll(ActiveScroll.@ref, assignmentList));
         }
     }
 
     private void ReadPushout(List<MMTDeclaration> pushoutFacts)
     {
-        Popup.hidePopUp(); //close error Window
+        Popup.HidePopUp(); //close error Window
 
         bool samestep = false;
         for (int i = 0; i < pushoutFacts.Count; i++)
@@ -215,11 +292,11 @@ private void ReadPushout(List<MMTDeclaration> pushoutFacts)
         }
     }
 
-    private void processScrollDynamicInfo(Scroll.ScrollDynamicInfo scrollDynamicInfo)
+    private void processScrollDynamicInfo(ScrollDynamicInfo scrollDynamicInfo)
     {
         LatestCompletions = scrollDynamicInfo.completions.Count > 0
             ? scrollDynamicInfo.completions[0]
-            : new List<Scroll.ScrollAssignment>();
+            : new List<ScrollAssignment>();
 
         List<string> hintUris = LatestCompletions
             .Select(completion => completion.fact.uri)
@@ -253,7 +330,7 @@ void _processRenderedScroll(Scroll rendered, List<string> hintUris)
                     RenderedScrollFact.Scroll = rendered;
 
                 //If ScrollFact is assigned -> No Hint
-                if (RenderedScrollFact.Fact == null)
+                if (!RenderedScrollFact.IsSet)
                 {
                     Fact HintFact =
                         ParsingDictionary.parseFactDictionary[rendered.requiredFacts[i].getType()]
@@ -280,10 +357,11 @@ public void animateHint(string scrollParameterUri)
                     FactWrapper.FactMaterials.Hint
                 );
 
-        Scroll.ScrollAssignment suitableCompletion =
+        Fact hintFact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri);
+
+        ScrollAssignment suitableCompletion =
             LatestCompletions.Find(x => x.fact.uri == scrollParameterUri);
 
-        Fact fact;
         if (suitableCompletion != null)
         {
             if (FactOrganizer.AllFacts.ContainsKey(suitableCompletion.assignment.uri))
@@ -294,10 +372,9 @@ public void animateHint(string scrollParameterUri)
                 );
             }
         }
-        else if (null !=
-            (fact = LatestRenderedHints.Find(x => x.Id == scrollParameterUri)))
+        else if (hintFact != null)
         {
-            if (FactOrganizer.FindEquivalent(StageStatic.stage.factState.MyFactSpace, fact, out string found_key, out Fact _, out bool _, false))
+            if (FactOrganizer.FindEquivalent(StageStatic.stage.factState.MyFactSpace, hintFact, out string found_key, out Fact _, out bool _, false))
                 // existing fact -> Animate that
                 AnimateExistingFactEvent.Invoke(
                     found_key,
@@ -305,9 +382,8 @@ public void animateHint(string scrollParameterUri)
                 );
 
             else
-            {
-                // Generate new FactRepresentation and animate it
-                AnimateNonExistingFactEvent.Invoke(fact);
+            {   // Generate new FactRepresentation and animate it
+                AnimateNonExistingFactEvent.Invoke(hintFact);
                 AnimateExistingFactEvent.Invoke(
                     scrollParameterUri,
                     FactWrapper.FactMaterials.Hint
diff --git a/Assets/Scripts/SOMDocManager.cs b/Assets/Scripts/SOMDocManager.cs
index 271b8026a6453c1963e24f9251bc4c5ac456be61..2cc38fefdf94ed082e03da29999f4427aaebb683 100644
--- a/Assets/Scripts/SOMDocManager.cs
+++ b/Assets/Scripts/SOMDocManager.cs
@@ -313,6 +313,7 @@ private static LambdaExpression MakeArray(LambdaExpression[] args_lamda, Paramet
     [JsonSubtypes.KnownSubType(typeof(OMC<Vector3>), "OMC<UnityEngine.Vector3>")]
     [JsonSubtypes.KnownSubType(typeof(OMC<float>), "OMC<System.Single>")]
     [JsonSubtypes.KnownSubType(typeof(OMC<double>), "OMC<System.Double>")]
+    [JsonSubtypes.FallBackSubType(typeof(OMS))] // dirty fix for wrong formated ScrollApplicationCheckingError.fact
     abstract public class SOMDoc
     {
         public string kind;
diff --git a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
index 789f07de1c31e29362d1bb662db848a7f8ce44c2..34f39f3add6159f42246266e30fea5f99b7ddb3f 100644
--- a/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
+++ b/Assets/Scripts/UI/FactExplorer/FactExplorer.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections;
 using System.Collections.Generic;
-using System.Reflection;
 using UnityEngine;
 using System.Linq;
 using UnityEngine.UI;
@@ -22,7 +19,7 @@ public class FactExplorer : MonoBehaviour
     #endregion InspectorVariables
 
     #region Variables
-    private Fact mainFact;
+    public Fact MainFact { get; private set; }
     private List<Fact> parentFacts;
     private List<Fact> childFacts;
     #endregion Variables
@@ -35,7 +32,7 @@ private void Update()
 
     public void Initialize(Fact fact, Vector3 factPosition)
     {
-        mainFact = fact;
+        MainFact = fact;
         parentFacts = GetParentFacts();
         childFacts = GetChildFacts();
 
@@ -50,20 +47,21 @@ public void Initialize(Fact fact, Vector3 factPosition)
 
     #region Implementation
     private List<Fact> GetParentFacts()
-    {   
-        _ = StageStatic.stage.factState.safe_dependencies(mainFact.Id, out var parentFactIds);
-        return parentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).Where(f => f != mainFact).ToList();
+    {
+        StageStatic.stage.factState.safe_dependencies(MainFact.Id, out var parentFactIds);
+        return parentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).Where(f => f != MainFact).ToList();
     }
 
     private List<Fact> GetChildFacts()
-    {
-        return mainFact.DependentFactIds.Distinct().Select(factId => FactOrganizer.AllFacts[factId]).ToList();
-    }
+        => MainFact.DependentFactIds
+                .Distinct()
+                .Select(factId => FactOrganizer.AllFacts[factId])
+                .ToList();
 
     private void UpdateFactExplorerUI()
     {
         SpawnUIFacts(factParentsUI, parentFacts);
-        SpawnUIFacts(mainFactUI, new List<Fact>() { mainFact });
+        SpawnUIFacts(mainFactUI, new List<Fact>() { MainFact });
         SpawnUIFacts(factChildrenUI, childFacts);
 
         // Force rebuild of FactExplorer layout, since the positions of the factObjects will be wrong otherwise
@@ -76,8 +74,9 @@ private void UpdateFactExplorerUI()
     private void DestroyIfClickedOutside()
     {
         // Destroy on tab press or left click outside of FactExplorer
-        if (Input.GetKeyDown(KeyCode.Tab) 
-            || (Input.GetMouseButtonDown(0) && !RectTransformUtility.RectangleContainsScreenPoint(transform.GetComponent<RectTransform>(), Input.mousePosition, null)))
+        if (Input.GetKeyDown(KeyCode.Tab)
+         || (Input.GetMouseButtonDown(0)
+          && !RectTransformUtility.RectangleContainsScreenPoint(transform.GetComponent<RectTransform>(), Input.mousePosition, null)))
         {
             Destroy(gameObject);
         }
@@ -111,13 +110,8 @@ private void SpawnUIFacts(Transform uiParent, List<Fact> toSpawn)
             uiParent.gameObject.SetActive(false);
 
         foreach (Fact fact in toSpawn)
-        {
-            var spot = Instantiate(factSpotPrefab, uiParent);
-
-            // TODO: this link to DisplayFacts is not ideal: maybe refactor to SciptableObject or such
-            var display = DisplayFacts.InstantiateDisplay(fact, spot.transform);
-            display.transform.localPosition = Vector3.zero;
-        }
+            // TODO: SE: this link to DisplayFacts is not ideal: maybe refactor to SciptableObject or such
+            DisplayFacts.CreateDisplay(fact, uiParent);
     }
 
     private void SpawnParentLines(GameObject parent, Transform mainFactUI)
@@ -125,7 +119,7 @@ private void SpawnParentLines(GameObject parent, Transform mainFactUI)
         var mainTransform = mainFactUI.GetComponent<RectTransform>();
         var factWidth = mainTransform.rect.width;
         // transform.positions are weird due to LayoutGroups => manually calculate offset
-        float xOffset = -factParentsUI.GetComponent<RectTransform>().rect.width / 2 +  factWidth / 2;
+        float xOffset = -factParentsUI.GetComponent<RectTransform>().rect.width / 2 + factWidth / 2;
         float yOffset = transform.GetComponent<VerticalLayoutGroup>().spacing;
         parent.ForAllChildren(par =>
         {
@@ -155,7 +149,7 @@ private void SpawnChildLines(GameObject parent, Transform mainFactUI)
 
             var uiLine = line.GetComponent<UILine>();
             uiLine.points = new List<Vector2>() {
-                Vector2.zero, 
+                Vector2.zero,
                 new Vector2(0, -yOffset/2),
                 new Vector2(-xOffset, -yOffset/2),
                 new Vector2(-xOffset, -yOffset)
diff --git a/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs b/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs
index 9d9bd45e06ba49f87db1e01c689fdf80d4c6632c..4f1afd71217476405c1192363a2be484336b2112 100644
--- a/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs
+++ b/Assets/Scripts/UI/FactExplorer/OpenFactExplorer.cs
@@ -1,8 +1,6 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
 using UnityEngine;
 using UnityEngine.EventSystems;
+using static UnityEngine.EventSystems.PointerEventData;
 
 [RequireComponent(typeof(FactWrapper), typeof(RectTransform), typeof(DragHandling))]
 public class OpenFactExplorer : MonoBehaviour, IPointerClickHandler
@@ -13,23 +11,30 @@ public class OpenFactExplorer : MonoBehaviour, IPointerClickHandler
     private static Transform factExplorer;
     private float pressTime = 0f;
     private const float LONG_PRESS_DURATION = 0.5f;
+    private bool beganTouch = false;
 
     private DragHandling CachedDragHandling;
+    private FactWrapper CachedFactWrapper;
     #endregion Variables
 
     #region UnityMethods
     public void OnPointerClick(PointerEventData eventData)
-    {
-        // open FactExplorer on right click on PC
-        if (eventData.button == PointerEventData.InputButton.Right)
-        {
+    { // Handles PC clicks
+        if (eventData.dragging)
+            return;
+
+        if (eventData.button == InputButton.Right)
             DoOpenFactExplorer();
-        }
+        else
+        if (eventData.button == InputButton.Left
+         )//&& eventData.clickCount >= 2)
+            DoSetActive();
     }
 
     private void Awake()
     {
         CachedDragHandling = GetComponent<DragHandling>();
+        CachedFactWrapper = GetComponent<FactWrapper>();
     }
 
     private void Update()
@@ -57,31 +62,54 @@ private void HandleTouches()
 
         switch (touch.phase)
         {
-            case TouchPhase.Moved:
             case TouchPhase.Began:
+                beganTouch = true;
+                pressTime = 0;
+                break;
+
             case TouchPhase.Ended:
+                if (beganTouch
+                 && pressTime < LONG_PRESS_DURATION)
+                    DoSetActive();
+                goto case TouchPhase.Canceled;
+
+            case TouchPhase.Moved:
             case TouchPhase.Canceled:
+                beganTouch = false;
                 pressTime = 0;
                 break;
 
             case TouchPhase.Stationary:
                 pressTime += Time.deltaTime;
                 if (pressTime >= LONG_PRESS_DURATION)
+                {
                     DoOpenFactExplorer();
+                    goto case TouchPhase.Canceled;
+                }
                 break;
         }
     }
 
     private void DoOpenFactExplorer()
     {
-        Destroy(factExplorer != null ? factExplorer.gameObject : null);
+        if (factExplorer != null
+         && factExplorer.GetComponent<FactExplorer>().MainFact.Id == CachedFactWrapper.URI)
+        {
+            Destroy(factExplorer.gameObject);
+            return;
+        }
+
+        if (factExplorer != null)
+            Destroy(factExplorer.gameObject);
 
         var parent = transform.GetComponentInParent<Canvas>().transform;
-        var fact = transform.GetComponent<FactWrapper>().Fact;
 
         factExplorer = Instantiate(factExplorerPrefab.transform, Input.mousePosition, Quaternion.identity, parent);
-        factExplorer.GetComponent<FactExplorer>().Initialize(fact, transform.position);
+        factExplorer.GetComponent<FactExplorer>().Initialize(CachedFactWrapper.Fact, transform.position);
     }
+
+    private bool DoSetActive()
+        => ScrollDetails.Instance.SetNextEmptyTo(CachedFactWrapper as FactObjectUI);
     #endregion Implementation
 }
 
diff --git a/Assets/Scripts/UI/InGame/PopupBehavior.cs b/Assets/Scripts/UI/InGame/PopupBehavior.cs
index 7228809397fcf048b620afb1b8c027ae488b08b8..bf528da2bd147f840710446bc1a63c49a24a659e 100644
--- a/Assets/Scripts/UI/InGame/PopupBehavior.cs
+++ b/Assets/Scripts/UI/InGame/PopupBehavior.cs
@@ -5,6 +5,7 @@
 using UnityEngine.UI;
 using System.Linq;
 using static SOMDocManager;
+using static Scroll;
 
 public class PopupBehavior : MonoBehaviour
 {
@@ -12,6 +13,11 @@ public class PopupBehavior : MonoBehaviour
     [SerializeField] GameObject canvas;
     [SerializeField] Button CloseButton;
     [SerializeField] TMP_Text message;
+    public string MessageText
+    {
+        get => message.text;
+        set => message.text = value;
+    }
 
     public Scroll ActiveScroll { private get; set; }
     public List<RenderedScrollFact> ParameterDisplays { private get; set; }
@@ -21,59 +27,56 @@ public class PopupBehavior : MonoBehaviour
     public string UnknownErrorMessage = "Unkown error - did you apply all facts?";
     public string InvalidAssignmentMessage = "Invalid Assignment";
 
-    private string errorMessage = "";
-    // Start is called before the first frame update
+    private string errorMessage;
+
+    #region UnityMethods
     void Awake()
     {
-        CommunicationEvents.PushoutFactFailEvent.AddListener(onFailedScrollInput);
+        CommunicationEvents.ScrollApplicationCheckingErrorEvent.AddListener(OnFailedScrollInput);
 
         CloseButton.onClick.RemoveAllListeners();
-        CloseButton.onClick.AddListener(hidePopUp);
-    }
+        CloseButton.onClick.AddListener(HidePopUp);
 
-    public void setMessage(string errorMessage)
-    {
-        this.message.text = errorMessage;
+        HidePopUp();
     }
+    #endregion UnityMethods
 
-    public void showPopUp()
+    public void ShowTimedPopUp()
     {
         canvas.SetActive(true);
-        StartCoroutine(hideAfter5sec());
+        StartCoroutine(_BlossomAndDie());
 
-        IEnumerator hideAfter5sec()
+        IEnumerator _BlossomAndDie()
         {
-            yield return new WaitForSeconds(5);
-            hidePopUp();
+            yield return new WaitForSeconds(GlobalBehaviour.HintAnimationDuration);
+            HidePopUp();
         }
     }
 
-    public void hidePopUp()
-    {
-        canvas.SetActive(false);
-    }
+    public void HidePopUp()
+        => canvas.SetActive(false);
 
     /// <summary>
     /// this method creates a helpful error message and shows the popup. For it to work properly, the setScroll and setParameterDisplays must have been set.
     /// </summary>
     /// <param name="startfact"></param>
     /// <param name="errorInfo"></param>
-    public void onFailedScrollInput(Fact startfact, Scroll.ScrollApplicationInfo errorInfo)
+    public void OnFailedScrollInput(ScrollApplicationCheckingError[] errorInfo)
     {
-        setMessage(generateHelpfulMessageAndAnimateScrollParam(errorInfo));
-        showPopUp();
+        MessageText = generateHelpfulMessageAndAnimateScrollParam(errorInfo);
+        ShowTimedPopUp();
     }
 
-    private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicationInfo errorInfo)
+    private string generateHelpfulMessageAndAnimateScrollParam(ScrollApplicationCheckingError[] errorInfo)
     {
         if (errorInfo == null)
             return ServerErrorMessage;
 
         int invAssCount = 0;
         errorMessage = "";
-        for (int i = 0; i < errorInfo.errors.Length; i++)
+        for (int i = 0; i < errorInfo.Length; i++)
         {
-            Scroll.ScrollApplicationCheckingError error = errorInfo.errors[i];
+            ScrollApplicationCheckingError error = errorInfo[i];
 
             //check which error ocurred and set Message to a helpful error message.
             if (error.kind == "nonTotal")
@@ -120,11 +123,11 @@ private string generateHelpfulMessageAndAnimateScrollParam(Scroll.ScrollApplicat
     }
 
     //this should be changed, the Fact Object should be parsed by JSON. This is a workaround because the MMT servers JSON serialization contains a bug
-    private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError error)
+    private MMTDeclaration parseFactFromError(ScrollApplicationCheckingError error)
     {
         if (error == null || error.msg == null)
             return null;
-        
+
         string message = error.msg;
 
         //cut start of string
@@ -145,6 +148,6 @@ private MMTDeclaration parseFactFromError(Scroll.ScrollApplicationCheckingError
 
         //find the required fact in the active scroll thats invalidly assigned
         return ActiveScroll?.requiredFacts
-            .FirstOrDefault(decl => decl.@ref.uri.Equals(factUri));
+            .Find(decl => decl.@ref.uri == (error.fact as OMS).uri);
     }
 }