diff --git a/build.gradle b/build.gradle
index 5e30a2fb60f35e41bf8848389bc61eee625d55bf..6ecf3d49b6ab902b77f12604aabad15a94dfc327 100644
--- a/build.gradle
+++ b/build.gradle
@@ -71,10 +71,8 @@ repositories {
     jcenter()
 }
 
-configurations {
-    sourceCompatibility = 1.7
-    targetCompatibility = 1.7
-}
+sourceCompatibility = 1.7
+targetCompatibility = 1.7
 
 if (hasProperty("archiveName")) {
     war.archiveName = archiveName.endsWith(".war") ? archiveName : "${archiveName}.war"
@@ -82,17 +80,6 @@ if (hasProperty("archiveName")) {
 war.baseName = "xnat-web"
 }
 
-sourceSets {
-    main {
-        java {
-            srcDirs 'src/main/java', 'src/generated/java'
-        }
-        resources {
-            srcDir 'src/generated/resources'
-        }
-    }
-}
-
 tomcatRun.contextPath = '/'
 tomcatRunWar.contextPath = '/'
 
diff --git a/src/main/java/org/nrg/schedule/TriggerTaskProxy.java b/src/main/java/org/nrg/schedule/TriggerTaskProxy.java
new file mode 100644
index 0000000000000000000000000000000000000000..562b88d541f92224beb6636c98850aa4d9592073
--- /dev/null
+++ b/src/main/java/org/nrg/schedule/TriggerTaskProxy.java
@@ -0,0 +1,36 @@
+package org.nrg.schedule;
+
+import org.springframework.scheduling.Trigger;
+import org.springframework.scheduling.config.TriggerTask;
+import org.springframework.scheduling.support.CronTrigger;
+import org.springframework.scheduling.support.PeriodicTrigger;
+
+import java.util.concurrent.TimeUnit;
+
+public class TriggerTaskProxy extends TriggerTask {
+    public TriggerTaskProxy(final Runnable runnable, final long period) {
+        this(runnable, period, null);
+    }
+
+    public TriggerTaskProxy(final Runnable runnable, final long period, final TimeUnit timeUnit) {
+        this(runnable, new PeriodicTrigger(period, timeUnit));
+    }
+
+    public TriggerTaskProxy(final Runnable runnable, final long period, final int initialDelay) {
+        this(runnable, period, null, initialDelay);
+    }
+
+    public TriggerTaskProxy(final Runnable runnable, final long period, final TimeUnit timeUnit, final int initialDelay) {
+        this(runnable, new PeriodicTrigger(period, timeUnit) {{
+            setInitialDelay(initialDelay);
+        }});
+    }
+
+    public TriggerTaskProxy(final Runnable runnable, final String expression) {
+        this(runnable, new CronTrigger(expression));
+    }
+
+    public TriggerTaskProxy(final Runnable runnable, final Trigger trigger) {
+        super(runnable, trigger);
+    }
+}
diff --git a/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java b/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java
index ea308773aca7781a0fa2bf0a3de440bc86dfa2ca..b8da14561f00e55d8278fecc58bd8ee9dd5e759a 100644
--- a/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/DatabaseConfig.java
@@ -6,6 +6,7 @@ import org.hibernate.cfg.ImprovedNamingStrategy;
 import org.nrg.framework.exceptions.NrgServiceError;
 import org.nrg.framework.exceptions.NrgServiceException;
 import org.nrg.framework.orm.hibernate.AggregatedAnnotationSessionFactoryBean;
+import org.nrg.framework.orm.hibernate.HibernateEntityPackageList;
 import org.nrg.framework.orm.hibernate.PrefixedTableNamingStrategy;
 import org.nrg.framework.utilities.Beans;
 import org.postgresql.Driver;
@@ -26,6 +27,7 @@ import javax.inject.Inject;
 import javax.sql.DataSource;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
+import java.util.List;
 import java.util.Properties;
 
 /**
@@ -95,9 +97,10 @@ public class DatabaseConfig {
     }
 
     @Bean
-    public LocalSessionFactoryBean sessionFactory() throws NrgServiceException {
+    public LocalSessionFactoryBean sessionFactory(final List<HibernateEntityPackageList> packageLists) throws NrgServiceException {
         try {
             final AggregatedAnnotationSessionFactoryBean bean = new AggregatedAnnotationSessionFactoryBean();
+            bean.setEntityPackageLists(packageLists);
             bean.setDataSource(dataSource());
             bean.setCacheRegionFactory(regionFactory());
             bean.setHibernateProperties(hibernateProperties().getObject());
@@ -109,8 +112,8 @@ public class DatabaseConfig {
     }
 
     @Bean
-    public PlatformTransactionManager transactionManager() throws NrgServiceException {
-        return new HibernateTransactionManager(sessionFactory().getObject());
+    public PlatformTransactionManager transactionManager(final List<HibernateEntityPackageList> packageLists) throws NrgServiceException {
+        return new HibernateTransactionManager(sessionFactory(packageLists).getObject());
     }
 
     private static Properties setDefaultDatasourceProperties(final Properties properties) {
diff --git a/src/main/java/org/nrg/xnat/configuration/FeaturesConfig.java b/src/main/java/org/nrg/xnat/configuration/FeaturesConfig.java
index e028390fa626838774d927c4a32a55edb2edf12b..5ed2a0c84deee46164a8f6bad19a8ef710f5bb99 100644
--- a/src/main/java/org/nrg/xnat/configuration/FeaturesConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/FeaturesConfig.java
@@ -2,99 +2,64 @@ package org.nrg.xnat.configuration;
 
 import org.apache.commons.lang3.StringUtils;
 import org.nrg.config.exceptions.SiteConfigurationException;
-import org.nrg.config.services.SiteConfigurationService;
 import org.nrg.xdat.security.services.FeatureRepositoryServiceI;
 import org.nrg.xdat.security.services.FeatureServiceI;
 import org.nrg.xdat.security.services.RoleRepositoryServiceI;
 import org.nrg.xdat.security.services.RoleServiceI;
+import org.nrg.xnat.initialization.InitializerSiteConfiguration;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 
+import javax.inject.Inject;
+
 @Configuration
 public class FeaturesConfig {
 
+    public static final String DEFAULT_FEATURE_SERVICE = "org.nrg.xdat.security.services.impl.FeatureServiceImpl";
+    public static final String DEFAULT_FEATURE_REPO_SERVICE = "org.nrg.xdat.security.services.impl.FeatureRepositoryServiceImpl";
+    public static final String DEFAULT_ROLE_SERVICE = "org.nrg.xdat.security.services.impl.RoleServiceImpl";
+    public static final String DEFAULT_ROLE_REPO_SERVICE = "org.nrg.xdat.security.services.impl.RoleRepositoryServiceImpl";
+
     @Bean
-    public FeatureServiceI featureService() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
-        String serviceImpl = null;
-        try {
-            serviceImpl = _configurationService.getSiteConfigurationProperty("security.services.feature.default");
-        } catch (SiteConfigurationException e) {
-            _log.warn("An error occurred trying to retrieve the security.services.feature.default site configuration property. Continuing and using default value.", e);
-        }
-        if (StringUtils.isBlank(serviceImpl)) {
-            serviceImpl = StringUtils.isNotBlank(_featureServiceImpl) ? _featureServiceImpl : DEFAULT_FEATURE_SERVICE;
+    public FeatureServiceI featureService() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException {
+        final String serviceImpl = StringUtils.defaultIfBlank(_preferences.getFeatureService(), DEFAULT_FEATURE_SERVICE);
+        if (_log.isDebugEnabled()) {
+            _log.debug("Creating feature service with implementing class " + serviceImpl);
         }
-        final Class<? extends FeatureServiceI> clazz = Class.forName(serviceImpl).asSubclass(FeatureServiceI.class);
-        return clazz.newInstance();
+        return Class.forName(serviceImpl).asSubclass(FeatureServiceI.class).newInstance();
     }
 
     @Bean
-    public FeatureRepositoryServiceI featureRepositoryService() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
-        String serviceImpl = null;
-        try {
-            serviceImpl = _configurationService.getSiteConfigurationProperty("security.services.featureRepository.default");
-        } catch (SiteConfigurationException e) {
-            _log.warn("An error occurred trying to retrieve the security.services.featureRepository.default site configuration property. Continuing and using default value.", e);
+    public FeatureRepositoryServiceI featureRepositoryService() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException {
+        final String serviceImpl = StringUtils.defaultIfBlank(_preferences.getFeatureRepositoryService(), DEFAULT_FEATURE_REPO_SERVICE);
+        if (_log.isDebugEnabled()) {
+            _log.debug("Creating feature repository service with implementing class " + serviceImpl);
         }
-        if (StringUtils.isBlank(serviceImpl)) {
-            serviceImpl = StringUtils.isNotBlank(_featureRepoServiceImpl) ? _featureRepoServiceImpl : DEFAULT_FEATURE_REPO_SERVICE;
-        }
-        final Class<? extends FeatureRepositoryServiceI> clazz = Class.forName(serviceImpl).asSubclass(FeatureRepositoryServiceI.class);
-        return clazz.newInstance();
+        return Class.forName(serviceImpl).asSubclass(FeatureRepositoryServiceI.class).newInstance();
     }
 
     @Bean
-    public RoleServiceI roleService() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
-        String serviceImpl = null;
-        try {
-            serviceImpl = _configurationService.getSiteConfigurationProperty("security.services.role.default");
-        } catch (SiteConfigurationException e) {
-            _log.warn("An error occurred trying to retrieve the security.services.role.default site configuration property. Continuing and using default value.", e);
-        }
-        if (StringUtils.isBlank(serviceImpl)) {
-            serviceImpl = StringUtils.isNotBlank(_roleServiceImpl) ? _roleServiceImpl : DEFAULT_ROLE_SERVICE;
+    public RoleServiceI roleService() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException {
+        final String serviceImpl = StringUtils.defaultIfBlank(_preferences.getRoleService(), DEFAULT_ROLE_SERVICE);
+        if (_log.isDebugEnabled()) {
+            _log.debug("Creating role service with implementing class " + serviceImpl);
         }
-        final Class<? extends RoleServiceI> clazz = Class.forName(serviceImpl).asSubclass(RoleServiceI.class);
-        return clazz.newInstance();
+        return Class.forName(serviceImpl).asSubclass(RoleServiceI.class).newInstance();
     }
 
     @Bean
-    public RoleRepositoryServiceI roleRepositoryService() throws ClassNotFoundException, IllegalAccessException, InstantiationException {
-        String serviceImpl = null;
-        try {
-            serviceImpl = _configurationService.getSiteConfigurationProperty("security.services.roleRepository.default");
-        } catch (SiteConfigurationException e) {
-            _log.warn("An error occurred trying to retrieve the security.services.roleRepository.default site configuration property. Continuing and using default value.", e);
+    public RoleRepositoryServiceI roleRepositoryService() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException {
+        final String serviceImpl = StringUtils.defaultIfBlank(_preferences.getRoleRepositoryService(), DEFAULT_ROLE_REPO_SERVICE);
+        if (_log.isDebugEnabled()) {
+            _log.debug("Creating role repository service with implementing class " + serviceImpl);
         }
-        if (StringUtils.isBlank(serviceImpl)) {
-            serviceImpl = StringUtils.isNotBlank(_roleRepoServiceImpl) ? _roleRepoServiceImpl : DEFAULT_ROLE_REPO_SERVICE;
-        }
-        final Class<? extends RoleRepositoryServiceI> clazz = Class.forName(serviceImpl).asSubclass(RoleRepositoryServiceI.class);
-        return clazz.newInstance();
+        return Class.forName(serviceImpl).asSubclass(RoleRepositoryServiceI.class).newInstance();
     }
 
-    private static final String DEFAULT_FEATURE_SERVICE = "org.nrg.xdat.security.services.impl.FeatureServiceImpl";
-    private static final String DEFAULT_FEATURE_REPO_SERVICE = "org.nrg.xdat.security.services.impl.FeatureRepositoryServiceImpl";
-    private static final String DEFAULT_ROLE_SERVICE = "org.nrg.xdat.security.services.impl.RoleServiceImpl";
-    private static final String DEFAULT_ROLE_REPO_SERVICE = "org.nrg.xdat.security.services.impl.RoleRepositoryServiceImpl";
     private static final Logger _log = LoggerFactory.getLogger(FeaturesConfig.class);
 
-    @Autowired
-    private SiteConfigurationService _configurationService;
-
-    @Value("${security.services.feature.default:}")
-    private String _featureServiceImpl;
-
-    @Value("${security.services.featureRepository.default:}")
-    private String _featureRepoServiceImpl;
-
-    @Value("${security.services.role.default:}")
-    private String _roleServiceImpl;
-
-    @Value("${security.services.roleRepository.default:}")
-    private String _roleRepoServiceImpl;
+    @Inject
+    private InitializerSiteConfiguration _preferences;
 }
diff --git a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
index 06dc28ba9c6835f5bec942c4a7ec05a8b368b431..a132589a5d47e8ff83bb95895b5c78cfdf08ac9d 100644
--- a/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/NotificationsConfig.java
@@ -1,17 +1,20 @@
 package org.nrg.xnat.configuration;
 
+import org.apache.commons.lang3.StringUtils;
+import org.nrg.config.exceptions.SiteConfigurationException;
 import org.nrg.framework.orm.hibernate.HibernateEntityPackageList;
 import org.nrg.notify.entities.ChannelRendererProvider;
 import org.nrg.notify.renderers.ChannelRenderer;
 import org.nrg.notify.renderers.NrgMailChannelRenderer;
-import org.springframework.beans.factory.annotation.Value;
+import org.nrg.xnat.initialization.InitializerSiteConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
-import org.springframework.mail.MailSender;
 import org.springframework.mail.javamail.JavaMailSender;
 import org.springframework.mail.javamail.JavaMailSenderImpl;
 
+import javax.inject.Inject;
+import java.io.IOException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
@@ -21,12 +24,13 @@ import java.util.Map;
 public class NotificationsConfig {
 
     @Bean
-    public JavaMailSender mailSender() {
+    public JavaMailSender mailSender() throws IOException, SiteConfigurationException {
+        final Map<String, String> smtp = _preferences.getSmtpServer();
         final JavaMailSenderImpl sender = new JavaMailSenderImpl();
-        sender.setHost(_host);
-        sender.setPort(_port);
-        sender.setUsername(_username);
-        sender.setPassword(_password);
+        sender.setHost(StringUtils.defaultIfBlank(smtp.get("host"), "localhost"));
+        sender.setPort(Integer.parseInt(StringUtils.defaultIfBlank(smtp.get("port"), "25")));
+        sender.setUsername(StringUtils.defaultIfBlank(smtp.get("username"), ""));
+        sender.setPassword(StringUtils.defaultIfBlank(smtp.get("password"), ""));
         return sender;
     }
 
@@ -36,15 +40,15 @@ public class NotificationsConfig {
     }
 
     @Bean
-    public ChannelRenderer mailChannelRenderer() {
+    public ChannelRenderer mailChannelRenderer() throws SiteConfigurationException {
         final NrgMailChannelRenderer renderer = new NrgMailChannelRenderer();
-        renderer.setFromAddress(_fromAddress);
-        renderer.setSubjectPrefix(_subjectPrefix);
+        renderer.setFromAddress(_preferences.getAdminEmail());
+        renderer.setSubjectPrefix(_preferences.getEmailPrefix());
         return renderer;
     }
 
     @Bean
-    public Map<String, ChannelRenderer> renderers() {
+    public Map<String, ChannelRenderer> renderers() throws SiteConfigurationException {
         final Map<String, ChannelRenderer> renderers = new HashMap<>();
         renderers.put("htmlMail", mailChannelRenderer());
         renderers.put("textMail", mailChannelRenderer());
@@ -52,27 +56,12 @@ public class NotificationsConfig {
     }
 
     @Bean
-    public ChannelRendererProvider rendererProvider() {
+    public ChannelRendererProvider rendererProvider() throws SiteConfigurationException {
         final ChannelRendererProvider provider = new ChannelRendererProvider();
         provider.setRenderers(renderers());
         return provider;
     }
 
-    @Value("${mailserver.host}")
-    private String _host;
-    
-    @Value("${mailserver.port}")
-    private int _port;
-
-    @Value("${mailserver.username}")
-    private String _username;
-
-    @Value("${mailserver.password}")
-    private String _password;
-
-    @Value("${mailserver.admin}")
-    private String _fromAddress;
-
-    @Value("${mailserver.prefix}")
-    private String _subjectPrefix;
+    @Inject
+    private InitializerSiteConfiguration _preferences;
 }
diff --git a/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java b/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java
index 1a77ad34e84a9caee918b632c147b340d34c5480..9fcf0b5e727fd4162c45ff65f60733420a3a8771 100644
--- a/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/PreferencesConfig.java
@@ -6,19 +6,21 @@ import org.nrg.config.services.SiteConfigurationService;
 import org.nrg.config.services.UserConfigurationService;
 import org.nrg.config.services.impl.DefaultConfigService;
 import org.nrg.config.services.impl.DefaultUserConfigurationService;
-import org.nrg.framework.orm.hibernate.HibernateEntityPackageList;
+import org.nrg.prefs.configuration.NrgPrefsServiceConfiguration;
 import org.nrg.prefs.services.PreferenceService;
+import org.nrg.xnat.initialization.InitializerSiteConfiguration;
 import org.nrg.xnat.resolvers.XnatPreferenceEntityResolver;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.ComponentScan;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Import;
 
+import javax.inject.Inject;
 import java.io.IOException;
-import java.util.Collections;
 
 @Configuration
-@ComponentScan({"org.nrg.config.daos", "org.nrg.prefs.services.impl.hibernate", "org.nrg.prefs.repositories"})
+@ComponentScan("org.nrg.config.daos")
+@Import(NrgPrefsServiceConfiguration.class)
 public class PreferencesConfig {
 
     @Bean
@@ -34,20 +36,15 @@ public class PreferencesConfig {
     @Bean
     public SiteConfigurationService siteConfigurationService() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SiteConfigurationException {
         // TODO: Add direct prefs call or JDBC call to get the site configuration setting from the database.
-        final Class<? extends SiteConfigurationService> clazz = Class.forName(_siteConfigServiceImpl).asSubclass(SiteConfigurationService.class);
+        final Class<? extends SiteConfigurationService> clazz = Class.forName(_preferences.getSiteConfigurationService()).asSubclass(SiteConfigurationService.class);
         return clazz.newInstance();
     }
 
-    @Bean
-    public HibernateEntityPackageList nrgPrefsEntityPackages() {
-        return new HibernateEntityPackageList(Collections.singletonList("org.nrg.prefs.entities"));
-    }
-
     @Bean
     public XnatPreferenceEntityResolver defaultResolver(final PreferenceService preferenceService) throws IOException {
         return new XnatPreferenceEntityResolver(preferenceService);
     }
 
-    @Value("${admin.siteConfig.service:org.nrg.config.services.impl.PrefsBasedSiteConfigurationService}")
-    private String _siteConfigServiceImpl;
+    @Inject
+    private InitializerSiteConfiguration _preferences;
 }
diff --git a/src/main/java/org/nrg/xnat/configuration/PropertiesConfig.java b/src/main/java/org/nrg/xnat/configuration/PropertiesConfig.java
index b2e133d440606f1ab92e082f5ad726d9841a9f9d..124bd16664a649ad2f7b486398f86e91c118a4e6 100644
--- a/src/main/java/org/nrg/xnat/configuration/PropertiesConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/PropertiesConfig.java
@@ -2,6 +2,7 @@ package org.nrg.xnat.configuration;
 
 import org.apache.commons.configuration.ConfigurationException;
 import org.apache.commons.lang3.StringUtils;
+import org.python.google.common.base.Joiner;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.context.annotation.Bean;
@@ -25,21 +26,25 @@ import java.util.List;
  */
 @Configuration
 @PropertySources({
-        @PropertySource(value = "file:${xnat.home}/config/services.properties", ignoreResourceNotFound = true),
-        @PropertySource(value = "file:${xnat.config.home}/services.properties", ignoreResourceNotFound = true),
-        @PropertySource(value = "file:${xnat.config}", ignoreResourceNotFound = true)})
+     @PropertySource(value = PropertiesConfig.XNAT_HOME_URL, ignoreResourceNotFound = true),
+     @PropertySource(value = PropertiesConfig.XNAT_CONFIG_HOME_URL, ignoreResourceNotFound = true),
+     @PropertySource(value = PropertiesConfig.XNAT_CONFIG_URL, ignoreResourceNotFound = true)})
 public class PropertiesConfig {
 
-    public static final String ENV_HOME = "HOME";
-    public static final String ENV_XNAT_HOME = "XNAT_HOME";
-    public static final String JAVA_XNAT_HOME = "xnat.home";
+    public static final String ENV_HOME              = "HOME";
+    public static final String ENV_XNAT_HOME         = "XNAT_HOME";
+    public static final String JAVA_XNAT_HOME        = "xnat.home";
     public static final String JAVA_XNAT_CONFIG_HOME = "xnat.config.home";
-    public static final String JAVA_XNAT_CONFIG = "xnat.config";
-    public static final List<String> CONFIG_LOCATIONS = Collections.unmodifiableList(Arrays.asList(JAVA_XNAT_CONFIG, JAVA_XNAT_CONFIG_HOME, JAVA_XNAT_HOME, ENV_XNAT_HOME, ENV_HOME, ENV_HOME));
-    public static final List<String> CONFIG_PATHS = Collections.unmodifiableList(Arrays.asList("", "services.properties", "config/services.properties", "config/services.properties", "xnat/config/services.properties", "config/services.properties"));
+    public static final String JAVA_XNAT_CONFIG      = "xnat.config";
+    public static final String XNAT_CONF_FILE        = "xnat-conf.properties";
+    public static final String BASE_CONF_FOLDER      = "config";
+    public static final String EXT_CONF_FOLDER       = "xnat/config";
+    public static final String XNAT_HOME_URL         = "file:${" + JAVA_XNAT_HOME + "}/" + BASE_CONF_FOLDER + "/" + XNAT_CONF_FILE;
+    public static final String XNAT_CONFIG_HOME_URL  = "file:${" + JAVA_XNAT_CONFIG_HOME + "}/" + XNAT_CONF_FILE;
+    public static final String XNAT_CONFIG_URL       = "file:${" + JAVA_XNAT_CONFIG + "}";
 
-    // TODO: The lines above should be combined into a list of expressions below. I can't get the SpEL expressions to evaluate correctly against the environment variables though.
-    // private static final List<String> CONFIG_EXPRESSIONS = Collections.unmodifiableList(Arrays.asList("${xnat.config}", "${xnat.config.home}/services.properties", "${XNAT_HOME}/config/services.properties", "${xnat.home}/config/services.properties", "${HOME}/xnat/config/services.properties"));
+    public static final List<String> CONFIG_LOCATIONS = Collections.unmodifiableList(Arrays.asList(JAVA_XNAT_CONFIG, JAVA_XNAT_CONFIG_HOME, JAVA_XNAT_HOME, ENV_XNAT_HOME, ENV_HOME, ENV_HOME));
+    public static final List<String> CONFIG_PATHS     = Collections.unmodifiableList(Arrays.asList("", XNAT_CONF_FILE, Paths.get(BASE_CONF_FOLDER, XNAT_CONF_FILE).toString(), Paths.get(BASE_CONF_FOLDER, XNAT_CONF_FILE).toString(), Paths.get(EXT_CONF_FOLDER, XNAT_CONF_FILE).toString(), Paths.get(BASE_CONF_FOLDER, XNAT_CONF_FILE).toString()));
 
     @Bean
     public static PropertySourcesPlaceholderConfigurer properties(final Environment environment) throws ConfigurationException {
@@ -92,7 +97,7 @@ public class PropertiesConfig {
                 }
             }
             if (_configFolderPaths.size() == 0) {
-                throw new RuntimeException("No XNAT home specified in any of the accepted locations.");
+                throw new RuntimeException("No XNAT home specified in any of the accepted locations: " + Joiner.on(", ").join(CONFIG_URLS));
             }
         }
         return _configFolderPaths;
@@ -104,7 +109,7 @@ public class PropertiesConfig {
             if (path.toFile().exists() && path.toFile().isFile()) {
                 return path.toFile();
             }
-            final File candidate = path.resolve("services.properties").toFile();
+            final File candidate = path.resolve(XNAT_CONF_FILE).toFile();
             if (candidate.exists()) {
                 return candidate;
             }
@@ -124,14 +129,18 @@ public class PropertiesConfig {
             }
         }
         if (configFolderPaths.size() == 0) {
-            throw new RuntimeException("No XNAT home specified in any of the accepted locations.");
+            throw new RuntimeException("No XNAT home specified in any of the accepted locations: " + Joiner.on(", ").join(CONFIG_URLS));
         }
         return configFolderPaths;
     }
 
     private static Path getConfigFolder(final Environment environment, final String variable, final String relative) {
+        final String url = "${" + variable + "}/" + relative;
+        if (!CONFIG_URLS.contains(url)) {
+            CONFIG_URLS.add(url);
+        }
         if (_log.isDebugEnabled()) {
-            _log.debug("Testing path suggested by environment variable {} for XNAT home candidate.", variable);
+            _log.debug("Testing path for XNAT home candidate: {}", url);
         }
         final String value = environment.getProperty(variable);
         if (StringUtils.isBlank(value)) {
@@ -141,7 +150,7 @@ public class PropertiesConfig {
             return null;
         }
         final Path candidate = Paths.get(value, relative);
-        final File file = candidate.toFile();
+        final File file      = candidate.toFile();
         if (file.exists()) {
             // If it's a directory...
             if (file.isDirectory()) {
@@ -152,7 +161,7 @@ public class PropertiesConfig {
                 return candidate;
             } else {
                 // If it's a file, then the parent is probably a config folder, so if this is services.properties (the default) or the specific file identified by xnat.config...
-                if (file.getName().equals("services.properties") || StringUtils.equals(candidate.toString(), environment.getProperty("xnat.config"))) {
+                if (file.getName().equals(XNAT_CONF_FILE) || StringUtils.equals(candidate.toString(), environment.getProperty(JAVA_XNAT_CONFIG))) {
                     // So its parent is a config folder, QED.
                     return candidate.getParent();
                 }
@@ -164,17 +173,13 @@ public class PropertiesConfig {
     }
 
     private static final Logger _log = LoggerFactory.getLogger(PropertiesConfig.class);
-    private static final List<String> CONFIG_CANDIDATES = Arrays.asList("${HOME}/config/services.properties",
-            "${HOME}/xnat/config/services.properties",
-            "${XNAT_HOME}/config/services.properties",
-            "${xnat.home}/config/services.properties",
-            "${xnat.config.home}/services.properties",
-            "${xnat.config}");
+
+    private static final List<String> CONFIG_URLS = new ArrayList<>();
 
     @Inject
     private Environment _environment;
 
-    private final List<Path> _configFolderPaths = new ArrayList<>();
+    private final List<Path>   _configFolderPaths     = new ArrayList<>();
     private final List<String> _configFolderLocations = new ArrayList<>();
     private Path _xnatHome;
 }
diff --git a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
index 83c4acec2bc4009855bc69b64b9a6db4692b395f..d6715fc08c0468c93359e427317c2dcc20b42ba8 100644
--- a/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/SchedulerConfig.java
@@ -1,62 +1,72 @@
 package org.nrg.xnat.configuration;
 
+import org.nrg.config.exceptions.SiteConfigurationException;
 import org.nrg.mail.services.EmailRequestLogService;
+import org.nrg.schedule.TriggerTaskProxy;
 import org.nrg.xnat.helpers.prearchive.SessionXMLRebuilder;
+import org.nrg.xnat.initialization.InitializerSiteConfiguration;
 import org.nrg.xnat.security.DisableInactiveUsers;
 import org.nrg.xnat.security.ResetEmailRequests;
 import org.nrg.xnat.security.ResetFailedLogins;
 import org.nrg.xnat.security.alias.ClearExpiredAliasTokens;
 import org.nrg.xnat.utils.XnatUserProvider;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.jms.core.JmsTemplate;
 import org.springframework.scheduling.annotation.EnableScheduling;
-import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.scheduling.annotation.SchedulingConfigurer;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
+import org.springframework.scheduling.config.ScheduledTaskRegistrar;
 
 import javax.inject.Inject;
 import javax.sql.DataSource;
+import java.util.List;
 
 @Configuration
 @EnableScheduling
-public class SchedulerConfig {
-    @Scheduled(cron = "0 0 1 * * ?")
-    public void disableInactiveUsers() {
-        _log.debug("Now running the disable inactive users process.");
-        final DisableInactiveUsers disableInactiveUsers = new DisableInactiveUsers(_inactivityBeforeLockout);
-        disableInactiveUsers.call();
+public class SchedulerConfig implements SchedulingConfigurer {
+    @Bean
+    public TriggerTaskProxy disableInactiveUsers() throws SiteConfigurationException {
+        return new TriggerTaskProxy(new DisableInactiveUsers(_preferences.getInactivityBeforeLockout()), _preferences.getInactivityBeforeLockoutSchedule());
     }
 
-    @Scheduled(fixedRateString = "${security.max_failed_logins_lockout_duration:86400000}")
-    public void resetFailedLogins() {
-        _log.debug("Now running the reset failed logins process.");
-        final ResetFailedLogins resetFailedLogins = new ResetFailedLogins(_dataSource);
-        resetFailedLogins.call();
+    @Bean
+    public TriggerTaskProxy resetFailedLogins() throws SiteConfigurationException {
+        return new TriggerTaskProxy(new ResetFailedLogins(_dataSource), _preferences.getMaxFailedLoginsLockoutDuration());
     }
 
-    @Scheduled(fixedRate = 900000)
-    public void resetEmailRequests() {
-        _log.debug("Now running the reset email requests process.");
-        final ResetEmailRequests resetEmailRequests = new ResetEmailRequests(_emailRequestLogService);
-        resetEmailRequests.call();
+    @Bean
+    public TriggerTaskProxy resetEmailRequests() {
+        return new TriggerTaskProxy(new ResetEmailRequests(_emailRequestLogService), 900000);
     }
 
-    @Scheduled(fixedRate = 3600000)
-    public void clearExpiredAliasTokens() {
-        _log.debug("Now running the clear expired alias tokens process.");
-        final ClearExpiredAliasTokens clearExpiredAliasTokens = new ClearExpiredAliasTokens(_dataSource, _tokenTimeout);
-        clearExpiredAliasTokens.call();
+    @Bean
+    public TriggerTaskProxy clearExpiredAliasTokens() throws SiteConfigurationException {
+        return new TriggerTaskProxy(new ClearExpiredAliasTokens(_dataSource, _preferences.getAliasTokenTimeout()), 3600000);
     }
 
-    @Scheduled(fixedRateString = "${services.rebuilder.repeat:60000}", initialDelay = 60000)
-    public void rebuildSessionXmls() {
-        _log.debug("Now running the session rebuild process.");
-        final SessionXMLRebuilder sessionXMLRebuilder = new SessionXMLRebuilder(_provider, _interval, _jmsTemplate);
-        sessionXMLRebuilder.call();
+    @Bean
+    public TriggerTaskProxy rebuildSessionéXmls() throws SiteConfigurationException {
+        return new TriggerTaskProxy(new SessionXMLRebuilder(_provider, _preferences.getSessionXmlRebuilderInterval(), _jmsTemplate), _preferences.getSessionXmlRebuilderRepeat(), 60000);
     }
 
-    private static final Logger _log = LoggerFactory.getLogger(SchedulerConfig.class);
+    @Bean(destroyMethod = "shutdown")
+    public ThreadPoolTaskScheduler taskScheduler() {
+        return new ThreadPoolTaskScheduler();
+    }
+
+    @Override
+    public void configureTasks(final ScheduledTaskRegistrar taskRegistrar) {
+        taskRegistrar.setScheduler(taskScheduler());
+//        taskRegistrar.addTriggerTask(resetFailedLogins());
+//        taskRegistrar.addTriggerTask(disableInactiveUsers());
+//        taskRegistrar.addTriggerTask(resetEmailRequests());
+//        taskRegistrar.addTriggerTask(clearExpiredAliasTokens());
+//        taskRegistrar.addTriggerTask(rebuildSessionXmls());
+        for (final TriggerTaskProxy triggerTask : _triggerTasks) {
+            taskRegistrar.addTriggerTask(triggerTask);
+        }
+    }
 
     @Inject
     private DataSource _dataSource;
@@ -70,12 +80,10 @@ public class SchedulerConfig {
     @Inject
     private JmsTemplate _jmsTemplate;
 
-    @Value("${security.inactivity_before_lockout:31556926}")
-    private int _inactivityBeforeLockout;
-
-    @Value("${security.token_timeout:2 days}")
-    private String _tokenTimeout;
+    @Inject
+    private InitializerSiteConfiguration _preferences;
 
-    @Value("${services.rebuilder.interval:5}")
-    private int _interval;
+    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
+    @Inject
+    private List<TriggerTaskProxy> _triggerTasks;
 }
\ No newline at end of file
diff --git a/src/main/java/org/nrg/xnat/configuration/SerializerConfig.java b/src/main/java/org/nrg/xnat/configuration/SerializerConfig.java
deleted file mode 100644
index 3871859ede4960d66ad820fd82a28217b4c10d78..0000000000000000000000000000000000000000
--- a/src/main/java/org/nrg/xnat/configuration/SerializerConfig.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.nrg.xnat.configuration;
-
-import com.fasterxml.jackson.core.JsonParser;
-import com.fasterxml.jackson.core.PrettyPrinter;
-import com.fasterxml.jackson.core.util.DefaultIndenter;
-import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
-import org.jetbrains.annotations.NotNull;
-import org.nrg.framework.services.SerializerService;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-public class SerializerConfig {
-
-    @Bean
-    @NotNull
-    public PrettyPrinter prettyPrinter() {
-        final DefaultIndenter      indenter = new DefaultIndenter("    ", DefaultIndenter.SYS_LF);
-        final DefaultPrettyPrinter printer  = new DefaultPrettyPrinter();
-        printer.indentObjectsWith(indenter);
-        printer.indentArraysWith(indenter);
-        return printer;
-    }
-
-    @Bean
-    public ObjectMapper jsonObjectMapper() {
-        final PrettyPrinter printer = prettyPrinter();
-        final ObjectMapper  mapper  = new ObjectMapper().setDefaultPrettyPrinter(printer);
-        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
-        return mapper;
-    }
-
-    @Bean
-    public ObjectMapper yamlObjectMapper() {
-        final PrettyPrinter printer = prettyPrinter();
-        final ObjectMapper  mapper  = new ObjectMapper(new YAMLFactory()).setDefaultPrettyPrinter(printer);
-        mapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
-        return mapper;
-    }
-
-    @Bean
-    public SerializerService serializerService() {
-        return new SerializerService();
-    }
-}
diff --git a/src/main/java/org/nrg/xnat/configuration/SiteConfigPreferences.java b/src/main/java/org/nrg/xnat/configuration/SiteConfigPreferences.java
new file mode 100644
index 0000000000000000000000000000000000000000..afe93e53a10adfc0db92427466f815d79440d33e
--- /dev/null
+++ b/src/main/java/org/nrg/xnat/configuration/SiteConfigPreferences.java
@@ -0,0 +1,881 @@
+package org.nrg.xnat.configuration;
+
+import org.nrg.prefs.annotations.NrgPreference;
+import org.nrg.prefs.annotations.NrgPreferenceBean;
+import org.nrg.prefs.beans.AbstractPreferenceBean;
+import org.nrg.prefs.exceptions.InvalidPreferenceName;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+@NrgPreferenceBean(toolId = SiteConfigPreferences.SITE_CONFIG_TOOL_ID,
+                   toolName = "XNAT Site Preferences",
+                   description = "Manages site configurations and settings for the XNAT system.",
+
+                   strict = false)
+public class SiteConfigPreferences extends AbstractPreferenceBean {
+    public static final String SITE_CONFIG_TOOL_ID = "siteConfig";
+
+    @NrgPreference(defaultValue = "XNAT")
+    public String getSiteTitle() {
+        return getValue("siteTitle");
+    }
+
+    public void setSiteTitle(final String siteTitle) {
+        try {
+            set(siteTitle, "siteTitle");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name siteTitle: something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference
+    public String getSiteUrl() {
+        return getValue("siteUrl");
+    }
+
+    public void setSiteUrl(final String siteUrl) {
+        try {
+            set(siteUrl, "siteUrl");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name siteUrl: something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "you@yoursite.org")
+    public String getAdminEmail() {
+        return getValue("adminEmail");
+    }
+
+    public void setAdminEmail(final String adminEmail) {
+        try {
+            set(adminEmail, "adminEmail");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'adminEmail': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/archive")
+    public String getArchiveRootPath() {
+        return getValue("archiveRootPath");
+    }
+
+    public void setArchiveRootPath(final String archiveRootPath) {
+        try {
+            set(archiveRootPath, "archiveRootPath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'archiveRootPath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/prearchive")
+    public String getPrearchivePath() {
+        return getValue("prearchivePath");
+    }
+
+    public void setPrearchivePath(final String prearchivePath) {
+        try {
+            set(prearchivePath, "prearchivePath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'prearchivePath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/cache")
+    public String getCachePath() {
+        return getValue("cachePath");
+    }
+
+    public void setCachePath(final String cachePath) {
+        try {
+            set(cachePath, "cachePath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'cachePath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/ftp")
+    public String getFtpPath() {
+        return getValue("ftpPath");
+    }
+
+    public void setFtpPath(final String ftpPath) {
+        try {
+            set(ftpPath, "ftpPath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'ftpPath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/build")
+    public String getBuildPath() {
+        return getValue("buildPath");
+    }
+
+    public void setBuildPath(final String buildPath) {
+        try {
+            set(buildPath, "buildPath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'buildPath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/data/xnat/pipeline")
+    public String getPipelinePath() {
+        return getValue("pipelinePath");
+    }
+
+    public void setPipelinePath(final String pipelinePath) {
+        try {
+            set(pipelinePath, "pipelinePath");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'pipelinePath': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "{'host':'mail.server','port':'25'}")
+    public Map<String, String> getSmtpServer() {
+        return getMapValue("smtpServer");
+    }
+
+    public void setSmtpServer(final Map<String, String> smtpServer) {
+        try {
+            setMapValue("smtpServer", smtpServer);
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'smtpServer': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "^.*$")
+    public String getPasswordComplexity() {
+        return getValue("passwordComplexity");
+    }
+
+    public void setPasswordComplexity(final String passwordComplexity) {
+        try {
+            set(passwordComplexity, "passwordComplexity");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordComplexity': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Password is not sufficiently complex.")
+    public String getPasswordComplexityMessage() {
+        return getValue("passwordComplexityMessage");
+    }
+
+    public void setPasswordComplexityMessage(final String passwordComplexityMessage) {
+        try {
+            set(passwordComplexityMessage, "passwordComplexityMessage");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordComplexityMessage': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "365")
+    public int getPasswordHistoryDuration() {
+        return getIntegerValue("passwordHistoryDuration");
+    }
+
+    public void setPasswordHistoryDuration(final int passwordHistoryDuration) {
+        try {
+            setIntegerValue(passwordHistoryDuration, "passwordHistoryDuration");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordHistoryDuration': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getRequireLogin() {
+        return getBooleanValue("requireLogin");
+    }
+
+    public void setRequireLogin(final boolean requireLogin) {
+        try {
+            setBooleanValue(requireLogin, "requireLogin");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'requireLogin': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false")
+    public boolean getUserRegistration() {
+        return getBooleanValue("userRegistration");
+    }
+
+    public void setUserRegistration(final boolean userRegistration) {
+        try {
+            setBooleanValue(userRegistration, "userRegistration");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'userRegistration': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getEmailVerification() {
+        return getBooleanValue("emailVerification");
+    }
+
+    public void setEmailVerification(final boolean emailVerification) {
+        try {
+            setBooleanValue(emailVerification, "emailVerification");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'emailVerification': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getEnableCsrfToken() {
+        return getBooleanValue("enableCsrfToken");
+    }
+
+    public void setEnableCsrfToken(final boolean enableCsrfToken) {
+        try {
+            setBooleanValue(enableCsrfToken, "enableCsrfToken");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'enableCsrfToken': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false")
+    public boolean getRestrictUserListAccessToAdmins() {
+        return getBooleanValue("restrictUserListAccessToAdmins");
+    }
+
+    public void setRestrictUserListAccessToAdmins(final boolean restrictUserListAccessToAdmins) {
+        try {
+            setBooleanValue(restrictUserListAccessToAdmins, "restrictUserListAccessToAdmins");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'restrictUserListAccessToAdmins': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getRequireSaltedPasswords() {
+        return getBooleanValue("requireSaltedPasswords");
+    }
+
+    public void setRequireSaltedPasswords(final boolean requireSaltedPasswords) {
+        try {
+            setBooleanValue(requireSaltedPasswords, "requireSaltedPasswords");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'requireSaltedPasswords': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getEmailAllowNonuserSubscribers() {
+        return getBooleanValue("emailAllowNonuserSubscribers");
+    }
+
+    public void setEmailAllowNonuserSubscribers(final boolean emailAllowNonuserSubscribers) {
+        try {
+            setBooleanValue(emailAllowNonuserSubscribers, "emailAllowNonuserSubscribers");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'emailAllowNonuserSubscribers': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Interval")
+    public String getPasswordExpirationType() {
+        return getValue("passwordExpirationType");
+    }
+
+    public void setPasswordExpirationType(final String passwordExpirationType) {
+        try {
+            set(passwordExpirationType, "passwordExpirationType");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordExpirationType': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "365")
+    public int getPasswordExpirationInterval() {
+        return getIntegerValue("passwordExpirationInterval");
+    }
+
+    public void setPasswordExpirationInterval(final int passwordExpirationInterval) {
+        try {
+            setIntegerValue(passwordExpirationInterval, "passwordExpirationInterval");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordExpirationInterval': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference
+    public Date getPasswordExpirationDate() {
+        return getDateValue("passwordExpirationDate");
+    }
+
+    public void setPasswordExpirationDate(final Date passwordExpirationDate) {
+        try {
+            setDateValue(passwordExpirationDate, "passwordExpirationDate");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'passwordExpirationDate': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false")
+    public boolean getShowApplet() {
+        return getBooleanValue("showApplet");
+    }
+
+    public void setShowApplet(final boolean showApplet) {
+        try {
+            setBooleanValue(showApplet, "showApplet");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'showApplet': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false")
+    public boolean getEnableProjectAppletScript() {
+        return getBooleanValue("enableProjectAppletScript");
+    }
+
+    public void setEnableProjectAppletScript(final boolean enableProjectAppletScript) {
+        try {
+            setBooleanValue(enableProjectAppletScript, "enableProjectAppletScript");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'enableProjectAppletScript': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getChecksums() {
+        return getBooleanValue("checksums");
+    }
+
+    public void setChecksums(final boolean checksums) {
+        try {
+            setBooleanValue(checksums, "checksums");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'checksums': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean getScanTypeMapping() {
+        return getBooleanValue("scanTypeMapping");
+    }
+
+    public void setScanTypeMapping(final boolean scanTypeMapping) {
+        try {
+            setBooleanValue(scanTypeMapping, "scanTypeMapping");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'scanTypeMapping': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "org.nrg.xnat.utils.ChecksumsSiteConfigurationListener", property = "checksums.property.changed.listener")
+    public String getChecksumsPropertyChangedListener() {
+        return getValue("checksums.property.changed.listener");
+    }
+
+    public void setChecksumsPropertyChangedListener(final String checksumsPropertyChangedListener) {
+        try {
+            set(checksumsPropertyChangedListener, "checksums.property.changed.listener");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'checksums.property.changed.listener': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true")
+    public boolean isEnableDicomReceiver() {
+        return getBooleanValue("enableDicomReceiver");
+    }
+
+    public void setEnableDicomReceiver(final boolean enableDicomReceiver) {
+        try {
+            setBooleanValue(enableDicomReceiver, "enableDicomReceiver");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'enableDicomReceiver': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "org.nrg.dcm.DicomSCPSiteConfigurationListener", property = "enableDicomReceiver.property.changed.listener")
+    public String getEnableDicomReceiverPropertyChangedListener() {
+        return getValue("enableDicomReceiver.property.changed.listener");
+    }
+
+    public void setEnableDicomReceiverPropertyChangedListener(final String enableDicomReceiverPropertyChangedListener) {
+        try {
+            set(enableDicomReceiverPropertyChangedListener, "enableDicomReceiver.property.changed.listener");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'enableDicomReceiver.property.changed.listener': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "admin")
+    public String getReceivedFileUser() {
+        return getValue("receivedFileUser");
+    }
+
+    public void setReceivedFileUser(final String receivedFileUser) {
+        try {
+            set(receivedFileUser, "receivedFileUser");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'receivedFileUser': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Session", property = "displayNameForGenericImageSession.singular")
+    public String getImageSessionDisplayNameSingular() {
+        return getValue("displayNameForGenericImageSession.singular");
+    }
+
+    public void setImageSessionDisplayNameSingular(final String displayNameForGenericImageSessionSingular) {
+        try {
+            set(displayNameForGenericImageSessionSingular, "displayNameForGenericImageSession.singular");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'displayNameForGenericImageSession.singular': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Sessions", property = "displayNameForGenericImageSession.plural")
+    public String getImageSessionDisplayNamePlural() {
+        return getValue("displayNameForGenericImageSession.plural");
+    }
+
+    public void setImageSessionDisplayNamePlural(final String displayNameForGenericImageSessionPlural) {
+        try {
+            set(displayNameForGenericImageSessionPlural, "displayNameForGenericImageSession.plural");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'displayNameForGenericImageSession.plural': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "['zip','jar','rar','ear','gar','mrb']")
+    public List<String> getZipExtensions() {
+        return getListValue("zipExtensions");
+    }
+
+    public void setZipExtensions(final List<String> zipExtensions) {
+        try {
+            setListValue("zipExtensions", zipExtensions);
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'zipExtensions': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Page")
+    public String getSiteDescriptionType() {
+        return getValue("siteDescriptionType");
+    }
+
+    public void setSiteDescriptionType(final String siteDescriptionType) {
+        try {
+            set(siteDescriptionType, "siteDescriptionType");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteDescriptionType': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/screens/site_description.vm")
+    public String getSiteDescriptionPage() {
+        return getValue("siteDescriptionPage");
+    }
+
+    public void setSiteDescriptionPage(final String siteDescriptionPage) {
+        try {
+            set(siteDescriptionPage, "siteDescriptionPage");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteDescriptionPage': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "SITE DESCRIPTION HERE: Go to Administer -> Configuration -> Site Information to change.")
+    public String getSiteDescriptionText() {
+        return getValue("siteDescriptionText");
+    }
+
+    public void setSiteDescriptionText(final String siteDescriptionText) {
+        try {
+            set(siteDescriptionText, "siteDescriptionText");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteDescriptionText': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/screens/QuickSearch.vm")
+    public String getSiteLoginLanding() {
+        return getValue("siteLoginLanding");
+    }
+
+    public void setSiteLoginLanding(final String siteLoginLanding) {
+        try {
+            set(siteLoginLanding, "siteLoginLanding");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteLoginLanding': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/Index.vm")
+    public String getSiteLandingLayout() {
+        return getValue("siteLandingLayout");
+    }
+
+    public void setSiteLandingLayout(final String siteLandingLayout) {
+        try {
+            set(siteLandingLayout, "siteLandingLayout");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteLandingLayout': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/screens/QuickSearch.vm")
+    public String getSiteHome() {
+        return getValue("siteHome");
+    }
+
+    public void setSiteHome(final String siteHome) {
+        try {
+            set(siteHome, "siteHome");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteHome': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "/Index.vm")
+    public String getSiteHomeLayout() {
+        return getValue("siteHomeLayout");
+    }
+
+    public void setSiteHomeLayout(final String siteHomeLayout) {
+        try {
+            set(siteHomeLayout, "siteHomeLayout");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'siteHomeLayout': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false", property = "UI.debug-extension-points")
+    public boolean getUiDebugExtensionPoints() {
+        return getBooleanValue("UI.debug-extension-points");
+    }
+
+    public void setUiDebugExtensionPoints(final boolean uiDebugExtensionPoints) {
+        try {
+            setBooleanValue(uiDebugExtensionPoints, "UI.debug-extension-points");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.debug-extension-points': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.allow-advanced-search")
+    public boolean getUiAllowAdvancedSearch() {
+        return getBooleanValue("UI.allow-advanced-search");
+    }
+
+    public void setuiAllowAdvancedSearch(final boolean uiAllowAdvancedSearch) {
+        try {
+            setBooleanValue(uiAllowAdvancedSearch, "UI.allow-advanced-search");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.allow-advanced-search': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.allow-new-user-comments")
+    public boolean getUiAllowNewUserComments() {
+        return getBooleanValue("UI.allow-new-user-comments");
+    }
+
+    public void setUiAllowNewUserComments(final boolean uiAllowNewUserComments) {
+        try {
+            setBooleanValue(uiAllowNewUserComments, "UI.allow-new-user-comments");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.allow-new-user-comments': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.allow-scan-addition")
+    public boolean getUiAllowScanAddition() {
+        return getBooleanValue("UI.allow-scan-addition");
+    }
+
+    public void setUiAllowScanAddition(final boolean uiAllowScanAddition) {
+        try {
+            setBooleanValue(uiAllowScanAddition, "UI.allow-scan-addition");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.allow-scan-addition': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-left-bar")
+    public boolean getUiShowLeftBar() {
+        return getBooleanValue("UI.show-left-bar");
+    }
+
+    public void setUiShowLeftBar(final boolean uiShowLeftBar) {
+        try {
+            setBooleanValue(uiShowLeftBar, "UI.show-left-bar");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-left-bar': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-left-bar-projects")
+    public boolean getUiShowLeftBarProjects() {
+        return getBooleanValue("UI.show-left-bar-projects");
+    }
+
+    public void setUiShowLeftBarProjects(final boolean uiShowLeftBarProjects) {
+        try {
+            setBooleanValue(uiShowLeftBarProjects, "UI.show-left-bar-projects");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-left-bar-projects': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-left-bar-favorites")
+    public boolean getUiShowLeftBarFavorites() {
+        return getBooleanValue("UI.show-left-bar-favorites");
+    }
+
+    public void setUiShowLeftBarFavorites(final boolean uiShowLeftBarFavorites) {
+        try {
+            setBooleanValue(uiShowLeftBarFavorites, "UI.show-left-bar-favorites");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-left-bar-favorites': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-left-bar-search")
+    public boolean getUiShowLeftBarSearch() {
+        return getBooleanValue("UI.show-left-bar-search");
+    }
+
+    public void setUiShowLeftBarSearch(final boolean uiShowLeftBarSearch) {
+        try {
+            setBooleanValue(uiShowLeftBarSearch, "UI.show-left-bar-search");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-left-bar-search': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-left-bar-browse")
+    public boolean getUiShowLeftBarBrowse() {
+        return getBooleanValue("UI.show-left-bar-browse");
+    }
+
+    public void setUiShowLeftBarBrowse(final boolean uiShowLeftBarBrowse) {
+        try {
+            setBooleanValue(uiShowLeftBarBrowse, "UI.show-left-bar-browse");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-left-bar-browse': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.show-manage-files")
+    public boolean getUiShowManageFiles() {
+        return getBooleanValue("UI.show-manage-files");
+    }
+
+    public void setUiShowManageFiles(final boolean uiShowManageFiles) {
+        try {
+            setBooleanValue(uiShowManageFiles, "UI.show-manage-files");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.show-manage-files': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "true", property = "UI.allow-non-admin-project-creation")
+    public boolean getUiAllowNonAdminProjectCreation() {
+        return getBooleanValue("UI.allow-non-admin-project-creation");
+    }
+
+    public void setUiAllowNonAdminProjectCreation(final boolean uiAllowNonAdminProjectCreation) {
+        try {
+            setBooleanValue(uiAllowNonAdminProjectCreation, "UI.allow-non-admin-project-creation");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.allow-non-admin-project-creation': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "Your login attempt failed because the username and password combination you provided was invalid. After %d failed login attempts, your user account will be locked. If you believe your account is currently locked, you can:<ul><li>Unlock it by resetting your password</li><li>Wait one hour for it to unlock automatically</li></ul>", property = "UI.login_failure_message")
+    public String getUiLogin_failure_message() {
+        return getValue("UI.login_failure_message");
+    }
+
+    public void setUiLoginFailureMessage(final String uiLoginFailureMessage) {
+        try {
+            set(uiLoginFailureMessage, "UI.login_failure_message");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.login_failure_message': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "false", property = "UI.allow-blocked-subject-assessor-view")
+    public boolean getUiAllowBlockedSubjectAssessorView() {
+        return getBooleanValue("UI.allow-blocked-subject-assessor-view");
+    }
+
+    public void setUiAllowBlockedSubjectAssessorView(final boolean uiAllowBlockedSubjectAssessorView) {
+        try {
+            setBooleanValue(uiAllowBlockedSubjectAssessorView, "UI.allow-blocked-subject-assessor-view");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'UI.allow-blocked-subject-assessor-view': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = FeaturesConfig.DEFAULT_FEATURE_SERVICE, property = "security.services.feature.default")
+    public String getFeatureService() {
+        return getValue("security.services.feature.default");
+    }
+
+    public void setFeatureService(final String featureService) {
+        try {
+            set(featureService, "security.services.feature.default");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'security.services.feature.default': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = FeaturesConfig.DEFAULT_FEATURE_REPO_SERVICE, property = "security.services.featureRepository.default")
+    public String getFeatureRepositoryService() {
+        return getValue("security.services.featureRepository.default");
+    }
+
+    public void setFeatureRepositoryService(final String featureRepositoryService) {
+        try {
+            set(featureRepositoryService, "security.services.featureRepository.default");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'security.services.featureRepository.default': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = FeaturesConfig.DEFAULT_ROLE_SERVICE, property = "security.services.role.default")
+    public String getRoleService() {
+        return getValue("security.services.role.default");
+    }
+
+    public void setRoleService(final String roleService) {
+        try {
+            set(roleService, "security.services.role.default");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'security.services.role.default': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = FeaturesConfig.DEFAULT_ROLE_REPO_SERVICE, property = "security.services.roleRepository.default")
+    public String getRoleRepositoryService() {
+        return getValue("security.services.roleRepository.default");
+    }
+
+    public void setRoleRepositoryService(final String roleRepositoryService) {
+        try {
+            set(roleRepositoryService, "security.services.roleRepository.default");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'security.services.roleRepository.default': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "XNAT")
+    public String getEmailPrefix() {
+        return getValue("emailPrefix");
+    }
+
+    public void setEmailPrefix(final String emailPrefix) {
+        try {
+            set(emailPrefix, "emailPrefix");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'emailPrefix': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "org.nrg.config.services.impl.PrefsBasedSiteConfigurationService", property = "admin.siteConfig.service")
+    public String getSiteConfigurationService() {
+        return getValue("admin.siteConfig.service");
+    }
+
+    public void setSiteConfigurationService(final String siteConfigurationService) {
+        try {
+            set(siteConfigurationService, "admin.siteConfig.service");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'admin.siteConfig.service': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "86400000")
+    public int getMaxFailedLoginsLockoutDuration() {
+        return getIntegerValue("maxFailedLoginsLockoutDuration");
+    }
+
+    public void setMaxFailedLoginsLockoutDuration(final int maxFailedLoginsLockoutDuration) {
+        try {
+            setIntegerValue(maxFailedLoginsLockoutDuration, "maxFailedLoginsLockoutDuration");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'maxFailedLoginsLockoutDuration': something is very wrong here.", e);
+        }
+    }
+
+    private static final Logger _log = LoggerFactory.getLogger(SiteConfigPreferences.class);
+
+    @NrgPreference(defaultValue = "31556926")
+    public int getInactivityBeforeLockout() {
+        return getIntegerValue("inactivityBeforeLockout");
+    }
+
+    public void setInactivityBeforeLockout(final int inactivityBeforeLockout) {
+        try {
+            setIntegerValue(inactivityBeforeLockout, "inactivityBeforeLockout");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'inactivityBeforeLockout': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "0 0 1 * * ?")
+    public String getInactivityBeforeLockoutSchedule() {
+        return getValue("inactivityBeforeLockoutSchedule");
+    }
+
+    public void setInactivityBeforeLockoutSchedule(final String inactivityBeforeLockoutSchedule) {
+        try {
+            set(inactivityBeforeLockoutSchedule, "inactivityBeforeLockoutSchedule");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'inactivityBeforeLockoutSchedule': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "60000")
+    public long getSessionXmlRebuilderRepeat() {
+        return getLongValue("sessionXmlRebuilderRepeat");
+    }
+
+    public void setSessionXmlRebuilderRepeat(final long sessionXmlRebuilderRepeat) {
+        try {
+            setLongValue(sessionXmlRebuilderRepeat, "sessionXmlRebuilderRepeat");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'sessionXmlRebuilderRepeat': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "5")
+    public int getSessionXmlRebuilderInterval() {
+        return getIntegerValue("sessionXmlRebuilderInterval");
+    }
+
+    public void setSessionXmlRebuilderInterval(final int sessionXmlRebuilderInterval) {
+        try {
+            setIntegerValue(sessionXmlRebuilderInterval, "sessionXmlRebuilderInterval");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'sessionXmlRebuilderInterval': something is very wrong here.", e);
+        }
+    }
+
+    @NrgPreference(defaultValue = "2 days")
+    public String getAliasTokenTimeout() {
+        return getValue("aliasTokenTimeout");
+    }
+
+    public void setAliasTokenTimeout(final String aliasTokenTimeout) {
+        try {
+            set(aliasTokenTimeout, "aliasTokenTimeout");
+        } catch (InvalidPreferenceName e) {
+            _log.error("Invalid preference name 'aliasTokenTimeout': something is very wrong here.", e);
+        }
+    }
+}
diff --git a/src/main/java/org/nrg/xnat/helpers/prearchive/SessionXMLRebuilder.java b/src/main/java/org/nrg/xnat/helpers/prearchive/SessionXMLRebuilder.java
index 88c0f5ecee8bf211c2c9f4c522e5a6fd688b184d..f9333c785ca42f67da612501c4e994c0947224c8 100644
--- a/src/main/java/org/nrg/xnat/helpers/prearchive/SessionXMLRebuilder.java
+++ b/src/main/java/org/nrg/xnat/helpers/prearchive/SessionXMLRebuilder.java
@@ -25,9 +25,8 @@ import java.io.IOException;
 import java.sql.SQLException;
 import java.util.Calendar;
 import java.util.List;
-import java.util.concurrent.Callable;
 
-public class SessionXMLRebuilder implements Callable<Void> {
+public class SessionXMLRebuilder implements Runnable {
     public SessionXMLRebuilder(final Provider<UserI> provider, final double interval, final JmsTemplate jmsTemplate) {
         _provider = provider;
         _interval = interval;
@@ -35,11 +34,11 @@ public class SessionXMLRebuilder implements Callable<Void> {
     }
 
     @Override
-    public Void call() {
+    public void run() {
         final UserI user = _provider.get();
         logger.trace("Running prearc job as {}", user.getLogin());
         List<SessionData> sds = null;
-        long now = Calendar.getInstance().getTimeInMillis();
+        long              now = Calendar.getInstance().getTimeInMillis();
         try {
             if (PrearcDatabase.ready) {
                 sds = PrearcDatabase.getAllSessions();
@@ -55,15 +54,15 @@ public class SessionXMLRebuilder implements Callable<Void> {
             logger.error("", e);
         }
         int updated = 0;
-        int total = 0;
+        int total   = 0;
         if (sds != null && sds.size() > 0) {
             for (final SessionData sessionData : sds) {
                 total++;
                 if (sessionData.getStatus().equals(PrearcUtils.PrearcStatus.RECEIVING) && !sessionData.getPreventAutoCommit() && !StringUtils.trimToEmpty(sessionData.getSource()).equals("applet")) {
                     try {
-                        final File sessionDir = PrearcUtils.getPrearcSessionDir(user, sessionData.getProject(), sessionData.getTimestamp(), sessionData.getFolderName(), false);
-                        final long then = sessionData.getLastBuiltDate().getTime();
-                        final double diff = diffInMinutes(then, now);
+                        final File   sessionDir = PrearcUtils.getPrearcSessionDir(user, sessionData.getProject(), sessionData.getTimestamp(), sessionData.getFolderName(), false);
+                        final long   then       = sessionData.getLastBuiltDate().getTime();
+                        final double diff       = diffInMinutes(then, now);
                         if (diff >= _interval && !PrearcUtils.isSessionReceiving(sessionData.getSessionDataTriple())) {
                             updated++;
                             try {
@@ -92,7 +91,6 @@ public class SessionXMLRebuilder implements Callable<Void> {
             }
         }
         logger.info("Built {} of {}", updated, total);
-        return null;
     }
 
     public static double diffInMinutes(long start, long end) {
@@ -103,6 +101,6 @@ public class SessionXMLRebuilder implements Callable<Void> {
     private static final Logger logger = LoggerFactory.getLogger(SessionXMLRebuilder.class);
 
     private final Provider<UserI> _provider;
-    private final double _interval;
-    private final JmsTemplate _jmsTemplate;
+    private final double          _interval;
+    private final JmsTemplate     _jmsTemplate;
 }
diff --git a/src/main/java/org/nrg/xnat/initialization/InitializerSiteConfiguration.java b/src/main/java/org/nrg/xnat/initialization/InitializerSiteConfiguration.java
new file mode 100644
index 0000000000000000000000000000000000000000..f5714bba1363eace7d1d60a1fe01fc2ef2dbc4d6
--- /dev/null
+++ b/src/main/java/org/nrg/xnat/initialization/InitializerSiteConfiguration.java
@@ -0,0 +1,154 @@
+/**
+ * InitializerSiteConfig
+ * (C) 2016 Washington University School of Medicine
+ * All Rights Reserved
+ *
+ * Released under the Simplified BSD License
+ */
+package org.nrg.xnat.initialization;
+
+import org.apache.commons.lang3.StringUtils;
+import org.nrg.config.exceptions.SiteConfigurationException;
+import org.nrg.config.services.impl.PropertiesBasedSiteConfigurationService;
+import org.nrg.framework.exceptions.NrgServiceError;
+import org.nrg.framework.exceptions.NrgServiceRuntimeException;
+import org.nrg.framework.services.SerializerService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ResultSetExtractor;
+import org.springframework.stereotype.Service;
+
+import javax.inject.Inject;
+import java.io.IOException;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Properties;
+
+@Service
+public class InitializerSiteConfiguration extends PropertiesBasedSiteConfigurationService {
+    public String getSiteConfigurationService() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("admin.siteConfig.service");
+    }
+
+    public String getPasswordComplexity() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("passwordComplexity");
+    }
+
+    public String getPasswordComplexityMessage() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("passwordComplexityMessage");
+    }
+
+    public int getPasswordHistoryDuration() throws SiteConfigurationException {
+        return getIntegerSiteConfigurationProperty("passwordHistoryDuration");
+    }
+
+    public String getReceivedFileUser() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("receivedFileUser");
+    }
+
+    public int getInactivityBeforeLockout() throws SiteConfigurationException {
+        return getIntegerSiteConfigurationProperty("inactivityBeforeLockout");
+    }
+
+    public long getInactivityBeforeLockoutSchedule() throws SiteConfigurationException {
+        return getLongSiteConfigurationProperty("inactivityBeforeLockoutSchedule");
+    }
+
+    public long getMaxFailedLoginsLockoutDuration() throws SiteConfigurationException {
+        return getLongSiteConfigurationProperty("maxFailedLoginsLockoutDuration");
+    }
+
+    public double getSessionXmlRebuilderInterval() throws SiteConfigurationException {
+        return getDoubleSiteConfigurationProperty("sessionXmlRebuilderInterval");
+    }
+
+    public long getSessionXmlRebuilderRepeat() throws SiteConfigurationException {
+        return getLongSiteConfigurationProperty("sessionXmlRebuilderRepeat");
+    }
+
+    public String getAliasTokenTimeout() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("aliasTokenTimeout");
+    }
+
+    public Map<String, String> getSmtpServer() throws SiteConfigurationException, IOException {
+        final String definition = getSiteConfigurationProperty("smtpServer");
+        if (StringUtils.isBlank(definition)) {
+            return null;
+        }
+        return _serializerService.deserializeJsonToMapOfStrings(definition);
+    }
+
+    public String getAdminEmail() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("adminEmail");
+    }
+
+    public String getEmailPrefix() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("emailPrefix");
+    }
+
+    public String getFeatureService() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("featureService");
+    }
+
+    public String getFeatureRepositoryService() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("featureRepositoryService");
+    }
+
+    public String getRoleService() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("roleService");
+    }
+
+    public String getRoleRepositoryService() throws SiteConfigurationException {
+        return getSiteConfigurationProperty("roleRepositoryService");
+    }
+
+    @Override
+    protected void setPreferenceValue(final String username, final String property, final String value) {
+        throw new NrgServiceRuntimeException(NrgServiceError.PermissionsViolation, "This site configuration service is for initialization and is read only.");
+    }
+
+    @Override
+    protected void getPreferenceValuesFromPersistentStore(final Properties properties) {
+        final Integer siteConfigToolKey = getSiteConfigToolKey();
+        if (siteConfigToolKey == null) {
+            _log.info("Didn't find a tool for the {} ID, checking for import values from configuration service.", SITE_CONFIG_TOOL_ID);
+            final Properties existing = checkForConfigServiceSiteConfiguration();
+            if (existing != null) {
+                _log.info("Found {} properties in the configuration service, importing those.", existing.size());
+                properties.putAll(existing);
+            }
+        } else {
+            _log.info("Working with the existing {} tool, checking for new import values.", SITE_CONFIG_TOOL_ID);
+            properties.putAll(getPersistedSiteConfiguration(siteConfigToolKey));
+        }
+    }
+
+    @SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
+    private Properties getPersistedSiteConfiguration(final int toolId) {
+        return getJdbcTemplate().query("select name, value from xhbm_preference where tool = ?", PROPERTIES_RESULT_SET_EXTRACTOR, toolId);
+    }
+
+    @SuppressWarnings({"SqlDialectInspection", "SqlNoDataSourceInspection"})
+    private Integer getSiteConfigToolKey() {
+        return getJdbcTemplate().queryForObject("select id from xhbm_tool where tool_id = ?", Integer.class, SITE_CONFIG_TOOL_ID);
+    }
+
+    private static final ResultSetExtractor<Properties> PROPERTIES_RESULT_SET_EXTRACTOR = new ResultSetExtractor<Properties>() {
+        @Override
+        public Properties extractData(final ResultSet results) throws SQLException, DataAccessException {
+            final Properties properties = new Properties();
+            while (results.next()) {
+                properties.put(results.getString("name"), results.getString("value"));
+            }
+            return properties;
+        }
+    };
+
+    private static final Logger _log                = LoggerFactory.getLogger(InitializerSiteConfiguration.class);
+    private static final String SITE_CONFIG_TOOL_ID = "siteConfig";
+
+    @Inject
+    private SerializerService _serializerService;
+}
diff --git a/src/main/java/org/nrg/xnat/initialization/RootConfig.java b/src/main/java/org/nrg/xnat/initialization/RootConfig.java
index d8d23ebb241e4426dc01385b351f2ceeb6bf16a2..963fdb5f122e09f9d41a66cb5c88ac3e9f3d6b55 100644
--- a/src/main/java/org/nrg/xnat/initialization/RootConfig.java
+++ b/src/main/java/org/nrg/xnat/initialization/RootConfig.java
@@ -1,61 +1,48 @@
 package org.nrg.xnat.initialization;
 
+import org.nrg.config.exceptions.SiteConfigurationException;
+import org.nrg.framework.configuration.FrameworkConfig;
 import org.nrg.framework.datacache.SerializerRegistry;
 import org.nrg.framework.orm.hibernate.HibernateEntityPackageList;
 import org.nrg.framework.services.ContextService;
 import org.nrg.xdat.security.HistoricPasswordValidator;
 import org.nrg.xdat.security.PasswordValidatorChain;
 import org.nrg.xdat.security.RegExpValidator;
-import org.nrg.xnat.utils.XnatUserProvider;
 import org.nrg.xnat.event.conf.EventPackages;
 import org.nrg.xnat.restlet.XnatRestletExtensions;
 import org.nrg.xnat.restlet.actions.importer.ImporterHandlerPackages;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.ImportResource;
+import org.nrg.xnat.utils.XnatUserProvider;
+import org.springframework.context.annotation.*;
 
+import javax.inject.Inject;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 
 @Configuration
-@ComponentScan({"org.nrg.framework.datacache.impl.hibernate",
-                "org.nrg.framework.services.impl",
-                "org.nrg.xdat.daos",
-                "org.nrg.xnat.daos",
-                "org.nrg.xnat.services.impl.hibernate",
-                "org.nrg.xdat.services",
-                "org.nrg.xft.daos",
-                "org.nrg.xft.services",
-                "org.nrg.xapi.configuration",
-                "org.nrg.xnat.helpers.merge",
-                "org.nrg.xnat.configuration",
-                "org.nrg.xnat.services",
-                "org.nrg.prefs.repositories",
-                "org.nrg.prefs.services.impl.hibernate",
-                "org.nrg.dicomtools.filters"})
+@ComponentScan({"org.nrg.xdat.daos", "org.nrg.xnat.daos", "org.nrg.xnat.services.impl.hibernate", "org.nrg.xdat.services", "org.nrg.xft.daos", "org.nrg.xft.services", "org.nrg.xnat.helpers.merge", "org.nrg.xnat.configuration", "org.nrg.xnat.services", "org.nrg.dicomtools.filters"})
+@Import(FrameworkConfig.class)
 @ImportResource({"WEB-INF/conf/xnat-security.xml", "WEB-INF/conf/mq-context.xml"})
 public class RootConfig {
 
-    public static final List<String> DEFAULT_ENTITY_PACKAGES = Arrays.asList("org.nrg.framework.datacache", "org.nrg.xft.entities", "org.nrg.xft.event.entities", "org.nrg.xdat.entities",
-                                                                              "org.nrg.xnat.entities", "org.nrg.xnat.event.entities", "org.nrg.prefs.entities", "org.nrg.config.entities");
+    public static final List<String> DEFAULT_ENTITY_PACKAGES = Arrays.asList("org.nrg.xft.entities", "org.nrg.xft.event.entities", "org.nrg.xdat.entities", "org.nrg.xnat.entities", "org.nrg.xnat.event.entities", "org.nrg.config.entities");
 
     @Bean
-    public String siteId() {
-        return _siteId;
+    public InitializerSiteConfiguration initializerSiteConfiguration() {
+        return new InitializerSiteConfiguration();
     }
 
     @Bean
-    public RegExpValidator regexValidator(@Value("${security.password_complexity:^.*$}") final String complexityExpression,
-                                          @Value("${security.password_complexity_message:Password is not sufficiently complex.}") final String complexityMessage) {
+    public RegExpValidator regexValidator() throws SiteConfigurationException {
+        final String complexityExpression = _preferences.getPasswordComplexity();
+        final String complexityMessage = _preferences.getPasswordComplexityMessage();
         return new RegExpValidator(complexityExpression, complexityMessage);
     }
 
     @Bean
-    public HistoricPasswordValidator historicPasswordValidator(@Value("${security.password_history:365}") final int durationInDays) {
+    public HistoricPasswordValidator historicPasswordValidator() throws SiteConfigurationException {
+        final int durationInDays = _preferences.getPasswordHistoryDuration();
         return new HistoricPasswordValidator(durationInDays);
     }
 
@@ -81,24 +68,25 @@ public class RootConfig {
     }
 
     @Bean
-    public XnatUserProvider receivedFileUserProvider(@Value("${services.dicom.scp.receivedfileuser:admin}") final String receivedFileUser) {
+    public XnatUserProvider receivedFileUserProvider() throws SiteConfigurationException {
+        final String receivedFileUser = _preferences.getReceivedFileUser();
         return new XnatUserProvider(receivedFileUser);
     }
 
     @Bean
     public XnatRestletExtensions xnatRestletExtensions() {
-		return new XnatRestletExtensions(new HashSet<String>(Arrays.asList(new String[] {"org.nrg.xnat.restlet.extensions"})));
+        return new XnatRestletExtensions(new HashSet<>(Arrays.asList(new String[]{"org.nrg.xnat.restlet.extensions"})));
     }
 
     @Bean
     public ImporterHandlerPackages importerHandlerPackages() {
-		return new ImporterHandlerPackages(new HashSet<String>(Arrays.asList(new String[] {"org.nrg.xnat.restlet.actions","org.nrg.xnat.archive"})));
+        return new ImporterHandlerPackages(new HashSet<>(Arrays.asList(new String[]{"org.nrg.xnat.restlet.actions", "org.nrg.xnat.archive"})));
     }
 
     @Bean
     public EventPackages eventPackages() {
-    	// NOTE:  These should be treated as parent packages.  All sub-packages should be searched 
-		return new EventPackages(new HashSet<String>(Arrays.asList(new String[] {"org.nrg.xnat.event","org.nrg.xft.event","org.nrg.xdat.event"})));
+        // NOTE:  These should be treated as parent packages.  All sub-packages should be searched
+        return new EventPackages(new HashSet<>(Arrays.asList(new String[]{"org.nrg.xnat.event", "org.nrg.xft.event", "org.nrg.xdat.event"})));
     }
 
     @Bean
@@ -106,6 +94,6 @@ public class RootConfig {
         return new SerializerRegistry();
     }
 
-    @Value("${site.title:XNAT}")
-    private String _siteId;
+    @Inject
+    private InitializerSiteConfiguration _preferences;
 }
diff --git a/src/main/java/org/nrg/xnat/security/DisableInactiveUsers.java b/src/main/java/org/nrg/xnat/security/DisableInactiveUsers.java
index a3351d3e5e628c34dd247a92ee2d911addc950d4..33132ad86f2c5f3b645913075df9b277794f4dda 100644
--- a/src/main/java/org/nrg/xnat/security/DisableInactiveUsers.java
+++ b/src/main/java/org/nrg/xnat/security/DisableInactiveUsers.java
@@ -26,9 +26,8 @@ import java.sql.SQLException;
 import java.util.Calendar;
 import java.util.Date;
 import java.util.GregorianCalendar;
-import java.util.concurrent.Callable;
 
-public class DisableInactiveUsers implements Callable<Void> {
+public class DisableInactiveUsers implements Runnable {
 
     public DisableInactiveUsers(final int inactivityBeforeLockout) {
         _inactivityBeforeLockout = inactivityBeforeLockout;
@@ -39,7 +38,7 @@ public class DisableInactiveUsers implements Callable<Void> {
      * and disables them.
      */
     @Override
-    public Void call() {
+    public void run() {
         try {
             final XFTTable table = XFTTable.Execute("SELECT xdat_user.login FROM xdat_user INNER JOIN " +
                     "(" +
@@ -76,7 +75,6 @@ public class DisableInactiveUsers implements Callable<Void> {
         } catch (DBPoolException e) {
             logger.error("A database connection or pooling error occurred.", e);
         }
-        return null;
     }
 
     /**
diff --git a/src/main/java/org/nrg/xnat/security/ResetEmailRequests.java b/src/main/java/org/nrg/xnat/security/ResetEmailRequests.java
index 733b43d8624fe31dc63dae13d45d73b571245270..d8c88bb31b497f28ead92615ed193289cf8a6eb4 100644
--- a/src/main/java/org/nrg/xnat/security/ResetEmailRequests.java
+++ b/src/main/java/org/nrg/xnat/security/ResetEmailRequests.java
@@ -14,17 +14,16 @@ import org.nrg.mail.services.EmailRequestLogService;
 
 import java.util.concurrent.Callable;
 
-public class ResetEmailRequests implements Callable<Void> {
+public class ResetEmailRequests implements Runnable {
     public ResetEmailRequests(final EmailRequestLogService service) {
         _service = service;
     }
 
     @Override
-    public Void call() {
+    public void run() {
         if (_service != null) {
             _service.clearLogs();
         }
-        return null;
     }
 
     private final EmailRequestLogService _service;
diff --git a/src/main/java/org/nrg/xnat/security/ResetFailedLogins.java b/src/main/java/org/nrg/xnat/security/ResetFailedLogins.java
index c32309cccff291ed5c32d1c837470444148212b8..d2bf58ae78925b3bbfdf490ad7aeeb8b1dd974c8 100644
--- a/src/main/java/org/nrg/xnat/security/ResetFailedLogins.java
+++ b/src/main/java/org/nrg/xnat/security/ResetFailedLogins.java
@@ -18,18 +18,17 @@ import javax.inject.Inject;
 import javax.sql.DataSource;
 import java.util.concurrent.Callable;
 
-public class ResetFailedLogins implements Callable<Void> {
+public class ResetFailedLogins implements Runnable {
 
     public ResetFailedLogins(final DataSource dataSource) {
         _dataSource = dataSource;
     }
 
     @Override
-    public Void call() {
+    public void run() {
         JdbcTemplate template = new JdbcTemplate(_dataSource);
         template.execute("UPDATE xhbm_xdat_user_auth SET failed_login_attempts=0");
         _log.info("Reset all failed login attempts.");
-        return null;
     }
 
     private static final Logger _log = LoggerFactory.getLogger(ResetFailedLogins.class);
diff --git a/src/main/java/org/nrg/xnat/security/alias/ClearExpiredAliasTokens.java b/src/main/java/org/nrg/xnat/security/alias/ClearExpiredAliasTokens.java
index 9eef3cb7e2d0e0a45e376b4af22ef4b1671eeb9e..5d8067cfb6fe7f5753b84f04593b3c0c3504e0e6 100644
--- a/src/main/java/org/nrg/xnat/security/alias/ClearExpiredAliasTokens.java
+++ b/src/main/java/org/nrg/xnat/security/alias/ClearExpiredAliasTokens.java
@@ -17,9 +17,8 @@ import org.springframework.jdbc.core.JdbcTemplate;
 import javax.sql.DataSource;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.Callable;
 
-public class ClearExpiredAliasTokens implements Callable<Void> {
+public class ClearExpiredAliasTokens implements Runnable {
     public ClearExpiredAliasTokens(final DataSource dataSource, final String timeout) {
         if (_log.isDebugEnabled()) {
             _log.debug("Initializing the alias token sweeper job with an interval of: " + timeout);
@@ -32,7 +31,7 @@ public class ClearExpiredAliasTokens implements Callable<Void> {
     /**
      */
     @Override
-    public Void call() {
+    public void run() {
         if (_log.isDebugEnabled()) {
             _log.debug("Executing alias token sweep function");
         }
@@ -44,14 +43,13 @@ public class ClearExpiredAliasTokens implements Callable<Void> {
             }
             template.execute(query);
         }
-        return null;
     }
 
-    private static final Logger _log = LoggerFactory.getLogger(ClearExpiredAliasTokens.class);
-    private static final String QUERY_DELETE_TOKEN_IP_ADDRESSES = "DELETE FROM xhbm_alias_token_validipaddresses WHERE alias_token in (SELECT id FROM xhbm_alias_token WHERE created < NOW() - INTERVAL '%s')";
-    private static final String QUERY_DELETE_ALIAS_TOKENS = "DELETE FROM xhbm_alias_token WHERE created < NOW() - INTERVAL '%s'";
-    private static final List<String> ALIAS_TOKEN_QUERIES = Arrays.asList(QUERY_DELETE_TOKEN_IP_ADDRESSES, QUERY_DELETE_ALIAS_TOKENS);
+    private static final Logger       _log                            = LoggerFactory.getLogger(ClearExpiredAliasTokens.class);
+    private static final String       QUERY_DELETE_TOKEN_IP_ADDRESSES = "DELETE FROM xhbm_alias_token_validipaddresses WHERE alias_token in (SELECT id FROM xhbm_alias_token WHERE created < NOW() - INTERVAL '%s')";
+    private static final String       QUERY_DELETE_ALIAS_TOKENS       = "DELETE FROM xhbm_alias_token WHERE created < NOW() - INTERVAL '%s'";
+    private static final List<String> ALIAS_TOKEN_QUERIES             = Arrays.asList(QUERY_DELETE_TOKEN_IP_ADDRESSES, QUERY_DELETE_ALIAS_TOKENS);
 
     private final DataSource _dataSource;
-    private final String _timeout;
+    private final String     _timeout;
 }
diff --git a/src/main/webapp/WEB-INF/conf/xnat-conf.properties b/src/main/webapp/WEB-INF/conf/xnat-conf.properties
new file mode 100644
index 0000000000000000000000000000000000000000..518aba10f78c8c90ced3268194939d422d65b8c3
--- /dev/null
+++ b/src/main/webapp/WEB-INF/conf/xnat-conf.properties
@@ -0,0 +1,18 @@
+#
+# xnat-conf.properties
+# XNAT http://www.xnat.org
+# Copyright (c) 2016, Washington University School of Medicine
+# All Rights Reserved
+#
+# Released under the Simplified BSD.
+#
+datasource.driver=org.postgresql.Driver
+datasource.url=jdbc:postgresql://localhost/xnat
+datasource.username=xnat
+datasource.password=xnat
+
+hibernate.dialect=org.hibernate.dialect.PostgreSQL9Dialect
+hibernate.hbm2ddl.auto=update
+hibernate.show_sql=false
+hibernate.cache.use_second_level_cache=true
+hibernate.cache.use_query_cache=true
\ No newline at end of file