@Override
        public byte[] doInTransform(Instrumentor instrumentor, ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws InstrumentException {
            InstrumentClass target = instrumentor.getInstrumentClass(loader, className, classfileBuffer);

            if (!target.isInterceptable()) {
                return null;
            }

            target.addField(DatabaseInfoAccessor.class);

            final InstrumentMethod constructor = target.getConstructor("java.lang.String", "int", "java.util.Properties", "java.lang.String", "java.lang.String");
            if (constructor != null) {
                constructor.addInterceptor(MySQLConnectionCreateInterceptor.class);
            }
            // 6.0.2 ~ 6.0.3
            InstrumentMethod constructor_6_X = target.getConstructor("com.mysql.cj.core.ConnectionString", "java.lang.String", "int", "java.util.Properties");
            if (constructor_6_X == null) {
                // 6.0.4+
                constructor_6_X = target.getConstructor("com.mysql.cj.core.conf.url.HostInfo");
            }
            if (constructor_6_X == null) {
                // 8.x+
                constructor_6_X = target.getConstructor("com.mysql.cj.conf.HostInfo");
            }
            if (constructor_6_X != null) {
                target.addGetter(OrigHostToConnectToGetter.class, "origHostToConnectTo");
                target.addGetter(OrigPortToConnectToGetter.class, "origPortToConnectTo");
                target.addGetter(DatabaseGetter.class, "database");
                constructor_6_X.addInterceptor(MySQL_6_X_ConnectionCreateInterceptor.class);
            }

            // close
            InstrumentUtils.findMethodOrIgnore(target, "close").addScopedInterceptor(ConnectionCloseInterceptor.class, MYSQL_SCOPE);

            // createStatement
            final Class<? extends Interceptor> statementCreate = StatementCreateInterceptor.class;
            InstrumentUtils.findMethodOrIgnore(target, "createStatement").addScopedInterceptor(statementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "createStatement", "int", "int").addScopedInterceptor(statementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "createStatement", "int", "int", "int").addScopedInterceptor(statementCreate, MYSQL_SCOPE);

            // preparedStatement
            final Class<? extends Interceptor> preparedStatementCreate = PreparedStatementCreateInterceptor.class;
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String", "int").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String", "int[]").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String", "java.lang.String[]").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String", "int", "int").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareStatement", "java.lang.String", "int", "int", "int").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);

            // preparecall
            InstrumentUtils.findMethodOrIgnore(target, "prepareCall", "java.lang.String").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareCall", "java.lang.String", "int", "int").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);
            InstrumentUtils.findMethodOrIgnore(target, "prepareCall", "java.lang.String", "int", "int", "int").addScopedInterceptor(preparedStatementCreate, MYSQL_SCOPE);

            if (config.isProfileSetAutoCommit()) {
                InstrumentUtils.findMethodOrIgnore(target, "setAutoCommit", "boolean").addScopedInterceptor(TransactionSetAutoCommitInterceptor.class, MYSQL_SCOPE);
            }
            if (config.isProfileCommit()) {
                InstrumentUtils.findMethodOrIgnore(target, "commit").addScopedInterceptor(TransactionCommitInterceptor.class, MYSQL_SCOPE);
            }
            if (config.isProfileRollback()) {
                InstrumentUtils.findMethodOrIgnore(target, "rollback").addScopedInterceptor(TransactionRollbackInterceptor.class, MYSQL_SCOPE);
            }

            return target.toBytecode();
        }
@author Jongho Moon
@author HyunGil Jeong
agent-module/plugins/mysql-jdbc/src/main/java/com/navercorp/pinpoint/plugin/jdbc/mysql/MySqlPlugin.java