class CombinedConnectionSemaphore extends PerHostConnectionSemaphore {
    protected final MaxConnectionSemaphore globalMaxConnectionSemaphore;

    CombinedConnectionSemaphore(int maxConnections, int maxConnectionsPerHost, int acquireTimeout) {
        super(maxConnectionsPerHost, acquireTimeout);
        globalMaxConnectionSemaphore = new MaxConnectionSemaphore(maxConnections, acquireTimeout);
    }

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

    protected void releaseGlobal(Object partitionKey) {
        globalMaxConnectionSemaphore.releaseChannelLock(partitionKey);
    }

    protected long acquireGlobal(Object partitionKey) throws IOException {
        globalMaxConnectionSemaphore.acquireChannelLock(partitionKey);
        return 0;
    }

    /*
     * Acquires the global lock and returns the remaining time, in millis, to acquire the per-host lock
     */
    protected long acquireGlobalTimed(Object partitionKey) throws IOException {
        long beforeGlobalAcquire = System.currentTimeMillis();
        acquireGlobal(partitionKey);
        long lockTime = System.currentTimeMillis() - beforeGlobalAcquire;
        return acquireTimeout - lockTime;
    }

    @Override
    public void releaseChannelLock(Object partitionKey) {
        globalMaxConnectionSemaphore.releaseChannelLock(partitionKey);
        super.releaseChannelLock(partitionKey);
    }
}

        long remainingTime = acquireTimeout > 0 ? acquireGlobalTimed(partitionKey) : acquireGlobal(partitionKey);

        try {
            if (remainingTime < 0 || !getFreeConnectionsForHost(partitionKey).tryAcquire(remainingTime, TimeUnit.MILLISECONDS)) {
                releaseGlobal(partitionKey);
                throw tooManyConnectionsPerHost;
            }
        } catch (InterruptedException e) {
            releaseGlobal(partitionKey);
            throw new RuntimeException(e);
        }
    
<methods>public void acquireChannelLock(java.lang.Object) throws java.io.IOException,public void releaseChannelLock(java.lang.Object) <variables>protected final non-sealed int acquireTimeout,protected final ConcurrentHashMap<java.lang.Object,java.util.concurrent.Semaphore> freeChannelsPerHost,protected final non-sealed int maxConnectionsPerHost,protected final non-sealed java.io.IOException tooManyConnectionsPerHost