class SwapperSet {

    synchronized int allocate( PageSwapper swapper )
    {
        SwapperMapping[] swapperMappings = this.swapperMappings;

        // First look for an available freed slot.
        synchronized ( free )
        {
            if ( !free.isEmpty() )
            {
                int id = free.intIterator().next();
                free.remove( id );
                swapperMappings[id] = new SwapperMapping( id, swapper );
                this.swapperMappings = swapperMappings; // Volatile store synchronizes-with loads in getters.
                return id;
            }
        }

        // No free slot was found above, so we extend the array to make room for a new slot.
        int id = swapperMappings.length;
        if ( id + 1 > MAX_SWAPPER_ID )
        {
            throw new IllegalStateException( "All swapper ids are allocated: " + MAX_SWAPPER_ID );
        }
        swapperMappings = Arrays.copyOf( swapperMappings, id + 1 );
        swapperMappings[id] = new SwapperMapping( id, swapper );
        this.swapperMappings = swapperMappings; // Volatile store synchronizes-with loads in getters.
        return id;
    }

}