// Path: croquet-core/src/main/java/com/metrink/croquet/AbstractSettings.java
// public abstract class AbstractSettings implements Serializable {
//     private static final long serialVersionUID = -2385834291456376380L;
//     private static final Logger LOG = LoggerFactory.getLogger(AbstractSettings.class);
// 
//     private static final int DEFAULT_PORT = 8080;
// 
//     @JsonProperty("development")
//     private Boolean development = false;
// 
//     @JsonProperty("port")
//     private Integer port = DEFAULT_PORT;
// 
//     @JsonProperty("pid_file")
//     private String pidFile;
// 
//     @JsonProperty("logging")
//     private LoggingSettings loggingSettings = new LoggingSettings();
// 
//     @JsonProperty("db")
//     private DatabaseSettings dbSettings;
// 
// 
//     /**
//      * Perform post de-serialization modification of the Settings.
//      */
//     protected final void initialize() {
//         // Enabling development mode forces these settings. This is somewhat inelegant, because to configure one of
//         // these values differently will require disabling development mode and manually configure the remaining values.
//         if (development) {
//             loggingSettings.getLoggers().put("org.hibernate.SQL", Level.DEBUG);
//             loggingSettings.getLoggers().put("com.metrink.croquet", Level.DEBUG);
//         }
// 
//         // call the class's init method
//         init();
//     }
// 
//     /**
//      * Perform post de-serialization modification of the Settings.
//      */
//     protected abstract void init();
// 
//     /**
//      * Helper method used to obtain a class from a fully qualified class name. If the value is null or an exception is
//      * thrown, return the default result instead.
//      * @param className the fully qualified class name to try
//      * @param defaultResult the nullable default result
//      * @param <T> the class type
//      * @return the class or null
//      */
//     @SuppressWarnings("unchecked")
//     protected <T> Class<T> getClassOrDefault(final String className, final Class<T> defaultResult) {
//         try {
//             return className == null
//                     ? defaultResult
//                     : (Class<T>)Class.forName(className);
//         } catch (final ClassNotFoundException e) {
//             LOG.error("ClassNotFoundException for {} - defaulting to {}", className, defaultResult);
//             return defaultResult;
//         }
//     }
// 
//     /**
//      * In development mode?
//      * Defaults to false to avoid accidental deployment of development mode in production.
//      * @return true if in development mode
//      */
//     public Boolean getDevelopment() {
//         return development;
//     }
// 
//     /**
//      * Get the TCP port which will be bound to Jetty.
//      * @return the port
//      */
//     public int getPort() {
//         return port;
//     }
// 
// 
//     /**
//      * Get the {@link DatabaseSettings}.
//      * @return the {@link DatabaseSettings}.
//      */
//     public DatabaseSettings getDatabaseSettings() {
//         return dbSettings;
//     }
// 
//     /**
//      * Get the {@link LoggingSettings}.
//      * @return the {@link LoggingSettings}.
//      */
//     public LoggingSettings getLoggingSettings() {
//         return loggingSettings;
//     }
// 
//     /**
//      * Get pidFile.
//      * @return the pidFile
//      */
//     public String getPidFile() {
//         return pidFile;
//     }
// 
//     /**
//      * Set pidFile.
//      * @param pidFile the pidFile to set
//      */
//     public void setPidFile(final String pidFile) {
//         this.pidFile = pidFile;
//     }
// 
// }


import java.io.Serializable;
import javax.annotation.Nullable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.persist.PersistService;
import com.google.inject.persist.UnitOfWork;
import com.metrink.croquet.AbstractSettings;
package com.metrink.croquet.hibernate;





/**
 * A PersistService, UnitOfWork, and Provider<EntityManager> implementation that configures Hibernate.
 *
 * The persist.xml file is NOT used to configure Hibernate. Everything is driven through the DatabaseSettings class.
 */
@Singleton
class CroquetPersistService implements Provider<EntityManager>, UnitOfWork, PersistService {
    private static final Logger LOG = LoggerFactory.getLogger(CroquetPersistService.class);
    private static final String TRUE_STRING = "true";
    private static final String FALSE_STRING = "false";

    //CHECKSTYLE:OFF stupid stuff
    private final AbstractSettings settings;
    //CHECKSTYLE:ON
    private final String persistenceUnitName;
    private final ConnectionProvider connectionProvider;
    private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();
    private volatile EntityManagerFactory entityManagerFactory;

    /**
     * Constructs the {@link CroquetPersistService}.
     * @param settings the settings to configure everything with.
     * @param connectionProvider the {@link ConnectionProvider} to use.
     */
    @Inject
    public CroquetPersistService(final AbstractSettings settings,
                                 @Nullable @Named("jpa-unit-name") final String persistenceUnitName,
                                 final ConnectionProvider connectionProvider) {
        this.settings = settings;
        this.persistenceUnitName = persistenceUnitName;
        this.connectionProvider = connectionProvider;
    }

    public String getPersistenceUnitName() {
        return persistenceUnitName;
    }

    /**
     * Returns the current {@link EntityManagerFactory}.
     * @return {@link EntityManagerFactory}.
     */
    protected EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    /**
     * Sets the {@link EntityManagerFactory}.
     * @param entityManagerFactory the {@link EntityManagerFactory} to set.
     */
// Path: croquet-core/src/main/java/com/metrink/croquet/AbstractSettings.java
// public abstract class AbstractSettings implements Serializable {
//     private static final long serialVersionUID = -2385834291456376380L;
//     private static final Logger LOG = LoggerFactory.getLogger(AbstractSettings.class);
// 
//     private static final int DEFAULT_PORT = 8080;
// 
//     @JsonProperty("development")
//     private Boolean development = false;
// 
//     @JsonProperty("port")
//     private Integer port = DEFAULT_PORT;
// 
//     @JsonProperty("pid_file")
//     private String pidFile;
// 
//     @JsonProperty("logging")
//     private LoggingSettings loggingSettings = new LoggingSettings();
// 
//     @JsonProperty("db")
//     private DatabaseSettings dbSettings;
// 
// 
//     /**
//      * Perform post de-serialization modification of the Settings.
//      */
//     protected final void initialize() {
//         // Enabling development mode forces these settings. This is somewhat inelegant, because to configure one of
//         // these values differently will require disabling development mode and manually configure the remaining values.
//         if (development) {
//             loggingSettings.getLoggers().put("org.hibernate.SQL", Level.DEBUG);
//             loggingSettings.getLoggers().put("com.metrink.croquet", Level.DEBUG);
//         }
// 
//         // call the class's init method
//         init();
//     }
// 
//     /**
//      * Perform post de-serialization modification of the Settings.
//      */
//     protected abstract void init();
// 
//     /**
//      * Helper method used to obtain a class from a fully qualified class name. If the value is null or an exception is
//      * thrown, return the default result instead.
//      * @param className the fully qualified class name to try
//      * @param defaultResult the nullable default result
//      * @param <T> the class type
//      * @return the class or null
//      */
//     @SuppressWarnings("unchecked")
//     protected <T> Class<T> getClassOrDefault(final String className, final Class<T> defaultResult) {
//         try {
//             return className == null
//                     ? defaultResult
//                     : (Class<T>)Class.forName(className);
//         } catch (final ClassNotFoundException e) {
//             LOG.error("ClassNotFoundException for {} - defaulting to {}", className, defaultResult);
//             return defaultResult;
//         }
//     }
// 
//     /**
//      * In development mode?
//      * Defaults to false to avoid accidental deployment of development mode in production.
//      * @return true if in development mode
//      */
//     public Boolean getDevelopment() {
//         return development;
//     }
// 
//     /**
//      * Get the TCP port which will be bound to Jetty.
//      * @return the port
//      */
//     public int getPort() {
//         return port;
//     }
// 
// 
//     /**
//      * Get the {@link DatabaseSettings}.
//      * @return the {@link DatabaseSettings}.
//      */
//     public DatabaseSettings getDatabaseSettings() {
//         return dbSettings;
//     }
// 
//     /**
//      * Get the {@link LoggingSettings}.
//      * @return the {@link LoggingSettings}.
//      */
//     public LoggingSettings getLoggingSettings() {
//         return loggingSettings;
//     }
// 
//     /**
//      * Get pidFile.
//      * @return the pidFile
//      */
//     public String getPidFile() {
//         return pidFile;
//     }
// 
//     /**
//      * Set pidFile.
//      * @param pidFile the pidFile to set
//      */
//     public void setPidFile(final String pidFile) {
//         this.pidFile = pidFile;
//     }
// 
// }


// Path: croquet-core/src/main/java/com/metrink/croquet/hibernate/CroquetPersistService.java
import java.io.Serializable;
import javax.annotation.Nullable;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.spi.PersistenceUnitTransactionType;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.jdbc.connections.spi.ConnectionProvider;
import org.hibernate.jpa.HibernateEntityManagerFactory;
import org.hibernate.jpa.internal.EntityManagerFactoryImpl;
import org.hibernate.service.ServiceRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.persist.PersistService;
import com.google.inject.persist.UnitOfWork;
import com.metrink.croquet.AbstractSettings;

package com.metrink.croquet.hibernate;





/**
 * A PersistService, UnitOfWork, and Provider<EntityManager> implementation that configures Hibernate.
 *
 * The persist.xml file is NOT used to configure Hibernate. Everything is driven through the DatabaseSettings class.
 */
@Singleton
class CroquetPersistService implements Provider<EntityManager>, UnitOfWork, PersistService {
    private static final Logger LOG = LoggerFactory.getLogger(CroquetPersistService.class);
    private static final String TRUE_STRING = "true";
    private static final String FALSE_STRING = "false";

    //CHECKSTYLE:OFF stupid stuff
    private final AbstractSettings settings;
    //CHECKSTYLE:ON
    private final String persistenceUnitName;
    private final ConnectionProvider connectionProvider;
    private final ThreadLocal<EntityManager> entityManager = new ThreadLocal<EntityManager>();
    private volatile EntityManagerFactory entityManagerFactory;

    /**
     * Constructs the {@link CroquetPersistService}.
     * @param settings the settings to configure everything with.
     * @param connectionProvider the {@link ConnectionProvider} to use.
     */
    @Inject
    public CroquetPersistService(final AbstractSettings settings,
                                 @Nullable @Named("jpa-unit-name") final String persistenceUnitName,
                                 final ConnectionProvider connectionProvider) {
        this.settings = settings;
        this.persistenceUnitName = persistenceUnitName;
        this.connectionProvider = connectionProvider;
    }

    public String getPersistenceUnitName() {
        return persistenceUnitName;
    }

    /**
     * Returns the current {@link EntityManagerFactory}.
     * @return {@link EntityManagerFactory}.
     */
    protected EntityManagerFactory getEntityManagerFactory() {
        return entityManagerFactory;
    }

    /**
     * Sets the {@link EntityManagerFactory}.
     * @param entityManagerFactory the {@link EntityManagerFactory} to set.
     */
    protected void setEntityManagerFactory(final EntityManagerFactory entityManagerFactory) {