diff --git a/build.gradle b/build.gradle
index 49b2b8fc0d8292d36c150c4de4950b64b68d8077..f249716621b2f3b054668ef2ab5547ff86caac54 100644
--- a/build.gradle
+++ b/build.gradle
@@ -301,8 +301,7 @@ dependencies {
     compile "org.nrg:ecat4xnat:1.7.0-SNAPSHOT"
     compile "org.nrg:DicomDB:4.1.0"
     compile "org.nrg:ExtAttr:4.1.0"
-//    compile "org.nrg:DicomEdit:4.2.1"
-    compile "org.nrg:DicomEdit:4.2.2"
+    compile "org.nrg:DicomEdit:4.2.3"
     compile "org.nrg:DicomImageUtils:${vXnat}"
     compile "org.nrg:DicomUtils:1.3.1"
     compile "org.nrg:PrearcImporter:${vXnat}"
@@ -386,7 +385,7 @@ dependencies {
     compile "org.apache.httpcomponents:httpcore-nio:4.4.4"
 
     compile "org.codehaus.groovy:groovy-all:${vGroovy}"
-    compile "org.python:jython:${vJython}"
+    compile "org.python:jython-standalone:${vJython}"
 
     compile "net.sourceforge.saxon:saxon:${vSaxon}"
     compile "xalan:xalan:2.7.2"
diff --git a/src/main/java/org/nrg/xapi/rest/event/EventHandlerApi.java b/src/main/java/org/nrg/xapi/rest/event/EventHandlerApi.java
index e8717e550508f34b4d6553b5055354026c38996e..166549e9cb25cc9e06f77132994cd930eeb6741f 100644
--- a/src/main/java/org/nrg/xapi/rest/event/EventHandlerApi.java
+++ b/src/main/java/org/nrg/xapi/rest/event/EventHandlerApi.java
@@ -12,8 +12,9 @@ import org.nrg.automation.event.entities.AutomationFilters;
 import org.nrg.automation.services.impl.hibernate.HibernateAutomationEventIdsService;
 import org.nrg.automation.services.impl.hibernate.HibernateAutomationFiltersService;
 import org.nrg.framework.annotations.XapiRestController;
+import org.nrg.framework.event.EventClass;
 import org.nrg.framework.event.Filterable;
-import org.nrg.framework.utilities.Reflection;
+import org.nrg.framework.utilities.BasicXnatResourceLocator;
 import org.nrg.xapi.model.event.EventClassInfo;
 import org.nrg.xdat.XDAT;
 import org.nrg.xdat.om.XnatProjectdata;
@@ -22,11 +23,12 @@ import org.nrg.xdat.security.XDATUser;
 import org.nrg.xdat.security.helpers.Permissions;
 import org.nrg.xdat.security.services.RoleHolder;
 import org.nrg.xft.security.UserI;
-import org.nrg.xnat.event.conf.EventPackages;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.core.annotation.AnnotationUtils;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.support.PropertiesLoaderUtils;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
@@ -44,6 +46,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 
 /**
  * The Class EventHandlerApi.
@@ -69,13 +72,6 @@ public class EventHandlerApi {
     @Autowired
     private HibernateAutomationFiltersService filtersService;
 
-    /**
-     * The event packages.
-     */
-    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
-    @Autowired
-    private EventPackages eventPackages;
-
     /**
      * Inits the this.
      */
@@ -183,7 +179,7 @@ public class EventHandlerApi {
                         Collections.sort(valueList);
                         filterableFields.put(autoFilters.getField(), valueList);
                     } else {
-                        for (String value : autoFilters.getValues()) {
+                        for (final String value : autoFilters.getValues()) {
                             final List<String> values = filterableFields.get(autoFilters.getField());
                             if (!values.contains(value)) {
                                 values.add(value);
@@ -206,23 +202,28 @@ public class EventHandlerApi {
      */
     private List<String> getEventClassList(List<AutomationEventIds> eventIdsList) {
         final List<String> classList = Lists.newArrayList();
-        // ClassList should be pulled from available event classes rather than from events
-        if (eventPackages != null) {
-            for (final String pkg : eventPackages) {
-                try {
-                    for (final Class<?> clazz : Reflection.getClassesForPackage(pkg)) {
-                        if (AutomationEventImplementerI.class.isAssignableFrom(clazz) && !clazz.isInterface() &&
-                            !Modifier.isAbstract(clazz.getModifiers())) {
-                            if (!classList.contains(clazz.getName())) {
-                                classList.add(clazz.getName());
-                            }
-                        }
-                    }
-                } catch (ClassNotFoundException | IOException e) {
-                    // Do nothing.
-                }
-            }
-        }
+        try {
+			for (final Resource resource : BasicXnatResourceLocator.getResources("classpath*:META-INF/xnat/events/*-event.properties")) {
+				final Properties properties = PropertiesLoaderUtils.loadProperties(resource);
+				if (!properties.containsKey(EventClass.EVENT_CLASS)) {
+					continue;
+				}
+				final String clssStr = properties.get(EventClass.EVENT_CLASS).toString();
+				try {
+					final Class<?> clazz = Class.forName(clssStr);
+					if (AutomationEventImplementerI.class.isAssignableFrom(clazz) && !clazz.isInterface() &&
+							!Modifier.isAbstract(clazz.getModifiers())) {
+						if (!classList.contains(clazz.getName())) {
+							classList.add(clazz.getName());
+						}
+					}
+				} catch (ClassNotFoundException cex) {
+					_log.debug("Could not load class for class name (" + clssStr + ")");
+				}
+			}
+		} catch (IOException e) {
+			_log.debug("Could not load event class properties resources (META-INF/xnat/*-event.properties)");
+		}
         // I think for now we'll not pull from the database if we've found event classes.  If the database
         // contains any thing different, it should only be event classes that are no longer available.
         if (classList.size() < 1) {
diff --git a/src/main/java/org/nrg/xnat/configuration/ReactorConfig.java b/src/main/java/org/nrg/xnat/configuration/ReactorConfig.java
index 27138d6cc5b2346a7ff67ef57123914de76c3023..d831d26cc2c0ac18405ca4c72617f6f4e5ae5750 100755
--- a/src/main/java/org/nrg/xnat/configuration/ReactorConfig.java
+++ b/src/main/java/org/nrg/xnat/configuration/ReactorConfig.java
@@ -26,12 +26,6 @@ public class ReactorConfig {
         return new XftItemEventListener(eventBus);
     }
 
-    @Bean
-    public EventPackages eventPackages() {
-        // 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"})));
-    }
-
     /**
      * Env.
      *
diff --git a/src/main/java/org/nrg/xnat/event/entities/ScriptLaunchRequestEvent.java b/src/main/java/org/nrg/xnat/event/entities/ScriptLaunchRequestEvent.java
index ff474487300f6466cf9b1477b3ad27231163d383..e5d2d2a0c488abc3599e836ed9c255a5092d33e0 100644
--- a/src/main/java/org/nrg/xnat/event/entities/ScriptLaunchRequestEvent.java
+++ b/src/main/java/org/nrg/xnat/event/entities/ScriptLaunchRequestEvent.java
@@ -10,15 +10,16 @@ import org.nrg.automation.event.AutomationEventImplementerI;
 import org.nrg.automation.event.entities.AutomationCompletionEvent;
 import org.nrg.automation.event.entities.PersistentEvent;
 import org.nrg.framework.event.EventClass;
-import org.nrg.framework.event.persist.PersistentEventImplementerI;
+
+import com.google.common.collect.Maps;
 
 /**
  * The Class AutomationLaunchRequestEvent.
  */
 @Entity
 @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")
-@EventClass(displayName="Script Launch Request Event")
-public class ScriptLaunchRequestEvent extends PersistentEvent implements PersistentEventImplementerI, AutomationEventImplementerI {
+@EventClass(name="ScriptLaunchRequestEvent", description="Script Launch Request Event")
+public class ScriptLaunchRequestEvent extends PersistentEvent implements AutomationEventImplementerI {
 	
 	/** The Constant serialVersionUID. */
 	private static final long serialVersionUID = 7465778737330635218L;
@@ -26,7 +27,7 @@ public class ScriptLaunchRequestEvent extends PersistentEvent implements Persist
 	/** The automation completion event. */
 	private AutomationCompletionEvent automationCompletionEvent;
 	
-	private Map<String,Object> parameterMap;
+	private Map<String,Object> parameterMap = Maps.newHashMap();
 	
 	/**
 	 * Instantiates a new automation launch request event.
diff --git a/src/main/java/org/nrg/xnat/event/listeners/AutomationEventScriptHandler.java b/src/main/java/org/nrg/xnat/event/listeners/AutomationEventScriptHandler.java
index 6f0d32a1cca965653e26b03c6a342bffa06c2a30..b5e4be6171514a8277d89c3851e6f9e15cf60a76 100644
--- a/src/main/java/org/nrg/xnat/event/listeners/AutomationEventScriptHandler.java
+++ b/src/main/java/org/nrg/xnat/event/listeners/AutomationEventScriptHandler.java
@@ -22,6 +22,7 @@ import org.nrg.framework.constants.Scope;
 import org.nrg.framework.event.Filterable;
 import org.nrg.framework.event.persist.PersistentEventImplementerI;
 import org.nrg.framework.exceptions.NrgServiceException;
+import org.nrg.framework.exceptions.NrgServiceRuntimeException;
 import org.nrg.framework.services.NrgEventService;
 import org.nrg.xdat.XDAT;
 import org.nrg.xdat.security.helpers.Users;
@@ -444,14 +445,23 @@ public class AutomationEventScriptHandler implements Consumer<Event<AutomationEv
             if (PersistentWorkflowUtils.IN_PROGRESS.equals(workflow.getStatus())) {
                 WorkflowUtils.complete(workflow, workflow.buildEvent());
             }
-        } catch (NrgServiceException e) {
-            final String message = String.format("Failed running the script %s by user %s for event %s on data type %s instance %s from project %s",
+        } catch (NrgServiceException | NrgServiceRuntimeException e) {
+            final String message = String.format("Failed running the script %s by user %s for event %s on data type %s instance %s from project %s  (Exception=%s)",
                                                  request.getScriptId(),
                                                  request.getUser().getLogin(),
                                                  request.getEvent(),
                                                  request.getDataType(),
                                                  request.getDataId(),
-                                                 request.getExternalId());
+                                                 request.getExternalId(),
+                                                 e.toString());
+            if (scriptOut==null) {
+            	scriptOut = new ScriptOutput();
+            	scriptOut.setStatus(Status.ERROR);
+            	scriptOut.setOutput(message);
+            }
+            if (PersistentWorkflowUtils.IN_PROGRESS.equals(workflow.getStatus())) {
+                WorkflowUtils.fail(workflow, workflow.buildEvent());
+            }
             AdminUtils.sendAdminEmail("Script execution failure", message);
             logger.error(message, e);
             if (PersistentWorkflowUtils.IN_PROGRESS.equals(workflow.getStatus())) {
diff --git a/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java b/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java
index 7cc14d329c90596d45c01caa758d47becb2963a4..6bca03b5a2bf491b32dc29a83aceb0a328c3331d 100644
--- a/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java
+++ b/src/main/java/org/nrg/xnat/initialization/SecurityConfig.java
@@ -69,7 +69,7 @@ public class SecurityConfig {
 
     @Bean
     public XnatAuthenticationEntryPoint loginUrlAuthenticationEntryPoint() {
-        final XnatAuthenticationEntryPoint entryPoint = new XnatAuthenticationEntryPoint("/app/template/Login.vm");
+        final XnatAuthenticationEntryPoint entryPoint = new XnatAuthenticationEntryPoint("/app/template/Login.vm", _configuration);
         entryPoint.setDataPaths(Arrays.asList("/xapi/**", "/data/**", "/REST/**", "/fs/**"));
         entryPoint.setInteractiveAgents(Arrays.asList(".*MSIE.*", ".*Mozilla.*", ".*AppleWebKit.*", ".*Opera.*"));
         return entryPoint;
@@ -100,8 +100,7 @@ public class SecurityConfig {
         RegisterSessionAuthenticationStrategy registerSessionAuthenticationStrategy = new RegisterSessionAuthenticationStrategy(sessionRegistry);
         authStrategies.add(registerSessionAuthenticationStrategy);
 
-        final CompositeSessionAuthenticationStrategy compositeSessionAuthenticationStrategy = new CompositeSessionAuthenticationStrategy(authStrategies);
-        return compositeSessionAuthenticationStrategy;
+        return new CompositeSessionAuthenticationStrategy(authStrategies);
     }
 
     @Bean
diff --git a/src/main/java/org/nrg/xnat/security/XnatAuthenticationEntryPoint.java b/src/main/java/org/nrg/xnat/security/XnatAuthenticationEntryPoint.java
index 3c08027aa4f2df48283a2f49a53f6133d101458b..1c40b2b9f1aa27bff5000df7a4b61f55e6943f8b 100644
--- a/src/main/java/org/nrg/xnat/security/XnatAuthenticationEntryPoint.java
+++ b/src/main/java/org/nrg/xnat/security/XnatAuthenticationEntryPoint.java
@@ -13,6 +13,8 @@ package org.nrg.xnat.security;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.nrg.config.exceptions.SiteConfigurationException;
+import org.nrg.xdat.preferences.InitializerSiteConfiguration;
 import org.springframework.security.core.AuthenticationException;
 import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
 import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
@@ -28,8 +30,9 @@ import java.util.regex.Pattern;
 
 public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoint {
 
-    public XnatAuthenticationEntryPoint(String loginFormUrl) {
+    public XnatAuthenticationEntryPoint(final String loginFormUrl, final InitializerSiteConfiguration configuration) {
         super(loginFormUrl);
+        _configuration = configuration;
     }
 
     /**
@@ -41,8 +44,9 @@ public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoi
      * @param request       HTTP request object.
      * @param response      HTTP response object.
      * @param authException An authentication exception that may have redirected the agent to re-authenticate.
-     * @throws IOException
-     * @throws ServletException
+     *
+     * @throws IOException When an error occurs reading or writing data.
+     * @throws ServletException When an error occurs in the framework.
      */
     @Override
     public void commence(final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException authException) throws IOException, ServletException {
@@ -51,27 +55,33 @@ public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoi
 
         if (_log.isDebugEnabled()) {
             _log.debug("Evaluating data path request: " + strippedUri + ", user agent: " + userAgent);
-            }
-
-        if(!StringUtils.isBlank(strippedUri) && strippedUri.contains("/action/AcceptProjectAccess/par/")) {
-        	int index=strippedUri.indexOf("/par/")+5;
-        	if(strippedUri.length()>index){//par number included?
-        		String parS=strippedUri.substring(index);
-        		if(parS.contains("/")){
-        			parS=parS.substring(0,parS.indexOf("/"));
-        		}
-        		
-        		request.getSession().setAttribute("par", parS);
-        	}
         }
-        
-        if (isDataPath(request) && !isInteractiveAgent(userAgent)) {
-            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
-            return;
+
+        if (!StringUtils.isBlank(strippedUri) && strippedUri.contains("/action/AcceptProjectAccess/par/")) {
+            int index = strippedUri.indexOf("/par/") + 5;
+            if (strippedUri.length() > index) {//par number included?
+                String parS = strippedUri.substring(index);
+                if (parS.contains("/")) {
+                    parS = parS.substring(0, parS.indexOf("/"));
+                }
+
+                request.getSession().setAttribute("par", parS);
+            }
         }
 
+        if (isDataPath(request) && !isInteractiveAgent(userAgent)) {
+            try {
+                response.setHeader("WWW-Authenticate", "Basic realm=\"" + _configuration.getSiteId() + "\"");
+                response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            } catch (SiteConfigurationException e) {
+                _log.error("An error occurred trying to access system resources: siteId", e);
+                response.setHeader("WWW-Authenticate", "Basic");
+                response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
+            }
+        } else {
             super.commence(request, response, authException);
         }
+    }
 
     /**
      * Sets the data paths, i.e. those paths which require a user-agent interactivity test to determine whether the user
@@ -83,7 +93,7 @@ public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoi
     public void setDataPaths(final List<String> dataPaths) {
         if (_log.isDebugEnabled()) {
             _log.debug("Adding " + dataPaths + " data paths");
-    }
+        }
 
         for (final String dataPath : dataPaths) {
             if (_log.isDebugEnabled()) {
@@ -102,7 +112,7 @@ public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoi
         for (final String interactiveAgent : interactiveAgents) {
             if (_log.isDebugEnabled()) {
                 _log.debug("Adding interactive agent specifier: " + interactiveAgent);
-}
+            }
             final Pattern pattern = Pattern.compile(interactiveAgent);
             _agentPatterns.add(pattern);
         }
@@ -146,8 +156,10 @@ public class XnatAuthenticationEntryPoint extends LoginUrlAuthenticationEntryPoi
         return false;
     }
 
+    private final InitializerSiteConfiguration _configuration;
+
     private static final Log _log = LogFactory.getLog(XnatAuthenticationEntryPoint.class);
 
-    private final List<RequestMatcher> _dataPaths = new ArrayList<>();
-    private final List<Pattern> _agentPatterns = new ArrayList<>();
+    private final List<RequestMatcher> _dataPaths     = new ArrayList<>();
+    private final List<Pattern>        _agentPatterns = new ArrayList<>();
 }
diff --git a/src/main/java/org/nrg/xnat/services/messaging/automation/AutomatedScriptRequest.java b/src/main/java/org/nrg/xnat/services/messaging/automation/AutomatedScriptRequest.java
index 1512ed44f62fc7e25bf70c2e19683be229d2565d..c6204cebb86d50eac498735689fe7e80ecd4f789 100644
--- a/src/main/java/org/nrg/xnat/services/messaging/automation/AutomatedScriptRequest.java
+++ b/src/main/java/org/nrg/xnat/services/messaging/automation/AutomatedScriptRequest.java
@@ -87,7 +87,9 @@ public class AutomatedScriptRequest implements Serializable {
 	 */
 	public AutomatedScriptRequest(final String srcEventId, final String srcEventClass, final UserI user, final String scriptId, final String event, final String scriptWorkflow, final String dataType, final String dataId, final String externalId, Map<String,Object> argumentMap) {
 		this(srcEventId, srcEventClass, user, scriptId, event, scriptWorkflow, dataType, dataId, externalId);
-		_argumentMap.putAll(argumentMap);
+		if (argumentMap != null) {
+			_argumentMap.putAll(argumentMap);
+		}
 	}	
 
 	/**
diff --git a/src/main/webapp/WEB-INF/tags/page/xnat.tag b/src/main/webapp/WEB-INF/tags/page/xnat.tag
index 5509eb107147fac81d6c998c919ef9a1c9d6780f..df3ab8e8e0ecfdd3d300f79acb682a80701b44f2 100644
--- a/src/main/webapp/WEB-INF/tags/page/xnat.tag
+++ b/src/main/webapp/WEB-INF/tags/page/xnat.tag
@@ -359,36 +359,11 @@ ${bodyTop}
 
             <!-- search script -->
             <script type="text/javascript">
-                <!--
-                function DefaultEnterKey(e, button){
-                    var keynum, keychar, numcheck;
-
-                    if (window.event) // IE
-                    {
-                        keynum = e.keyCode;
-                        if (keynum == 13) {
-                            submitQuickSearch();
-                            return true;
-                        }
-                    }
-                    else if (e) // Netscape/Firefox/Opera
-                    {
-                        keynum = e.which;
-                        if (keynum == 13) {
-                            submitQuickSearch();
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-
                 function submitQuickSearch(){
-                    concealContent();
-                    if (document.getElementById('quickSearchForm').value != "")
-                        document.getElementById('quickSearchForm').submit();
+                  if($('#searchValue').val()!="") {
+                    $('#quickSearchForm').submit();
+                  }
                 }
-
-                //-->
             </script>
             <!-- end search script -->
 
@@ -426,11 +401,20 @@ ${bodyTop}
                     </optgroup>
                 </select>
                 <input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value="">
+                <input id="xnat_csrf" name="XNAT_CSRF" type="hidden" value="">
                 <button type="button" id="search_btn" class="btn2" onclick="submitQuickSearch();">Go</button>
 
                 <script>
-
-                    $('#searchValue').each(function(){
+                    var searchField = $('#searchValue');
+                    searchField.keyup(function( event ) {
+                      if (event.which == 13) {
+                        submitQuickSearch();
+                      }
+                    });
+                    
+                    $('#xnat_csrf').val(window.csrfToken);
+                    
+                    searchField.each(function(){
                         var _this = this;
                         _this.value = _this.value || 'search';
                         $(_this).focus(function(){
diff --git a/src/main/webapp/scripts/uploaders/AutomationBasedUploader.js b/src/main/webapp/scripts/uploaders/AutomationBasedUploader.js
index 77b4dd7cb1a981747ba8fa801891aaddf6900e2c..8e593ec50c7af1d4515eff3da2637891a6987875 100644
--- a/src/main/webapp/scripts/uploaders/AutomationBasedUploader.js
+++ b/src/main/webapp/scripts/uploaders/AutomationBasedUploader.js
@@ -270,8 +270,12 @@ XNAT.app.abu.eventHandlerChange = function(){
 	var eventHandler = $('#eventHandlerSelect').val();
 	if (typeof eventHandler === 'undefined' || eventHandler == null || eventHandler.length<1 && ($("#handlerDefaultOption").html() == 'NONE DEFINED' || $("#handlerDefaultOption").html() == 'SELECT')) {
 		$("#abu-process-button").addClass("abu-button-disabled");
+		//$("#abu-process-button-text").html("&nbsp;");
+		$("#abu-process-button").css("visibility","hidden");
 	} else if ((XNAT.app.abu.usageSelect=='Launch') || (abu._fileUploader._uploadStarted && abu._fileUploader._filesInProgress<1)) {
 		$("#abu-process-button").removeClass("abu-button-disabled");
+		//$("#abu-process-button-text").html("&nbsp;");
+		$("#abu-process-button").css("visibility","visible");
 	}
 	XNAT.app.abu.filesProcessed = false;
 }
@@ -411,7 +415,7 @@ XNAT.app.abu.populateEventHandlerSelect = function(){
 		if ($('#eventHandlerSelect').find('option').length==1) {
 			$('#handlerDefaultOption').html('NONE DEFINED'); 
 		} else if ($('#eventHandlerSelect').find('option').length==2) {
-			$('#eventHandlerSelect').find('option').get(0).remove();
+			$($('#eventHandlerSelect').find('option').get(0)).remove();
 		}
 	} else {
 		$('#eventHandlerSelect').append('<option value="">NONE DEFINED</option>'); 
@@ -591,6 +595,8 @@ XNAT.app.abu.initializeAbuUploader = function(usageType){
 					var eventHandler = $('#eventHandlerSelect').val();
 					if (typeof eventHandler !== 'undefined' && eventHandler != null && eventHandler.length>0) {
 						$("#abu-process-button").removeClass("abu-button-disabled");
+						$("#abu-process-button-text").html("Process Files");
+						$("#abu-process-button").css("visibility","visible");
 					} else {
 						$("#abu-done-button-text").html("Done");
 						$("#abu-done-button").removeClass("abu-button-disabled");
@@ -615,6 +621,7 @@ XNAT.app.abu.initializeAbuUploader = function(usageType){
 				var eventHandler = $('#eventHandlerSelect').val();
 				if (eventHandler != undefined && eventHandler != null && eventHandler.length>0) {
 					$("#abu-process-button").removeClass("abu-button-disabled");
+					$("#abu-process-button").css("visibility","visible");
 				} else {
 					$("#abu-done-button").removeClass("abu-button-disabled");
 					$("#abu-done-button-text").html("Done");
@@ -628,6 +635,8 @@ XNAT.app.abu.initializeAbuUploader = function(usageType){
 				$("#abu-done-button-text").html("Cancel");
 				if ($('#eventHandlerSelect option').size()>1 && $('#eventHandlerSelect').val()=="") {
 					$("#abu-process-button").addClass("abu-button-disabled");
+					//$("#abu-process-button-text").html("&nbsp;");
+					$("#abu-process-button").css("visibility","hidden");
 				} 
 				$("#file-uploader-instructions-sel").css("display","none");
 			} else {
@@ -637,6 +646,8 @@ XNAT.app.abu.initializeAbuUploader = function(usageType){
 					abu._fileUploader.DRAG_AND_DROP_ON = false;
 				} 
 				$("#abu-process-button").addClass("abu-button-disabled");
+				//$("#abu-process-button-text").html("&nbsp;");
+				$("#abu-process-button").css("visibility","hidden");
 				$(".upload-area").css("display","none");
 				$(".eventhandler-area").css("display","none");
 			}
@@ -662,8 +673,9 @@ XNAT.app.abu.usageSelectAction = function(){
 		$("#abu-upload-button").removeClass("abu-button-disabled");
 		abu._fileUploader.DRAG_AND_DROP_ON = true;
 		$("#abu-process-button").addClass("abu-button-disabled");
+		//$("#abu-process-button-text").html("&nbsp;");
+		$("#abu-process-button").css("visibility","hidden");
 		$("#script-select-text").html("Post-upload processing script:");
-		$("#abu-process-button-text").html("Process files");
 		$("#resourceSelect").prop('disabled',false);
 		$(".response_text").html('');
 	} else if (XNAT.app.abu.usageSelect=='Launch') { 
@@ -674,6 +686,7 @@ XNAT.app.abu.usageSelectAction = function(){
 		var eventHandler = $('#eventHandlerSelect').val();
 		if (eventHandler != undefined && eventHandler != null && eventHandler.length>0) {
 			$("#abu-process-button").removeClass("abu-button-disabled");
+			$("#abu-process-button").css("visibility","visible");
 		}
 		$("#script-select-text").html("Script to launch:");
 		$("#abu-process-button-text").html("Run script");
@@ -716,6 +729,8 @@ XNAT.app.abu.whatToDoChange = function(){
 	$('#eventHandlerSelect').val(launchSelect);
 	if (typeof abu !== 'undefined' && abu._fileUploader.uploadsStarted>0 && abu._fileUploader.uploadsInProgress==0) {
 		$("#abu-process-button").removeClass("abu-button-disabled");
+		$("#abu-process-button-text").html("Process files");
+		$("#abu-process-button").css("visibility","visible");
 	}
 	if (XNAT.app.abu.usageSelect == 'Upload' && $('#whatToDoSelect option').size()>1 && $('#whatToDoSelect').val()=="") {
 		$("#abu-upload-button").addClass("abu-button-disabled");
@@ -903,9 +918,9 @@ XNAT.app.abu.processFiles=function() {
 				 ((this.paramsToPass.length>0) ? "Please supply values for the following parameters:" :  "Please supply a value for the following parameter:") +
 '				</h3><div style="width:100px"><table>' + paramText + "</table>");
 			// Not sure why the setTimeout seems necessary.
-			$(".passParamInput").get(0).focus();
+			$($(".passParamInput").get(0)).focus();
 			setTimeout(function(){
-				$(".passParamInput").get(0).focus();
+				$($(".passParamInput").get(0)).focus();
 			},100);
 
 		} else {
diff --git a/src/main/webapp/scripts/uploaders/fileuploader.js b/src/main/webapp/scripts/uploaders/fileuploader.js
index e47a44d348a4c7b90d5d5d876c0db24978673f2e..c00698bc354151bc9f30a0f83551af2c6e58f928 100644
--- a/src/main/webapp/scripts/uploaders/fileuploader.js
+++ b/src/main/webapp/scripts/uploaders/fileuploader.js
@@ -27,7 +27,7 @@ abu.FileUploader = function(o){
 		$(this._options.element).append(
 			'<div class="abu-uploader">' +
 				'<div id="abu-files-processing" class="abu-files-processing">        Processing...... </div>' +
-				'<a id="file-uploader-instructions-sel" class="abu-uploader-instructions-sel" onclick="abu._fileUploader.uploaderHelp()">Click here for help.</a>' +
+				'<a id="file-uploader-instructions-sel" class="abu-uploader-instructions-sel" onclick="abu._fileUploader.uploaderHelp()">?</a>' +
 				'<div class="abu-upload-drop-area" style="display: none;"><span>Drop files here to upload</span></div>' +
 				'<div class="abu-xnat-interactivity-area">' +
 				'</div>' +
@@ -96,14 +96,35 @@ abu.FileUploader = function(o){
 		 });
 
 		if (this.ALLOW_DRAG_AND_DROP) {
+			$(".abu-upload-drop-area").on('dragleave',function(e) { 
+					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = false;
+						if (typeof this.timeout !== "undefined") {
+							clearTimeout( this.timeout );
+						}
+						this.timeout = setTimeout( function(){
+							if( !this.showDrag ){ 
+								$(".abu-upload-drop-area").css('display','none');
+								$(".abu-upload-drop-area").removeClass('abu-upload-drop-area-active');
+								try { 
+									e.preventDefault();
+									e.stopPropogation();
+								} catch(e) { /* Do nothing */ }
+ 							}
+						}.bind(this), 200 ).bind(this);
+					}
+				}.bind(this)
+			);
 			$(".abu-upload-drop-area").on('dragover',function(e) {
 					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = true;
 						this.activateUploadArea(e);
 					}
 				}.bind(this)
 			);
 			$(".abu-upload-drop-area").on('dragenter',function(e) {
 					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = true;
 						this.activateUploadArea(e);
 					}
 				}.bind(this)
@@ -120,14 +141,35 @@ abu.FileUploader = function(o){
 					}
 				}.bind(this)
 			);
+			$(this._options.element).on('dragleave',function(e) {
+					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = false;
+						if (typeof this.timeout !== "undefined") {
+							clearTimeout( this.timeout );
+						}
+						this.timeout = setTimeout( function(){
+							if( !this.showDrag ){ 
+								$(".abu-upload-drop-area").css('display','none');
+								$(".abu-upload-drop-area").removeClass('abu-upload-drop-area-active');
+								try { 
+									e.preventDefault();
+									e.stopPropogation();
+								} catch(e) { /* Do nothing */ }
+ 							}
+						}.bind(this), 200 ).bind(this);
+					}
+				}.bind(this)
+			).bind(this);
 			$(this._options.element).on('dragover',function(e) {
 					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = true;
 						this.activateUploadArea(e);
 					}
 				}.bind(this)
 			).bind(this);
 			$(this._options.element).on('dragenter',function(e) {
 					if (this.DRAG_AND_DROP_ON) {
+						this.showDrag = true;
 						this.activateUploadArea(e);
 					}
 				}.bind(this)
@@ -145,9 +187,10 @@ abu.FileUploader = function(o){
 
 	this.processingComplete = function() {
 		$("#abu-done-button-text").html("Done");
-		//$("#abu-process-button").css("display","None");
 		//$("#abu-upload-button").css("display","None");
 		$("#abu-process-button").addClass("abu-button-disabled");
+		//$("#abu-process-button-text").html("&nbsp;");
+		$("#abu-process-button").css("visibility","hidden");
 		$("#abu-upload-button").addClass("abu-button-disabled");
 		$("#abu-files-processing").css("display","None");
 	}
@@ -292,14 +335,16 @@ abu.FileUploader = function(o){
 			'<div id="file-uploader-instructions" class="abu-uploader-instructions">' + 
 			'<h3>Instructions</h3>' + 
 			'<ul>' +  
-			'<li>To upload, click the <b>Upload Files</b> button or drag files into the space below the buttons. (Drag-and-drop is supported in FF, Chrome.)</li>' +
+			((this.ALLOW_DRAG_AND_DROP) ?
+			'<li>To upload, click the <b>Upload Files</b> button or drag files into the space below the buttons. (Drag-and-drop is supported in FF, Chrome.)</li>' :
+			'<li>To upload, click the <b>Upload Files</b> to begin selection of files for upload.</li>') +
 			((this._options.maxFiles == 1) ?
 				'<li>This uploader supports only a single file upload</li>' :
 				'<li>Multiple files may be selected</li>'
 			) +
 			'<li>Uploads will begin automatically</li>' + 
 			'<li>Upload of directories is not supported</li>' + 
-			'<li>When finished uploading, press <b>Process Files</b> to process the uploaded files</li>' + 
+			'<li>When finished uploading, press <b>Done</b> to close the modal, or, if an automation script is to be launched by this upload process, press <b>Process Files</b> to process the uploaded files.</li>' + 
 			'</ul>' + 
 			'</div>';
 		xmodal.message("Uploader Instructions",templateV, undefined, {height:"400px",width:"800px"});
diff --git a/src/main/webapp/scripts/xnat/admin/themeManagement.js b/src/main/webapp/scripts/xnat/admin/themeManagement.js
index 930e230b9ced35ee49cde6d64c1d982e8f3d70bf..64b3702a8b2137fbd04e3df7661aecb9238a67ae 100644
--- a/src/main/webapp/scripts/xnat/admin/themeManagement.js
+++ b/src/main/webapp/scripts/xnat/admin/themeManagement.js
@@ -84,8 +84,8 @@ function removeTheme(){
 
 /*** Theme Package Upload Functions ***/
 themeUploadForm.action = themeUrl+q+csrf;
-$(themeUploadForm).parent().css('position','relative');
-$(themeUploadForm).parent().css('top','-30px');
+$(themeUploadForm).parent().parent().css('position','relative');
+$(themeUploadForm).parent().parent().css('top','-30px');
 themeUploadForm.onsubmit = function(event) {
     event.preventDefault();
     $(themeUploadSubmit).text('Uploading...');
@@ -120,7 +120,7 @@ themeUploadForm.onsubmit = function(event) {
         uploaded = true;
     }
     if(!uploaded){
-        xmodal.message('Nothing Uploaded', 'No valid theme package files were selected for upload.');
+        xmodal.message('Nothing Uploaded', 'No valid theme package files were selected for upload.<br><br>Click the "Choose Files" button below to browse for a theme package.');
         $(themeUploadSubmit).text('Upload');
         $(themeUploadSubmit).removeAttr('disabled');
     }
diff --git a/src/main/webapp/scripts/xnat/app/timeout.js b/src/main/webapp/scripts/xnat/app/timeout.js
index 96315e3a682826028f12b8352e614046cd84e723..04bb9561bd3213f6d778a6169220b2e61f1bad77 100644
--- a/src/main/webapp/scripts/xnat/app/timeout.js
+++ b/src/main/webapp/scripts/xnat/app/timeout.js
@@ -272,7 +272,7 @@ var XNAT = getObject(XNAT);
             // need to wait a little longer before reloading
             setTimeout(function(){
                 window.location.reload();
-            }, 120000);
+            }, 2000);
         }
 
 
diff --git a/src/main/webapp/scripts/xnat/ui/panel.js b/src/main/webapp/scripts/xnat/ui/panel.js
index 410aeb12a34e6f0957d271ccf597b651f9d7e332..6ef65f211c7f13beaed985ba7155821dd3614f1d 100644
--- a/src/main/webapp/scripts/xnat/ui/panel.js
+++ b/src/main/webapp/scripts/xnat/ui/panel.js
@@ -426,7 +426,8 @@ var XNAT = getObject(XNAT || {});
             }
 
             var ajaxConfig = {
-                method: opts.method,
+                //method: opts.method,
+                method: $form.data('method') || opts.method || 'POST',
                 url: this.action,
                 success: function(){
                     var obj = {};
@@ -845,54 +846,10 @@ var XNAT = getObject(XNAT || {});
     panel.data = {};
 
     panel.data.table = function(opts){
+
         // initialize the table
-        opts = cloneObject(opts);
-        opts.element = opts.element || {};
-        addClassName(opts.element, 'data-table xnat-table');
-        if (opts.sortable) {
-            if (opts.sortable === true) {
-                addClassName(opts.element, 'sortable');
-            }
-            else {
-                opts.sortable = opts.sortable.split(',').map(function(item){return item.trim()});
-            }
-        }
-        opts.element.style = {
-            width: opts.width || '100%'
-        };
-        var dataTable = XNAT.table(opts.element);
-        // request data for table rows
-        XNAT.xhr.get({
-            url: XNAT.url.rootUrl(opts.load||opts.url),
-            dataType: opts.dataType || 'json',
-            success: function(data){
-                var props = [];
-                if (opts.items) {
-                    dataTable.tr();
-                    forOwn(opts.items, function(name, val){
-                        props.push(name);
-                        dataTable.th(val);
-                        if (opts.sortable === true || opts.sortable.indexOf(name) !== -1) {
-                            addClassName(dataTable.last.th, 'sort');
-                        }
-                    });
-                }
-                else {
-                    forOwn(data[0], function(name, val){
-                        props.push(name);
-                    });
-                }
-                data.forEach(function(item){
-                    dataTable.tr();
-                    props.forEach(function(name){
-                        dataTable.td({ className: name }, item[name]);
-                    });
-                });
-                if (opts.container) {
-                    $$(opts.container).append(dataTable.table);
-                }
-            }
-        });
+        var dataTable = XNAT.table.dataTable(opts.data||[], opts);
+
         return {
             element: dataTable.table,
             spawned: dataTable.table,
@@ -900,6 +857,7 @@ var XNAT = getObject(XNAT || {});
                 return dataTable.table
             }
         };
+        
     };
 
     panel.data.list = function(opts){
diff --git a/src/main/webapp/scripts/xnat/ui/table.js b/src/main/webapp/scripts/xnat/ui/table.js
index 5a645866d1561676b29942bc306b2e242645dff0..ec651f9445b3086c73c0b42e8f414aa715d4f0b4 100755
--- a/src/main/webapp/scripts/xnat/ui/table.js
+++ b/src/main/webapp/scripts/xnat/ui/table.js
@@ -275,6 +275,7 @@ var XNAT = getObject(XNAT);
         else {
             obj = data || {};
         }
+
         if (obj.header) {
             // if there's a 'header' property
             // set to true, pick the header from
@@ -347,15 +348,103 @@ var XNAT = getObject(XNAT);
 
     // helper for future XNAT DataTable widget
     table.dataTable = function(data, opts){
+
         var tableData = data;
+
         // tolerate reversed arguments
         if (Array.isArray(opts)){
             tableData = opts;
-            opts = data;
+            opts = getObject(data);
         }
-        addClassName(opts, 'xnat-table data-table');
-        var newTable = new Table(opts);
-        return newTable.init(tableData);
+
+        // don't modify original object
+        opts = cloneObject(opts);
+
+        var allItems = opts.header || (opts.items && opts.items === 'all');
+
+        // properties for spawned element
+        opts.element = opts.element || {};
+
+        addClassName(opts.element, 'data-table xnat-table');
+
+        if (opts.sortable) {
+            if (opts.sortable === true) {
+                addClassName(opts.element, 'sortable');
+            }
+            else {
+                opts.sortable = opts.sortable.split(',').map(function(item){return item.trim()});
+            }
+        }
+
+        opts.element = extend(true, {
+            style: {
+                width: opts.width || '100%'
+            }
+        }, opts.element);
+
+        // initialize the table
+        var newTable = new Table(opts.element);
+
+        function createTable(rows){
+            var props = [];
+            if (!allItems && (opts.items || opts.properties)) {
+                newTable.tr();
+                forOwn(opts.items||opts.properties, function(name, val){
+                    props.push(name);
+                    newTable.th(val);
+                    if (!opts.sortable) return;
+                    if (opts.sortable === true || opts.sortable.indexOf(name) !== -1) {
+                        addClassName(newTable.last.th, 'sort');
+                    }
+                });
+            }
+            else {
+                if (allItems) {
+                    newTable.tr();
+                }
+                forOwn(rows[0], function(name, val){
+                    if (allItems) {
+                        newTable.th(name);
+                    }
+                    props.push(name);
+                });
+            }
+            rows.forEach(function(item){
+                newTable.tr();
+                props.forEach(function(name){
+                    newTable.td({ className: name }, item[name]);
+                });
+            });
+        }
+
+        // if 'tableData' is a string, use as the url
+        if (typeof tableData == 'string') {
+            opts.url = tableData;
+        }
+
+        // request data for table rows
+        if (opts.load || opts.url) {
+            XNAT.xhr.get({
+                url: XNAT.url.rootUrl(opts.load||opts.url),
+                dataType: opts.dataType || 'json',
+                success: function(json){
+                    // handle data returned in ResultSet.Result array
+                    json = (json.ResultSet && json.ResultSet.Result) ? json.ResultSet.Result : json;
+                    createTable(json);
+                }
+            });
+        }
+        else {
+            createTable(tableData.data||tableData);
+            // newTable.init(tableData);
+        }
+
+        if (opts.container) {
+            $$(opts.container).append(newTable.table);
+        }
+
+        return newTable;
+
     };
 
     // table with <input> elements in the cells
@@ -395,4 +484,3 @@ var XNAT = getObject(XNAT);
     XNAT.ui.inputTable = XNAT.inputTable = table.inputTable;
 
 }));
-
diff --git a/src/main/webapp/scripts/xnat/ui/tabs.js b/src/main/webapp/scripts/xnat/ui/tabs.js
index 61bec657552be5fde90b963b8a7246cf0d4bf80d..73eaf37aa06abe936f9f260c154a195e415d0bba 100755
--- a/src/main/webapp/scripts/xnat/ui/tabs.js
+++ b/src/main/webapp/scripts/xnat/ui/tabs.js
@@ -171,9 +171,9 @@ var XNAT = getObject(XNAT || {});
 
         // set container and layout before spawning:
         // XNAT.tabs.container = 'div.foo';
-        container = tabs.container || 'div.xnat-tab-container';
+        container = obj.container || tabs.container || 'div.xnat-tab-container';
 
-        layout = tabs.layout || 'left';
+        layout = obj.layout || tabs.layout || 'left';
 
         navTabs = spawn('div.xnat-nav-tabs');
         tabContent = spawn('div.xnat-tab-content');
diff --git a/src/main/webapp/style/uploaders/fileuploader.css b/src/main/webapp/style/uploaders/fileuploader.css
index 9d74966143518c36c510c409035f0160c92ecf98..fe323e24d1c0f126c3b975e2cfaea3ff59b3d952 100644
--- a/src/main/webapp/style/uploaders/fileuploader.css
+++ b/src/main/webapp/style/uploaders/fileuploader.css
@@ -85,13 +85,14 @@ div.abu-xnat-interactivity-area-sub {
 .abu-upload-duplicate {display:inline;color:#008800}
 .abu-upload-duplicate.abu-upload-duplicate-text {display:inline;color:#008800}
 
-.abu-uploader-instructions-sel {margin-bottom:0px; margin-right:10px; display:inline; width:100%; float:right; background-color:#CCCCCC; border-color:#1A75BB; color:#1A75BB; border-style:solid; border-width:1px; border-color:#1A75BB; font-size:14px; font-weight: bold; padding:2px; }
+.abu-uploader-instructions-sel {margin-bottom:0px; margin-right:10px; display:inline; float:right; background-color:#CCCCCC; border-style:solid; border-width:1px; width:auto; font-size:14px; font-weight: bold; padding:2px; }
+
 .abu-uploader-instructions {margin-bottom:10px; display:inline}
 
 .abu-return-floatmessage {position:absolute;z-index:10001;width:auto;cursor:pointer;background-color:#FFFFCC; }
 .abu-return-message {width:auto;cursor:pointer;background-color:#FFFFCC; }
 
-.abu-options-div { position: relative; float: left; width: 430px; margin-left: 10px; }
+.abu-options-div { position: relative; float: left; width: 420px; margin-left: 10px; }
 .abu-options-cb {
     display:block; /* or inline-block */
     width: auto; padding: 7px 0; text-align:center; margin-left:10px; float:left; padding-top: 0px; padding-bottom: 0px;    
diff --git a/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm b/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm
index 8ca2b170f9954c376e3b7a5d9cde0f717b792a21..41babb23fcda36252325fb0af436a9f930ab5292 100755
--- a/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm
+++ b/src/main/webapp/xnat-templates/navigations/XNATQuickSearch.vm
@@ -1,35 +1,11 @@
 <!-- search script -->
 <script type="text/javascript">
-<!--
-function DefaultEnterKey(e,button){
-var keynum, keychar, numcheck ;
-
-if(window.event) // IE
-	{
-	  keynum = e.keyCode ;
-	  if (keynum==13){
-	    submitQuickSearch();
-	    return true;
-	  }
-	}
-else if(e) // Netscape/Firefox/Opera
-	{
-	  keynum = e.which ;
-	  if (keynum==13){
-	    submitQuickSearch();
-	    return false;
-	  }
-	}
-	  return true;
-}
-
 function submitQuickSearch(){
-	    concealContent();
-	    if(document.getElementById('quickSearchForm').value!="")
-    		   document.getElementById('quickSearchForm').submit();
+  concealContent();
+  if($('#searchValue').val()!="") {
+    $('#quickSearchForm').submit();
+  }
 }
-
-//-->
 </script>
 <!-- end search script -->
 
@@ -64,15 +40,21 @@ function submitQuickSearch(){
 			<!-- stored searches will show up here -->
 		</optgroup>
 	</select>
-	<input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value="$!field" />
+	<input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value="$!field"/>
     <button type="button" id="search_btn" class="btn2" onclick="submitQuickSearch();">Go</button>
 #if($turbineUtils.toBoolean($siteConfig.getProperty("UI.allow-advanced-search","true")))
 
     <script>
 
         (function(){
-
-            $('#searchValue').each(function(){
+            var searchField = $('#searchValue');
+            searchField.keyup(function( event ) {
+              if (event.which == 13) {
+                submitQuickSearch();
+              }
+            });
+            
+            searchField.each(function(){
                 this.value = this.value || 'search';
                 $(this).focus(function(){
                     $(this).removeClass('clean');
diff --git a/src/main/webapp/xnat-templates/screens/XDATScreen_search_wizard2.vm b/src/main/webapp/xnat-templates/screens/XDATScreen_search_wizard2.vm
index 8a41e47bbe4f027bc2de8005a5e7678597e7840b..64020385dc209c9a92e8d883b996ad4c21b25c92 100644
--- a/src/main/webapp/xnat-templates/screens/XDATScreen_search_wizard2.vm
+++ b/src/main/webapp/xnat-templates/screens/XDATScreen_search_wizard2.vm
@@ -57,13 +57,13 @@
 
             <p>Define the constraints which will determine which rows show up in your search results.</p>
 
-            <p style="margin-bottom:20px;">
+            <!-- p style="margin-bottom:20px;">
                 You must also select a search method (this affects all tabs below):
                 <label class="search-method-label" style="border-right:1px solid #ccc;">
                     <input type="checkbox" class="search-method by-criteria" value="by-criteria"> By Specific Criteria</label>
                 <label class="search-method-label">
                     <input type="checkbox" class="search-method by-id" value="by-id"> By Exact ID</label>
-            </p>
+            </p -->
 
             <div id="super_search" class="yui-navset" style="max-width:800px !important;margin-top:30px;margin-left:-40px;">
                 <ul class="yui-nav" style="">