boolean closeAndRemoveResourcesInSet(Set s, Method closeMethod) {
    boolean okay = true;

    Set temp;
    synchronized (s) {
      temp = new HashSet(s);
    }

    for (Iterator ii = temp.iterator(); ii.hasNext(); ) {
      Object rsrc = ii.next();
      try {
        closeMethod.invoke(rsrc, CLOSE_ARGS);
      } catch (Exception e) {
        Throwable t = e;
        if (t instanceof InvocationTargetException)
          t = ((InvocationTargetException) e).getTargetException();
        logger.log(MLevel.WARNING, "An exception occurred while cleaning up a resource.", t);
        // t.printStackTrace();
        okay = false;
      } finally {
        s.remove(rsrc);
      }
    }

    // We had to abandon the idea of simply iterating over s directly, because
    // our resource close methods sometimes try to remove the resource from
    // its parent Set. This is important (when the user closes the resources
    // directly), but leads to ConcurrenModificationExceptions while we are
    // iterating over the Set to close. So, now we iterate over a copy, but remove
    // from the original Set. Since removal is idempotent, it don't matter if
    // the close method already provoked a remove. Sucks that we have to copy
    // the set though.
    //
    // Original (direct iteration) version:
    //
    //  	synchronized (s)
    //  	    {
    //  		for (Iterator ii = s.iterator(); ii.hasNext(); )
    //  		    {
    //  			Object rsrc = ii.next();
    //  			try
    //  			    { closeMethod.invoke(rsrc, CLOSE_ARGS); }
    //  			catch (Exception e)
    //  			    {
    //  				Throwable t = e;
    //  				if (t instanceof InvocationTargetException)
    //  				    t = ((InvocationTargetException) e).getTargetException();
    //  				t.printStackTrace();
    //  				okay = false;
    //  			    }
    //  			finally
    //  			    { ii.remove(); }
    //  		    }
    //  	    }

    return okay;
  }
  public static SQLException toSQLException(String msg, String sqlState, Throwable t) {
    if (t instanceof SQLException) {
      if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable(MLevel.FINER)) {
        SQLException s = (SQLException) t;
        StringBuffer tmp = new StringBuffer(255);
        tmp.append("Attempted to convert SQLException to SQLException. Leaving it alone.");
        tmp.append(" [SQLState: ");
        tmp.append(s.getSQLState());
        tmp.append("; errorCode: ");
        tmp.append(s.getErrorCode());
        tmp.append(']');
        if (msg != null) tmp.append(" Ignoring suggested message: '" + msg + "'.");
        logger.log(MLevel.FINER, tmp.toString(), t);

        SQLException s2 = s;
        while ((s2 = s2.getNextException()) != null)
          logger.log(MLevel.FINER, "Nested SQLException or SQLWarning: ", s2);
      }
      return (SQLException) t;
    } else {
      if (Debug.DEBUG) {
        // t.printStackTrace();
        if (logger.isLoggable(MLevel.FINE))
          logger.log(MLevel.FINE, "Converting Throwable to SQLException...", t);
      }

      if (msg == null)
        msg = "An SQLException was provoked by the following failure: " + t.toString();
      if (VersionUtils.isAtLeastJavaVersion14()) {
        SQLException out = new SQLException(msg);
        out.initCause(t);
        return out;
      } else
        return new SQLException(
            msg
                + System.getProperty("line.separator")
                + "[Cause: "
                + ThrowableUtils.extractStackTrace(t)
                + ']',
            sqlState);
    }
  }
  private void reset(boolean known_resolved_txn) throws SQLException {
    ensureOkay();
    C3P0ImplUtils.resetTxnState(
        physicalConnection,
        forceIgnoreUnresolvedTransactions,
        autoCommitOnClose,
        known_resolved_txn);
    if (isolation_lvl_nondefault) {
      physicalConnection.setTransactionIsolation(dflt_txn_isolation);
      isolation_lvl_nondefault = false;
    }
    if (catalog_nondefault) {
      physicalConnection.setCatalog(dflt_catalog);
      catalog_nondefault = false;
    }
    if (holdability_nondefault) // we don't test if holdability is supported, 'cuz it can never go
                                // nondefault if it's not.
    {
      physicalConnection.setHoldability(dflt_holdability);
      holdability_nondefault = false;
    }

    try {
      physicalConnection.setReadOnly(false);
    } catch (Throwable t) {
      if (logger.isLoggable(MLevel.FINE))
        logger.log(
            MLevel.FINE,
            "A Throwable occurred while trying to reset the readOnly property of our Connection to false!",
            t);
    }

    try {
      if (supports_setTypeMap) physicalConnection.setTypeMap(Collections.EMPTY_MAP);
    } catch (Throwable t) {
      if (logger.isLoggable(MLevel.FINE))
        logger.log(
            MLevel.FINE,
            "A Throwable occurred while trying to reset the typeMap property of our Connection to Collections.EMPTY_MAP!",
            t);
    }
  }
  // must be called from sync'ed method
  private void doBadUpdate(int new_status) {
    this.connection_status = new_status;
    try {
      this.close(true);
    } catch (SQLException e) {
      // 		System.err.print("Broken Connection Close Error: ");
      // 		e.printStackTrace();

      logger.log(MLevel.WARNING, "Broken Connection Close Error. ", e);
    }
  }
  public synchronized void close() {
    resetPoolManager();
    is_closed = true;

    C3P0Registry.markClosed(this);

    if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable(MLevel.FINEST)) {
      logger.log(
          MLevel.FINEST,
          this.getClass().getName()
              + '@'
              + Integer.toHexString(System.identityHashCode(this))
              + " has been closed. ",
          new Exception("DEBUG STACK TRACE for PoolBackedDataSource.close()."));
    }
  }
 protected void initializeNamedConfig(String configName) {
   try {
     if (configName != null) {
       C3P0Config.bindNamedConfigToBean(this, configName);
       if (this.getDataSourceName()
           .equals(this.getIdentityToken())) // dataSourceName has not been specified in config
       this.setDataSourceName(configName);
     }
   } catch (Exception e) {
     if (logger.isLoggable(MLevel.WARNING))
       logger.log(
           MLevel.WARNING,
           "Error binding PoolBackedDataSource to named-config '"
               + configName
               + "'. Some default-config values may be used.",
           e);
   }
 }
 boolean closeAndRemoveResultSets(Set rsSet) {
   boolean okay = true;
   synchronized (rsSet) {
     for (Iterator ii = rsSet.iterator(); ii.hasNext(); ) {
       ResultSet rs = (ResultSet) ii.next();
       try {
         rs.close();
       } catch (SQLException e) {
         if (Debug.DEBUG)
           logger.log(MLevel.WARNING, "An exception occurred while cleaning up a ResultSet.", e);
         // e.printStackTrace();
         okay = false;
       } finally {
         ii.remove();
       }
     }
   }
   return okay;
 }
 synchronized void closeMaybeCheckedOut(boolean checked_out) throws SQLException {
   if (checked_out) {
     // reset transaction state
     try {
       C3P0ImplUtils.resetTxnState(
           physicalConnection, forceIgnoreUnresolvedTransactions, autoCommitOnClose, false);
     } catch (Exception e) {
       if (logger.isLoggable(MLevel.FINER))
         logger.log(
             MLevel.FINER,
             "Failed to reset the transaction state of  "
                 + physicalConnection
                 + "just prior to close(). "
                 + "Only relevant at all if this was a Connection being forced close()ed midtransaction.",
             e);
     }
   }
   close(false);
 }
  // must be called from sync'ed method to protecte
  // exposedProxy
  private Connection getCreateNewConnection() throws SQLException {
    try {
      // DEBUG
      // origGet = new Exception("[DOUBLE_GET_TESTER] -- Orig Get");

      ensureOkay();
      /*
       * we reset the physical connection when we close an exposed proxy
       * no need to do it again when we create one
       */
      // reset();
      return (exposedProxy = createProxyConnection());
    } catch (SQLException e) {
      throw e;
    } catch (Exception e) {
      // e.printStackTrace();
      logger.log(MLevel.WARNING, "Failed to acquire connection!", e);
      throw new SQLException("Failed to acquire connection!");
    }
  }
  static {
    try {
      CON_PROXY_CTOR = createProxyConstructor(ProxyConnection.class);

      Class[] argClasses = new Class[0];
      RS_CLOSE_METHOD = ResultSet.class.getMethod("close", argClasses);
      STMT_CLOSE_METHOD = Statement.class.getMethod("close", argClasses);

      CLOSE_ARGS = new Object[0];

      OBJECT_METHODS =
          Collections.unmodifiableSet(new HashSet(Arrays.asList(Object.class.getMethods())));
    } catch (Exception e) {
      // e.printStackTrace();
      logger.log(
          MLevel.SEVERE,
          "An Exception occurred in static initializer of" + C3P0PooledConnection.class.getName(),
          e);
      throw new InternalError(
          "Something is very wrong, or this is a pre 1.3 JVM."
              + "We cannot set up dynamic proxies and/or methods!");
    }
  }
  // TODO: factor out repetitive debugging code
  private synchronized void close(boolean known_invalid) throws SQLException {
    // System.err.println("Closing " + this);
    if (physicalConnection != null) {
      try {
        StringBuffer debugOnlyLog = null;
        if (Debug.DEBUG && known_invalid) {
          debugOnlyLog = new StringBuffer();
          debugOnlyLog.append("[ exceptions: ");
        }

        Exception exc = cleanupUncachedActiveStatements();
        if (Debug.DEBUG && exc != null) {
          if (known_invalid) debugOnlyLog.append(exc.toString() + ' ');
          else
            logger.log(
                MLevel.WARNING,
                "An exception occurred while cleaning up uncached active Statements.",
                exc);
          // exc.printStackTrace();
        }

        try {
          // we've got to use silentClose() rather than close() here,
          // 'cuz if there's still an exposedProxy (say a user forgot to
          // close his Connection) before we close, and we use regular (loud)
          // close, we will try to check this dead or dying PooledConnection
          // back into the pool. We only want to do this when close is called
          // on user proxies, and the underlying PooledConnection might still
          // be good. The PooledConnection itself should only be closed by the
          // pool.
          if (exposedProxy != null) exposedProxy.silentClose(known_invalid);
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            // e.printStackTrace();
          }
          exc = e;
        }
        try {
          this.closeAll();
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            // e.printStackTrace();
          }
          exc = e;
        }

        try {
          physicalConnection.close();
        } catch (Exception e) {
          if (Debug.DEBUG) {
            if (known_invalid) debugOnlyLog.append(e.toString() + ' ');
            else logger.log(MLevel.WARNING, "An exception occurred.", exc);
            e.printStackTrace();
          }
          exc = e;
        }

        if (exc != null) {
          if (known_invalid) {
            debugOnlyLog.append(" ]");
            if (Debug.DEBUG) {
              // 						System.err.print("[DEBUG]" + this + ": while closing a PooledConnection known
              // to be invalid, ");
              // 						System.err.println("  some exceptions occurred. This is probably not a
              // problem:");
              // 						System.err.println( debugOnlyLog.toString() );

              logger.fine(
                  this
                      + ": while closing a PooledConnection known to be invalid, "
                      + "  some exceptions occurred. This is probably not a problem: "
                      + debugOnlyLog.toString());
            }
          } else
            throw new SQLException(
                "At least one error occurred while attempting "
                    + "to close() the PooledConnection: "
                    + exc);
        }
        if (Debug.TRACE == Debug.TRACE_MAX)
          logger.fine("C3P0PooledConnection closed. [" + this + ']');
        // System.err.println("C3P0PooledConnection closed. [" + this + ']');
      } finally {
        physicalConnection = null;
      }
    }
  }