class SwiftKeystoneFactoryV3 implements Supplier<OSClient> {

    public OSClient.OSClientV3 get() {
        Token currentToken = atomicToken.get();
        // First call to we have to authenticate
        Date nearTime = LocalDateUtil.getDate(LocalDateUtil.now().plusSeconds(configuration.getSwiftHardRenewTokenDelayBeforeExpireTime()));
        if (currentToken == null || currentToken.getExpires().before(nearTime)) {
            synchronized (monitor) {
                currentToken = atomicToken.get();
                // Double-checked locking through AtomicReference
                if (currentToken == null) {
                    OSClient.OSClientV3 osClientV3 = renewToken();
                    currentToken = osClientV3.getToken();
                    atomicToken.set(currentToken);
                    return osClientV3;
                }
            }
        }

        // Renew Token before expiration only one thread should re-authenticate
        Date farTime = LocalDateUtil.getDate(LocalDateUtil.now().plusSeconds(configuration.getSwiftSoftRenewTokenDelayBeforeExpireTime()));
        if (currentToken.getExpires().before(farTime)) {
            // Only one thread should re-authentication
            if (oneThread.compareAndSet(true, false)) {
                try {
                    OSClient.OSClientV3 osClientV3 = renewToken();
                    currentToken = osClientV3.getToken();
                    atomicToken.set(currentToken);
                    return osClientV3;
                } finally {
                    oneThread.set(true);
                }
            }
        }

        // If current client already exists
        OSClientSession.OSClientSessionV3 currentClient = (OSClientSession.OSClientSessionV3) OSClientSession.OSClientSessionV3.getCurrent();
        if (null != currentClient && currentToken.equals(currentClient.getToken())) {
            return currentClient;
        }

        // In all other cases, create a new client from token
        return OSFactory.clientFromToken(currentToken, configOS4J);
    }

    public  SwiftKeystoneFactoryV3(StorageConfiguration configuration);

}