diff --git a/.gitignore b/.gitignore
index 681947f7ff38ef3bb2c398d79c496ecc6172d9cb..a2dca2bee7e168df398b922f596e4e4a6e230a26 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,4 +6,5 @@ media/*
 venv
 celerybeat-*
 env.sh
-.cache
\ No newline at end of file
+.cache
+.idea/
\ No newline at end of file
diff --git a/helios/crypto/utils.py b/helios/crypto/utils.py
index dd395a598fbbec1df4bce90f81e7d95a9228b32b..258f4130cb45bf509bc62710674363830ebe6a5d 100644
--- a/helios/crypto/utils.py
+++ b/helios/crypto/utils.py
@@ -1,7 +1,7 @@
 """
 Crypto Utils
 """
-
+import hashlib
 import hmac, base64, json
 
 from hashlib import sha256
@@ -21,3 +21,11 @@ def to_json(d):
 def from_json(json_str):
   if not json_str: return None
   return json.loads(json_str)
+
+
+def do_hmac(k,s):
+  """
+  HMAC a value with a key, hex output
+  """
+  mac = hmac.new(k, s, hashlib.sha1)
+  return mac.hexdigest()
\ No newline at end of file
diff --git a/helios/urls.py b/helios/urls.py
index 67c0077672cd476a705ca58d4bf9ab6ca4288e07..8effba1727a9bbd7623471c2c70f00ae43dff62e 100644
--- a/helios/urls.py
+++ b/helios/urls.py
@@ -1,12 +1,8 @@
 # -*- coding: utf-8 -*-
-from django.conf.urls import *
-
-from django.conf import settings
+from django.conf.urls import patterns, include
 
 from views import *
 
-urlpatterns = None
-
 urlpatterns = patterns('',
   (r'^autologin$', admin_autologin),
   (r'^testcookie$', test_cookie),
diff --git a/helios/utils.py b/helios/utils.py
index d053dc11fec961d94b6edeee4879826107622d5c..03095a75074b55123571991a8e35cf0924248431 100644
--- a/helios/utils.py
+++ b/helios/utils.py
@@ -5,9 +5,7 @@ Ben Adida - ben@adida.net
 2005-04-11
 """
 
-import urllib, re, sys, datetime, urlparse, string
-
-import boto.ses
+import urllib, re, datetime, string
 
 # utils from helios_auth, too
 from helios_auth.utils import *
@@ -15,14 +13,6 @@ from helios_auth.utils import *
 from django.conf import settings
   
 import random, logging
-import hashlib, hmac, base64
-
-def do_hmac(k,s):
-  """
-  HMAC a value with a key, hex output
-  """
-  mac = hmac.new(k, s, hashlib.sha1)
-  return mac.hexdigest()
 
 
 def split_by_length(str, length, rejoin_with=None):
@@ -167,7 +157,7 @@ def one_val_raw_sql(raw_sql, values=[]):
   """
   for a simple aggregate
   """
-  from django.db import connection, transaction
+  from django.db import connection
   cursor = connection.cursor()
 
   cursor.execute(raw_sql, values)
diff --git a/helios/views.py b/helios/views.py
index d8766a1690323caa53c0d6f4c4dd0e37bbf453fe..3eb6c68c5d565953abc111f7d2554a15f96ebedd 100644
--- a/helios/views.py
+++ b/helios/views.py
@@ -6,41 +6,41 @@ Ben Adida (ben@adida.net)
 """
 
 from django.core.urlresolvers import reverse
-from django.core.mail import send_mail
 from django.core.paginator import Paginator
 from django.core.exceptions import PermissionDenied
-from django.http import *
+from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseForbidden
 from django.db import transaction, IntegrityError
 
-from mimetypes import guess_type
-
 from validate_email import validate_email
 
-import csv, urllib, os, base64
+import urllib, os, base64
 
 from crypto import algs, electionalgs, elgamal
 from crypto import utils as cryptoutils
 from workflows import homomorphic
-from helios import utils as helios_utils
-from view_utils import *
+from helios import utils, VOTERS_EMAIL, VOTERS_UPLOAD
+from view_utils import SUCCESS, FAILURE, return_json, render_template, render_template_raw
 
-from helios_auth.security import *
+from helios_auth.security import check_csrf, login_required, get_user, save_in_session_across_logouts
 from helios_auth.auth_systems import AUTH_SYSTEMS, can_list_categories
 from helios_auth.models import AuthenticationExpired
 
-from helios import security
 from helios_auth import views as auth_views
 
 import tasks
 
-from security import *
-from helios_auth.security import get_user, save_in_session_across_logouts
+from security import (election_view, election_admin,
+                      trustee_check, set_logged_in_trustee,
+                      can_create_election, user_can_see_election, get_voter,
+                      user_can_admin_election, user_can_feature_election)
 
 import uuid, datetime
+import logging
 
-from models import *
+from models import User, Election, CastVote, Voter, VoterFile, Trustee, AuditedBallot
+import datatypes
 
-import forms, signals
+import forms
 
 # Parameters for everything
 ELGAMAL_PARAMS = elgamal.Cryptosystem()
@@ -196,7 +196,7 @@ def election_new(request):
       election_params = dict(election_form.cleaned_data)
       
       # is the short name valid
-      if helios_utils.urlencode(election_params['short_name']) == election_params['short_name']:      
+      if utils.urlencode(election_params['short_name']) == election_params['short_name']:
         election_params['uuid'] = str(uuid.uuid1())
         election_params['cast_url'] = settings.SECURE_URL_HOST + reverse(one_election_cast, args=[election_params['uuid']])
       
@@ -293,8 +293,8 @@ def election_badge(request, election):
 @election_view()
 def one_election_view(request, election):
   user = get_user(request)
-  admin_p = security.user_can_admin_election(user, election)
-  can_feature_p = security.user_can_feature_election(user, election)
+  admin_p = user_can_admin_election(user, election)
+  can_feature_p = user_can_feature_election(user, election)
   
   notregistered = False
   eligible_p = True
@@ -383,7 +383,7 @@ def list_trustees(request, election):
 def list_trustees_view(request, election):
   trustees = Trustee.get_by_election(election)
   user = get_user(request)
-  admin_p = security.user_can_admin_election(user, election)
+  admin_p = user_can_admin_election(user, election)
   
   return render_template(request, 'list_trustees', {'election': election, 'trustees': trustees, 'admin_p':admin_p})
   
@@ -446,7 +446,7 @@ Your trustee dashboard is at
 Helios  
 """ % (election.name, url)
 
-  helios_utils.send_email(settings.SERVER_EMAIL, ["%s <%s>" % (trustee.name, trustee.email)], 'your trustee homepage for %s' % election.name, body)
+  utils.send_email(settings.SERVER_EMAIL, ["%s <%s>" % (trustee.name, trustee.email)], 'your trustee homepage for %s' % election.name, body)
 
   logging.info("URL %s " % url)
   return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(list_trustees_view, args = [election.uuid]))
@@ -471,7 +471,7 @@ def trustee_upload_pk(request, election, trustee):
     if not trustee.public_key.verify_sk_proof(trustee.pok, algs.DLog_challenge_generator):
       raise Exception("bad pok for this public key")
     
-    trustee.public_key_hash = utils.hash_b64(utils.to_json(trustee.public_key.toJSONDict()))
+    trustee.public_key_hash = cryptoutils.hash_b64(utils.to_json(trustee.public_key.toJSONDict()))
 
     trustee.save()
     
@@ -923,7 +923,7 @@ def one_election_set_featured(request, election):
   """
 
   user = get_user(request)
-  if not security.user_can_feature_election(user, election):
+  if not user_can_feature_election(user, election):
     raise PermissionDenied()
 
   featured_p = bool(int(request.GET['featured_p']))
@@ -987,7 +987,7 @@ def one_election_copy(request, election):
 def one_election_questions(request, election):
   questions_json = utils.to_json(election.questions)
   user = get_user(request)
-  admin_p = security.user_can_admin_election(user, election)
+  admin_p = user_can_admin_election(user, election)
 
   return render_template(request, 'election_questions', {'election': election, 'questions_json' : questions_json, 'admin_p': admin_p})
 
@@ -1191,7 +1191,7 @@ def voters_list_pretty(request, election):
     order_by = 'alias'
 
   user = get_user(request)
-  admin_p = security.user_can_admin_election(user, election)
+  admin_p = user_can_admin_election(user, election)
 
   categories = None
   eligibility_category_id = None
@@ -1224,9 +1224,9 @@ def voters_list_pretty(request, election):
   return render_template(request, 'voters_list', 
                          {'election': election, 'voters_page': voters_page,
                           'voters': voters_page.object_list, 'admin_p': admin_p, 
-                          'email_voters': helios.VOTERS_EMAIL,
+                          'email_voters': VOTERS_EMAIL,
                           'limit': limit, 'total_voters': total_voters,
-                          'upload_p': helios.VOTERS_UPLOAD, 'q' : q,
+                          'upload_p': VOTERS_UPLOAD, 'q' : q,
                           'voter_files': voter_files,
                           'categories': categories,
                           'eligibility_category_id' : eligibility_category_id})
@@ -1330,7 +1330,7 @@ def voters_upload_cancel(request, election):
 
 @election_admin(frozen=True)
 def voters_email(request, election):
-  if not helios.VOTERS_EMAIL:
+  if not VOTERS_EMAIL:
     return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid]))
   TEMPLATES = [
     ('vote', 'Time to Vote'),
diff --git a/helios_auth/security/__init__.py b/helios_auth/security/__init__.py
index b036067d9b837e4156df46fd9a6efdc78516b98f..facc0c32d73b225997acb529de57b501de2f8aad 100644
--- a/helios_auth/security/__init__.py
+++ b/helios_auth/security/__init__.py
@@ -10,6 +10,7 @@ from functools import update_wrapper
 from django.http import HttpResponse, Http404, HttpResponseRedirect
 from django.core.exceptions import *
 from django.conf import settings
+from django.http import HttpResponseNotAllowed
 
 import oauth
 
diff --git a/heliosbooth/boothworker-single.js b/heliosbooth/boothworker-single.js
index edb1debb5132006a7efcd8af99706ebd19b9d1bb..1c87986cad03eef9b61fd5320a0ff8659d6e8af3 100644
--- a/heliosbooth/boothworker-single.js
+++ b/heliosbooth/boothworker-single.js
@@ -49,12 +49,16 @@ function do_encrypt(message) {
 // receive either
 // a) an election and an integer position of the question
 // that this worker will be used to encrypt
-// {'type': 'setup', 'question_num' : 2, 'election' : election_json}
+// {'type': 'setup', 'election': election_json}
 //
 // b) an answer that needs encrypting
-// {'type': 'encrypt', 'answer' : answer_json}
+// {'type': 'encrypt', 'q_num': 2, 'id': id, 'answer': answer_json}
 //
 self.onmessage = function(event) {
     // dispatch to method
-    self['do_' + event.data.type](event.data);
-}
+    if (event.data.type === "setup") {
+        do_setup(event.data);
+	} else if (event.data.type === "encrypt") {
+        do_encrypt(event.data);
+    }
+};
diff --git a/reset.sh b/reset.sh
index f7ad853220fcc371459bc86beeff2efdbac7122d..52141e13601899518420a971142f26d30f772ab2 100755
--- a/reset.sh
+++ b/reset.sh
@@ -1,4 +1,5 @@
 #!/bin/bash
+set -e  # Exit immediately if a command exits with a non-zero status.
 dropdb helios
 createdb helios
 python manage.py syncdb
diff --git a/server_ui/urls.py b/server_ui/urls.py
index d71e04dcac68008d2001ca99c7df7f055bd6404a..0711bd7c15047d880c8d3d18926aceea00e338b4 100644
--- a/server_ui/urls.py
+++ b/server_ui/urls.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
-from django.conf.urls import *
+from django.conf.urls import patterns
 
-from views import *
+from views import home, about, docs, faq, privacy
 
 urlpatterns = patterns('',
   (r'^$', home),