/**
   * INTERNAL: Applies customization to connection. Called only if connection is not already
   * customized (isActive()==false). The method may throw SQLException wrapped into
   * DatabaseException. isActive method called after this method should return true only in case the
   * connection was actually customized.
   */
  public void customize() {
    // Lazily initialize proxy properties - customize method may be never called
    // in case of ClientSession using external connection pooling.
    if (proxyProperties == null) {
      buildProxyProperties();
    }

    Connection connection = accessor.getConnection();
    if (connection instanceof OracleConnection) {
      oracleConnection = (OracleConnection) connection;
    } else {
      connection = session.getServerPlatform().unwrapConnection(connection);
      if (connection instanceof OracleConnection) {
        oracleConnection = (OracleConnection) connection;
      } else {
        throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnection();
      }
    }
    try {
      clearConnectionCache();
      Object[] args = null;
      if (this.session.shouldLog(SessionLog.FINEST, SessionLog.CONNECTION)) {
        Properties logProperties = proxyProperties;
        if (proxyProperties.containsKey(OracleConnection.PROXY_USER_PASSWORD)) {
          logProperties = (Properties) proxyProperties.clone();
          logProperties.setProperty(OracleConnection.PROXY_USER_PASSWORD, "******");
        }
        args = new Object[] {oracleConnection, logProperties};
      }
      if (oracleConnection.isProxySession()) {
        // Unexpectedly oracleConnection already has a proxy session - probably it was not closed
        // when connection was returned back to connection pool.
        // That may happen on jta transaction rollback (especially triggered outside of user's
        // thread - such as timeout)
        // when beforeCompletion is never issued
        // and application server neither closes proxySession nor allows access to connection in
        // afterCompletion.
        try {
          if (args != null) {
            ((AbstractSession) this.session)
                .log(
                    SessionLog.FINEST,
                    SessionLog.CONNECTION,
                    "proxy_connection_customizer_already_proxy_session",
                    args);
          }
          oracleConnection.close(OracleConnection.PROXY_SESSION);
        } catch (SQLException exception) {
          // Ignore
          this.session
              .getSessionLog()
              .logThrowable(SessionLog.WARNING, SessionLog.CONNECTION, exception);
        }
      }
      oracleConnection.openProxySession(proxyType, proxyProperties);
      // 12c driver will default to an autoCommit setting of true on calling openProxySession
      oracleConnection.setAutoCommit(false);
      if (args != null) {
        ((AbstractSession) this.session)
            .log(
                SessionLog.FINEST,
                SessionLog.CONNECTION,
                "proxy_connection_customizer_opened_proxy_session",
                args);
      }
    } catch (SQLException exception) {
      oracleConnection = null;
      throw DatabaseException.sqlException(exception);
    } catch (NoSuchMethodError noSuchMethodError) {
      oracleConnection = null;
      throw ValidationException.oracleJDBC10_1_0_2ProxyConnectorRequiresOracleConnectionVersion();
    }
  }