@Test
public void enhancerAppearsThreadsafe() throws InterruptedException {

    int iter = 5000;
    int threads = 10;
    ExecutorService exec = Executors.newFixedThreadPool(threads);
    final CountDownLatch start = new CountDownLatch(1);
    final CountDownLatch done = new CountDownLatch(threads * iter);
    final List<SampleClass2> newObjects = Collections.synchronizedList(new ArrayList<SampleClass2>());
    final List<Enhancer<SampleClass2>> enhancers = new ArrayList<Enhancer<SampleClass2>>();
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    enhancers.add(EnhancerHelper.makePersistentEnhancer(SampleClass2.class));
    for (int i = 0; i < threads * iter; i++) {
        exec.submit(new Runnable() {
            public void run() {
                try {
                    Enhancer<SampleClass2> enhancer = enhancers.get(newObjects.size() % enhancers.size());
                    SampleClass2 test = enhancer.newInstance();
                    ((Snapshot) test).snapshot();
                    start.await();
                    long bar = System.nanoTime();
                    assertDirty(test, false);
                    test.setBar(bar);
                    assertEquals(bar, test.getBar());
                    assertDirty(test, true);
                    newObjects.add(test);
                } catch (Exception e) {
                    e.printStackTrace();
                    // failure will be caught by not enough objects in collection at end
                } finally {
                    done.countDown();
                }
            }
        });
    }
    start.countDown();
    done.await();
    assertEquals("Bug in test", 0, exec.shutdownNow().size());
    assertEquals(threads * iter, newObjects.size());
}