class ConnectionHandle implements Connection,Serializable {

	public PreparedStatement prepareStatement(String sql) throws SQLException {
		PreparedStatementHandle result = null;
		String cacheKey = null;

		checkClosed();

		try {
			long statStart=0;
			if (this.statisticsEnabled){
				statStart = System.nanoTime();
			}
			if (this.statementCachingEnabled) {
				cacheKey = sql;
				result = (PreparedStatementHandle) this.preparedStatementCache.get(cacheKey);
			}

			if (result == null){
				result =  new PreparedStatementHandle(this.connection.prepareStatement(sql), sql, this, cacheKey, this.preparedStatementCache);
			} else {
				result = new PreparedStatementHandle(result.getInternalPreparedStatement(), result.sql, this, cacheKey, this.preparedStatementCache);
			}
			result.setLogicallyOpen();

			if (this.pool.closeConnectionWatch && this.statementCachingEnabled){ // debugging mode enabled?
				result.setOpenStackTrace(this.pool.captureStackTrace(STATEMENT_NOT_CLOSED));
			}
			if (this.closeOpenStatements){
				this.trackedStatement.put(result, maybeCaptureStackTrace());
			}

			if (this.statisticsEnabled){
				this.statistics.addStatementPrepareTime(System.nanoTime()-statStart);
				this.statistics.incrementStatementsPrepared();
			}

		} catch (SQLException e) {
			throw markPossiblyBroken(e);
		}
		return result;
	}

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

}