diff --git a/Assets/Images/ScreenCapture.png b/Assets/Images/ScreenCapture.png
index c70705a944c0543d3f0bba7d25c34dc113ccc5a7..621c446729514d79f2d8af748ac71210a23b818d 100644
Binary files a/Assets/Images/ScreenCapture.png and b/Assets/Images/ScreenCapture.png differ
diff --git a/Assets/Plugins/EasyRoads3D/images/Thumbs.db b/Assets/Plugins/EasyRoads3D/images/Thumbs.db
deleted file mode 100644
index 0f6e502921fa95db1f1a15556ef226070e1bef1b..0000000000000000000000000000000000000000
Binary files a/Assets/Plugins/EasyRoads3D/images/Thumbs.db and /dev/null differ
diff --git a/Assets/Plugins/EasyRoads3D/images/Thumbs.db.meta b/Assets/Plugins/EasyRoads3D/images/Thumbs.db.meta
deleted file mode 100644
index 4c1cc9d5ca5a6849a9d4ea4873d43ec27cc713c3..0000000000000000000000000000000000000000
--- a/Assets/Plugins/EasyRoads3D/images/Thumbs.db.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 903066108a5d14444b8c9ffda790e310
-timeCreated: 1471875076
-licenseType: Store
-DefaultImporter:
-  userData: 
-  assetBundleName: 
-  assetBundleVariant: 
diff --git a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
index ddbb4f527b3b5e8805311c87443a080d414f328b..ff8eeb7496ba6b90e2ecffee24e7cd1f6a04dd8f 100644
--- a/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
+++ b/Assets/Scripts/InteractionEngine/CommunicationEvents.cs
@@ -54,6 +54,8 @@ public class AnimationEventWithUris : UnityEvent<List<string>> { }
     //TODO? [SolutionManager, List<[HashSet<string>, FactComparer]>]
     public static List<Fact> Solution = new List<Fact>();
 
+    public static (FactOrganizer, List<(HashSet<string>, FactComparer)>) SolutionSet;
+
     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 3432465952c8f0ac10c9d9b5d55d1b1d4316964c..2185116ec7c25fa6540c02c368804640cda2f462 100644
--- a/Assets/Scripts/InteractionEngine/Fact.cs
+++ b/Assets/Scripts/InteractionEngine/Fact.cs
@@ -388,7 +388,7 @@ public override Boolean hasDependentFacts() {
     }
 
     public override string[] getDependentFactIds() {
-        return new string[] { }; ;
+        return new string[] { };
     }
 
     public override GameObject instantiateDisplay(GameObject prefab, Transform transform) {
@@ -405,7 +405,7 @@ public override int GetHashCode()
 
     protected override bool EquivalentWrapped(PointFact f1, PointFact f2)
     {
-        return f1.Point == f2.Point;
+        return Math3d.IsApproximatelyEqual(f1.Point, f2.Point);
     }
 
 }
diff --git a/Assets/Scripts/InteractionEngine/FactOrganizer.cs b/Assets/Scripts/InteractionEngine/FactOrganizer.cs
index 76ad5c7fb489e5ce5a5c9ec15ec33dbf87dd6984..1b4c69f5d512483c2323ed8a17732d75f86d8541 100644
--- a/Assets/Scripts/InteractionEngine/FactOrganizer.cs
+++ b/Assets/Scripts/InteractionEngine/FactOrganizer.cs
@@ -7,7 +7,6 @@
 using System.Linq;
 using System;
 
-//TODO? PERF? (often inserts) SortedDict <-> Dict (often reads)
 //TODO: MMT: move some functionality there
 //TODO: consequent!= samestep != dependent
 
@@ -547,6 +546,38 @@ public bool DynamiclySolved(List<Fact> MinimalSolution, out List<Fact> MissingEl
         return MissingElements.Count == 0;
     }
 
+    //TODO: repair
+    public bool DynamiclySolvedEXP(
+        (FactOrganizer solutionorganizer, List<(HashSet<string> subsolution, FactComparer comparer)> validationsets) MinimalSolution,
+        out List<List<string>> MissingElements,
+        out List<List<string>> Solutions)
+    {
+        MissingElements = new List<List<string>>();
+        Solutions = new List<List<string>>();
+
+        int MissingElementsCount = 0;
+        var activeList = FactDict.Values.Where(f => MetaInf[f.Id].active);
+
+        foreach (var ValidationSet in MinimalSolution.validationsets)
+        {
+            var part_minimal = 
+                ValidationSet.subsolution.Select(URI => MinimalSolution.solutionorganizer[URI]);
+
+            var part_solution =
+                activeList.Where(active => part_minimal.Contains(active, ValidationSet.comparer.SetSearchRight()));
+
+            var part_missing =
+                part_minimal.Except(part_solution, ValidationSet.comparer.SetSearchLeft());
+
+            Solutions.Add(part_solution.Select(fact => fact.Id).ToList());
+            MissingElements.Add(part_missing.Select(fact => fact.Id).ToList());
+
+            MissingElementsCount += part_missing.Count();
+        }
+
+        return MissingElementsCount == 0;
+    }
+
 }
 
 
diff --git a/Assets/Scripts/Level.cs b/Assets/Scripts/Level.cs
index 49eadeef8cc6dd77782df6f18409fd3e0e6edae2..039474c8b5ba5349fbfb0eb70d7ab08f9d1c2587 100644
--- a/Assets/Scripts/Level.cs
+++ b/Assets/Scripts/Level.cs
@@ -24,17 +24,29 @@ void Start()
         LineFact target = new LineFact(buttom.Id, top.Id, SolutionManager);
         Solution.Add(SolutionManager[SolutionManager.Add(target, out _, true)]);
         Fact.Clear();
+
+        SolutionSet = (SolutionManager,
+            new List<(HashSet<string>, FactComparer)> 
+            { (new HashSet<string> { target.Id, buttom.Id }, new LineFactHightDirectionComparer()) });
     }
 
     public static bool gameSolved()
     {
         bool solved =
             LevelFacts.DynamiclySolved(Solution, out _, out List<Fact> hits, FactComparer: new LineFactHightDirectionComparer());
+        bool solvedEXP =
+            LevelFacts.DynamiclySolvedEXP(SolutionSet, out _, out List<List<string>> hitsEXP);
+
 
         if (solved)
             foreach (var hit in hits)
                 AnimateExistingFactEvent.Invoke(hit);
 
+        if (solvedEXP)
+            foreach (var hitlist in hitsEXP)
+                foreach(var hit in hitlist)
+                    AnimateExistingFactEvent.Invoke(LevelFacts[hit]);
+
         return solved;
     }
 
diff --git a/Assets/Scripts/Math3d.cs b/Assets/Scripts/Math3d.cs
index 73156d61f7c638b7db57178e8956e69027c5a9bf..69d83484d2078f0b255412549523e0ec23757ec1 100644
--- a/Assets/Scripts/Math3d.cs
+++ b/Assets/Scripts/Math3d.cs
@@ -556,6 +556,12 @@ public static bool IsApproximatelyParallel(Vector3 vectorA, Vector3 vectorB, dou
              < precission;
     }
 
+    //This function returns true if two Vector3s are approximately Equal
+    public static bool IsApproximatelyEqual(Vector3 vectorA, Vector3 vectorB, double precission = Math3d.vectorPrecission)
+    {
+        return (vectorA - vectorB).sqrMagnitude < precission;
+    }
+
     //This function returns a point which is a projection from a point to a line segment.
     //If the projected point lies outside of the line segment, the projected point will 
     //be clamped to the appropriate line edge.
diff --git a/ProjectSettings/ProjectVersion.txt b/ProjectSettings/ProjectVersion.txt
index 5ac0724b154edd981a56dd62063814d09c931b38..35d8282d7654b7ecbe1a9f92cddeef016be6e089 100644
--- a/ProjectSettings/ProjectVersion.txt
+++ b/ProjectSettings/ProjectVersion.txt
@@ -1,2 +1,2 @@
-m_EditorVersion: 2020.3.15f2
-m_EditorVersionWithRevision: 2020.3.15f2 (6cf78cb77498)
+m_EditorVersion: 2020.3.16f1
+m_EditorVersionWithRevision: 2020.3.16f1 (049d6eca3c44)