diff --git a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
index 46d3aba93d4bc5b387b32bb0716f3be91e553ea7..32150b78489d563a3ea416771e5c1b1af7f0999a 100644
--- a/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
+++ b/src/main/resources/META-INF/xnat/spawner/site-admin-elements.yaml
@@ -15,24 +15,61 @@ siteInfo:
     contents:
         siteId:
             kind: panel.input.text
+            id: siteId
             name: siteId
             label: Site ID
             validation: required id onblur
-            element:  # the 'config' property is applied directly to the underlying spawn() function
-                id: site-id
-                style:
-                  display: block
+            description: "The id used to refer to this site (also used to generate database ids). No spaces or non-alphanumeric characters. It should be a short, one-word name or acronym which describes your site."
+        siteUrl:
+            kind: panel.input.text
+            id: siteUrl
+            name: siteUrl
+            label: Site Url
+            validation: required id onblur
+            description: ""
+        siteDescriptionOption:
+            kind: panel.display  # make this a radio button group
+            id: siteDescriptionOption
+            name: siteDescriptionOption
+            label: Site Description
+            value: Select a site description option below
+            # onchange: # some javascript that toggles display of the elements below appropriately
+        siteDescriptionOptionText:
+            kind: panel.input.checkbox  # make this a radio button group
+            id: siteDescriptionOptionText
+            label: "Text (Markdown)"
+        siteDescriptionOptionPage:
+            kind: panel.input.checkbox  # make this a radio button group
+            id: siteDescriptionOptionPage
+            label: "Page"
+        siteDescriptionFile:
+            kind: panel.input.text
+            id: siteDescriptionFile
+            name: siteDescriptionFile
+            label: ""
+            description: "Specify a velocity template file to display on the login page"
+        siteDescriptionText:
+            kind: panel.input.text
+            id: siteDescriptionText
+            name: siteDescriptionText
+            label: ""
+            description: "Specify a simple text description of this site"
+
+adminInfo:
+    kind: panel.form
+    name: adminInfo
+    label: Admin Information
+    contents:
         adminEmail:
             kind: panel.input.email
             name: adminEmail
-            label: Administrator Email Address
-        someInfo:
-            #kind: element
-            tag: div.message
-            element:
-                html: Hello people.
-                style:
-                    fontWeight: bold
+            label: Site Admin Email Address
+#        someInfo:
+#            tag: div.message
+#            element:
+#                html: Hello people.
+#                style:
+#                    fontWeight: bold
                     
 generalSecuritySettings:
     kind: panel.form
@@ -41,10 +78,10 @@ generalSecuritySettings:
     contents:
         securityChannel:
             kind: panel.select.single
-            name: securityChannel
+            id: securityChannel
+            name: security.channel
             label: Security Channel
             value: https
-#           contains: options
             options:
                 http:
                     label: http
@@ -55,7 +92,164 @@ generalSecuritySettings:
             config:
                 id: security-channel
                 title: Security Channel
+        requireUserLogin:
+            kind: panel.input.checkbox
+            id: requireUserLogin
+            name: require_login
+            label: Require User Login
+            description: If checked, then only registered users will be able to access your site. If false, anyone visiting your site will automatically be logged in as 'guest' with access to public data.
+
+userLoginsSessionControls:
+    kind: panel.form
+    name: userLoginsSessionControls
+    label: User Logins / Session Controls
+    contents:
+        sessionTimeout:
+            kind: panel.input.number
+            id: sessionTimeout
+            name: security.token_timeout
+            label: Session Timeout
+            value: 15
+            description: "Interval for timing out alias tokens. Uses PostgreSQL interval notation: http://www.postgresql.org/docs/9.0/static/functions-datetime.html"
+        sessionTimeoutMessage:
+            kind: panel.input.text
+            id: sessionTimeoutMessage
+            name: sessionTimeoutMessage
+            label: Session Timeout Message
+            value: "Your session has timed out."
+            description: Alert message provided to users after a session timeout and logout.
+        allowResumeOnNextLogin:
+            kind: panel.input.checkbox
+            id: allowResumeOnNextLogin
+            name: allowResumeOnNextLogin
+            label: Allow Resume On Next Login?
+            value: true
+            description: Allow user to resume where they left off, if logging back in after a session timeout?
+        maximumConcurrentSessions:
+            kind: panel.input.number
+            id: maximumConcurrentSessions
+            name: security.sessions.concurrent_max
+            label: Maximum Concurrent Sessions
+            value: 5
+            description: The maximum number of permitted sessions a user can have open simultaneously
+        loginFailureMessage:
+            kind: panel.input.text
+            id: loginFailureMessage
+            name: UI.login_failure_message
+            label: Login Failure Message
+            value: Login failed
+            description: Text to show when a user fails to login
+        maximumFailedLogins:
+            kind: panel.input.number
+            id: maximumFailedLogins
+            name: security.max_failed_logins
+            label: Maximum Failed Logins
+            value: -1
+            description: Number of failed login attempts before accounts are temporarily locked. (-1 disables feature)
+        failedLoginLockoutDuration:
+            kind: panel.input.number
+            id: failedLoginLockoutDuration
+            name: security.max_failed_logins_lockout_duration
+            label: Failed Login Lockout Duration
+            value: 0
+            description: Number of milliseconds to lock user accounts that have exceeded the max_failed_logins count. Select (3600000 for 1 hour, 86400000 for 24 hours)
+        userInactivityLockout:
+            kind: panel.input.number
+            id: userInactivityLockout
+            name: security.inactivity_before_lockout
+            label: User Inactivity Lockout
+            value: 31556926
+            description: Number of seconds of inactivity before an account is disabled (31556926 for 1 year)
+
+passwords:
+    kind: panel.form
+    name: passwords
+    label: Passwords
+    contents:
+        passwordComplexity:
+            kind: panel.input.text
+            id: passwordComplexity
+            name: security.password_complexity
+            label: Password Complexity
+            value: "^.*$"
+            description: Must be a valid regular expression.
+        passwordComplexityMessage:
+            kind: panel.input.text
+            id: passwordComplexityMessage
+            name: security.password_complexity_message
+            label: Password Complexity Message
+            value: "Your password must contain..."
+        passwordExpirationInterval:
+            kind: panel.input.number
+            id: passwordExpirationInterval
+            name: security.password_expiration_interval
+            label: Password Expiration (Interval)
+            value: -1
+            description: "-1 to disable"
+        passwordExpirationDate:
+            kind: panel.input.text
+            id: passwordExpirationDate
+            name: security.password_expiration_date
+            label: Password Expiration (Date)
+            description: Dates must be formatted MM/DD/YYYY
+        passwordReuseRestriction:
+            kind: panel.select.single
+            id: passwordReuseRestriction
+            name: security.password_history
+            label: Password Reuse Restriction
+        requirePasswordsToBeSalted:
+            kind: panel.input.checkbox
+            id: requirePasswordsToBeSalted
+            name: security.salted_passwords
+            label: Require Passwords To Be Salted
+            value: false
+
+csrf:
+    kind: panel.form
+    name: csrf
+    label: CSRF
+    contents:
+        requireCsrfToken:
+            kind: panel.input.checkbox
+            id: requireCsrfToken
+            name: enable_csrf_token
+            label: Require CSRF Token?
+            value: true
+            description: Should this site require the use of a token to prevent CSRF attacks on POST, PUT, and DELETEs?
+        csrfEmailAlert:
+            kind: panel.input.checkbox
+            id: csrfEmailAlert
+            name: enable_csrf_email_alert
+            label: CSRF Email Alert
+            value: "Should this site send an email to the site admin whenever a CSRF attack is attempted?"
 
+auditTrail:
+    kind: panel.form
+    name: auditTrail
+    label: Audit Trail Configuration
+    contents:
+        enableAuditTrail:
+            kind: panel.input.checkbox
+            id: enableAuditTrail
+            name: audit.enable
+            label: Enable Audit Trail?
+            value: true
+        allowUserJustificationForChanges:
+            kind: panel.input.checkbox
+            id: allowUserJustificationForChanges
+            name: audit.show_change_justification
+            label: Allow User Justification For Changes
+            value: true
+            description: "Allow users to enter change justifications when modifying data"
+        requireUserJustificationForChanges:
+            kind: panel.input.checkbox
+            id: requireUserJustificationForChanges
+            name: audit.require_change_justification
+            label: Require User Justification For Changes
+            value: false
+            description: "Force users to enter change justifications when modifying data"
+
+            
 emailServerSettings:
     kind: panel.form
     name: emailServerSettings
@@ -115,29 +309,41 @@ themeManagement:
     name: themeManagement
     label: Theme Management
     contents:
-      themeScript:
-          tag: script|type=text/javascript|src=../../scripts/themeManagement.js
-      currentTheme:
-          # kind: span  # this doesn't work
-          tag: span
-          label: Current Theme
-          description: The currently selected global theme.
-          html: None
-      existingTheme:
-          kind: panel.select.single
-          label: Select an existing theme
-          description: Selected a new global theme from those available on the system.
-          value: None
-          options:
-              default:
-                  label: None
-                  value: None
-      uploadTheme:
-          kind: panel.input.text  # file
-          name: xnat.theme.upload
-          label: Upload a theme package
-          description: Upload a zipped theme package for selection above.
-          after: "<form id=\"uploadThemeForm\" method=\"POST\" class=\"optOutOfXnatDefaultFormValidation\"><span class=\"label bold\">Upload a theme package: </span><input type=\"file\" id=\"themeFileUpload\" name=\"themeFileUpload\" multiple style=\"width: 270px; display: inline; float: left;\"/><button type=\"submit\" id=\"submitThemeUploadButton\" style=\"position: relative; top:-15px;\">Upload</button></form>"
+        themeScript:
+            tag: script|type=text/javascript;src=../../scripts/themeManagement.js
+        themeStyle:
+            tag: style
+            element:
+                html: ".themeUploader{width:270px;display:inline !important;}"
+        currentTheme:
+            kind: panel.display
+            id: currentTheme
+            label: Current Theme
+            description: The currently selected global theme.
+            value: None
+            element:
+                style:
+                    color: 'red'
+        existingTheme:
+            kind: panel.select.single
+            id: themeSelection
+            label: Select an existing theme
+            description: Selected a new global theme from those available on the system.
+            value: None
+            options:
+                default:
+                    label: None
+                    value: None
+            after:
+                - "&nbsp;<!--button id=\"submitThemeButton\" onclick=\"setTheme();\">Set Theme</button-->&nbsp;&nbsp;<button id=\"removeThemeButton\" onclick=\"removeTheme();\">Remove Theme</button>"
+        uploadTheme:
+            kind: panel.input.upload
+            id: themeFileUpload
+            name: xnat.theme.upload
+            label: Upload a theme package
+            description: Upload a zipped theme package for selection above.
+            className: themeUploader
+          
 
           
 authenticationMethods:
@@ -179,7 +385,54 @@ dicomScpReceivers:
     kind: panel
     name: dicomScpReceivers
     label: DICOM SCP Receivers
-#    contents:
+    contents:
+        enableDicomReceiver:
+            kind: panel.input.checkbox
+            id: enableDicomReceiver
+            name: enableDicomReceiver
+            label: DICOM Receiver Enabled?
+            value: true
+            description: "Should the DICOM receiver listen for connections?"
+        someInfo:
+            tag: div.message
+            element:
+                html: "Caution: Changes to this setting will take effect immediately. Before disabling the receiver, verify that there are no transmissions currently in progress."
+                style:
+                    fontWeight: bold
+        # hidden form element...
+        # enableDicomReceiver.property.changed.listener
+        # org.nrg.dcm.DicomSCPSiteConfigurationListener
+        dicomHost:
+            kind: panel.input.text
+            id: dicomHost
+            name: dicomHost
+            label: DICOM Host
+            description: "Hostname(s) for DICOM Receiver(s)"
+        dicomAeTitle:
+            kind: panel.input.text
+            id: dicomAeTitle
+            name: dicomAeTitle
+            label: DICOM AE Title
+            description: "AE Title(s) for DICOM Receiver(s)"
+        dicomPortNumber:
+            kind: panel.input.number
+            id: dicomPortNumber
+            name: dicomPortNumber
+            label: DICOM Host
+            description: "Port for DICOM Receiver(s)"
+        defaultDicomReceiver:
+            kind: panel.select.single
+            id: defaultDicomReceiver
+            name: services.dicom.scp.aetitle
+            label: Default DICOM Receiver
+            description: "AE Title for default DICOM receiver"
+        defaultDicomReceiverUser:
+            kind: panel.input.text
+            id: defaultDicomReceiverUser
+            name: services.dicom.scp.receivedfileuser
+            label: Default DICOM Receiver: User
+            value: Login failed
+            description: User account for default DICOM receiver
           
           
 siteAdmin:
@@ -190,20 +443,19 @@ siteAdmin:
         ${tabGroups}
     contains: tabs
     tabs:  # this property name is the same as 'contains', so it will be treated like 'contents'
-    
         siteSetup:
             kind: tab
             name: siteSetup
             label: Site Setup
             group: xnatSetup
             active: true
-            config:
-                data:
-                    foo: bar
+#            config:
+#                data:
+#                    foo: bar
             contains: panels # the value for 'contains' can be a custom name for 'contents'
             panels:
                 ${siteInfo}
-
+                ${adminInfo}
         security:
             kind: tab
             name: security
@@ -211,7 +463,10 @@ siteAdmin:
             group: xnatSetup
             contents:
                 ${generalSecuritySettings}
-
+                ${userLoginsSessionControls}
+                ${passwords}
+                ${csrf}
+                ${auditTrail}
         emailServer:
             kind: tab
             name: emailServer
@@ -219,7 +474,6 @@ siteAdmin:
             group: xnatSetup
             contents:
                 ${emailServerSettings}
-
         notifications:
             kind: tab
             name: notifications
@@ -227,7 +481,6 @@ siteAdmin:
             group: xnatSetup
             contents:
                 ${notifications}
-
         themesAndFeatures:
             kind: tab
             name: themesAndFeatures
@@ -235,7 +488,6 @@ siteAdmin:
             group: xnatSetup
             contents:
                 ${themeManagement}
-                
         authenticationMethods:
             kind: tab
             name: authenticationMethods
@@ -243,7 +495,6 @@ siteAdmin:
             group: manageAccess
             contents:
                 ${authenticationMethods}
-
         users:
             kind: tab
             name: users
@@ -251,7 +502,6 @@ siteAdmin:
             group: manageAccess
             contents:
                 ${users}
-
         userRoles:
             kind: tab
             name: userRoles
@@ -259,7 +509,6 @@ siteAdmin:
             group: manageAccess
             contents:
                 ${userRoles}
-
         registrationOptions:
             kind: tab
             name: registrationOptions
@@ -267,7 +516,6 @@ siteAdmin:
             group: manageAccess
             contents:
                 ${registrationOptions}
-
         dicomScpReceivers:
             kind: tab
             name: dicomScpReceivers
@@ -275,8 +523,6 @@ siteAdmin:
             group: advanced
             contents:
                 ${dicomScpReceivers}
-                
-                
         databaseSettings:
             kind: tab
             name: databaseSettings
diff --git a/src/main/webapp/scripts/themeManagement.js b/src/main/webapp/scripts/themeManagement.js
index 4e8d49929663710e6f765a2281773647d01082ab..677ea79cd99ed6a1708d65a5968a6bbea43102f9 100644
--- a/src/main/webapp/scripts/themeManagement.js
+++ b/src/main/webapp/scripts/themeManagement.js
@@ -15,9 +15,9 @@ var csrf = 'XNAT_CSRF='+window.csrfToken;
 $('#titleAppName').text(XNAT.app.siteId);
 var currentTheme = $('#currentTheme');
 var themeSelector = $('#themeSelection');
-var uploadForm = document.getElementById('uploadThemeForm');
-var themeUploader = document.getElementById('themeFileUpload');
-var themeUploadSubmit = document.getElementById('submitThemeUploadButton');
+var uploadForm = document.getElementById('themeFileUpload-form');
+var themeUploader = document.getElementById('themeFileUpload-input');
+var themeUploadSubmit = document.getElementById('themeFileUpload-button');
 var selectedTheme = null;
 function populateThemes(){
     getCurrentTheme(getAvailableThemes);
diff --git a/src/main/webapp/scripts/xnat/ui/panel.js b/src/main/webapp/scripts/xnat/ui/panel.js
index 61dbf26d8983e755380af9c9f55eaa026809fd9f..264b23db800abfc707a394c1231146adf307da23 100644
--- a/src/main/webapp/scripts/xnat/ui/panel.js
+++ b/src/main/webapp/scripts/xnat/ui/panel.js
@@ -33,7 +33,7 @@ var XNAT = getObject(XNAT || {});
     }
 
     panel.init = function(opts){
-        
+
         opts = getObject(opts);
         opts.element = opts.element || opts.config || {};
 
@@ -52,7 +52,7 @@ var XNAT = getObject(XNAT || {});
                 (hideFooter ? ['div.hidden'] : ['div.panel-footer', opts.footer])
 
             ]);
-        
+
         // add an id to the outer panel element if present
         if (opts.id || opts.element.id) {
             _panel.id = (opts.id || opts.element.id) + '-panel';
@@ -156,6 +156,10 @@ var XNAT = getObject(XNAT || {});
 
     panel.input = {};
 
+    panel.display = function(opts){
+        return XNAT.ui.template.panelDisplay(opts).spawned;
+    };
+    
     panel.input.text = function(opts){
         return XNAT.ui.template.panelInput(opts).spawned;
     };
@@ -202,12 +206,10 @@ var XNAT = getObject(XNAT || {});
                 type: 'file',
                 id: opts.id + '-input',
                 multiple: true,
-                style: {
-                    width: '270px'
-                }
+                className: addClassName(opts, 'file-upload-input')
             }],
             ['button', {
-                type: 'button',
+                type: 'submit',
                 id: opts.id +'-button',
                 html: 'Upload'
             }]
diff --git a/src/main/webapp/scripts/xnat/ui/templates.js b/src/main/webapp/scripts/xnat/ui/templates.js
index 8891d2ac9415ca81995f31fefb3fc0fa0390059a..0308f495db010e66c5ab9f50ed241690f95019d5 100644
--- a/src/main/webapp/scripts/xnat/ui/templates.js
+++ b/src/main/webapp/scripts/xnat/ui/templates.js
@@ -21,7 +21,7 @@ var XNAT = getObject(XNAT);
 
     XNAT.ui = getObject(XNAT.ui || {});
 
-    XNAT.ui.template = template = 
+    XNAT.ui.template = template =
         XNAT.ui.template || {};
 
 
@@ -52,6 +52,28 @@ var XNAT = getObject(XNAT);
     };
     // ========================================
 
+    // ========================================
+    // display only element for form panels
+    template.panelDisplay = function(opts, element){
+        opts = getObject(opts);
+        opts.id = opts.id||toDashed(opts.name);
+        opts.label = opts.label||opts.title||opts.name||'';
+        return template.panelElement(opts, [
+            ['label.element-label|for='+opts.id, opts.label],
+            ['div.element-wrapper', [
+                element || ['div', {
+                    id: opts.id,
+                    name: opts.name,
+                    className: opts.className||'',
+                    size: 25,
+                    title: opts.title||opts.name||opts.id,
+                    html: opts.value||''
+                }],
+                ['div.description', opts.description||opts.body||opts.html]
+            ]]
+        ]);
+    };
+    // ========================================
 
     // ========================================
     // input element for form panels
@@ -84,7 +106,7 @@ var XNAT = getObject(XNAT);
         opts = getObject(opts);
         opts.name = opts.name || opts.id;
         opts.id = opts.id || toDashed(opts.name);
-        
+
         var _select = spawn('select', {
             id: opts.id,
             name: opts.name,
@@ -103,7 +125,7 @@ var XNAT = getObject(XNAT);
             if (prop.value === opts.value){
                 _option.selected = true;
             }
-            _select.appendChild(_option)    
+            _select.appendChild(_option)
         });
         return template.panelElement(opts, [
             ['label.element-label|for='+opts.id, opts.label||opts.title||opts.name],