class AbstractClientHistory extends LocalAbortable implements Identifiable<LocalHistoryIdentifier> {

    HistoryReconnectCohort startReconnect(final ConnectedClientConnection<ShardBackendInfo> newConn) {
        /*
         * This looks ugly and unusual and there is a reason for that, as the locking involved is in multiple places.
         *
         * We need to make sure that a new proxy is not created while we are reconnecting, which is partially satisfied
         * by client.getConnection() throwing InversibleLockException by the time this method is invoked. That does
         * not cover the case when createHistoryProxy() has already acquired the connection, but has not yet populated
         * the history map.
         *
         * Hence we need to make sure no potential computation is happening concurrently with us looking at the history
         * map. Once we have performed that lookup, though, we can release the lock immediately, as all creation
         * requests are established to happen either before or after the reconnect attempt.
         */
        final ProxyHistory oldProxy;
        final long stamp = lock.writeLock();
        try {
            oldProxy = histories.get(newConn.cookie());
        } finally {
            lock.unlockWrite(stamp);
        }

        if (oldProxy == null) {
            return null;
        }

        final ProxyReconnectCohort proxy = verifyNotNull(oldProxy.startReconnect(newConn));
        return new HistoryReconnectCohort() {
            @Override
            ProxyReconnectCohort getProxy() {
                return proxy;
            }

            @Override
            void replayRequests(final Collection<ConnectionEntry> previousEntries) {
                proxy.replayRequests(previousEntries);
            }

            @Override
            public void close() {
                LOG.debug("Client history {} finishing reconnect to {}", AbstractClientHistory.this, newConn);
                final ProxyHistory newProxy = proxy.finishReconnect();
                if (!histories.replace(newConn.cookie(), oldProxy, newProxy)) {
                    LOG.warn("Failed to replace proxy {} with {} in {}", oldProxy, newProxy,
                        AbstractClientHistory.this);
                }
            }
        };
    }

      AbstractClientHistory(final AbstractDataStoreClientBehavior client, final LocalHistoryIdentifier identifier);

}