package mb.statix.solver;

import io.usethesource.capsule.Set;
import mb.nabl2.terms.ITerm;
import mb.nabl2.terms.ITermVar;
import mb.nabl2.util.CapsuleUtil;
import mb.statix.scopegraph.reference.CriticalEdge;

public class Delay extends Throwable {

    private static final long serialVersionUID = 1L;

    private final Set.Immutable<ITermVar> vars;
    private final Set.Immutable<CriticalEdge> criticalEdges;

    public Delay(Iterable<? extends ITermVar> vars, Iterable<CriticalEdge> criticalEdges) {
        super("delayed", null, false, false);
        this.vars = CapsuleUtil.toSet(vars);
        this.criticalEdges = CapsuleUtil.toSet(criticalEdges);
    }

    public Set.Immutable<ITermVar> vars() {
        return vars;
    }

    public Set.Immutable<CriticalEdge> criticalEdges() {
        return criticalEdges;
    }

    public Delay retainAll(Iterable<? extends ITermVar> vars, Iterable<? extends ITerm> scopes) {
        final Set.Immutable<ITermVar> retainedVars = this.vars.__retainAll(CapsuleUtil.toSet(vars));
        final Set.Immutable<ITerm> scopeSet = CapsuleUtil.toSet(scopes);
        final Set.Transient<CriticalEdge> retainedCriticalEdges = Set.Transient.of();
        this.criticalEdges.stream().filter(ce -> scopeSet.contains(ce.scope()))
                .forEach(retainedCriticalEdges::__insert);
        return new Delay(retainedVars, retainedCriticalEdges.freeze());
    }

    public Delay removeAll(Iterable<? extends ITermVar> vars, Iterable<? extends ITerm> scopes) {
        final Set.Immutable<ITermVar> retainedVars = this.vars.__removeAll(CapsuleUtil.toSet(vars));
        final Set.Immutable<ITerm> scopeSet = CapsuleUtil.toSet(scopes);
        final Set.Transient<CriticalEdge> retainedCriticalEdges = Set.Transient.of();
        this.criticalEdges.stream().filter(ce -> !scopeSet.contains(ce.scope()))
                .forEach(retainedCriticalEdges::__insert);
        return new Delay(retainedVars, retainedCriticalEdges.freeze());
    }

    public static Delay of() {
        return new Delay(Set.Immutable.of(), Set.Immutable.of());
    }

    public static Delay ofVar(ITermVar var) {
        return ofVars(Set.Immutable.of(var));
    }

    public static Delay ofVars(Iterable<ITermVar> vars) {
        return new Delay(vars, Set.Immutable.of());
    }

    public static Delay ofCriticalEdge(CriticalEdge edge) {
        return new Delay(Set.Immutable.of(), Set.Immutable.of(edge));
    }

}
@@ -1972,32 +1972,342 @@
 eeze());%0A    %7D%0A%0A
+    @Override public String toString() %7B%0A        final StringBuilder sb = new StringBuilder();%0A        sb.append(%22Delay(%22);%0A        sb.append(%22vars=%22).append(vars);%0A        sb.append(%22, %22);%0A        sb.append(%22criticalEdges=%22).append(criticalEdges);%0A        sb.append(%22)%22);%0A        return sb.toString();%0A    %7D%0A%0A
     public stati

Add toString to Delay.