diff --git a/auth/auth_systems/cas.py b/auth/auth_systems/cas.py
index c246839d71c2f9c78dccbbf83b6b910e87345b35..d5b824e86acce5bd10436c71ba8d7b32033598f5 100644
--- a/auth/auth_systems/cas.py
+++ b/auth/auth_systems/cas.py
@@ -9,12 +9,13 @@ from django.http import *
 from django.core.mail import send_mail
 from django.conf import settings
 
-import sys, os, cgi, urllib, urllib2, re
+import sys, os, cgi, urllib, urllib2, re, uuid, datetime
 from xml.etree import ElementTree
 
 CAS_EMAIL_DOMAIN = "princeton.edu"
 CAS_URL= 'https://fed.princeton.edu/cas/'
 CAS_LOGOUT_URL = 'https://fed.princeton.edu/cas/logout?service=%s'
+CAS_SAML_VALIDATE_URL = 'https://fed.princeton.edu/cas/samlValidate?TARGET=%s'
 
 # eligibility checking
 if hasattr(settings, 'CAS_USERNAME'):
@@ -34,7 +35,7 @@ def _get_service_url():
   from django.conf import settings
   from django.core.urlresolvers import reverse
   
-  return settings.URL_HOST + reverse(after)
+  return settings.SECURE_URL_HOST + reverse(after)
   
 def get_auth_url(request, redirect_url):
   request.session['cas_redirect_url'] = redirect_url
@@ -52,6 +53,47 @@ def get_user_category(user_id):
   parsed_result = ElementTree.fromstring(result)
   return parsed_result.text
   
+def get_saml_info(ticket):
+  """
+  Using SAML, get all of the information needed
+  """
+
+  import logging
+
+  saml_request = """<?xml version='1.0' encoding='UTF-8'?> 
+  <soap-env:Envelope 
+     xmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/'> 
+     <soap-env:Header />
+     <soap-env:Body> 
+       <samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
+                      MajorVersion="1" MinorVersion="1"
+                      RequestID="%s"
+                      IssueInstant="%sZ">
+           <samlp:AssertionArtifact>%s</samlp:AssertionArtifact>
+       </samlp:Request>
+     </soap-env:Body> 
+  </soap-env:Envelope>
+""" % (uuid.uuid1(), datetime.datetime.utcnow().isoformat(), ticket)
+
+  url = CAS_SAML_VALIDATE_URL % urllib.quote(_get_service_url())
+
+  # by virtue of having a body, this is a POST
+  req = urllib2.Request(url, saml_request)
+  raw_response = urllib2.urlopen(req).read()
+
+  logging.info("RESP:\n%s\n\n" % raw_response)
+
+  response = ElementTree.fromstring(raw_response)
+
+  # ugly path down the tree of attributes
+  attributes = response.findall('{http://schemas.xmlsoap.org/soap/envelope/}Body/{urn:oasis:names:tc:SAML:1.0:protocol}Response/{urn:oasis:names:tc:SAML:1.0:assertion}Assertion/{urn:oasis:names:tc:SAML:1.0:assertion}AttributeStatement/{urn:oasis:names:tc:SAML:1.0:assertion}Attribute')
+
+  values = {}
+  for attribute in attributes:
+    values[str(attribute.attrib['AttributeName'])] = attribute.findtext('{urn:oasis:names:tc:SAML:1.0:assertion}AttributeValue')
+  
+  # parse response for netid, display name, and employee type (category)
+  return {'user_id': values.get('mail',None), 'name': values.get('displayName', None), 'category': values.get('employeeType',None)}
   
 def get_user_info(user_id):
   url = 'http://dsml.princeton.edu/'
@@ -101,34 +143,49 @@ def get_user_info(user_id):
   else:
     return None
   
-def get_user_info_after_auth(request):
-  ticket = request.GET.get('ticket', None)
-  
-  # if no ticket, this is a logout
-  if not ticket:
-    return None
-
+def get_user_info_special(ticket):
   # fetch the information from the CAS server
   val_url = CAS_URL + "validate" + \
      '?service=' + urllib.quote(_get_service_url()) + \
      '&ticket=' + urllib.quote(ticket)
-  r = urllib.urlopen(val_url).readlines()   # returns 2 lines
+  r = urllib.urlopen(val_url).readlines() # returns 2 lines
 
   # success
   if len(r) == 2 and re.match("yes", r[0]) != None:
     netid = r[1].strip()
     
     category = get_user_category(netid)
-    user_info = get_user_info(netid)
+    
+    #try:
+    #  user_info = get_user_info(netid)
+    #except:
+    #  user_info = None
+
+    # for now, no need to wait for this request to finish
+    user_info = None
 
     if user_info:
       info = {'name': user_info['name'], 'category': category}
     else:
       info = {'name': netid, 'category': category}
       
-    return {'type': 'cas', 'user_id': netid, 'name': info['name'], 'info': info, 'token': None}
+    return {'user_id': netid, 'name': info['name'], 'info': info, 'token': None}
   else:
     return None
+
+def get_user_info_after_auth(request):
+  ticket = request.GET.get('ticket', None)
+  
+  # if no ticket, this is a logout
+  if not ticket:
+    return None
+
+  #user_info = get_saml_info(ticket)
+  user_info = get_user_info_special(ticket)
+
+  user_info['type'] = 'cas'  
+
+  return user_info
     
 def do_logout(user):
   """
diff --git a/helios/forms.py b/helios/forms.py
index e7973d67ce12f1abb1f1eeb21018b63018d9d3f4..d2c887087bcafcf5a3586fb68a4b81c06b2f40cb 100644
--- a/helios/forms.py
+++ b/helios/forms.py
@@ -33,8 +33,8 @@ class EmailVotersForm(forms.Form):
 
 class TallyNotificationEmailForm(forms.Form):
   subject = forms.CharField(max_length=80)
-  body = forms.CharField(max_length=2000, widget=forms.Textarea)
-  send_to = forms.ChoiceField(label="Send To", choices= [('all', 'all voters'), ('voted', 'only voters who cast a ballot')])
+  body = forms.CharField(max_length=2000, widget=forms.Textarea, required=False)
+  send_to = forms.ChoiceField(label="Send To", choices= [('all', 'all voters'), ('voted', 'only voters who cast a ballot'), ('none', 'no one -- are you sure about this?')])
 
 class VoterPasswordForm(forms.Form):
   voter_id = forms.CharField(max_length=50)
diff --git a/helios/templates/list_trustees.html b/helios/templates/list_trustees.html
index 15b2e60835481650392fdfdfecacb082e7848568..94d41580cd39ad92540aaa99af76d0d32e9a733d 100644
--- a/helios/templates/list_trustees.html
+++ b/helios/templates/list_trustees.html
@@ -27,7 +27,9 @@
 {% for t in trustees %}
 <h3> Trustee #{{forloop.counter}}: {{t.name}} 
 {% if admin_p %}
-{% if not t.secret_key %}
+{% if t.secret_key %}
+{% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove Helios as a trustee?');" href="{% url helios.views.delete_trustee election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %}
+{% else %}
 ({{t.email}})
 {% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove this Trustee?');" href="{% url helios.views.delete_trustee election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %}
 [<a onclick="return confirm('Are you sure you want to send this trustee his/her admin URL?');" href="{% url helios.views.trustee_send_url election.uuid t.uuid %}">send login</a>]
diff --git a/helios/views.py b/helios/views.py
index b9a8d8bd29b8480c00549224f429c201178c3b81..f33e17d0a536b83c312317213edd621faf4fc7c7 100644
--- a/helios/views.py
+++ b/helios/views.py
@@ -353,7 +353,7 @@ def new_trustee_helios(request, election):
   election.generate_trustee(ELGAMAL_PARAMS)
   return HttpResponseRedirect(reverse(list_trustees_view, args=[election.uuid]))
   
-@election_admin()
+@election_admin(frozen=False)
 def delete_trustee(request, election):
   trustee = Trustee.get_by_election_and_uuid(election, request.GET['uuid'])
   trustee.delete()
@@ -538,7 +538,7 @@ def one_election_cast_confirm(request, election):
     # status update this vote
     if voter and user and user.can_update_status():
       status_update_label = voter.user.update_status_template() % "your smart ballot tracker"
-      status_update_message = "I voted in %s, my smart tracker is %s.. -- %s" % (election.name, cast_vote.vote_hash[:10], get_election_url(election))
+      status_update_message = "I voted in %s - my smart tracker is %s.. #heliosvoting" % (get_election_url(election),cast_vote.vote_hash[:10])
     else:
       status_update_label = None
       status_update_message = None
@@ -929,21 +929,24 @@ def combine_decryptions(request, election):
         'election' : election
         }
 
-      # exclude those who have not voted
-      if email_form.cleaned_data['send_to'] == 'voted':
-        voter_constraints_exclude = {'vote_hash' : None}
-      else:
-        voter_constraints_exclude = {}
+      # if the user opted for notifying no one, then we skip this step
+      if email_form.cleaned_data['send_to'] != 'none':
+        # exclude those who have not voted
+        if email_form.cleaned_data['send_to'] == 'voted':
+          voter_constraints_exclude = {'vote_hash' : None}
+        else:
+          voter_constraints_exclude = {}
       
-      # full-length email
-      tasks.voters_email.delay(election_id = election.id,
-                               subject_template = 'email/result_subject.txt',
-                               body_template = 'email/result_body.txt',
-                               extra_vars = extra_vars,
-                               voter_constraints_exclude = voter_constraints_exclude)
+        # full-length email
+        tasks.voters_email.delay(election_id = election.id,
+                                 subject_template = 'email/result_subject.txt',
+                                 body_template = 'email/result_body.txt',
+                                 extra_vars = extra_vars,
+                                 voter_constraints_exclude = voter_constraints_exclude)
 
       # rapid short-message notification
       # this inherently only applies to those who have voted (for the most part)
+      # and this is not configurable, this is ALWAYS sent
       tasks.voters_notify.delay(election_id = election.id,
                                 notification_template = 'notification/result.txt',
                                 extra_vars = extra_vars)