public void returnConnection(Connection connection) {
    int inFlight = connection.inFlight.decrementAndGet();

    if (connection.isDefunct()) {
      if (host.getMonitor().signalConnectionFailure(connection.lastException())) shutdown();
      else replace(connection);
    } else {

      if (trash.contains(connection) && inFlight == 0) {
        if (trash.remove(connection)) close(connection);
        return;
      }

      if (connections.size() > options().getCoreConnectionsPerHost(hostDistance)
          && inFlight <= options().getMinSimultaneousRequestsPerConnectionThreshold(hostDistance)) {
        trashConnection(connection);
      } else {
        signalAvailableConnection();
      }
    }
  }
  public void logState() {
    Session s = sessions[0];
    Cluster cluster = s.getCluster();
    LoadBalancingPolicy lbPolicy =
        cluster.getConfiguration().getPolicies().getLoadBalancingPolicy();

    int count = 0;
    String keyspace = null;
    for (final Session session : sessions) {
      SessionManager sessionM = (SessionManager) session;
      Session.State sessionState = session.getState();

      String newKeyspace = session.getLoggedKeyspace();
      if (keyspace == null || !keyspace.equals(newKeyspace)) {
        count = 0;
        keyspace = newKeyspace;
      }

      int sessionKey = count++;
      logger.info("Host States for Session {}#{}:", keyspace, sessionKey);
      Collection<Host> hosts = sessionState.getConnectedHosts();
      for (final Host host : hosts) {
        HostConnectionPool pool = sessionM.pools.get(host);
        HostDistance distance = lbPolicy.distance(host);
        // Whether or not the host will reconnect while in a suspected state.
        boolean isReconnectingFromSuspected =
            host.getInitialReconnectionAttemptFuture() != null
                && !host.getInitialReconnectionAttemptFuture().isDone();
        // Whether or not the host will reconnect while in a down state.
        boolean isReconnectingFromDown =
            host.getReconnectionAttemptFuture() != null
                && !host.getReconnectionAttemptFuture().isDone();

        if (pool != null) {
          String msg =
              String.format(
                  "\t[%s:%s:%s] version=%s, state=%s, dist=%s, inFlight=%d, openConnections=%d, "
                      + "trashedConnections=%d, reconnectFromSuspected=%s, reconnectFromDown=%s. pool=%s, poolClosed=%s",
                  host.getDatacenter(),
                  host.getRack(),
                  host.getAddress(),
                  host.getCassandraVersion(),
                  host.state,
                  distance,
                  sessionState.getInFlightQueries(host),
                  sessionState.getOpenConnections(host),
                  pool.trash.size(),
                  isReconnectingFromSuspected,
                  isReconnectingFromDown,
                  pool.hashCode(),
                  pool.isClosed());

          logger.info(msg);

          for (Connection connection : pool.connections) {
            long now = System.currentTimeMillis();
            Connection.State state = connection.state.get();
            if (connection.isClosed()
                || connection.isDefunct()
                || state == Connection.State.TRASHED
                || state == Connection.State.GONE
                || connection.maxIdleTime > 0 && connection.maxIdleTime < now) {
              logger.warn(
                  "\t\t{} defunct?={}, state={}, maxIdleTime={}",
                  connection,
                  connection.isDefunct(),
                  state,
                  new Date(connection.maxIdleTime));
            } else {
              logger.info(
                  "\t\t{} defunct?={}, state={}, maxIdleTime={}",
                  connection,
                  connection.isDefunct(),
                  state,
                  new Date(connection.maxIdleTime));
            }
          }
          for (Connection connection : pool.trash) {
            Connection.State state = connection.state.get();
            if (connection.isClosed()
                || connection.isDefunct()
                || state == Connection.State.OPEN
                || state == Connection.State.GONE) {
              logger.warn(
                  "\t\t{} defunct?={}, state={}, maxIdleTime={} [trash]",
                  connection,
                  connection.isDefunct(),
                  state,
                  new Date(connection.maxIdleTime));
            } else {
              logger.info(
                  "\t\t{} defunct?={}, state={}, maxIdleTime={} [trash]",
                  connection,
                  connection.isDefunct(),
                  state,
                  new Date(connection.maxIdleTime));
            }
          }
        } else {
          logger.error("Pool is null for {}.", host);
        }

        // Register by host / session metrics if not already registered.
        // Replace periods with underscores (better graphite metric names) in host, also remove
        // backslashes.
        // If the host is no longer part of the session, it will return 0.
        String prefix =
            "Session."
                + sessionKey
                + "."
                + host.getAddress().toString().replaceAll("\\.", "_").replaceAll("/", "")
                + ".";
        String inFlightKey = prefix + "inFlight";
        String openConnectionsKey = prefix + "openConnections";
        if (!metricRegistry.getMetrics().containsKey(inFlightKey)) {
          metricRegistry.register(
              inFlightKey,
              new CachedGauge<Integer>(1, TimeUnit.SECONDS) {

                @Override
                protected Integer loadValue() {
                  Session.State sessionState = session.getState();
                  if (sessionState.getConnectedHosts().contains(host)) {
                    return sessionState.getInFlightQueries(host);
                  } else {
                    return 0;
                  }
                }
              });
        }
        if (!metricRegistry.getMetrics().containsKey(openConnectionsKey)) {
          metricRegistry.register(
              openConnectionsKey,
              new CachedGauge<Integer>(1, TimeUnit.SECONDS) {

                @Override
                protected Integer loadValue() {
                  Session.State sessionState = session.getState();
                  if (sessionState.getConnectedHosts().contains(host)) {
                    return sessionState.getOpenConnections(host);
                  } else {
                    return 0;
                  }
                }
              });
        }
      }
    }

    ControlConnection connection = cluster.manager.controlConnection;
    if (connection.isOpen()) {
      logger.info("Control connection is open to {}.", connection.connectedHost());
    } else {
      logger.warn("Control connection is closed.");
    }

    List<Host> queryPlan = Lists.newArrayList(lbPolicy.newQueryPlan(null, new SimpleStatement("")));
    if (queryPlan.size() == 0) {
      logger.warn("Query Plan is empty!");
    } else {
      logger.info("Query Plan: {}", queryPlan);
    }
  }