class WorkSync {

    public AsyncApply applyAsync( W work )
    {
        // Schedule our work on the stack.
        WorkUnit<Material,W> unit = enqueueWork( work );

        // Apply the work if the lock is immediately available.
        Throwable initialThrowable = tryDoWork( unit, 100, false );

        return new AsyncApply()
        {
            Throwable throwable = initialThrowable;

            @Override
            public void await() throws ExecutionException
            {

                checkFailure( throwable );
                int tryCount = 0;
                while ( !unit.isDone() )
                {
                    tryCount++;
                    checkFailure( throwable = tryDoWork( unit, tryCount, true ) );
                }
            }
        };
    }

    public  WorkSync( Material material );

}