// Path: src/main/java/org/tyrannyofheaven/bukkit/util/ToHLoggingUtils.java
// public static void log(Plugin plugin, Level level, String format, Object... args) {
//     Logger logger = plugin.getLogger();
//     if (logger.isLoggable(level)) { // Avoid unnecessary String.format() calls
//         if (args.length > 0 && args[args.length - 1] instanceof Throwable) {
//             // Last argument is a Throwable, treat accordingly
//             logger.log(level, createLogMessage(format, Arrays.copyOf(args, args.length - 1)), (Throwable)args[args.length - 1]);
//         }
//         else {
//             logger.log(level, createLogMessage(format, args));
//         }
//     }
// }


import static org.tyrannyofheaven.bukkit.util.ToHLoggingUtils.log;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.persistence.PersistenceException;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.NamingConvention;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.config.dbplatform.SQLitePlatform;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.ddl.CreateSequenceVisitor;
import com.avaje.ebeaninternal.server.ddl.CreateTableVisitor;
import com.avaje.ebeaninternal.server.ddl.DdlGenContext;
import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
import com.avaje.ebeaninternal.server.ddl.VisitorUtil;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation;
import com.google.common.io.CharStreams;
     * 
     * @param ebeanServer the EbeanServer
     * @param namingConvention the associated NamingConvention
     * @param classLoader the plugin's class loader
     * @param pluginEntity any entity class (aside from ToHSchemaVersion) used by the plugin
     * @param updatePath path to the root of the update scripts
     */
    public static void upgradeDatabase(JavaPlugin plugin, NamingConvention namingConvention, ClassLoader classLoader, String updatePath) throws IOException {
        if (plugin == null)
            throw new IllegalArgumentException("plugin cannot be null");
        if (namingConvention == null)
            throw new IllegalArgumentException("namingConvention cannot be null");
        if (classLoader == null)
            throw new IllegalArgumentException("classLoader cannot be null");
        if (!ToHStringUtils.hasText(updatePath))
            throw new IllegalArgumentException("updatePath must have a value");

        // Find an entity class that is not ToHSchemaVersion. We'll select the
        // first one that matches from getDatabaseClasses(). This class will be
        // used to determine if the full schema should be generated.
        Class<?> pluginEntity = null;
        for (Class<?> clazz : plugin.getDatabaseClasses()) {
            // Use anything except ToHSchemaVersion
            if (clazz != ToHSchemaVersion.class) {
                pluginEntity = clazz;
                break;
            }
        }
        if (pluginEntity == null)
            throw new IllegalArgumentException("plugin.getDatabaseClasses() must have a non-ToHSchemaVersion class");
// Path: src/main/java/org/tyrannyofheaven/bukkit/util/ToHLoggingUtils.java
// public static void log(Plugin plugin, Level level, String format, Object... args) {
//     Logger logger = plugin.getLogger();
//     if (logger.isLoggable(level)) { // Avoid unnecessary String.format() calls
//         if (args.length > 0 && args[args.length - 1] instanceof Throwable) {
//             // Last argument is a Throwable, treat accordingly
//             logger.log(level, createLogMessage(format, Arrays.copyOf(args, args.length - 1)), (Throwable)args[args.length - 1]);
//         }
//         else {
//             logger.log(level, createLogMessage(format, args));
//         }
//     }
// }


// Path: src/main/java/org/tyrannyofheaven/bukkit/util/ToHDatabaseUtils.java
import static org.tyrannyofheaven.bukkit.util.ToHLoggingUtils.log;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.persistence.PersistenceException;
import org.bukkit.configuration.Configuration;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.NamingConvention;
import com.avaje.ebean.config.ServerConfig;
import com.avaje.ebean.config.dbplatform.DatabasePlatform;
import com.avaje.ebean.config.dbplatform.SQLitePlatform;
import com.avaje.ebeaninternal.api.SpiEbeanServer;
import com.avaje.ebeaninternal.server.ddl.CreateSequenceVisitor;
import com.avaje.ebeaninternal.server.ddl.CreateTableVisitor;
import com.avaje.ebeaninternal.server.ddl.DdlGenContext;
import com.avaje.ebeaninternal.server.ddl.DdlGenerator;
import com.avaje.ebeaninternal.server.ddl.VisitorUtil;
import com.avaje.ebeaninternal.server.deploy.BeanDescriptor;
import com.avaje.ebeaninternal.server.lib.sql.TransactionIsolation;
import com.google.common.io.CharStreams;

     * 
     * @param ebeanServer the EbeanServer
     * @param namingConvention the associated NamingConvention
     * @param classLoader the plugin's class loader
     * @param pluginEntity any entity class (aside from ToHSchemaVersion) used by the plugin
     * @param updatePath path to the root of the update scripts
     */
    public static void upgradeDatabase(JavaPlugin plugin, NamingConvention namingConvention, ClassLoader classLoader, String updatePath) throws IOException {
        if (plugin == null)
            throw new IllegalArgumentException("plugin cannot be null");
        if (namingConvention == null)
            throw new IllegalArgumentException("namingConvention cannot be null");
        if (classLoader == null)
            throw new IllegalArgumentException("classLoader cannot be null");
        if (!ToHStringUtils.hasText(updatePath))
            throw new IllegalArgumentException("updatePath must have a value");

        // Find an entity class that is not ToHSchemaVersion. We'll select the
        // first one that matches from getDatabaseClasses(). This class will be
        // used to determine if the full schema should be generated.
        Class<?> pluginEntity = null;
        for (Class<?> clazz : plugin.getDatabaseClasses()) {
            // Use anything except ToHSchemaVersion
            if (clazz != ToHSchemaVersion.class) {
                pluginEntity = clazz;
                break;
            }
        }
        if (pluginEntity == null)
            throw new IllegalArgumentException("plugin.getDatabaseClasses() must have a non-ToHSchemaVersion class");
        log(plugin, Level.CONFIG, "Selected %s as plugin-specific entity", pluginEntity.getSimpleName());