// Path: src/main/java/com/github/phantomthief/failover/util/SharedResourceV2.java
// public static class UnregisterFailedException extends RuntimeException {
// 
//     private final Object removed;
// 
//     private UnregisterFailedException(Throwable cause, Object removed) {
//         super(cause);
//         this.removed = removed;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T getRemoved() {
//         return (T) removed;
//     }
// }


import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.github.phantomthief.failover.util.SharedResourceV2.UnregisterFailedException;
import com.google.common.util.concurrent.Uninterruptibles;
        assertFalse(mockResource1.isShutdown());

        resources.unregister("1");
        mockResource1 = resources.get("1");
        assertNotNull(mockResource1);
        assertFalse(mockResource1.isShutdown());

        resources.unregister("1");
        assertTrue(mockResource1.isShutdown());
        mockResource1 = resources.get("1");
        assertNull(mockResource1);
    }

    @Test
    void testUnpairUnregister() {
        resources.register("3");
        MockResource mock = resources.get("3");
        assertSame(mock, resources.unregister("3"));
        assertThrows(IllegalStateException.class,
                () -> resources.unregister("3"));
    }

    @Test
    void testCleanupFailed() {
        SharedResourceV2<String, MockResource> resources =
                new SharedResourceV2<>(MockResource::new, it -> {
                    throw new IllegalArgumentException();
                });
        resources.register("4");
        MockResource mock = resources.get("4");
// Path: src/main/java/com/github/phantomthief/failover/util/SharedResourceV2.java
// public static class UnregisterFailedException extends RuntimeException {
// 
//     private final Object removed;
// 
//     private UnregisterFailedException(Throwable cause, Object removed) {
//         super(cause);
//         this.removed = removed;
//     }
// 
//     @SuppressWarnings("unchecked")
//     public <T> T getRemoved() {
//         return (T) removed;
//     }
// }


// Path: src/test/java/com/github/phantomthief/failover/util/SharedResourceV2Test.java
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.github.phantomthief.failover.util.SharedResourceV2.UnregisterFailedException;
import com.google.common.util.concurrent.Uninterruptibles;

        assertFalse(mockResource1.isShutdown());

        resources.unregister("1");
        mockResource1 = resources.get("1");
        assertNotNull(mockResource1);
        assertFalse(mockResource1.isShutdown());

        resources.unregister("1");
        assertTrue(mockResource1.isShutdown());
        mockResource1 = resources.get("1");
        assertNull(mockResource1);
    }

    @Test
    void testUnpairUnregister() {
        resources.register("3");
        MockResource mock = resources.get("3");
        assertSame(mock, resources.unregister("3"));
        assertThrows(IllegalStateException.class,
                () -> resources.unregister("3"));
    }

    @Test
    void testCleanupFailed() {
        SharedResourceV2<String, MockResource> resources =
                new SharedResourceV2<>(MockResource::new, it -> {
                    throw new IllegalArgumentException();
                });
        resources.register("4");
        MockResource mock = resources.get("4");
        UnregisterFailedException e = assertThrows(UnregisterFailedException.class,