class MaxConnectionSemaphore implements ConnectionSemaphore {

    protected final Semaphore freeChannels;
    protected final IOException tooManyConnections;
    protected final int acquireTimeout;

    MaxConnectionSemaphore(int maxConnections, int acquireTimeout) {
        tooManyConnections = unknownStackTrace(new TooManyConnectionsException(maxConnections), MaxConnectionSemaphore.class, "acquireChannelLock");
        freeChannels = maxConnections > 0 ? new Semaphore(maxConnections) : InfiniteSemaphore.INSTANCE;
        this.acquireTimeout = Math.max(0, acquireTimeout);
    }

    @Override
    public void acquireChannelLock(Object partitionKey) throws IOException {<FILL_FUNCTION_BODY>}

    @Override
    public void releaseChannelLock(Object partitionKey) {
        freeChannels.release();
    }
}

        try {
            if (!freeChannels.tryAcquire(acquireTimeout, TimeUnit.MILLISECONDS)) {
                throw tooManyConnections;
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    
<no_super_class>