@Override
	protected ByteBuffer onAllocate(int size, AtomicBoolean cache) 
	{
		// If the power is to small or to large then return a HeapByteBuffer.
		if (size < minBufferSize || size > maxBufferSize) {
			try {
				return ByteBuffer.allocate(size);
			}
			catch (OutOfMemoryError e) {
				System.err.format("Cannot allocate a ByteBuffer of size %d; out of memory.\n", size);
				return null;
			}
		}

		// Compute the power of the buffer using log2
		int power = log2(size);
		
		// Calculate the index of the pool using minPower.
		int index = power - minPower;

		// Pop the next buffer on this stack.
		ByteBuffer buffer = pool[index].pop();
		
		// If no buffer existed on the stack allocate a new one.
		if (buffer == null) {
			try {
				buffer = ByteBuffer.allocateDirect(1 << power);
			}
			catch (OutOfMemoryError e) {
				System.err.format("Cannot allocate a ByteBuffer of size %d; out of memory.\n", size);
				return null;
			}
		}
		else {
			cache.set(true);
		}
		
		// Return the allocated buffer!
		return buffer;
	}