class ConnectionHandle implements Connection,Serializable {

	protected SQLException markPossiblyBroken(SQLException e) {
	    String state = e.getSQLState();
	    boolean alreadyDestroyed = false;

		ConnectionState connectionState = this.getConnectionHook() != null ? this.getConnectionHook().onMarkPossiblyBroken(this, state, e) : ConnectionState.NOP; 
		if (state == null){ // safety;
			state = "08999"; 
		}

		if (((sqlStateDBFailureCodes.contains(state) || connectionState.equals(ConnectionState.TERMINATE_ALL_CONNECTIONS)) && this.pool != null) && this.pool.getDbIsDown().compareAndSet(false, true) ){
			logger.error("Database access problem. Killing off this connection and all remaining connections in the connection pool. SQL State = " + state);
			this.pool.connectionStrategy.terminateAllConnections();
			this.pool.destroyConnection(this);
			this.logicallyClosed.set(true);
			alreadyDestroyed = true;

			for (int i=0; i < this.pool.partitionCount; i++) {
				// send a signal to try re-populating again.
				this.pool.partitions[i].getPoolWatchThreadSignalQueue().offer(new Object()); // item being pushed is not important.
			}
		}

		//case where either the connection is closed or
		//two concurrent connections loose connections with
		//the 08S01 code but one one is killed in the code
		//above give dbIsDown is set for the first connection
		if (state.equals("08003") || sqlStateDBFailureCodes.contains(state) || e.getCause() instanceof SocketException) {
		    if (!alreadyDestroyed) {
			this.pool.destroyConnection(this);
			this.logicallyClosed.set(true);
			getOriginatingPartition().getPoolWatchThreadSignalQueue().offer(new Object()); // item being pushed is not important.
		    }
		}
		
		// SQL-92 says:
		//		 Class values that begin with one of the <digit>s '5', '6', '7',
		//         '8', or '9' or one of the <simple Latin upper case letter>s 'I',
		//         'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
		//         'W', 'X', 'Y', or 'Z' are reserved for implementation-specified
		//         conditions.

		// FIXME: We should look into this.connection.getMetaData().getSQLStateType();
		// to determine if we have SQL:92 or X/OPEN sqlstatus codes.

		//		char firstChar = state.charAt(0);
		// if it's a communication exception, a mysql deadlock or an implementation-specific error code, flag this connection as being potentially broken.
		// state == 40001 is mysql specific triggered when a deadlock is detected
		// state == HY000 is firebird specific triggered when a connection is broken
		char firstChar = state.charAt(0);
		if (connectionState.equals(ConnectionState.CONNECTION_POSSIBLY_BROKEN) || state.equals("40001") || 
				state.equals("HY000") ||
				state.startsWith("08") ||  (firstChar >= '5' && firstChar <='9') /*|| (firstChar >='I' && firstChar <= 'Z')*/){
			this.possiblyBroken = true;
		}

		// Notify anyone who's interested
		if (this.possiblyBroken  && (this.getConnectionHook() != null)){
			this.possiblyBroken = this.getConnectionHook().onConnectionException(this, state, e);
		}

		return e;
	}

	protected  ConnectionHandle(Connection connection, ConnectionPartition partition, BoneCP pool, boolean recreating);
	private  ConnectionHandle();

}