import java.util.concurrent.*;

public class ScopedValueDemo {
    static final ScopedValue<String> USER = ScopedValue.newInstance();

    static void show(String label) {
        System.out.println(label + " -> " + (USER.isBound() ? USER.get() : "<unbound>"));
    }

    public static void main(String[] args) throws Exception {
        show("before");

        ScopedValue.where(USER, "alice").run(() -> {
            show("inside");
            ScopedValue.where(USER, "bob").run(() -> show("nested"));
            show("restored");

            Thread child = Thread.ofVirtual().start(() -> show("child virtual"));
            try {
                child.join();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });

        show("after");
    }
}
