Merge branch issue1676.
diff --git a/app/app.yaml.template b/app/app.yaml.template
index 415ec3b..accfeaa 100644
--- a/app/app.yaml.template
+++ b/app/app.yaml.template
@@ -15,7 +15,7 @@
 # TODO(proto): uncomment and supply a Google App Engine application instance
 # application: FIXME
 # TODO(release): see the instructions in README about the "version:" field
-version: 2-0-20121130
+version: 2-0-20121217
 runtime: python
 api_version: 1
 
diff --git a/app/soc/content/css/v2/gci/style.css b/app/soc/content/css/v2/gci/style.css
index e7f39b8..65f5834 100644
--- a/app/soc/content/css/v2/gci/style.css
+++ b/app/soc/content/css/v2/gci/style.css
@@ -1416,7 +1416,7 @@
             line-height: 18px;
             padding: 4px 25px 5px 10px;
         }
-        .block-how-it-works .block-how-it-works-start a.example-tasks {
+        .block-how-it-works .block-how-it-works-start a.example-tasks, a.all-tasks-tasks {
             color: #c53926;
             display: block;
             float: left;
@@ -1427,6 +1427,10 @@
             margin-left: 100px;
             padding: 4px 25px 5px 10px;
         }
+        a.all-tasks-tasks {
+            font-size: 14px;
+            margin-left: 75px;
+        }
 .block-featured-task {/*Featured Task*/
 }
     .block-featured-task .block-title {
diff --git a/app/soc/logic/delete_account.py b/app/soc/logic/delete_account.py
index 0ff9f24..0edf00c 100644
--- a/app/soc/logic/delete_account.py
+++ b/app/soc/logic/delete_account.py
@@ -31,6 +31,7 @@
 from soc.modules.gci.models import task as task_model
 
 
+
 ADMIN_REQUEST_EMAIL_SUBJEST = """
 User %(link_id)s has requested account deletion.
 """
diff --git a/app/soc/modules/gci/templates/task_list.py b/app/soc/modules/gci/templates/task_list.py
index e61e6c9..46f2ff4 100644
--- a/app/soc/modules/gci/templates/task_list.py
+++ b/app/soc/modules/gci/templates/task_list.py
@@ -97,7 +97,15 @@
     if 'mentors' in self._columns:
       list_config.addColumn('mentors', 'Mentors',
           lambda entity, mentors, *args: ', '.join(
-              mentors[i].name() for i in entity.mentors))
+              mentors[i].name() for i in entity.mentors), hidden=True)
+
+    if 'types' in self._columns:
+      list_config.addColumn('types', 'Category',
+          lambda entity, *args: ', '.join(entity.types))
+
+    if 'tags' in self._columns:
+      list_config.addColumn('tags', 'Tags',
+          lambda entity, *args: ', '.join(entity.tags))
 
     if 'status' in self._columns:
       list_config.addSimpleColumn('status', 'Status')
diff --git a/app/soc/modules/gci/views/accepted_orgs.py b/app/soc/modules/gci/views/accepted_orgs.py
index dc33373..2b1afce 100644
--- a/app/soc/modules/gci/views/accepted_orgs.py
+++ b/app/soc/modules/gci/views/accepted_orgs.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GCI accepted orgs.
-"""
-
+"""Module containing the views for GCI accepted orgs."""
 
 from django.conf.urls.defaults import url as django_url
 
@@ -42,14 +38,19 @@
         self.data.program.name)
 
   def _getListConfig(self):
-    r = self.data.redirect
+    # TODO(nathaniel): squeeze this back into a lambda expression in
+    # the call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf(url_names.GCI_ORG_HOME)
 
     list_config = lists.ListConfiguration()
     list_config.addColumn('name', 'Name',
         lambda e, *args: e.name.strip())
     list_config.addSimpleColumn('link_id', 'Link ID', hidden=True)
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf(url_names.GCI_ORG_HOME))
+    list_config.setRowAction(RowAction)
     list_config.addColumn(
         'ideas', 'Ideas',
         (lambda e, *args: url_helper.urlize(e.ideas, name="[ideas page]")),
@@ -106,14 +107,19 @@
         self.data.program.name)
 
   def _getListConfig(self):
-    r = self.data.redirect
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf(url_names.GCI_ORG_HOME)
 
     list_config = lists.ListConfiguration()
     list_config.addColumn('name', 'Name',
         lambda e, *args: e.name.strip())
     list_config.addSimpleColumn('link_id', 'Link ID', hidden=True)
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf(url_names.GCI_ORG_HOME))
+    list_config.setRowAction(RowAction)
     list_config.setDefaultPagination(False)
     list_config.setDefaultSort('name')
     list_config.addColumn(
diff --git a/app/soc/modules/gci/views/admin.py b/app/soc/modules/gci/views/admin.py
index bb35606..3b2281a 100644
--- a/app/soc/modules/gci/views/admin.py
+++ b/app/soc/modules/gci/views/admin.py
@@ -229,13 +229,6 @@
             'title': 'List of documents',
             'link': r.urlOf('list_gci_documents')
         },
-        {
-            'name': 'students_info',
-            'description': ugettext(
-                'Details of students participating in the current program.'),
-            'title': 'Details of students',
-            'link': r.urlOf(url_names.GCI_STUDENTS_INFO) 
-        },
     ]
 
     super(ProgramSettingsDashboard, self).__init__(request, data, subpages)
@@ -362,6 +355,13 @@
             'title': 'List students',
             'link': r.urlOf(url_names.GCI_STUDENTS_INFO)
         },
+        {
+            'name': 'leaderboard',
+            'description': ugettext(
+                'Leaderboard for the program'),
+            'title': 'Leaderboard',
+            'link': r.urlOf(url_names.GCI_LEADERBOARD)
+        },
     ]
 
     super(ParticipantsDashboard, self).__init__(request, data, subpages)
diff --git a/app/soc/modules/gci/views/age_check.py b/app/soc/modules/gci/views/age_check.py
index e39e212..6b45518 100644
--- a/app/soc/modules/gci/views/age_check.py
+++ b/app/soc/modules/gci/views/age_check.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GCI age check.
-"""
-
+"""Module for the GCI age check."""
 
 from django import forms
 
@@ -109,4 +105,7 @@
       self.response.set_cookie('age_check', '0')
 
     # redirect to the same page and have the cookies sent across
-    self.redirect.program().to('gci_age_check')
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+
+    self.redirect.to('gci_age_check')
diff --git a/app/soc/modules/gci/views/all_tasks.py b/app/soc/modules/gci/views/all_tasks.py
index 1e07f7d..adf65b8 100644
--- a/app/soc/modules/gci/views/all_tasks.py
+++ b/app/soc/modules/gci/views/all_tasks.py
@@ -22,9 +22,9 @@
 from soc.views.helper import url_patterns
 
 from soc.modules.gci.logic import task as task_logic
-from soc.modules.gci.models.task import CLAIMABLE
 from soc.modules.gci.templates.task_list import TaskList
 from soc.modules.gci.views.base import GCIRequestHandler
+from soc.modules.gci.views.helper import url_names
 from soc.modules.gci.views.helper.url_patterns import url
 
 
@@ -32,7 +32,8 @@
   """Template for list of all tasks which are claimable for the program.
   """
 
-  _LIST_COLUMNS = ['title', 'organization', 'mentors', 'status']
+  _LIST_COLUMNS = ['title', 'organization', 'tags', 'types',
+                   'mentors', 'status']
 
   def __init__(self, request, data):
     super(AllTasksList, self).__init__(request, data)
@@ -59,7 +60,7 @@
   def djangoURLPatterns(self):
     return [
         url(r'tasks/%s$' % url_patterns.PROGRAM, self,
-            name='gci_list_tasks'),
+            name=url_names.GCI_ALL_TASKS_LIST),
     ]
 
   def checkAccess(self):
diff --git a/app/soc/modules/gci/views/base_templates.py b/app/soc/modules/gci/views/base_templates.py
index fb9ae20..492d5a2 100644
--- a/app/soc/modules/gci/views/base_templates.py
+++ b/app/soc/modules/gci/views/base_templates.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,7 +14,6 @@
 
 """This module contains the view for the site menus."""
 
-
 import datetime
 
 from google.appengine.api import users
@@ -62,7 +59,9 @@
     context['dashboard_link'] = redirect.dashboard().url()
 
   if data.timeline.tasksPubliclyVisible():
-    context['tasks_link'] = redirect.program().urlOf('gci_list_tasks')
+    # TODO(nathaniel): make this .program() call unnecessary.
+    redirect.program()
+    context['tasks_link'] = redirect.urlOf('gci_list_tasks')
     if not data.user:
       context['register_as_student_link'] = redirect.createProfile(
           'student').urlOf('create_gci_profile', secure=True)
diff --git a/app/soc/modules/gci/views/bulk_create.py b/app/soc/modules/gci/views/bulk_create.py
index 4056a0a..2fdf0fd 100644
--- a/app/soc/modules/gci/views/bulk_create.py
+++ b/app/soc/modules/gci/views/bulk_create.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GCI view to bulk create GCITasks.
-"""
-
+"""Module for the GCI view to bulk create GCITasks."""
 
 from django import forms
 
@@ -97,5 +93,7 @@
         form.cleaned_data['task_data'], self.data.organization,
         self.data.profile)
 
-    self.redirect.organization(self.data.organization)
+    # TODO(nathaniel): make this .organization call unnecessary.
+    self.redirect.organization(organization=self.data.organization)
+
     self.redirect.to(url_names.GCI_TASK_BULK_CREATE, validated=True)
diff --git a/app/soc/modules/gci/views/dashboard.py b/app/soc/modules/gci/views/dashboard.py
index 43c01ca..f2ff3bc 100644
--- a/app/soc/modules/gci/views/dashboard.py
+++ b/app/soc/modules/gci/views/dashboard.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,8 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GCI participant dashboard.
-"""
+"""Module for the GCI participant dashboard."""
 
 import logging
 
@@ -892,9 +889,15 @@
             'organization you will create the task for.')}
 
   def _setRowAction(self, request, data):
-    self._list_config.setRowAction(
-        lambda e, *args: data.redirect.organization(e).
-            urlOf('gci_create_task'))
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # setRowAction call below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      data.redirect.organization(organization=e)
+
+      return data.redirect.urlOf('gci_create_task')
+
+    self._list_config.setRowAction(RowAction)
 
 
 class MyOrgsListBeforeBulkCreateTask(MyOrgsList):
@@ -918,9 +921,15 @@
             'organization you will upload the tasks for.')}
 
   def _setRowAction(self, request, data):
-    self._list_config.setRowAction(
-        lambda e, *args: data.redirect.organization(e).
-            urlOf(url_names.GCI_TASK_BULK_CREATE))
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # setRowAction call below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      data.redirect.organization(organization=e)
+
+      return data.redirect.urlOf(url_names.GCI_TASK_BULK_CREATE)
+
+    self._list_config.setRowAction(RowAction)
 
 
 class MyOrgsListBeforeInviteMentor(MyOrgsList):
@@ -987,9 +996,15 @@
     self.idx = 12
 
   def _setRowAction(self, request, data):
-    self._list_config.setRowAction(
-        lambda e, *args: data.redirect.organization(e)
-            .urlOf(url_names.GCI_ORG_SCORES))
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      data.redirect.organization(organization=e)
+
+      return data.redirect.urlOf(url_names.GCI_ORG_SCORES)
+
+    self._list_config.setRowAction(RowAction)
 
   def getListData(self):
     if lists.getListIndex(self.request) != self.idx:
@@ -1096,9 +1111,15 @@
             'organization you will edit the profile for.')}
 
   def _setRowAction(self, request, data):
-    self._list_config.setRowAction(
-        lambda e, *args: data.redirect.organization(e).
-            urlOf(url_names.EDIT_GCI_ORG_PROFILE, secure=True))
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      data.redirect.organization(organization=e)
+
+      return data.redirect.urlOf(url_names.EDIT_GCI_ORG_PROFILE, secure=True)
+
+    self._list_config.setRowAction(RowAction)
 
 
 class AllOrgsListBeforeRequestRole(MyOrgsList):
diff --git a/app/soc/modules/gci/views/delete_account.py b/app/soc/modules/gci/views/delete_account.py
index 728162a..b71b4fc 100644
--- a/app/soc/modules/gci/views/delete_account.py
+++ b/app/soc/modules/gci/views/delete_account.py
@@ -45,4 +45,6 @@
 
   def post(self):
     delete_account.request_account_deletion(self.data.user)
-    self.redirect.program().to('gci_delete_account', validated=True)
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+    self.redirect.to('gci_delete_account', validated=True)
diff --git a/app/soc/modules/gci/views/helper/url_names.py b/app/soc/modules/gci/views/helper/url_names.py
index 89776b2..a14d023 100644
--- a/app/soc/modules/gci/views/helper/url_names.py
+++ b/app/soc/modules/gci/views/helper/url_names.py
@@ -35,6 +35,8 @@
 GCI_ORG_CHOOSE_FOR_SCORE = 'gci_org_choose_for_score'
 GCI_ORG_TASKS_ALL = 'gci_org_tasks_all'
 
+GCI_ALL_TASKS_LIST = 'gci_list_tasks'
+
 GCI_LEADERBOARD = 'gci_leaderboard'
 GCI_STUDENT_TASKS = 'gci_student_tasks'
 GCI_STUDENT_TASKS_FOR_ORG = 'gci_student_tasks_for_org'
diff --git a/app/soc/modules/gci/views/homepage.py b/app/soc/modules/gci/views/homepage.py
index e5a9250..0aaf40d 100644
--- a/app/soc/modules/gci/views/homepage.py
+++ b/app/soc/modules/gci/views/homepage.py
@@ -26,8 +26,7 @@
 
 
 class HowItWorks(Template):
-  """How it works template.
-  """
+  """How it works template."""
 
   CONTEST_BEGINS_ON_MSG = "Contest begins on %s %s"
 
@@ -37,30 +36,40 @@
     self.data = data
 
   def context(self):
-    r = self.data.redirect
     program = self.data.program
 
     from soc.modules.gci.models.program import GCIProgram
     about_page = GCIProgram.about_page.get_value_for_datastore(program)
 
     example_tasks_link = ''
+    all_tasks_link = ''
 
     main_text = self._getMainText()
 
     if self.data.timeline.orgSignup():
+      # TODO(nathaniel): make this .program() call unnecessary.
+      self.data.redirect.program()
+
       start_text = 'Sign up as organization'
-      start_link = r.program().urlOf('gci_take_org_app')
+      start_link = self.data.redirect.urlOf('gci_take_org_app')
       if self.data.program.example_tasks:
         example_tasks_link = self.data.program.example_tasks
     elif self.data.timeline.studentSignup() and not self.data.profile:
       start_text = 'Register As Student'
-      start_link = r.createProfile('student').urlOf('create_gci_profile',
-          secure=True)
-      if self.data.program.example_tasks:
-        example_tasks_link = self.data.program.example_tasks
+
+      start_link = self.data.redirect.createProfile('student').urlOf(
+          'create_gci_profile', secure=True)
+
+      # TODO(nathaniel): make this .program() call unnecessary.
+      self.data.redirect.program()
+
+      all_tasks_link = self.data.redirect.urlOf(url_names.GCI_ALL_TASKS_LIST)
     elif self.data.timeline.tasksPubliclyVisible():
+      # TODO(nathaniel): make this .program() call unnecessary.
+      self.data.redirect.program()
+
       start_text = 'Search for tasks'
-      start_link = self.data.redirect.program().urlOf('gci_list_tasks')
+      start_link = self.data.redirect.urlOf('gci_list_tasks')
     elif self.data.program.example_tasks:
       start_text = 'See example tasks'
       start_link = self.data.program.example_tasks
@@ -68,10 +77,11 @@
       start_text = start_link = ''
 
     return {
-        'about_link': r.document(about_page).url(),
+        'about_link': self.data.redirect.document(about_page).url(),
         'start_text': start_text,
         'start_link': start_link,
         'example_tasks_link': example_tasks_link,
+        'all_tasks_link': all_tasks_link,
         'main_text': main_text,
     }
 
@@ -119,14 +129,12 @@
     self.data = data
 
   def context(self):
-    r = self.data.redirect
-
     participating_orgs = []
     current_orgs = org_logic.participating(
         self.data.program, org_count=self._ORG_COUNT)
     for org in current_orgs:
       participating_orgs.append({
-          'link': r.orgHomepage(org.link_id).url(),
+          'link': self.data.redirect.orgHomepage(org.link_id).url(),
           'logo': org.logo_url,
           'name': org.short_name,
           })
@@ -143,7 +151,10 @@
         row, orgs = orgs[:self._TABLE_WIDTH], orgs[self._TABLE_WIDTH:]
         participating_orgs_table_rows.append(row)
 
-    accepted_orgs_url = r.program().urlOf('gci_accepted_orgs')
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.data.redirect.program()
+
+    accepted_orgs_url = self.data.redirect.urlOf('gci_accepted_orgs')
 
     return {
         'participating_orgs': participating_orgs,
@@ -158,16 +169,17 @@
 
 
 class Leaderboard(Template):
-  """Leaderboard template.
-  """
+  """Leaderboard template."""
 
   def __init__(self, data):
     self.data = data
 
   def context(self):
-    r = self.data.redirect
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.data.redirect.program()
+
     return {
-        'leaderboard_url': r.program().urlOf(url_names.GCI_LEADERBOARD),
+        'leaderboard_url': self.data.redirect.urlOf(url_names.GCI_LEADERBOARD),
     }
 
   def templatePath(self):
diff --git a/app/soc/modules/gci/views/leaderboard.py b/app/soc/modules/gci/views/leaderboard.py
index 23c0af8..1bef7ae 100644
--- a/app/soc/modules/gci/views/leaderboard.py
+++ b/app/soc/modules/gci/views/leaderboard.py
@@ -124,7 +124,7 @@
     ]
 
   def checkAccess(self):
-    pass
+    self.check.isHost()
 
   def jsonContext(self):
     list_content = LeaderboardList(self.request, self.data).getListData()
@@ -164,10 +164,16 @@
     ]
 
   def checkAccess(self):
-    pass
+    self.mutator.studentFromKwargs()
+    try:
+      self.check.isHost()
+    except AccessViolation:
+      self.check.hasProfile()
+      # check if the profile in URL kwargs is the current profile
+      if self.data.profile.key() != self.data.url_profile.key():
+        raise AccessViolation('You do not have access to this data')
 
   def jsonContext(self):
-    self.mutator.studentFromKwargs()
     list_content = AllStudentTasksList(self.request, self.data).getListData()
 
     if not list_content:
@@ -176,7 +182,6 @@
     return list_content.content()
 
   def context(self):
-    self.mutator.studentFromKwargs()
     return {
         'page_name': "Tasks closed by %s" % self.data.url_profile.name(),
         'tasks_list': AllStudentTasksList(self.request, self.data),
diff --git a/app/soc/modules/gci/views/org_app.py b/app/soc/modules/gci/views/org_app.py
index 16d6a5a..9a71999 100644
--- a/app/soc/modules/gci/views/org_app.py
+++ b/app/soc/modules/gci/views/org_app.py
@@ -62,9 +62,12 @@
     else:
       page_name = 'Create new organization application'
 
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+
     context = {
         'page_name': page_name,
-        'post_url': self.redirect.program().urlOf('gci_edit_org_app'),
+        'post_url': self.redirect.urlOf('gci_edit_org_app'),
         'forms': [form],
         'error': bool(form.errors),
         }
@@ -101,8 +104,10 @@
   def post(self):
     org_app = self.orgAppFromForm()
     if org_app:
-      r = self.redirect.program()
-      r.to('gci_edit_org_app', validated=True)
+      # TODO(nathaniel): make unnecessary this .program() call.
+      self.redirect.program()
+
+      self.redirect.to('gci_edit_org_app', validated=True)
     else:
       self.get()
 
@@ -157,7 +162,11 @@
     # FIXME: There will never be organization in kwargs
     show_url = None
     if 'organization' in self.kwargs:
-      show_url = self.data.redirect.organization().urlOf('gci_show_org_app')
+      # TODO(nathaniel): make this .organization() call unnecessary. Like,
+      # more than it already is (see the note above).
+      self.data.redirect.organization()
+
+      show_url = self.data.redirect.urlOf('gci_show_org_app')
 
     self.check.isSurveyActive(self.data.org_app, show_url)
 
diff --git a/app/soc/modules/gci/views/org_profile.py b/app/soc/modules/gci/views/org_profile.py
index cd94328..f8d1184 100644
--- a/app/soc/modules/gci/views/org_profile.py
+++ b/app/soc/modules/gci/views/org_profile.py
@@ -96,15 +96,18 @@
         }
 
     if self.data.organization:
-      r = self.data.redirect.organization()
-      context['org_home_page_link'] = r.urlOf('gci_org_home')
+      # TODO(nathaniel): make this .organization() call unnecessary.
+      self.data.redirect.organization()
+      context['org_home_page_link'] = self.data.redirect.urlOf('gci_org_home')
 
     return context
 
   def post(self):
     org_profile = self.createOrgProfileFromForm()
     if org_profile:
-      self.redirect.organization(org_profile)
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.redirect.organization(organization=org_profile)
+
       self.redirect.to('edit_gci_org_profile', validated=True)
     else:
       self.get()
@@ -115,7 +118,6 @@
     Returns:
       a newly created organization entity or None
     """
-
     if self.data.organization:
       form = OrgProfileForm(self.data.POST, instance=self.data.organization)
     else:
@@ -128,7 +130,7 @@
       org_id = self.data.GET['org_id']
       form.cleaned_data['founder'] = self.data.user
       form.cleaned_data['scope'] = self.data.program
-      form.cleaned_data['scope_path'] = self.data.program.key().name() 
+      form.cleaned_data['scope_path'] = self.data.program.key().name()
       form.cleaned_data['link_id'] = org_id
       key_name = '%s/%s' % (self.data.program.key().name(), org_id)
       entity = form.create(key_name=key_name)
diff --git a/app/soc/modules/gci/views/org_score.py b/app/soc/modules/gci/views/org_score.py
index 526a810..73061a0 100644
--- a/app/soc/modules/gci/views/org_score.py
+++ b/app/soc/modules/gci/views/org_score.py
@@ -126,8 +126,10 @@
 
   def _getRedirect(self):
     def redirect(e, *args):
-      r = self.data.redirect
-      return r.organization(e).urlOf(url_names.GCI_ORG_SCORES)
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf(url_names.GCI_ORG_SCORES)
     return redirect
 
 
diff --git a/app/soc/modules/gci/views/profile.py b/app/soc/modules/gci/views/profile.py
index e8cd164..a90a749 100644
--- a/app/soc/modules/gci/views/profile.py
+++ b/app/soc/modules/gci/views/profile.py
@@ -312,7 +312,7 @@
     if 'delete_account' in self.data.POST:
       self.deleteAccountPostAction()
     else: # regular POST request
-      self.editProfilePostAction() 
+      self.editProfilePostAction()
 
   def deleteAccountPostAction(self):
     """Handler for Delete Account POST action.
@@ -321,19 +321,20 @@
     self.redirect.to('gci_delete_account', secure=True)
 
   def editProfilePostAction(self):
-    """Handler for regular (edit/create profile) POST action.
-    """
+    """Handler for regular (edit/create profile) POST action."""
     if not self.validate():
       self.get()
       return
 
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+
     org_id = self.data.GET.get('new_org')
 
     if org_id:
-      create_url = self.redirect.program().urlOf('create_gci_org_profile')
+      create_url = self.redirect.urlOf('create_gci_org_profile')
       raise RedirectRequest(create_url + '?org_id=' + org_id)
 
-    self.redirect.program()
     self.redirect.to(self._getEditProfileURLName(), validated=True, secure=True)
 
   def _getModulePrefix(self):
diff --git a/app/soc/modules/gci/views/request.py b/app/soc/modules/gci/views/request.py
index e0d3e18..78c6c66 100644
--- a/app/soc/modules/gci/views/request.py
+++ b/app/soc/modules/gci/views/request.py
@@ -244,6 +244,13 @@
     user_key = GCIRequest.user.get_value_for_datastore(
         self.data.request_entity)
 
+    profile_key_name = '/'.join([
+        self.data.program.key().name(), user_key.name()])
+    profile_key = db.Key.from_path(
+        'GCIProfile', profile_key_name, parent=user_key)
+
+    self.data.requester_profile = profile = db.get(profile_key)
+
     if 'accept' in self.data.POST:
       options = db.create_transaction_options(xg=True)
 
@@ -251,14 +258,8 @@
       organization_key = self.data.organization.key()
       messages = self.data.program.getProgramMessages()
 
-      link_id = user_key.name()
-      profile_key_name = '/'.join([self.data.program.key().name(), link_id])
-      profile_key = db.Key.from_path(
-          'GCIProfile', profile_key_name, parent=user_key)
-
       def accept_request_txn():
         request = db.get(request_key)
-        self.data.requester_profile = profile = db.get(profile_key)
 
         request.status = 'accepted'
 
diff --git a/app/soc/modules/gci/views/student_forms.py b/app/soc/modules/gci/views/student_forms.py
index b4a0c4a..5a3ccdf 100644
--- a/app/soc/modules/gci/views/student_forms.py
+++ b/app/soc/modules/gci/views/student_forms.py
@@ -63,8 +63,10 @@
     """
     super(UploadForm, self).__init__(*args, **kwargs)
 
-    base_url = request_data.redirect.program().urlOf(
-        url_names.GCI_STUDENT_FORM_UPLOAD)
+    # TODO(nathaniel): make this .program() call unnecessary.
+    request_data.redirect.program()
+
+    base_url = request_data.redirect.urlOf(url_names.GCI_STUDENT_FORM_UPLOAD)
 
     self['consent_form'].field.widget = gci_forms.AsyncFileInput(
         download_url='%s?%s' % (base_url, url_names.CONSENT_FORM_GET_PARAM),
@@ -78,7 +80,7 @@
             self['consent_form'].field.help_text,
             request_data.program.form_translations_url))
     self['student_id_form'].field.help_text = (
-        DEF_STUDENT_ID_FORM_TEXT_HELP % 
+        DEF_STUDENT_ID_FORM_TEXT_HELP %
             request_data.program.form_translations_url)
 
   def clean(self):
@@ -133,7 +135,10 @@
     return 'v2/modules/gci/student_forms/base.html'
 
   def jsonContext(self):
-    url = self.redirect.program().urlOf('gci_student_form_upload', secure=True)
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+
+    url = self.redirect.urlOf('gci_student_form_upload', secure=True)
     return {
         'upload_link': blobstore.create_upload_url(url),
         }
@@ -208,7 +213,10 @@
 
     form.save()
 
-    self.redirect.program().to('gci_student_form_upload')
+    # TODO(nathaniel): make this .program() call unnecessary.
+    self.redirect.program()
+
+    self.redirect.to('gci_student_form_upload')
 
 
 class StudentFormDownload(GCIRequestHandler):
diff --git a/app/soc/modules/gci/views/task.py b/app/soc/modules/gci/views/task.py
index bd72bbd..f6de11c 100644
--- a/app/soc/modules/gci/views/task.py
+++ b/app/soc/modules/gci/views/task.py
@@ -59,7 +59,7 @@
 DEF_NO_URL = ugettext(
     'An error occurred, please submit a valid URL.')
 
-DEF_NO_WORK_FOUND = ugettext('No submission found with id %i')
+DEF_NO_WORK_FOUND = ugettext('No submission found with id %s')
 
 DEF_NOT_ALLOWED_TO_DELETE = ugettext(
     'You are not allowed to delete this submission')
@@ -405,6 +405,10 @@
         for f in self.data.request.file_uploads.itervalues():
           f.delete()
         return self.redirect.id().to('gci_view_task', extra=['file=0'])
+    else:
+      logging.warning('Neither the URL nor the files were provided for work '
+                      'submission.')
+      return self.redirect.id().to('gci_view_task', extra=['ws_error=1'])
 
 
     task = self.data.task
@@ -535,7 +539,10 @@
     if is_student:
       if not self.data.timeline.tasksClaimEnded():
         if not profile_logic.hasStudentFormsUploaded(profile.student_info):
-          context['student_forms_link'] = self.data.redirect.program().urlOf(
+          # TODO(nathaniel): make this .program() call unnecessary.
+          self.data.redirect.program()
+
+          context['student_forms_link'] = self.data.redirect.urlOf(
               url_names.GCI_STUDENT_FORM_UPLOAD)
         # TODO(lennie): Separate the access check out in to different
         # methods and add a context variable to show separate messages.
@@ -623,6 +630,9 @@
       if self.data.GET.get('file', None) == '0':
         context['work_file_form'].addFileRequiredError()
 
+      if self.data.GET.get('ws_error', None) == '1':
+        context['ws_error'] = True
+
       url = '%s?submit_work' %(
           self.data.redirect.id().urlOf('gci_view_task'))
       context['direct_post_url'] = url
diff --git a/app/soc/modules/gci/views/task_list.py b/app/soc/modules/gci/views/task_list.py
index 77617e0..9afab77 100644
--- a/app/soc/modules/gci/views/task_list.py
+++ b/app/soc/modules/gci/views/task_list.py
@@ -17,7 +17,6 @@
 from soc.logic.exceptions import AccessViolation
 from soc.views.helper import url_patterns
 from soc.views.helper import lists
-from soc.views.helper.access_checker import isSet
 from soc.views.template import Template
 
 from soc.modules.gci.logic import task as task_logic
@@ -25,7 +24,6 @@
 from soc.modules.gci.templates.org_list import BasicOrgList
 from soc.modules.gci.templates.task_list import TaskList
 from soc.modules.gci.views.base import GCIRequestHandler
-from soc.modules.gci.views.forms import GCIModelForm
 #from soc.modules.gci.views.base_templates import ProgramSelect
 from soc.modules.gci.views.helper import url_names
 from soc.modules.gci.views.helper.url_patterns import url
@@ -168,8 +166,10 @@
 
   def _getRedirect(self):
     def redirect(e, *args):
-      r = self.data.redirect
-      return r.organization(e).urlOf(url_names.GCI_ORG_TASKS_ALL)
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return r.urlOf(url_names.GCI_ORG_TASKS_ALL)
     return redirect
 
   def _getDescription(self):
diff --git a/app/soc/modules/gsoc/logic/helper/notifications.py b/app/soc/modules/gsoc/logic/helper/notifications.py
index d040fef..e42562d 100644
--- a/app/soc/modules/gsoc/logic/helper/notifications.py
+++ b/app/soc/modules/gsoc/logic/helper/notifications.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2012 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,15 +12,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Notifications for the GSoC module.
-"""
+"""Notifications for the GSoC module."""
 
 from django.utils.translation import ugettext
 
 from soc.logic.helper.notifications import getContext
 from soc.views.helper.access_checker import isSet
 
-
 DEF_NEW_PROPOSAL_SUBJECT = ugettext(
     '[%(org)s] New proposal by %(proposer_name)s: %(proposal_name)s')
 
@@ -155,8 +151,10 @@
     slot_transfer: entity that holds the slot transfer request information
     update: True if the request was updated, False if the new one was created
   """
+  # TODO(nathaniel): make unnecessary this .program() call.
+  data.redirect.program()
 
-  slot_transfer_admin_url = data.redirect.program().urlOf(
+  slot_transfer_admin_url = data.redirect.urlOf(
       'gsoc_admin_slots_transfer', full=True)
 
   message_properties = {
diff --git a/app/soc/modules/gsoc/views/accept_proposals.py b/app/soc/modules/gsoc/views/accept_proposals.py
index 3f4fd52..fc4dced 100644
--- a/app/soc/modules/gsoc/views/accept_proposals.py
+++ b/app/soc/modules/gsoc/views/accept_proposals.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC accept proposals.
-"""
-
+"""Module containing the views for GSoC accept proposals."""
 
 from google.appengine.api import taskqueue
 
@@ -25,13 +21,12 @@
 from soc.views.helper import url_patterns
 
 from soc.modules.gsoc.logic import accept_proposals as conversion_logic
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
-class AcceptProposalsPage(RequestHandler):
-  """View for the host to trigger proposals to projets conversion.
-  """
+class AcceptProposalsPage(GSoCRequestHandler):
+  """View for the host to trigger proposals to projets conversion."""
 
   def templatePath(self):
     return 'v2/modules/gsoc/accept_proposals/base.html'
diff --git a/app/soc/modules/gsoc/views/accept_withdraw_projects.py b/app/soc/modules/gsoc/views/accept_withdraw_projects.py
index c041933..fc8d1ac 100644
--- a/app/soc/modules/gsoc/views/accept_withdraw_projects.py
+++ b/app/soc/modules/gsoc/views/accept_withdraw_projects.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,7 +35,7 @@
 from soc.modules.gsoc.models.profile import GSoCStudentInfo
 from soc.modules.gsoc.models.project import GSoCProject
 from soc.modules.gsoc.models.proposal import GSoCProposal
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
@@ -218,7 +216,7 @@
     return "v2/modules/gsoc/accept_withdraw_projects/_project_list.html"
 
 
-class AcceptProposals(RequestHandler):
+class AcceptProposals(GSoCRequestHandler):
   """View for accepting individual proposals.
   """
 
@@ -429,7 +427,7 @@
     return "v2/modules/gsoc/accept_withdraw_projects/_project_list.html"
 
 
-class WithdrawProjects(RequestHandler):
+class WithdrawProjects(GSoCRequestHandler):
   """View methods for withdraw projects
   """
 
diff --git a/app/soc/modules/gsoc/views/accepted_orgs.py b/app/soc/modules/gsoc/views/accepted_orgs.py
index 0d9da8e..03bc260 100644
--- a/app/soc/modules/gsoc/views/accepted_orgs.py
+++ b/app/soc/modules/gsoc/views/accepted_orgs.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC accepted orgs.
-"""
-
+"""Module containing the views for GSoC accepted orgs."""
 
 from django.conf.urls.defaults import url as django_url
 
@@ -28,25 +24,30 @@
 from soc.views.helper import url_patterns
 
 from soc.modules.gsoc.models.organization import GSoCOrganization
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
 class AcceptedOrgsList(Template):
-  """Template for list of accepted organizations.
-  """
+  """Template for list of accepted organizations."""
 
   def __init__(self, request, data):
     self.request = request
     self.data = data
-    r = data.redirect
+
+    # TODO(nathaniel): reduce this back to a lambda expression
+    # inside the setRowAction call below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(e)
+
+      return self.data.redirect.urlOf('gsoc_org_home')
 
     list_config = lists.ListConfiguration()
     list_config.addColumn('name', 'Name',
         lambda e, *args: e.name.strip())
     list_config.addSimpleColumn('link_id', 'Link ID', hidden=True)
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf('gsoc_org_home'))
+    list_config.setRowAction(RowAction)
     list_config.addColumn('tags', 'Tags',
                           lambda e, *args: ", ".join(e.tags))
     list_config.addColumn(
@@ -88,7 +89,7 @@
     return "v2/modules/gsoc/accepted_orgs/_project_list.html"
 
 
-class AcceptedOrgsPage(RequestHandler):
+class AcceptedOrgsPage(GSoCRequestHandler):
   """View for the accepted organizations page.
   """
 
diff --git a/app/soc/modules/gsoc/views/admin.py b/app/soc/modules/gsoc/views/admin.py
index 8db1160..0010568 100644
--- a/app/soc/modules/gsoc/views/admin.py
+++ b/app/soc/modules/gsoc/views/admin.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the admin pages.
-"""
-
+"""Module for the admin pages."""
 
 import logging
 
@@ -53,7 +49,7 @@
 from soc.modules.gsoc.models.proposal import GSoCProposal
 from soc.modules.gsoc.models.proposal_duplicates import GSoCProposalDuplicate
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.dashboard import BIRTHDATE_FORMAT
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -111,7 +107,7 @@
     return r.urlOf('gsoc_admin_dashboard')
 
 
-class DashboardPage(RequestHandler):
+class DashboardPage(GSoCRequestHandler):
   """Dashboard for admins.
   """
 
@@ -772,7 +768,7 @@
     }
 
 
-class LookupLinkIdPage(RequestHandler):
+class LookupLinkIdPage(GSoCRequestHandler):
   """View for the participant profile.
   """
 
@@ -837,15 +833,21 @@
     list_config.addColumn('org_admin', 'Org Admins',
         (lambda e, *args: args[0][e.key()]))
 
-    r = self.data.redirect
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf('gsoc_org_home'))
+    # TODO(nathaniel): squeeze this back into a lambda expression
+    # in the call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf('gsoc_org_home')
+
+    list_config.setRowAction(RowAction)
 
     return list_config
 
   def context(self):
     description = 'List of organizations accepted into %s' % (
-            self.data.program.name)
+        self.data.program.name)
 
     list = lists.ListConfigurationResponse(
         self.data, self._list_config, 0, description)
@@ -887,14 +889,18 @@
   """
 
   def extraColumn(self, list_config):
-    use_cbox = False
-    if self.request.GET.get('cbox'):
-      use_cbox = True
+    use_cbox = bool(self.request.GET.get('cbox'))
+
+    # TODO(nathaniel): squeeze this back into a lambda expression in the
+    # call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf('gsoc_proposals_org', cbox=use_cbox)
 
     r = self.data.redirect
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf('gsoc_proposals_org',
-            cbox=use_cbox))
+    list_config.setRowAction(RowAction)
     list_config.addSimpleColumn('slots_desired', 'min', width=20)
     list_config.addSimpleColumn('max_slots_desired', 'max', width=20)
     list_config.addSimpleColumn('slots', 'Slots', width=20)
@@ -914,7 +920,7 @@
     }
 
 
-class ProposalsAcceptedOrgsPage(RequestHandler):
+class ProposalsAcceptedOrgsPage(GSoCRequestHandler):
   """View for accepted orgs.
   """
 
@@ -952,14 +958,18 @@
   """
 
   def extraColumn(self, list_config):
-    use_cbox = False
-    if self.request.GET.get('cbox'):
-      use_cbox = True
+    use_cbox = bool(self.request.GET.get('cbox'))
+
+    # TODO(nathaniel): squeeze this back into a lambda expression in
+    # the call to setRowAction below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=e)
+
+      return self.data.redirect.urlOf('gsoc_projects_org', cbox=use_cbox)
 
     r = self.data.redirect
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf('gsoc_projects_org',
-            cbox=use_cbox))
+    list_config.setRowAction(RowAction)
     list_config.addSimpleColumn('slots_desired', 'min', width=20)
     list_config.addSimpleColumn('max_slots_desired', 'max', width=20)
     list_config.addSimpleColumn('slots', 'Slots', width=20)
@@ -988,7 +998,7 @@
     }
 
 
-class ProjectsAcceptedOrgsPage(RequestHandler):
+class ProjectsAcceptedOrgsPage(GSoCRequestHandler):
   """View for accepted orgs.
   """
 
@@ -1031,7 +1041,6 @@
     self.request = request
     self.data = data
 
-    r = data.redirect
     list_config = lists.ListConfiguration(add_key_column=False)
     list_config.addColumn('key', 'Key', (lambda ent, *args: "%s/%s" % (
         ent.parent().key().name(), ent.key().id())), hidden=True)
@@ -1149,7 +1158,7 @@
     return response_builder.build(accepted, duplicates)
 
 
-class ProposalsPage(RequestHandler):
+class ProposalsPage(GSoCRequestHandler):
   """View for proposals for particular org.
   """
 
@@ -1251,7 +1260,7 @@
     return "v2/modules/gsoc/admin/_projects_list.html"
 
 
-class ProjectsPage(RequestHandler):
+class ProjectsPage(GSoCRequestHandler):
   """View for projects of particular org.
   """
 
@@ -1402,7 +1411,7 @@
     return response_builder.build()
 
 
-class SlotsPage(RequestHandler):
+class SlotsPage(GSoCRequestHandler):
   """View for the participant profile.
   """
 
@@ -1441,7 +1450,7 @@
     }
 
 
-class SurveyReminderPage(RequestHandler):
+class SurveyReminderPage(GSoCRequestHandler):
   """Page to send out reminder emails to fill out a Survey.
   """
 
@@ -1623,7 +1632,7 @@
     }
 
 
-class StudentsListPage(RequestHandler):
+class StudentsListPage(GSoCRequestHandler):
   """View that lists all the students associated with the program.
   """
 
@@ -1655,7 +1664,7 @@
     }
 
 
-class ProjectsListPage(RequestHandler):
+class ProjectsListPage(GSoCRequestHandler):
   """View that lists all the projects associated with the program.
   """
 
@@ -1692,7 +1701,7 @@
     }
 
 
-class OrgsListPage(RequestHandler):
+class OrgsListPage(GSoCRequestHandler):
   """View that lists all the projects associated with the program.
   """
 
diff --git a/app/soc/modules/gsoc/views/base.py b/app/soc/modules/gsoc/views/base.py
index c509dc2..02da11d 100644
--- a/app/soc/modules/gsoc/views/base.py
+++ b/app/soc/modules/gsoc/views/base.py
@@ -18,15 +18,14 @@
 
 from django import http
 
-from soc.views.base import RequestHandler
+from soc.views import base
 
 from soc.modules.gsoc.views import base_templates
 from soc.modules.gsoc.views.helper import access_checker
-from soc.modules.gsoc.views.helper.request_data import RequestData
-from soc.modules.gsoc.views.helper.request_data import RedirectHelper
+from soc.modules.gsoc.views.helper import request_data
 
 
-class RequestHandler(RequestHandler):
+class GSoCRequestHandler(base.RequestHandler):
   """Customization required by GSoC to handle HTTP requests."""
 
   def render(self, template_path, context):
@@ -55,11 +54,11 @@
     context['header'] = base_templates.Header(self.data)
     context['mainmenu'] = base_templates.MainMenu(self.data)
     context['footer'] = base_templates.Footer(self.data)
-    return super(RequestHandler, self).render(template_path, context)
+    return super(GSoCRequestHandler, self).render(template_path, context)
 
   def init(self, request, args, kwargs):
-    self.data = RequestData()
-    self.redirect = RedirectHelper(self.data, self.response)
+    self.data = request_data.RequestData()
+    self.redirect = request_data.RedirectHelper(self.data, self.response)
     self.data.populate(self.redirect, request, args, kwargs)
     if self.data.is_developer:
       self.mutator = access_checker.DeveloperMutator(self.data)
@@ -67,12 +66,12 @@
     else:
       self.mutator = access_checker.Mutator(self.data)
       self.check = access_checker.AccessChecker(self.data)
-    super(RequestHandler, self).init(request, args, kwargs)
+    super(GSoCRequestHandler, self).init(request, args, kwargs)
 
   def error(self, status, message=None):
     """See base.RequestHandler.error for specification."""
     if not self.data.program:
-      return super(RequestHandler, self).error(status, message)
+      return super(GSoCRequestHandler, self).error(status, message)
 
     # If message is not set, set it to the default associated with the
     # given status (such as "Method Not Allowed" or "Service Unavailable").
diff --git a/app/soc/modules/gsoc/views/dashboard.py b/app/soc/modules/gsoc/views/dashboard.py
index 9d691bc..9bb29a9 100644
--- a/app/soc/modules/gsoc/views/dashboard.py
+++ b/app/soc/modules/gsoc/views/dashboard.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC participant dashboard.
-"""
-
+"""Module for the GSoC participant dashboard."""
 
 import logging
 
@@ -57,7 +53,7 @@
 from soc.modules.gsoc.models.proposal_duplicates import GSoCProposalDuplicate
 from soc.modules.gsoc.models.request import GSoCRequest
 from soc.modules.gsoc.models.score import GSoCScore
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -134,7 +130,7 @@
     }
 
 
-class DashboardPage(RequestHandler):
+class DashboardPage(GSoCRequestHandler):
   """View for the participant dashboard.
   """
 
@@ -1136,12 +1132,17 @@
   """
 
   def __init__(self, request, data):
-    """Initializes this component.
-    """
-    r = data.redirect
+    """Initializes this component."""
+    # TODO(nathaniel): put this back into a lambda expression in the
+    # setRowAction call below.
+    def RowAction(e, *args):
+      # TODO(nathaniel): make this .organization call unnecessary.
+      data.redirect.organization(organization=e)
+
+      return data.redirect.urlOf('gsoc_org_home')
+
     list_config = lists.ListConfiguration()
-    list_config.setRowAction(
-        lambda e, *args: r.organization(e).urlOf('gsoc_org_home'))
+    list_config.setRowAction(RowAction)
 
     if not data.program.allocations_visible:
       list_config.addSimpleColumn('name', 'name')
@@ -1398,12 +1399,14 @@
     def rowAction(d, *args):
       key = d['key']
       if key == 'tax_form':
-        return data.redirect.program().urlOf('gsoc_tax_form', secure=True)
+        data.redirect.program()
+        return data.redirect.urlOf('gsoc_tax_form', secure=True)
       if key == 'enrollment_form':
-        return data.redirect.program().urlOf('gsoc_enrollment_form',
-                                             secure=True)
+        data.redirect.program()
+        return data.redirect.urlOf('gsoc_enrollment_form', secure=True)
       if key == 'school_name':
-        url = data.redirect.program().urlOf('edit_gsoc_profile', secure=True)
+        data.redirect.program()
+        url = data.redirect.urlOf('edit_gsoc_profile', secure=True)
         return url + '#form_row_school_name'
       if key.isdigit():
         project_id = int(key)
diff --git a/app/soc/modules/gsoc/views/document.py b/app/soc/modules/gsoc/views/document.py
index 99be5b7..7fc2568 100644
--- a/app/soc/modules/gsoc/views/document.py
+++ b/app/soc/modules/gsoc/views/document.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC documents page.
-"""
-
+"""Module containing the views for GSoC documents page."""
 
 from django.conf.urls.defaults import url as django_url
 
@@ -28,7 +24,7 @@
 from soc.views.helper import url_patterns
 from soc.views.helper.access_checker import isSet
 
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.forms import GSoCModelForm
 from soc.modules.gsoc.views.helper.url_patterns import url
 from soc.modules.gsoc.views.helper import url_patterns as gsoc_url_patterns
@@ -46,7 +42,7 @@
     ]
 
 
-class EditDocumentPage(RequestHandler):
+class EditDocumentPage(GSoCRequestHandler):
   """Encapsulate all the methods required to edit documents.
   """
 
@@ -93,7 +89,7 @@
       self.get()
 
 
-class DocumentPage(RequestHandler):
+class DocumentPage(GSoCRequestHandler):
   """Encapsulate all the methods required to show documents.
   """
 
@@ -127,7 +123,7 @@
     }
 
 
-class EventsPage(RequestHandler):
+class EventsPage(GSoCRequestHandler):
   """Encapsulates all the methods required to show the events page.
   """
 
@@ -163,7 +159,7 @@
     return 'v2/modules/gsoc/document/_document_list.html'
 
 
-class DocumentListPage(RequestHandler):
+class DocumentListPage(GSoCRequestHandler):
   """View for the list documents page.
   """
 
diff --git a/app/soc/modules/gsoc/views/duplicates.py b/app/soc/modules/gsoc/views/duplicates.py
index 9a2b292..0b95fd4 100644
--- a/app/soc/modules/gsoc/views/duplicates.py
+++ b/app/soc/modules/gsoc/views/duplicates.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC proposal duplicates.
-"""
-
+"""Module containing the views for GSoC proposal duplicates."""
 
 from google.appengine.api import taskqueue
 from google.appengine.ext import db
@@ -29,13 +25,12 @@
 from soc.modules.gsoc.logic import duplicates as duplicates_logic
 from soc.modules.gsoc.models.proposal_duplicates import GSoCProposalDuplicate
 from soc.modules.gsoc.models.profile import GSoCProfile
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
-class DuplicatesPage(RequestHandler):
-  """View for the host to see duplicates.
-  """
+class DuplicatesPage(GSoCRequestHandler):
+  """View for the host to see duplicates."""
 
   def templatePath(self):
     return 'v2/modules/gsoc/duplicates/base.html'
@@ -110,19 +105,19 @@
     super(Duplicate, self).__init__(data)
 
   def context(self):
-    """Returns the context for the current template.
-    """
-    r = self.data.redirect
-
+    """Returns the context for the current template."""
     context = {'duplicate': self.duplicate}
     orgs = db.get(self.duplicate.orgs)
     proposals = db.get(self.duplicate.duplicates)
 
     orgs_details = {}
     for org in orgs:
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=org)
+
       orgs_details[org.key().id_or_name()] = {
           'name': org.name,
-          'link': r.organization(org).urlOf('gsoc_org_home')
+          'link': self.data.redirect.urlOf('gsoc_org_home')
           }
       q = GSoCProfile.all()
       q.filter('org_admin_for', org)
@@ -142,9 +137,9 @@
           orgs_details[org.key().id_or_name()]['proposals'].append({
               'key': proposal.key().id_or_name(),
               'title': proposal.title,
-              'link': r.review(proposal.key().id_or_name(),
-                               proposal.parent().link_id).urlOf(
-                                   'review_gsoc_proposal')
+              'link': self.data.redirect.review(
+                  proposal.key().id_or_name(),
+                  proposal.parent().link_id).urlOf('review_gsoc_proposal'),
               })
 
     context['orgs'] = orgs_details
@@ -152,6 +147,5 @@
     return context
 
   def templatePath(self):
-    """Returns the path to the template that should be used in render().
-    """
+    """Returns the path to the template that should be used in render()."""
     return 'v2/modules/gsoc/duplicates/proposal_duplicate.html'
diff --git a/app/soc/modules/gsoc/views/grading_record_details.py b/app/soc/modules/gsoc/views/grading_record_details.py
index 870f717..e9bc0d5 100644
--- a/app/soc/modules/gsoc/views/grading_record_details.py
+++ b/app/soc/modules/gsoc/views/grading_record_details.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for displaying GradingSurveyGroups and records.
-"""
-
+"""Module for displaying GradingSurveyGroups and records."""
 
 import collections
 
@@ -32,12 +28,12 @@
 from soc.modules.gsoc.logic import grading_record
 from soc.modules.gsoc.models.grading_record import GSoCGradingRecord
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper import url_patterns as gsoc_url_patterns
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
-class GradingRecordsOverview(RequestHandler):
+class GradingRecordsOverview(GSoCRequestHandler):
   """View to display all GradingRecords for a single group.
   """
 
@@ -232,7 +228,7 @@
     widgets = forms.choiceWidgets(GSoCGradingRecord, ['grade_decision'])
 
 
-class GradingRecordDetails(RequestHandler):
+class GradingRecordDetails(GSoCRequestHandler):
   """View to display GradingRecord details.
   """
 
diff --git a/app/soc/modules/gsoc/views/helper/access_checker.py b/app/soc/modules/gsoc/views/helper/access_checker.py
index 0969ae2..a36685b 100644
--- a/app/soc/modules/gsoc/views/helper/access_checker.py
+++ b/app/soc/modules/gsoc/views/helper/access_checker.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,7 +16,6 @@
 for checking access.
 """
 
-
 from google.appengine.ext import db
 
 from django.utils.translation import ugettext
@@ -440,8 +437,10 @@
     gsoc_org = q.get()
 
     if gsoc_org:
-      edit_url = self.data.redirect.organization(gsoc_org).urlOf(
-          'edit_gsoc_org_profile')
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=gsoc_org)
+
+      edit_url = self.data.redirect.urlOf('edit_gsoc_org_profile')
 
       raise AccessViolation(DEF_ORG_EXISTS % (org_id, edit_url))
 
diff --git a/app/soc/modules/gsoc/views/homepage.py b/app/soc/modules/gsoc/views/homepage.py
index 10533c3..c6f7eb8 100644
--- a/app/soc/modules/gsoc/views/homepage.py
+++ b/app/soc/modules/gsoc/views/homepage.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC home page.
-"""
-
+"""Module containing the views for GSoC home page."""
 
 from django.conf.urls.defaults import url as django_url
 
@@ -26,7 +22,7 @@
 
 from soc.modules.gsoc.logic import organization as org_logic
 from soc.modules.gsoc.logic import project as project_logic
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.helper.url_patterns import url
 
@@ -73,8 +69,7 @@
 
 
 class Apply(Template):
-  """Apply template.
-  """
+  """Apply template."""
 
   def __init__(self, data):
     self.data = data
@@ -82,11 +77,12 @@
   def context(self):
     context = {}
     accepted_orgs = None
-    r = self.data.redirect.program()
+    redirector = self.data.redirect
+    redirector.program()
 
     if self.data.timeline.orgsAnnounced():
       # accepted orgs block
-      accepted_orgs = r.urlOf('gsoc_accepted_orgs')
+      accepted_orgs = redirector.urlOf('gsoc_accepted_orgs')
       nr_orgs = self.data.program.nr_accepted_orgs
       context['nr_accepted_orgs'] = nr_orgs if nr_orgs else ""
       context['accepted_orgs_link'] = accepted_orgs
@@ -94,13 +90,13 @@
       current_orgs = org_logic.participating(self.data.program)
       for org in current_orgs:
         participating_orgs.append({
-            'link': r.orgHomepage(org.link_id).url(),
+            'link': redirector.orgHomepage(org.link_id).url(),
             'logo': org.logo_url,
             'name': org.short_name,
             })
       context['participating_orgs'] = participating_orgs
 
-    context['org_signup'] = self.data.timeline.orgSignup()  
+    context['org_signup'] = self.data.timeline.orgSignup()
     context['student_signup'] = self.data.timeline.studentSignup()
     context['mentor_signup'] = self.data.timeline.mentorSignup()
 
@@ -112,23 +108,25 @@
 
     # signup block
     if signup and not self.data.gae_user:
-      context['login_link'] = r.login().url()
+      context['login_link'] = redirector.login().url()
     if signup and not self.data.profile:
       if self.data.timeline.orgSignup():
-        r.createProfile('org_admin')
+        redirector.createProfile('org_admin')
       elif self.data.timeline.studentSignup():
-        r.createProfile('mentor')
-        context['mentor_profile_link'] = r.urlOf('create_gsoc_profile',
-                                                 secure=True)
-        r.createProfile('student')
+        redirector.createProfile('mentor')
+        context['mentor_profile_link'] = redirector.urlOf(
+            'create_gsoc_profile', secure=True)
+        redirector.createProfile('student')
       elif self.data.timeline.mentorSignup():
-        r.createProfile('mentor')
+        redirector.createProfile('mentor')
 
-      context['profile_link'] = r.urlOf('create_gsoc_profile', secure=True)
+      context['profile_link'] = redirector.urlOf(
+          'create_gsoc_profile', secure=True)
 
     if self.data.timeline.orgSignup() and self.data.profile:
-      context['org_apply_link'] = r.orgAppTake().urlOf('gsoc_take_org_app')
-      context['dashboard_link'] = r.dashboard().url()
+      context['org_apply_link'] = redirector.orgAppTake().urlOf(
+          'gsoc_take_org_app')
+      context['dashboard_link'] = redirector.dashboard().url()
 
     if ((self.data.timeline.studentSignup() or
         self.data.timeline.mentorSignup()) and self.data.profile):
@@ -194,7 +192,7 @@
     return "v2/modules/gsoc/_connect_with_us.html"
 
 
-class Homepage(RequestHandler):
+class Homepage(GSoCRequestHandler):
   """Encapsulate all the methods required to generate GSoC Home page.
   """
 
diff --git a/app/soc/modules/gsoc/views/invite.py b/app/soc/modules/gsoc/views/invite.py
index 39ce1ab..6d3267d 100644
--- a/app/soc/modules/gsoc/views/invite.py
+++ b/app/soc/modules/gsoc/views/invite.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the view for GSoC invitation page.
-"""
-
+"""Module containing the view for GSoC invitation page."""
 
 from google.appengine.ext import db
 from google.appengine.api import users
@@ -34,7 +30,7 @@
 
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.request import GSoCRequest
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 from soc.modules.gsoc.views import forms as gsoc_forms
 
@@ -69,7 +65,7 @@
     field.help_text = ugettext(
         'The link_id or email address of the invitee, '
         ' separate multiple values with a comma')
-    
+
   def clean_link_id(self):
     """Accepts link_id of users which may be invited.
     """
@@ -155,7 +151,7 @@
       raise djangoforms.ValidationError('That user already has this role.')
 
 
-class InvitePage(RequestHandler):
+class InvitePage(GSoCRequestHandler):
   """Encapsulate all the methods required to generate Invite page.
   """
 
@@ -201,7 +197,7 @@
     assert isSet(self.data.organization)
 
     invite_form = InviteForm(self.data, self.data.POST)
-    
+
     if not invite_form.is_valid():
       return None
 
@@ -239,7 +235,7 @@
       self.get()
 
 
-class ShowInvite(RequestHandler):
+class ShowInvite(GSoCRequestHandler):
   """Encapsulate all the methods required to generate Show Invite page.
   """
 
diff --git a/app/soc/modules/gsoc/views/mentor_evaluation.py b/app/soc/modules/gsoc/views/mentor_evaluation.py
index 7c39459..b019e93 100644
--- a/app/soc/modules/gsoc/views/mentor_evaluation.py
+++ b/app/soc/modules/gsoc/views/mentor_evaluation.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC project evaluations.
-"""
-
+"""Module for the GSoC project evaluations."""
 
 from django.utils.translation import ugettext
 
@@ -32,7 +28,7 @@
 from soc.modules.gsoc.models.grading_project_survey_record import \
     GSoCGradingProjectSurveyRecord
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.helper import url_patterns
 
@@ -89,7 +85,7 @@
     return True if grade == 'True' else False
 
 
-class GSoCMentorEvaluationEditPage(RequestHandler):
+class GSoCMentorEvaluationEditPage(GSoCRequestHandler):
   """View for creating/editing organization evaluation form.
   """
 
@@ -168,7 +164,7 @@
       self.get()
 
 
-class GSoCMentorEvaluationTakePage(RequestHandler):
+class GSoCMentorEvaluationTakePage(GSoCRequestHandler):
   """View for the organization to submit student evaluation.
   """
 
@@ -255,7 +251,7 @@
       self.get()
 
 
-class GSoCMentorEvaluationPreviewPage(RequestHandler):
+class GSoCMentorEvaluationPreviewPage(GSoCRequestHandler):
   """View for the host preview mentor evaluation.
   """
 
@@ -289,7 +285,7 @@
     return context
 
 
-class GSoCMentorEvaluationRecordsList(RequestHandler):
+class GSoCMentorEvaluationRecordsList(GSoCRequestHandler):
   """View for listing all records of a GSoCGradingProjectSurveyRecord.
   """
 
@@ -358,7 +354,7 @@
     survey_name = 'Mentor Evaluation'
 
 
-class GSoCMentorEvaluationShowPage(RequestHandler):
+class GSoCMentorEvaluationShowPage(GSoCRequestHandler):
   """View to display the readonly page for mentor evaluation.
   """
 
diff --git a/app/soc/modules/gsoc/views/org_app.py b/app/soc/modules/gsoc/views/org_app.py
index 2508f6e..463ae05 100644
--- a/app/soc/modules/gsoc/views/org_app.py
+++ b/app/soc/modules/gsoc/views/org_app.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC Organization Application.
-"""
-
+"""Module containing the views for GSoC Organization Application."""
 
 import logging
 
@@ -32,7 +28,7 @@
 
 from soc.logic import org_app as org_app_logic
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
 
@@ -71,7 +67,7 @@
     return 'v2/modules/gsoc/_form.html'
 
 
-class GSoCOrgAppEditPage(RequestHandler):
+class GSoCOrgAppEditPage(GSoCRequestHandler):
   """View for creating/editing organization application.
   """
 
@@ -100,9 +96,12 @@
     else:
       page_name = 'Create new organization application'
 
+    # TODO(nathaniel): is this really necessary?
+    self.redirect.program()
+
     context = {
         'page_name': page_name,
-        'post_url': self.redirect.program().urlOf('gsoc_edit_org_app'),
+        'post_url': self.redirect.urlOf('gsoc_edit_org_app'),
         'forms': [form],
         'error': bool(form.errors),
         }
@@ -139,13 +138,14 @@
   def post(self):
     org_app = self.orgAppFromForm()
     if org_app:
-      r = self.redirect.program()
-      r.to('gsoc_edit_org_app', validated=True)
+      # TODO(nathaniel): is this necessary?
+      self.redirect.program()
+      self.redirect.to('gsoc_edit_org_app', validated=True)
     else:
       self.get()
 
 
-class GSoCOrgAppPreviewPage(RequestHandler):
+class GSoCOrgAppPreviewPage(GSoCRequestHandler):
   """View for organizations to submit their application.
   """
 
@@ -177,7 +177,7 @@
     return context
 
 
-class GSoCOrgAppTakePage(RequestHandler):
+class GSoCOrgAppTakePage(GSoCRequestHandler):
   """View for organizations to submit their application.
   """
 
@@ -265,12 +265,12 @@
       self.get()
 
 
-class GSoCOrgAppRecordsList(org_app.OrgAppRecordsList, RequestHandler):
+class GSoCOrgAppRecordsList(org_app.OrgAppRecordsList, GSoCRequestHandler):
   """View for listing all records of a GSoC Organization application.
   """
 
   def __init__(self, *args, **kwargs):
-    RequestHandler.__init__(self, *args, **kwargs)
+    GSoCRequestHandler.__init__(self, *args, **kwargs)
     org_app.OrgAppRecordsList.__init__(self, 'gsoc_show_org_app')
 
   def djangoURLPatterns(self):
@@ -332,7 +332,7 @@
   template_path = 'v2/modules/gsoc/org_app/readonly_template.html'
 
 
-class GSoCOrgAppShowPage(RequestHandler):
+class GSoCOrgAppShowPage(GSoCRequestHandler):
   """View to display the readonly page for organization application.
   """
 
@@ -363,9 +363,9 @@
 
     if record:
       context['record'] = OrgAppReadOnlyTemplate(record)
-      
+
       # admin info should be available only to the hosts
-      if self.data.is_host: 
+      if self.data.is_host:
         context['main_admin_url'] = self.data.redirect.profile(
             record.main_admin.link_id).urlOf(url_names.GSOC_PROFILE_SHOW)
         context['backup_admin_url'] = self.data.redirect.profile(
@@ -376,7 +376,8 @@
         context['update_link'] = self.data.redirect.id().urlOf(
             'gsoc_retake_org_app')
       else:
-        context['create_link'] = self.data.redirect.program().urlOf(
-            'gsoc_take_org_app')
+        # TODO(nathaniel): is this program() necessary?
+        self.data.redirect.program()
+        context['create_link'] = self.data.redirect.urlOf('gsoc_take_org_app')
 
     return context
diff --git a/app/soc/modules/gsoc/views/org_home.py b/app/soc/modules/gsoc/views/org_home.py
index 7fc81f1..23d69d8 100644
--- a/app/soc/modules/gsoc/views/org_home.py
+++ b/app/soc/modules/gsoc/views/org_home.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for GSoC Homepage.
-"""
-
+"""Module containing the views for GSoC Homepage."""
 
 from django.conf.urls.defaults import url as django_url
 from django.utils.translation import ugettext
@@ -36,7 +32,7 @@
 from soc.modules.gsoc.models.organization import GSoCOrganization
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.project import GSoCProject
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
 
@@ -51,7 +47,6 @@
 
   def context(self):
     organization = self.data.organization
-    r = self.data.redirect
 
     context = {
         'request_data': self.data,
@@ -67,21 +62,24 @@
 
       if self.data.timeline.studentSignup():
         context['student_apply_block'] = True
-        profile_link = r.createProfile('student').urlOf('create_gsoc_profile',
-                                                        secure=True)
+        profile_link = self.data.redirect.createProfile('student').urlOf(
+            'create_gsoc_profile', secure=True)
         context['student_profile_link'] = profile_link + suffix
       else:
         context['mentor_apply_block'] = True
 
-      profile_link = r.createProfile('mentor').urlOf('create_gsoc_profile',
-                                                     secure=True)
+      profile_link = self.data.redirect.createProfile('mentor').urlOf(
+          'create_gsoc_profile', secure=True)
       context['mentor_profile_link'] = profile_link + suffix
       return context
 
     if self.data.student_info:
       if self.data.timeline.studentSignup():
         context['student_apply_block'] = True
-        submit_proposal_link = r.organization().urlOf('submit_gsoc_proposal')
+        # TODO(nathaniel): make this .organization() call unnecessary.
+        self.data.redirect.organization()
+
+        submit_proposal_link = self.data.redirect.urlOf('submit_gsoc_proposal')
         context['submit_proposal_link'] = submit_proposal_link
 
       return context
@@ -110,7 +108,10 @@
       context['invited_role'] = 'an administrator'
       return context
 
-    request_mentor_link = r.organization().urlOf('gsoc_request')
+    # TODO(nathaniel): make this .organization() call unnecessary.
+    self.data.redirect.organization()
+
+    request_mentor_link = self.data.redirect.urlOf('gsoc_request')
     context['mentor_request_link'] = request_mentor_link
     return context
 
@@ -199,7 +200,7 @@
     return "v2/modules/gsoc/org_home/_project_list.html"
 
 
-class GSoCBanOrgPost(BanOrgPost, RequestHandler):
+class GSoCBanOrgPost(BanOrgPost, GSoCRequestHandler):
   """Handles banning/unbanning of GSoC organizations.
   """
 
@@ -219,7 +220,7 @@
 class GSoCHostActions(HostActions):
   """Template to render the left side host actions.
   """
-  
+
   DEF_BAN_ORGANIZATION_HELP = ugettext(
       'When an organization is banned, it is not active in the program')
 
@@ -230,7 +231,7 @@
     return self.DEF_BAN_ORGANIZATION_HELP
 
 
-class OrgHome(RequestHandler):
+class OrgHome(GSoCRequestHandler):
   """View methods for Organization Home page.
   """
 
@@ -290,15 +291,21 @@
       context['ideas_link_trimmed'] = url_helper.trim_url_to(ideas, 50)
 
     if self.data.orgAdminFor(organization):
-      r = self.redirect
-      r.organization(organization)
-      context['edit_link'] =  r.urlOf('edit_gsoc_org_profile')
-      context['invite_admin_link'] = r.invite('org_admin').urlOf('gsoc_invite')
-      context['invite_mentor_link'] = r.invite('mentor').urlOf('gsoc_invite')
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.redirect.organization(organization=organization)
+
+      context['edit_link'] =  self.redirect.urlOf('edit_gsoc_org_profile')
+      context['invite_admin_link'] = self.redirect.invite('org_admin').urlOf(
+          'gsoc_invite')
+      context['invite_mentor_link'] = self.redirect.invite('mentor').urlOf(
+          'gsoc_invite')
 
       if (self.data.program.allocations_visible and
           self.data.timeline.beforeStudentsAnnounced()):
-        context['slot_transfer_link'] = r.organization(organization).urlOf(
+        # TODO(nathaniel): make this .organization call unnecessary.
+        self.redirect.organization(organization=organization)
+
+        context['slot_transfer_link'] = self.redirect.urlOf(
             'gsoc_slot_transfer')
 
     if self.data.timeline.studentsAnnounced():
@@ -312,13 +319,12 @@
     return context
 
   def getCurrentTimeline(self, timeline, org_app):
-    """Return where we are currently on the timeline.
-    """
+    """Return where we are currently on the timeline."""
     if timeline_helper.isActivePeriod(org_app, 'survey'):
       return 'org_signup_period'
     elif timeline_helper.isActivePeriod(timeline, 'student_signup'):
       return 'student_signup_period'
     elif timeline_helper.isActivePeriod(timeline, 'program'):
       return 'program_period'
-
-    return 'offseason'
+    else:
+      return 'offseason'
diff --git a/app/soc/modules/gsoc/views/org_profile.py b/app/soc/modules/gsoc/views/org_profile.py
index d84822e..33584ef 100644
--- a/app/soc/modules/gsoc/views/org_profile.py
+++ b/app/soc/modules/gsoc/views/org_profile.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC organization profile page.
-"""
-
+"""Module for the GSoC organization profile page."""
 
 from soc.views import forms
 
@@ -27,7 +23,7 @@
 from soc.views import org_profile
 
 from soc.modules.gsoc.models.organization import GSoCOrganization
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views import forms as gsoc_forms
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -143,7 +139,7 @@
         ['contact_country', 'shipping_country'])
 
 
-class OrgProfilePage(RequestHandler):
+class OrgProfilePage(GSoCRequestHandler):
   """View for the Organization Profile page.
   """
 
@@ -191,18 +187,21 @@
         }
 
     if self.data.organization:
-      r = self.data.redirect.organization()
-      context['org_home_page_link'] = r.urlOf('gsoc_org_home')
+      # TODO(nathaniel): make this .organization() unnecessary.
+      self.data.redirect.organization()
+
+      context['org_home_page_link'] = self.data.redirect.urlOf('gsoc_org_home')
       if (self.data.program.allocations_visible and
             self.data.timeline.beforeStudentsAnnounced()):
-        context['slot_transfer_page_link'] = r.urlOf('gsoc_slot_transfer')
+        context['slot_transfer_page_link'] = self.data.redirect.urlOf(
+            'gsoc_slot_transfer')
 
     return context
 
   def post(self):
     org_profile = self.createOrgProfileFromForm()
     if org_profile:
-      self.redirect.organization(org_profile)
+      self.redirect.organization(organization=org_profile)
       self.redirect.to('edit_gsoc_org_profile', validated=True)
     else:
       self.get()
diff --git a/app/soc/modules/gsoc/views/profile.py b/app/soc/modules/gsoc/views/profile.py
index a13d67b..9f33d44 100644
--- a/app/soc/modules/gsoc/views/profile.py
+++ b/app/soc/modules/gsoc/views/profile.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC profile page.
-"""
-
+"""Module for the GSoC profile page."""
 
 from django.forms import fields
 from django.core.urlresolvers import reverse
@@ -35,7 +31,7 @@
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.profile import GSoCStudentInfo
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 
 
@@ -195,9 +191,8 @@
   clean_school_home_page =  cleaning.clean_url('school_home_page')
 
 
-class GSoCProfilePage(profile.ProfilePage, RequestHandler):
-  """View for the GSoC participant profile.
-  """
+class GSoCProfilePage(profile.ProfilePage, GSoCRequestHandler):
+  """View for the GSoC participant profile."""
 
   def checkAccess(self):
     self.check.isLoggedIn()
diff --git a/app/soc/modules/gsoc/views/profile_show.py b/app/soc/modules/gsoc/views/profile_show.py
index aab7629..73522c7 100644
--- a/app/soc/modules/gsoc/views/profile_show.py
+++ b/app/soc/modules/gsoc/views/profile_show.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for displaying the GSoC profile read only page.
-"""
-
+"""Module for displaying the GSoC profile read only page."""
 
 from django.utils.translation import ugettext
 
@@ -29,7 +25,7 @@
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.project import GSoCProject
 from soc.modules.gsoc.views import readonly_template
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -54,7 +50,7 @@
 class GSoCHostActions(profile_show.HostActions):
   """Template to render the left side host actions.
   """
-  
+
   DEF_BAN_PROFILE_HELP = ugettext(
       'When a profile is banned, the user cannot participate in the program')
 
@@ -65,7 +61,7 @@
     return self.DEF_BAN_PROFILE_HELP
 
 
-class GSoCBanProfilePost(profile_show.BanProfilePost, RequestHandler):
+class GSoCBanProfilePost(profile_show.BanProfilePost, GSoCRequestHandler):
   """Handles banning/unbanning of GSoC profiles.
   """
 
@@ -82,7 +78,7 @@
     return GSoCProfile
 
 
-class GSoCProfileShowPage(profile_show.ProfileShowPage, RequestHandler):
+class GSoCProfileShowPage(profile_show.ProfileShowPage, GSoCRequestHandler):
   """View to display the read-only profile page.
   """
 
@@ -99,7 +95,7 @@
     return GSoCProfileReadOnlyTemplate(profile)
 
 
-class GSoCProfileAdminPage(RequestHandler):
+class GSoCProfileAdminPage(GSoCRequestHandler):
   """View to display the readonly profile page.
   """
 
diff --git a/app/soc/modules/gsoc/views/program.py b/app/soc/modules/gsoc/views/program.py
index 83b72a8..520b599 100644
--- a/app/soc/modules/gsoc/views/program.py
+++ b/app/soc/modules/gsoc/views/program.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,37 +12,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the program settings pages.
-"""
+"""Module for the program settings pages."""
 
+from soc.models import document
 
-from soc.models.document import Document
+from soc.views import program as soc_program_view
+from soc.views.helper import url_patterns as soc_url_patterns
 
-from soc.views import program as program_view
-from soc.views.helper import url_patterns
-
-from soc.modules.gsoc.models.program import GSoCProgram
-from soc.modules.gsoc.models.program import GSoCProgramMessages
-from soc.modules.gsoc.models.timeline import GSoCTimeline
-from soc.modules.gsoc.views.base import RequestHandler
-from soc.modules.gsoc.views.forms import GSoCModelForm
+from soc.modules.gsoc.models import program
+from soc.modules.gsoc.models import timeline
+from soc.modules.gsoc.views import base
+from soc.modules.gsoc.views import forms
 from soc.modules.gsoc.views.helper import url_names
-from soc.modules.gsoc.views.helper.url_patterns import url
+from soc.modules.gsoc.views.helper import url_patterns
 
 
-class TimelineForm(GSoCModelForm):
-  """Django form to edit timeline settings.
-  """
+class TimelineForm(forms.GSoCModelForm):
+  """Django form to edit timeline settings."""
 
   class Meta:
     css_prefix = 'timeline_form'
-    model = GSoCTimeline
+    model = timeline.GSoCTimeline
     exclude = ['link_id', 'scope', 'scope_path']
 
 
-class ProgramForm(GSoCModelForm):
-  """Django form for the program settings.
-  """
+class ProgramForm(forms.GSoCModelForm):
+  """Django form for the program settings."""
 
   def __init__(self, request_data, *args, **kwargs):
     self.request_data = request_data
@@ -52,38 +45,36 @@
 
   class Meta:
     css_prefix = 'program_form'
-    model = GSoCProgram
+    model = program.GSoCProgram
     exclude = ['link_id', 'scope', 'scope_path', 'timeline',
                'home', 'slots_allocation', 'student_max_age',
                'min_slots']
 
 
-class GSoCProgramMessagesForm(GSoCModelForm):
-  """Django form for the program settings.
-  """
+class GSoCProgramMessagesForm(forms.GSoCModelForm):
+  """Django form for the program settings."""
 
   def __init__(self, request_data, *args, **kwargs):
     self.request_data = request_data
-    super(GSoCProgramMessagesForm, self).__init__(*args, **kwargs)
+    super(program.GSoCProgramMessagesForm, self).__init__(*args, **kwargs)
 
   class Meta:
     css_prefix = 'program_messages_form'
-    model = GSoCProgramMessages
+    model = program.GSoCProgramMessages
 
 
-class ProgramPage(RequestHandler):
-  """View for the program profile.
-  """
+class ProgramPage(base.GSoCRequestHandler):
+  """View for the program profile."""
 
   def djangoURLPatterns(self):
     return [
-        url(r'program/%s$' % url_patterns.PROGRAM, self,
+        url_patterns.url(r'program/%s$' % soc_url_patterns.PROGRAM, self,
             name='edit_gsoc_program'),
-        url(r'program/edit/%s$' % url_patterns.PROGRAM, self),
+        url_patterns.url(r'program/edit/%s$' % soc_url_patterns.PROGRAM, self),
     ]
 
   def jsonContext(self):
-    q = Document.all()
+    q = document.Document.all()
     q.filter('prefix', 'gsoc_program')
     q.filter('scope', self.data.program.key())
 
@@ -115,19 +106,15 @@
     program_form = ProgramForm(self.data, self.data.POST,
                                instance=self.data.program)
 
-    if not program_form.is_valid():
+    if program_form.is_valid():
+      program_form.save()
+      return True
+    else:
       return False
 
-    program_form.save()
-    return True
-
   def post(self):
-    """Handler for HTTP POST request.
-    """
-    if self.data.GET.get('cbox'):
-      cbox = True
-    else:
-      cbox = False
+    """Handler for HTTP POST request."""
+    cbox = bool(self.data.GET.get('cbox'))
 
     if self.validate():
       self.redirect.program()
@@ -136,15 +123,14 @@
       self.get()
 
 
-class TimelinePage(RequestHandler):
-  """View for the participant profile.
-  """
+class TimelinePage(base.GSoCRequestHandler):
+  """View for the participant profile."""
 
   def djangoURLPatterns(self):
     return [
-        url(r'timeline/%s$' % url_patterns.PROGRAM, self,
+        url_patterns.url(r'timeline/%s$' % soc_url_patterns.PROGRAM, self,
             name='edit_gsoc_timeline'),
-        url(r'timeline/edit/%s$' % url_patterns.PROGRAM, self),
+        url_patterns.url(r'timeline/edit/%s$' % soc_url_patterns.PROGRAM, self),
     ]
 
   def checkAccess(self):
@@ -166,19 +152,15 @@
     timeline_form = TimelineForm(self.data.POST,
                                  instance=self.data.program_timeline)
 
-    if not timeline_form.is_valid():
+    if timeline_form.is_valid():
+      timeline_form.save()
+      return True
+    else:
       return False
 
-    timeline_form.save()
-    return True
-
   def post(self):
-    """Handler for HTTP POST request.
-    """
-    if self.data.GET.get('cbox'):
-      cbox = True
-    else:
-      cbox = False
+    """Handler for HTTP POST request."""
+    cbox = bool(self.data.GET.get('cbox'))
 
     if self.validate():
       self.redirect.program()
@@ -188,13 +170,13 @@
 
 
 class GSoCProgramMessagesPage(
-    program_view.ProgramMessagesPage, RequestHandler):
-  """View for the content of GSoC program specific messages to be sent.
-  """
+    soc_program_view.ProgramMessagesPage, base.GSoCRequestHandler):
+  """View for the content of GSoC program specific messages to be sent."""
 
   def djangoURLPatterns(self):
     return [
-        url(r'program/messages/edit/%s$' % url_patterns.PROGRAM, self,
+        url_patterns.url(
+            r'program/messages/edit/%s$' % soc_url_patterns.PROGRAM, self,
             name=self._getUrlName()),
     ]
 
@@ -202,11 +184,11 @@
     return 'v2/modules/gsoc/program/messages.html'
 
   def _getForm(self, entity):
-    return GSoCProgramMessagesForm(self.data, self.data.POST or None,
+    return program.GSoCProgramMessagesForm(self.data, self.data.POST or None,
         instance=entity)
 
   def _getModel(self):
-    return GSoCProgramMessages
+    return program.GSoCProgramMessages
 
   def _getUrlName(self):
     return url_names.GSOC_EDIT_PROGRAM_MESSAGES
diff --git a/app/soc/modules/gsoc/views/project_details.py b/app/soc/modules/gsoc/views/project_details.py
index c8c4b71..fc0def6 100644
--- a/app/soc/modules/gsoc/views/project_details.py
+++ b/app/soc/modules/gsoc/views/project_details.py
@@ -35,7 +35,7 @@
 from soc.modules.gsoc.models.code_sample import GSoCCodeSample
 from soc.modules.gsoc.views import assign_mentor
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper import url_names
 from soc.modules.gsoc.views.helper import url_patterns
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -167,7 +167,7 @@
     return 'v2/modules/gsoc/project_details/_upload_code_samples.html'
 
 
-class ProjectDetailsUpdate(RequestHandler):
+class ProjectDetailsUpdate(GSoCRequestHandler):
   """Encapsulate the methods required to generate Project Details update form.
   """
 
@@ -233,7 +233,7 @@
       self.get()
 
 
-class CodeSampleUploadFilePost(RequestHandler):
+class CodeSampleUploadFilePost(GSoCRequestHandler):
   """Handler for POST requests to upload files with code samples.
   """
 
@@ -289,7 +289,7 @@
     self.redirect.to('gsoc_project_details')
 
 
-class CodeSampleDownloadFileGet(RequestHandler):
+class CodeSampleDownloadFileGet(GSoCRequestHandler):
   """Handler for POST requests to download files with code samples.
   """
 
@@ -323,7 +323,7 @@
       raise BadRequest('id argument in GET data is not a number')
 
 
-class CodeSampleDeleteFilePost(RequestHandler):
+class CodeSampleDeleteFilePost(GSoCRequestHandler):
   """Handler for POST requests to delete code sample files.
   """
 
@@ -421,7 +421,7 @@
     return "v2/modules/gsoc/project_details/_user_action.html"
 
 
-class ProjectDetails(RequestHandler):
+class ProjectDetails(GSoCRequestHandler):
   """Encapsulate all the methods required to generate GSoC project
   details page.
   """
@@ -439,21 +439,18 @@
     ]
 
   def checkAccess(self):
-    """Access checks for GSoC project details page.
-    """
+    """Access checks for GSoC project details page."""
     self.mutator.projectFromKwargs()
 
   def context(self):
-    """Handler to for GSoC project details page HTTP get request.
-    """
-    project = self.data.project
-
-    r = self.redirect
+    """Handler to for GSoC project details page HTTP get request."""
+    # TODO(nathaniel): make this .organization call unnecessary?
+    self.redirect.organization(organization=self.data.project.org)
 
     context = {
         'page_name': 'Project details',
-        'project': project,
-        'org_home_link': r.organization(project.org).urlOf('gsoc_org_home'),
+        'project': self.data.project,
+        'org_home_link': self.redirect.urlOf('gsoc_org_home'),
     }
 
     if self.data.orgAdminFor(self.data.project.org):
@@ -462,7 +459,8 @@
     user_is_owner = self.data.user and \
         (self.data.user.key() == self.data.project_owner.parent_key())
     if user_is_owner:
-      context['update_link'] = r.project().urlOf(url_names.GSOC_PROJECT_UPDATE)
+      context['update_link'] = self.redirect.project().urlOf(
+          url_names.GSOC_PROJECT_UPDATE)
 
     if len(self.data.project.passed_evaluations) >= \
         project_logic.NUMBER_OF_EVALUATIONS:
@@ -471,7 +469,7 @@
     return context
 
 
-class AssignMentors(RequestHandler):
+class AssignMentors(GSoCRequestHandler):
   """View which handles assigning mentor to a project.
   """
 
@@ -543,7 +541,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class FeaturedProject(RequestHandler):
+class FeaturedProject(GSoCRequestHandler):
   """View which handles making the project featured by toggle button.
   """
 
diff --git a/app/soc/modules/gsoc/views/projects_list.py b/app/soc/modules/gsoc/views/projects_list.py
index d87614b..6c43769 100644
--- a/app/soc/modules/gsoc/views/projects_list.py
+++ b/app/soc/modules/gsoc/views/projects_list.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -15,7 +13,7 @@
 # limitations under the License.
 
 """Module containing the views for listing all the projects accepted
-into a GSoC program, excluding those which have been withdrawn 
+into a GSoC program, excluding those which have been withdrawn
 or failed one of the evaluations.
 """
 
@@ -28,7 +26,7 @@
 
 from soc.modules.gsoc.logic import project as project_logic
 from soc.modules.gsoc.models.project import GSoCProject
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
@@ -38,7 +36,7 @@
 
   def __init__(self, request, data, query, idx=0):
     """Initializes a new object.
-    
+
     Args:
       request: request object
       data: RequestData object associated with the request
@@ -117,7 +115,7 @@
     return "v2/modules/gsoc/projects_list/_project_list.html"
 
 
-class ListProjects(RequestHandler):
+class ListProjects(GSoCRequestHandler):
   """View methods for listing all the projects accepted into a program.
   """
 
diff --git a/app/soc/modules/gsoc/views/proposal.py b/app/soc/modules/gsoc/views/proposal.py
index 7231d4f..6b29a7d 100644
--- a/app/soc/modules/gsoc/views/proposal.py
+++ b/app/soc/modules/gsoc/views/proposal.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC proposal page.
-"""
-
+"""Module for the GSoC proposal page."""
 
 from google.appengine.ext import db
 
@@ -30,7 +26,7 @@
 from soc.modules.gsoc.logic.helper import notifications
 from soc.modules.gsoc.models.proposal import GSoCProposal
 from soc.modules.gsoc.models.profile import GSoCProfile
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.forms import GSoCModelForm
 from soc.modules.gsoc.views.helper import url_patterns as gsoc_url_patterns
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -49,7 +45,7 @@
 
   clean_content = cleaning.clean_html_content('content')
 
-class ProposalPage(RequestHandler):
+class ProposalPage(GSoCRequestHandler):
   """View for the submit proposal.
   """
 
@@ -139,7 +135,7 @@
       self.get()
 
 
-class UpdateProposal(RequestHandler):
+class UpdateProposal(GSoCRequestHandler):
   """View for the update proposal page.
   """
 
diff --git a/app/soc/modules/gsoc/views/proposal_review.py b/app/soc/modules/gsoc/views/proposal_review.py
index 99a3f2e..4b84568 100644
--- a/app/soc/modules/gsoc/views/proposal_review.py
+++ b/app/soc/modules/gsoc/views/proposal_review.py
@@ -39,7 +39,7 @@
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.score import GSoCScore
 from soc.modules.gsoc.views import assign_mentor
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.forms import GSoCModelForm
 from soc.modules.gsoc.views.helper import url_patterns
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -93,10 +93,7 @@
     super(Duplicate, self).__init__(data)
 
   def context(self):
-    """The context for this template used in render().
-    """
-    r = self.data.redirect
-
+    """The context for this template used in render()."""
     orgs = []
     for org in db.get(self.duplicate.orgs):
       q = GSoCProfile.all()
@@ -104,8 +101,11 @@
       q.filter('status', 'active')
       admins = q.fetch(1000)
 
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.data.redirect.organization(organization=org)
+
       data = {'name': org.name,
-              'link': r.organization(org).urlOf('gsoc_org_home'),
+              'link': self.data.redirect.urlOf('gsoc_org_home'),
               'admins': admins}
 
       orgs.append(data)
@@ -299,7 +299,7 @@
     return "v2/modules/gsoc/proposal/_user_action.html"
 
 
-class ReviewProposal(RequestHandler):
+class ReviewProposal(GSoCRequestHandler):
   """View for the Propsal Review page.
   """
 
@@ -490,7 +490,7 @@
     return context
 
 
-class PostComment(RequestHandler):
+class PostComment(GSoCRequestHandler):
   """View which handles publishing comments.
   """
 
@@ -586,7 +586,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class PostScore(RequestHandler):
+class PostScore(GSoCRequestHandler):
   """View which handles posting scores.
   """
 
@@ -675,7 +675,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class WishToMentor(RequestHandler):
+class WishToMentor(GSoCRequestHandler):
   """View handling wishing to mentor requests.
   """
 
@@ -739,7 +739,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class AssignMentor(RequestHandler):
+class AssignMentor(GSoCRequestHandler):
   """View which handles assigning mentor to a proposal.
   """
 
@@ -827,7 +827,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class IgnoreProposal(RequestHandler):
+class IgnoreProposal(GSoCRequestHandler):
   """View which allows org admins to ignore a proposal.
   """
 
@@ -885,7 +885,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class ProposalModificationPostDeadline(RequestHandler):
+class ProposalModificationPostDeadline(GSoCRequestHandler):
   """View allowing mentors to allow students to modify the proposal.
   """
 
@@ -941,7 +941,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class AcceptProposal(RequestHandler):
+class AcceptProposal(GSoCRequestHandler):
   """View allowing org admins to directly accept the proposal.
   """
 
@@ -996,7 +996,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class ProposalPubliclyVisible(RequestHandler):
+class ProposalPubliclyVisible(GSoCRequestHandler):
   """View allowing the proposer to make the proposal publicly visible.
   """
 
@@ -1050,7 +1050,7 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
 
-class WithdrawProposal(RequestHandler):
+class WithdrawProposal(GSoCRequestHandler):
   """View allowing the proposer to withdraw the proposal.
   """
 
diff --git a/app/soc/modules/gsoc/views/request.py b/app/soc/modules/gsoc/views/request.py
index c4f8390..4134f51 100644
--- a/app/soc/modules/gsoc/views/request.py
+++ b/app/soc/modules/gsoc/views/request.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the view for GSoC request page.
-"""
-
+"""Module containing the view for GSoC request page."""
 
 from google.appengine.ext import db
 
@@ -33,7 +29,7 @@
 
 from soc.modules.gsoc.models.profile import GSoCProfile
 from soc.modules.gsoc.models.request import GSoCRequest
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.forms import GSoCModelForm
 from soc.modules.gsoc.views.helper.url_patterns import url
@@ -74,7 +70,7 @@
     fields = ['message']
 
 
-class RequestPage(RequestHandler):
+class RequestPage(GSoCRequestHandler):
   """Encapsulate all the methods required to generate Request page.
   """
   def templatePath(self):
@@ -169,7 +165,7 @@
     return db.run_in_transaction(create_request_txn)
 
 
-class ShowRequest(RequestHandler):
+class ShowRequest(GSoCRequestHandler):
   """Encapsulate all the methods required to generate Show Request page.
   """
   # maps actions with button names
diff --git a/app/soc/modules/gsoc/views/search.py b/app/soc/modules/gsoc/views/search.py
index 30bfa60..3d78f2d 100644
--- a/app/soc/modules/gsoc/views/search.py
+++ b/app/soc/modules/gsoc/views/search.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,21 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC search page.
-"""
-
+"""Module for the GSoC search page."""
 
 import os
 
 from soc.views.helper import url_patterns
 
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views import base
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
-class SearchGsocPage(RequestHandler):
-  """View for the search gsoc page.
-  """
+class SearchGsocPage(base.GSoCRequestHandler):
+  """View for the search gsoc page."""
 
   def djangoURLPatterns(self):
     return [
diff --git a/app/soc/modules/gsoc/views/slot_transfer.py b/app/soc/modules/gsoc/views/slot_transfer.py
index 0d5a7b5..a18ce6b 100644
--- a/app/soc/modules/gsoc/views/slot_transfer.py
+++ b/app/soc/modules/gsoc/views/slot_transfer.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC slot transfer page.
-"""
-
+"""Module for the GSoC slot transfer page."""
 
 from google.appengine.ext import db
 
@@ -31,7 +27,7 @@
 from soc.modules.gsoc.logic.helper import notifications
 from soc.modules.gsoc.models.slot_transfer import GSoCSlotTransfer
 from soc.modules.gsoc.views import readonly_template
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views import forms
 from soc.modules.gsoc.views.helper.url_patterns import url
 
@@ -72,7 +68,7 @@
     exclude = ['program']
 
 
-class SlotTransferPage(RequestHandler):
+class SlotTransferPage(GSoCRequestHandler):
   """View for transferring the slots.
   """
 
@@ -92,8 +88,10 @@
     self.mutator.slotTransferEntities()
     if not self.data.slot_transfer_entities:
       if 'new' not in self.data.kwargs:
-        r = self.data.redirect
-        new_url = r.organization().urlOf('gsoc_update_slot_transfer')
+        # TODO(nathaniel): make this .organization() call unnecessary.
+        self.data.redirect.organization()
+
+        new_url = self.data.redirect.urlOf('gsoc_update_slot_transfer')
         raise RedirectRequest(new_url)
 
   def templatePath(self):
@@ -114,8 +112,10 @@
 
     if (self.data.program.allocations_visible and
         self.data.timeline.beforeStudentsAnnounced()):
-      r = self.data.redirect.organization()
-      edit_url = r.urlOf('gsoc_update_slot_transfer')
+      # TODO(nathaniel): make this .organization() call unnecessary.
+      self.data.redirect.organization()
+
+      edit_url = self.data.redirect.urlOf('gsoc_update_slot_transfer')
       if require_new_link:
         context['new_slot_transfer_page_link'] = edit_url
       else:
@@ -124,7 +124,7 @@
     return context
 
 
-class UpdateSlotTransferPage(RequestHandler):
+class UpdateSlotTransferPage(GSoCRequestHandler):
   """View for transferring the slots.
   """
 
@@ -170,9 +170,12 @@
         'error': slot_transfer_form.errors
         }
 
-    r = self.data.redirect.organization()
-    context['org_home_page_link'] = r.urlOf('gsoc_org_home')
-    context['slot_transfer_page_link'] = r.urlOf('gsoc_slot_transfer')
+    # TODO(nathaniel): make this .organization() call unnecessary.
+    self.data.redirect.organization()
+
+    context['org_home_page_link'] = self.data.redirect.urlOf('gsoc_org_home')
+    context['slot_transfer_page_link'] = self.data.redirect.urlOf(
+        'gsoc_slot_transfer')
 
     return context
 
@@ -230,12 +233,13 @@
     return db.run_in_transaction(create_or_update_slot_transfer_trx)
 
   def post(self):
-    """Handler for HTTP POST request.
-    """
+    """Handler for HTTP POST request."""
 
     slot_transfer_entity = self.createOrUpdateFromForm()
     if slot_transfer_entity:
-      self.redirect.organization(self.data.organization)
+      # TODO(nathaniel): make this .organization call unnecessary.
+      self.redirect.organization(organization=self.data.organization)
+
       self.redirect.to('gsoc_update_slot_transfer', validated=True)
     else:
       self.get()
diff --git a/app/soc/modules/gsoc/views/slot_transfer_admin.py b/app/soc/modules/gsoc/views/slot_transfer_admin.py
index aec740d..ca28c58 100644
--- a/app/soc/modules/gsoc/views/slot_transfer_admin.py
+++ b/app/soc/modules/gsoc/views/slot_transfer_admin.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC slot transfer admin page.
-"""
-
+"""Module for the GSoC slot transfer admin page."""
 
 import logging
 
@@ -31,7 +27,7 @@
 from soc.views.template import Template
 
 from soc.modules.gsoc.models.slot_transfer import GSoCSlotTransfer
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 
@@ -60,7 +56,7 @@
     list_config.addSimpleColumn('admin_remarks', 'Admin remarks')
     list_config.setColumnEditable('admin_remarks', True) #, edittype='textarea')
     list_config.addColumn(
-        'slots_desired', 'Min desired', 
+        'slots_desired', 'Min desired',
         (lambda e, *args: e.parent().slots_desired), width=25, hidden=True)
     list_config.addColumn(
         'max_slots_desired', 'Max desired',
@@ -110,7 +106,7 @@
 
     if button_id == 'reject':
       return self.postAccept(parsed, False)
-  
+
     if button_id == 'save':
       return self.postSave(parsed)
 
@@ -125,7 +121,7 @@
         slot_transfer = db.get(slot_transfer_key)
 
         if not slot_transfer:
-          logging.warning("Invalid slot_transfer_key '%s'" % 
+          logging.warning("Invalid slot_transfer_key '%s'" %
                           slot_transfer_key)
           return
 
@@ -222,7 +218,7 @@
     return "v2/modules/gsoc/slot_transfer_admin/_list.html"
 
 
-class SlotsTransferAdminPage(RequestHandler):
+class SlotsTransferAdminPage(GSoCRequestHandler):
   """View for the the list of slot transfer requests.
   """
 
diff --git a/app/soc/modules/gsoc/views/statistic.py b/app/soc/modules/gsoc/views/statistic.py
index 8b3a4e1..0f16fbc 100644
--- a/app/soc/modules/gsoc/views/statistic.py
+++ b/app/soc/modules/gsoc/views/statistic.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,6 +14,8 @@
 
 """Module for the GSoC statistics page."""
 
+# TODO(nathaniel): as of 1 December 2012 this module is unused
+# (see soc.modules.gsoc.callback:62). Should it be removed?
 
 from django.utils import simplejson
 from django.core.urlresolvers import reverse
@@ -27,7 +27,7 @@
 from soc.views.toggle_button import ToggleButtonTemplate
 
 from soc.modules.gsoc.models.statistic_info import GSoCStatisticInfo
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.helper.url_patterns import url
 
 from soc.modules.gsoc.statistics import mapping
@@ -36,8 +36,7 @@
 
 
 class ManageActions(Template):
-  """Template to render the left side admin actions.
-  """
+  """Template to render the left side admin actions."""
 
   IS_VISIBLE_HELP_MSG = ugettext(
       'Whether this statistic is publicly visible to all users or not.')
@@ -52,7 +51,7 @@
             labels = {
                 'checked': 'Yes',
                 'unchecked': 'No'})]
-    
+
     return {
         'toggle_buttons': self.toggle_buttons
     }
@@ -64,7 +63,7 @@
   pass
 
 
-class StatisticDashboard(RequestHandler):
+class StatisticDashboard(GSoCRequestHandler):
   """View for the statistic page.
   """
 
@@ -121,7 +120,7 @@
       manage_urls[name] = reverse(
           'gsoc_statistic_manage', kwargs={'key_name': name})
     return manage_urls
-  
+
   def _constructVisibilities(self, infos):
     visibilities = {}
     if self.isHost:
@@ -129,7 +128,7 @@
         visibilities[str(info.name)] = True if info.is_visible else False
     return simplejson.dumps(visibilities)
 
-class StatisticFetcher(RequestHandler):
+class StatisticFetcher(GSoCRequestHandler):
   """Loads data for a particular statistic.
   """
 
@@ -138,7 +137,7 @@
 
   def checkAccess(self):
     key_name = self.data.kwargs['key_name']
-    
+
     # TODO(dhans): check if the statistic is visible
     pass
 
@@ -161,14 +160,14 @@
       raise UnsupportedFormatException('Requested format is not supported.')
 
     return self._presenter.get(key_name)
-    
+
   def jsonContext(self):
     key_name = self.data.kwargs['key_name']
     presentation = self._getPresentation(key_name)
     return presentation
 
 
-class StatisticManager(RequestHandler):
+class StatisticManager(GSoCRequestHandler):
   """Manages the statistic entities.
   """
 
@@ -192,4 +191,3 @@
     if statistic.getVisible() != value:
       statistic.setVisible(value)
       GSoCStatisticInfo.getInstance().updateStatistic(statistic)
-      
\ No newline at end of file
diff --git a/app/soc/modules/gsoc/views/student_evaluation.py b/app/soc/modules/gsoc/views/student_evaluation.py
index 67c7764..4adeb10 100644
--- a/app/soc/modules/gsoc/views/student_evaluation.py
+++ b/app/soc/modules/gsoc/views/student_evaluation.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC project student survey.
-"""
-
+"""Module for the GSoC project student survey."""
 
 from soc.views import forms
 from soc.views import survey
@@ -33,7 +29,7 @@
 from soc.modules.gsoc.models.project_survey_record import \
     GSoCProjectSurveyRecord
 from soc.modules.gsoc.views import forms as gsoc_forms
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.base_templates import LoggedInMsg
 from soc.modules.gsoc.views.helper import url_patterns
 
@@ -66,7 +62,7 @@
     exclude = ['project', 'org', 'user', 'survey', 'created', 'modified']
 
 
-class GSoCStudentEvaluationEditPage(RequestHandler):
+class GSoCStudentEvaluationEditPage(GSoCRequestHandler):
   """View for creating/editing student evalution.
   """
 
@@ -144,7 +140,7 @@
     else:
       self.get()
 
-class GSoCStudentEvaluationTakePage(RequestHandler):
+class GSoCStudentEvaluationTakePage(GSoCRequestHandler):
   """View for students to submit their evaluation.
   """
 
@@ -238,7 +234,7 @@
       self.get()
 
 
-class GSoCStudentEvaluationPreviewPage(RequestHandler):
+class GSoCStudentEvaluationPreviewPage(GSoCRequestHandler):
   """View for the host to preview the evaluation.
   """
 
@@ -272,7 +268,7 @@
     return context
 
 
-class GSoCStudentEvaluationRecordsList(RequestHandler):
+class GSoCStudentEvaluationRecordsList(GSoCRequestHandler):
   """View for listing all records of a GSoCGProjectSurveyRecord.
   """
 
@@ -339,7 +335,7 @@
     survey_name = 'Student Evaluation'
 
 
-class GSoCStudentEvaluationShowPage(RequestHandler):
+class GSoCStudentEvaluationShowPage(GSoCRequestHandler):
   """View to display the readonly page for student evaluation.
   """
 
diff --git a/app/soc/modules/gsoc/views/student_forms.py b/app/soc/modules/gsoc/views/student_forms.py
index 74f2171..086073c 100644
--- a/app/soc/modules/gsoc/views/student_forms.py
+++ b/app/soc/modules/gsoc/views/student_forms.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for the GSoC student forms.
-"""
-
+"""Module for the GSoC student forms."""
 
 from google.appengine.ext import blobstore
 
@@ -26,7 +22,7 @@
 from soc.views.helper import url_patterns
 
 from soc.modules.gsoc.models.profile import GSoCStudentInfo
-from soc.modules.gsoc.views.base import RequestHandler
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 from soc.modules.gsoc.views.forms import GSoCModelForm
 from soc.modules.gsoc.views.helper.url_patterns import url
 
@@ -53,8 +49,11 @@
     return self.request_data.kwargs['admin']
 
   def _r(self):
-    r = self.request_data.redirect
-    return r.profile() if self._admin() else r.program()
+    if self._admin:
+      self.request_data.redirect.profile()
+    else:
+      self.request_data.redirect.program()
+    return self.request_data.redirect
 
   def _urlName(self):
     if self._admin():
@@ -97,8 +96,11 @@
     return self.request_data.kwargs['admin']
 
   def _r(self):
-    r = self.request_data.redirect
-    return r.profile() if self._admin() else r.program()
+    if self._admin():
+      self.request_data.redirect.profile()
+    else:
+      self.request_data.redirect.program()
+    return self.request_data.redirect
 
   def _urlName(self):
     if self._admin():
@@ -119,7 +121,7 @@
       field._link = self._r().urlOf(self._urlName())
 
 
-class FormPage(RequestHandler):
+class FormPage(GSoCRequestHandler):
   """View to upload student forms.
   """
 
@@ -195,7 +197,11 @@
     return 'gsoc_enrollment_form'
 
   def _r(self):
-    return self.redirect.profile() if self._admin() else self.redirect.program()
+    if self._admin():
+      self.redirect.profile()
+    else:
+      self.redirect.program()
+    return self.redirect
 
   def jsonContext(self):
     url = self._r().urlOf(self._urlName(), secure=True)
@@ -230,7 +236,7 @@
     self._r().to(self._urlName(), validated=True)
 
 
-class DownloadForm(RequestHandler):
+class DownloadForm(GSoCRequestHandler):
   """View for downloading a student form.
   """
 
diff --git a/app/soc/templates/v2/modules/gci/homepage/_how_it_works.html b/app/soc/templates/v2/modules/gci/homepage/_how_it_works.html
index 4357f43..3cdfab4 100644
--- a/app/soc/templates/v2/modules/gci/homepage/_how_it_works.html
+++ b/app/soc/templates/v2/modules/gci/homepage/_how_it_works.html
@@ -48,6 +48,9 @@
             {% if example_tasks_link %}
             <a class="example-tasks" href="{{ example_tasks_link }}">Or see example tasks</a>
             {% endif %}
+            {% if all_tasks_link %}
+            <a class="all-tasks-tasks" href="{{ all_tasks_link }}">Or see list of tasks</a>
+            {% endif %}
         </div>
     </div>
     {% endif %}
diff --git a/app/soc/templates/v2/modules/gci/task/_work_submissions.html b/app/soc/templates/v2/modules/gci/task/_work_submissions.html
index 45200dd..f496b36 100644
--- a/app/soc/templates/v2/modules/gci/task/_work_submissions.html
+++ b/app/soc/templates/v2/modules/gci/task/_work_submissions.html
@@ -54,6 +54,13 @@
 
     {% if work_file_form %}
       <span class="block-task-uploaded-code-note">Upload your final work file or paste in its URL, then click Submit.</span>
+      {% if ws_error %}
+        <div class="form-row error">
+          <span class="form-row-error-msg">
+            Your work was not submitted due to an error, please retry.
+          </span>
+        </div>
+      {% endif %}
       <form method="post" enctype="multipart/form-data" id="file-form" class="form-upload-code clearfix">
         {{ work_file_form.render }}
         <div class="form-row form-row-buttons">
diff --git a/app/soc/views/base.py b/app/soc/views/base.py
index 002ab60..19fa5e6 100644
--- a/app/soc/views/base.py
+++ b/app/soc/views/base.py
@@ -31,10 +31,6 @@
 from soc.views.helper import request_data
 from soc.views.helper import response as response_helper
 
-# TODO(nathaniel): Clean up this legacy API re-export by redirecting
-# clients using this module attribute to its actual definition.
-Response = response_helper.Response
-
 
 class RequestHandler(object):
   """Base class managing HTTP Requests."""
@@ -56,7 +52,7 @@
   def json(self):
     """Handler for HTTP GET request with a 'fmt=json' parameter."""
 
-    if not self.request.GET.get('plain'):
+    if not self.data.request.GET.get('plain'):
       self.response['Content-Type'] = 'application/json'
 
     # if the browser supports HTTP/1.1
@@ -69,7 +65,7 @@
 
     context = self.jsonContext()
 
-    if self.request.GET.get('marker'):
+    if self.data.request.GET.get('marker'):
       # allow the django test framework to capture the context dictionary
       loader.render_to_string('json_marker.html', dictionary=context)
 
@@ -93,24 +89,44 @@
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
   def head(self):
-    """Handler for HTTP HEAD request."""
-    self.response = self.error(httplib.METHOD_NOT_ALLOWED)
+    """Handler for HTTP HEAD request.
+
+    Returns:
+      An http.HttpResponse appropriate for this RequestHandler's request
+        object.
+    """
+    return self.error(httplib.METHOD_NOT_ALLOWED)
 
   def options(self):
-    """Handler for HTTP OPTIONS request."""
-    self.response = self.error(httplib.METHOD_NOT_ALLOWED)
+    """Handler for HTTP OPTIONS request.
+
+    Returns:
+      An http.HttpResponse appropriate for this RequestHandler's request
+        object.
+    """
+    return self.error(httplib.METHOD_NOT_ALLOWED)
 
   def put(self):
     """Handler for HTTP PUT request."""
     self.response = self.error(httplib.METHOD_NOT_ALLOWED)
 
   def delete(self):
-    """Handler for HTTP DELETE request."""
-    self.response = self.error(httplib.METHOD_NOT_ALLOWED)
+    """Handler for HTTP DELETE request.
+
+    Returns:
+      An http.HttpResponse appropriate for this RequestHandler's request
+        object.
+    """
+    return self.error(httplib.METHOD_NOT_ALLOWED)
 
   def trace(self):
-    """Handler for HTTP TRACE request."""
-    self.response = self.error(httplib.METHOD_NOT_ALLOWED)
+    """Handler for HTTP TRACE request.
+
+    Returns:
+      An http.HttpResponse appropriate for this RequestHandler's request
+        object.
+    """
+    return self.error(httplib.METHOD_NOT_ALLOWED)
 
   def error(self, status, message=None):
     """Constructs an HttpResponse indicating an error.
@@ -143,13 +159,22 @@
     raise NotImplementedError()
 
   def checkAccess(self):
-    # TODO(nathaniel): this doesn't actually raise an exception as it says.
-    # TODO(nathaniel): what exception should it raise if it did?
-    """Raise an exception if the user doesn't have access to the requested URL.
+    # TODO(nathaniel): eliminate this - it doesn't actually simplify
+    # the HTTP method implementations all that much to have it
+    # separated out.
+    """Ensure that the user's request should be satisfied.
+
+    Implementing subclasses must override this method.
+
+    Implementations must not mutate any of this RequestHandler's state and
+    should merely raise an exception if the user's request should not be
+    satisfied or return normally if the user's request should be satisfied.
+
+    Raises:
+      exceptions.Error: If the user's request should not be satisfied for
+        any reason.
     """
-    self.response = self.error(
-        httplib.UNAUTHORIZED,
-        'RequestHandler.checkAccess has not been overridden to allow access')
+    raise NotImplementedError()
 
   def render(self, template_path, render_context):
     """Renders the page content from the specified template and context.
@@ -176,38 +201,48 @@
     """
     raise NotImplementedError()
 
-  def accessViolation(self, status, message):
-    """Default access violation handler."""
-    self.response = self.error(status, message)
-
   def _dispatch(self):
-    """Dispatches the HTTP request to its respective handler method."""
-    if self.request.method == 'GET':
-      if self.request.GET.get('fmt') == 'json':
+    """Dispatches the HTTP request to its respective handler method.
+
+    Returns:
+      An http.HttpResponse appropriate for this RequestHandler's request
+        object.
+    """
+    if self.data.request.method == 'GET':
+      if self.data.request.GET.get('fmt') == 'json':
         self.json()
       else:
         self.get()
-    elif self.request.method == 'POST':
+      return self.response
+    elif self.data.request.method == 'POST':
       if db.WRITE_CAPABILITY.is_enabled():
         self.post()
       else:
-        referrer = self.request.META.get('HTTP_REFERER', '')
+        referrer = self.data.request.META.get('HTTP_REFERER', '')
         params = urllib.urlencode({'dsw_disabled': 1})
         url_with_params = '%s?%s' % (referrer, params)
         self.redirect.toUrl(url_with_params)
-    elif self.request.method == 'HEAD':
-      self.head()
-    elif self.request.method == 'OPTIONS':
-      self.options()
-    elif self.request.method == 'PUT':
+      return self.response
+    elif self.data.request.method == 'HEAD':
+      return self.head()
+    elif self.data.request.method == 'OPTIONS':
+      return self.options()
+    elif self.data.request.method == 'PUT':
       self.put()
-    elif self.request.method == 'DELETE':
-      self.delete()
-    elif self.request.method == 'TRACE':
-      self.trace()
+      return self.response
+    elif self.data.request.method == 'DELETE':
+      return self.delete()
+    elif self.data.request.method == 'TRACE':
+      return self.trace()
     else:
-      self.response = self.error(httplib.NOT_IMPLEMENTED)
+      return self.error(httplib.NOT_IMPLEMENTED)
 
+  # TODO(nathaniel): Note that while this says that it sets the "data" and
+  # "check" attributes, this implementation makes use of the "data" attribute
+  # without having set it. Therefore extending classes must set at least the
+  # "data" attribute before calling this superclass implementation if they
+  # choose to do so (they do). This is an obstacle just waiting to cause
+  # bigger problems.
   def init(self, request, args, kwargs):
     """Initializes the RequestHandler.
 
@@ -236,14 +271,12 @@
     try:
       self.init(request, args, kwargs)
       self.checkAccess()
-      self._dispatch()
+      self.response = self._dispatch()
     except exceptions.LoginRequest, e:
       request.get_full_path().encode('utf-8')
       self.redirect.login().to()
     except exceptions.RedirectRequest, e:
       self.redirect.toUrl(e.url)
-    except exceptions.AccessViolation, e:
-      self.accessViolation(e.status, e.args[0])
     except exceptions.GDocsLoginRequest, e:
       self.redirect.toUrl('%s?%s' % (self.redirect.urlOf(e.url_name),
                                      urllib.urlencode({'next':e.next})))
diff --git a/app/soc/views/base_templates.py b/app/soc/views/base_templates.py
index 0e621e6..665f89e 100644
--- a/app/soc/views/base_templates.py
+++ b/app/soc/views/base_templates.py
@@ -1,13 +1,11 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
 # You may obtain a copy of the License at
-# 
+#
 #   http://www.apache.org/licenses/LICENSE-2.0
-# 
+#
 # Unless required by applicable law or agreed to in writing, software
 # distributed under the License is distributed on an "AS IS" BASIS,
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,7 +14,6 @@
 
 """This module contains the view for the site menus."""
 
-
 from soc.models.site import Site
 
 from soc.views.template import Template
@@ -66,12 +63,16 @@
 
   def context(self):
     def url(program):
-      r = self.data.redirect.program(program)
-      return r.urlOf(self.url_name)
+      # TODO(nathaniel): make this .program call unnecessary.
+      self.data.redirect.program(program=program)
+
+      return self.data.redirect.urlOf(self.url_name)
+
     def attr(program):
       if program.key() == self.data.program.key():
         return "selected=selected"
-      return ""
+      else:
+        return ""
 
     program_key = Site.active_program.get_value_for_datastore(self.data.site)
 
diff --git a/app/soc/views/helper/context.py b/app/soc/views/helper/context.py
index 4956b97..0e4807b 100644
--- a/app/soc/views/helper/context.py
+++ b/app/soc/views/helper/context.py
@@ -60,5 +60,5 @@
       'ga_tracking_num': data.site.ga_tracking_num,
       'ds_write_disabled': data.ds_write_disabled,
       'css_path': css_path,
-      'gdata_is_logged_in': str(gdata_is_logged_in).lower(),
+      'gdata_is_logged_in': str(bool(gdata_is_logged_in)).lower(),
   }
diff --git a/app/soc/views/helper/request_data.py b/app/soc/views/helper/request_data.py
index f3f2a60..eb045cb 100644
--- a/app/soc/views/helper/request_data.py
+++ b/app/soc/views/helper/request_data.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -18,18 +16,18 @@
 request in the GSoC module.
 """
 
-
 import datetime
 
 from google.appengine.api import users
 from google.appengine.ext import db
 
-from django.core.urlresolvers import reverse
+from django.core import urlresolvers
+from django.utils import encoding
 
 from soc.logic import system
 from soc.logic import site
 from soc.logic import user
-from soc.views.helper.access_checker import isSet
+from soc.views.helper import access_checker
 
 
 def isBefore(date):
@@ -49,8 +47,7 @@
 
 
 def isBetween(start, end):
-  """Returns True iff utcnow() is between start and end.
-  """
+  """Returns True iff utcnow() is between start and end."""
   return isAfter(start) and isBefore(end)
 
 
@@ -67,13 +64,11 @@
     self.org_app = org_app
 
   def currentPeriod(self):
-    """Return where we are currently on the timeline.
-    """
+    """Return where we are currently on the timeline."""
     pass
 
   def nextDeadline(self):
-    """Determines the next deadline on the timeline.
-    """
+    """Determines the next deadline on the timeline."""
     pass
 
   def orgsAnnouncedOn(self):
@@ -169,8 +164,7 @@
   """
 
   def __init__(self):
-    """Constructs an empty RequestData object.
-    """
+    """Constructs an empty RequestData object."""
     self.site = None
     self.user = None
     self.request = None
@@ -189,24 +183,21 @@
 
   @property
   def login_url(self):
-    """Memoizes and returns the login_url for the current path.
-    """
+    """Memoizes and returns the login_url for the current path."""
     if not self._login_url:
       self._login_url = users.create_login_url(self.full_path)
     return self._login_url
 
   @property
   def logout_url(self):
-    """Memoizes and returns the logout_url for the current path.
-    """
+    """Memoizes and returns the logout_url for the current path."""
     if not self._logout_url:
       self._logout_url = users.create_logout_url(self.full_path)
     return self._logout_url
 
   @property
   def ds_write_disabled(self):
-    """Memoizes and returns whether datastore writes are disabled.
-    """
+    """Memoizes and returns whether datastore writes are disabled."""
     if self._ds_write_disabled is not None:
       return self._ds_write_disabled
 
@@ -267,20 +258,18 @@
     return invite.role if invite else None
 
 
+# TODO(nathaniel): This should be immutable.
 class RedirectHelper(object):
-  """Helper for constructing redirects.
-  """
+  """Helper for constructing redirects."""
 
   def __init__(self, data, response):
-    """Initializes the redirect helper.
-    """
+    """Initializes the redirect helper."""
     self._data = data
     self._response = response
     self._clear()
 
   def _clear(self):
-    """Clears the internal state.
-    """
+    """Clears the internal state."""
     self._no_url = False
     self._url_name = None
     self._url = None
@@ -288,38 +277,31 @@
     self.kwargs = {}
 
   def sponsor(self, program=None):
-    """Sets kwargs for an url_patterns.SPONSOR redirect.
-    """
+    """Sets kwargs for an url_patterns.SPONSOR redirect."""
     if not program:
-      assert isSet(self._data.program)
+      assert access_checker.isSet(self._data.program)
       program = self._data.program
     self._clear()
     self.kwargs['sponsor'] = program.scope_path
-    return self
 
   def program(self, program=None):
-    """Sets kwargs for an url_patterns.PROGRAM redirect.
-    """
+    """Sets kwargs for an url_patterns.PROGRAM redirect."""
     if not program:
-      assert isSet(self._data.program)
+      assert access_checker.isSet(self._data.program)
       program = self._data.program
     self.sponsor(program)
     self.kwargs['program'] = program.link_id
-    return self
 
   def organization(self, organization=None):
-    """Sets the kwargs for an url_patterns.ORG redirect.
-    """
+    """Sets the kwargs for an url_patterns.ORG redirect."""
     if not organization:
-      assert isSet(self._data.organization)
+      assert access_checker.isSet(self._data.organization)
       organization = self._data.organization
     self.program()
     self.kwargs['organization'] = organization.link_id
-    return self
 
   def id(self, id=None):
-    """Sets the kwargs for an url_patterns.ID redirect.
-    """
+    """Sets the kwargs for an url_patterns.ID redirect."""
     if not id:
       assert 'id' in self._data.kwargs
       id = self._data.kwargs['id']
@@ -328,8 +310,7 @@
     return self
 
   def key(self, key=None):
-    """Sets the kwargs for an url_patterns.KEY redirect.
-    """
+    """Sets the kwargs for an url_patterns.KEY redirect."""
     if not key:
       assert 'key' in self._data.kwargs
       key = self._data.kwargs['key']
@@ -338,15 +319,13 @@
     return self
 
   def createProfile(self, role):
-    """Sets args for an url_patterns.CREATE_PROFILE redirect.
-    """
+    """Sets args for an url_patterns.CREATE_PROFILE redirect."""
     self.program()
     self.kwargs['role'] = role
     return self
 
   def profile(self, user=None):
-    """Sets args for an url_patterns.PROFILE redirect.
-    """
+    """Sets args for an url_patterns.PROFILE redirect."""
     if not user:
       assert 'user' in self._data.kwargs
       user = self._data.kwargs['user']
@@ -374,14 +353,13 @@
     return self
 
   def userOrg(self, user=None, organization=None):
-    """Sets args for an url_patterns.USER_ORG redirect.
-    """
+    """Sets args for an url_patterns.USER_ORG redirect."""
     if not user:
       assert 'user' in self._data.kwargs
       user = self._data.kwargs['user']
 
     if not organization:
-      assert isSet(self._data.organization)
+      assert access_checker.isSet(self._data.organization)
       organization = self._data.organization
 
     self.program()
@@ -391,8 +369,7 @@
 
 
   def userId(self, user=None, id=None):
-    """Sets args for url_patterns.USER_ID redirect.
-    """
+    """Sets args for url_patterns.USER_ID redirect."""
     if not user:
       assert 'user' in self._data.kwargs
       user = self._data.kwargs['user']
@@ -411,20 +388,24 @@
 
     Uses internal state for args and kwargs.
     """
+    # TODO(nathaniel): Why isn't this just "url = reverse(name, args=self.args,
+    # kwargs=self.kwargs)"? Current suspicion: it's because there's a
+    # there's a difference in behavior between passing None and passing empty
+    # dicts. It's also curious that there isn't an "if self.args and
+    # self.kwargs" case at the top.
     if self.args:
-      url = reverse(name, args=self.args)
+      url = urlresolvers.reverse(name, args=self.args)
     elif self.kwargs:
-      url = reverse(name, kwargs=self.kwargs)
+      url = urlresolvers.reverse(name, kwargs=self.kwargs)
     else:
-      url = reverse(name)
+      url = urlresolvers.reverse(name)
 
     url = self._appendGetArgs(url, cbox=cbox, extra_get_args=extra)
 
     return self._fullUrl(url, full, secure)
 
   def url(self, full=False, secure=False):
-    """Returns the url of the current state.
-    """
+    """Returns the url of the current state."""
     if self._no_url:
       return None
     assert self._url or self._url_name
@@ -440,6 +421,7 @@
     if (not full) and (system.isLocal() or not secure):
       return url
 
+    # TODO(nathaniel): consider using scheme-relative urls here?
     if secure:
       protocol = 'https'
       hostname = system.getSecureHostname()
@@ -450,18 +432,17 @@
     return '%s://%s%s' % (protocol, hostname, url)
 
   def _appendAnchor(self, url, anchor=None):
-    """Appends the anchor to the URL.
-    """
+    """Appends the anchor to the URL."""
     if anchor:
       url = '%s#%s' % (url, anchor)
 
     return url
 
-  def _appendGetArgs(self, url, cbox=False, validated=False,
-      extra_get_args=[]):
-    """Appends GET arguments to the specified URL.
-    """
-    get_args = extra_get_args[:]
+  # TODO(nathaniel): Django's got to have a utility function for most of this.
+  def _appendGetArgs(
+      self, url, cbox=False, validated=False, extra_get_args=None):
+    """Appends GET arguments to the specified URL."""
+    get_args = extra_get_args or []
     if cbox:
       get_args.append('cbox=true')
 
@@ -509,30 +490,25 @@
     self.toUrl(url, full=full, secure=secure)
 
   def toUrl(self, url, full=False, secure=False):
-    """Redirects to the specified url.
-    """
-    from django.utils.encoding import iri_to_uri
+    """Redirects to the specified url."""
     url = self._fullUrl(url, full, secure)
     self._response.status_code = 302
-    self._response["Location"] = iri_to_uri(url)
+    self._response["Location"] = encoding.iri_to_uri(url)
 
   def login(self):
-    """Sets the _url to the login url.
-    """
+    """Sets the _url to the login url."""
     self._clear()
     self._url = self._data.login_url
     return self
 
   def logout(self):
-    """Sets the _url to the logout url.
-    """
+    """Sets the _url to the logout url."""
     self._clear()
     self._url = self._data.logout_url
     return self
 
   def acceptedOrgs(self):
-    """Sets the _url_name to the list of all accepted orgs.
-    """
+    """Sets the _url_name to the list of all accepted orgs."""
     self.program()
     return self
 
@@ -546,26 +522,22 @@
     return self
 
   def searchpage(self):
-    """Sets the _url_name for the searchpage of the current program.
-    """
+    """Sets the _url_name for the searchpage of the current program."""
     self.program()
     return self
 
   def orgHomepage(self, link_id):
-    """Sets the _url_name for the specified org homepage
-    """
+    """Sets the _url_name for the specified org homepage."""
     self.program()
     self.kwargs['organization'] = link_id
     return self
 
   def dashboard(self):
-    """Sets the _url_name for dashboard page of the current program.
-    """
+    """Sets the _url_name for dashboard page of the current program."""
     self.program()
     return self
 
   def events(self):
-    """Sets the _url_name for the events page, if it is set.
-    """
+    """Sets the _url_name for the events page, if it is set."""
     self.program()
     return self
diff --git a/app/soc/views/helper/requests.py b/app/soc/views/helper/requests.py
deleted file mode 100644
index 15a9d87..0000000
--- a/app/soc/views/helper/requests.py
+++ /dev/null
@@ -1,184 +0,0 @@
-#!/usr/bin/env python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Helpers for manipulating HTTP requests.
-"""
-
-
-import urlparse
-
-from soc.logic import system
-
-
-def getSingleIndexedParamValue(request, param_name, values=()):
-  """Returns a value indexed by a query parameter in the HTTP request.
-  
-  Args:
-    request: the Django HTTP request object
-    param_name: name of the query parameter in the HTTP request
-    values: list (or tuple) of ordered values; one of which is
-      retrieved by the index value of the param_name argument in
-      the HTTP request
-      
-  Returns:
-    None if the query parameter was not present, was not an integer, or
-      was an integer that is not a valid [0..len(values)-1] index into
-      the values list.
-    Otherwise, returns values[int(param_name value)]
-  """
-  value_idx = request.GET.get(param_name)
-  
-  if isinstance(value_idx, (tuple, list)):
-    # keep only the first argument if multiple are present
-    value_idx = value_idx[0]
-
-  try:
-    # GET parameter 'param_name' should be an integer value index
-    value_idx = int(value_idx) if value_idx is not None else -1
-  except ValueError:
-    # ignore bogus or missing parameter values, so return None (no message)
-    return None
-    
-  if value_idx < 0:
-    # value index out of range, so return None (no value)
-    return None
-
-  if value_idx >= len(values):
-    # value index out of range, so return None (no value)
-    return None
-
-  # return value associated with valid value index
-  return values[value_idx]
-
-
-def getSingleIndexedParamValueIfMissing(value, request, param_name,
-                                        values=()):
-  """Returns missing value indexed by a query parameter in the HTTP request.
-  
-  Args:
-    value: an existing value, or a "False" value such as None
-    request, param_name, values: see getSingleIndexParamValue()
-    
-  Returns:
-    value, if value is "non-False"
-    Otherwise, returns getSingleIndexedParamValue() result.
-  """
-  if value:
-    # value already present, so return it
-    return value
-
-  return getSingleIndexedParamValue(request, param_name, values=values)
-
-
-# TODO(tlarsen):  write getMultipleIndexParamValues() that returns a
-#   list of values if present, omitting those values that are
-#   out of range
-
-
-def isReferrerSelf(request,
-                   expected_prefix=None, suffix=None, url_name=None):
-  """Returns True if HTTP referrer path starts with the HTTP request path.
-    
-  Args:
-    request: the Django HTTP request object; request.path is used if
-      expected_path is not supplied (the most common usage)
-    expected_prefix: optional HTTP path to use instead of the one in
-      request.path; default is None (use request.path)
-    suffix: suffix to remove from the HTTP request path before comparing
-      it to the HTTP referrer path in the HTTP request object headers
-      (this is often an link ID, for example, that may be changing from
-      a POST referrer to a GET redirect target) 
-    url_name: url name of the entity that is being created
-  
-  Returns:
-    True if HTTP referrer path begins with the HTTP request path (either
-      request.path or expected_prefix instead if it was supplied), after
-      any suffix was removed from that request path
-    False otherwise
-       
-  """
-  http_from = request.META.get('HTTP_REFERER')
-
-  if not http_from:
-    # no HTTP referrer, so cannot possibly start with expected prefix
-    return False
-
-  http_host = 'http://%s/%s' % (system.getHostname(), url_name)
-
-  if http_from.startswith(http_host):
-    return True
-
-  from_path = urlparse.urlparse(http_from).path
-
-  if not expected_prefix:
-    # use HTTP request path, since expected_prefix was not supplied
-    expected_prefix = request.path
-
-  if suffix:
-    # remove suffix (such as a link ID) before comparison
-    chars_to_remove = len(suffix)
-    
-    if not suffix.startswith('/'):
-      chars_to_remove = chars_to_remove + 1
-
-    expected_prefix = expected_prefix[:-chars_to_remove]
-
-  if not from_path.startswith(expected_prefix):
-    # expected prefix did not match first part of HTTP referrer path
-    return False
-
-  # HTTP referrer started with (possibly truncated) expected prefix
-  return True
-
-
-def replaceSuffix(path, old_suffix, new_suffix=None, params=None):
-  """Replace the last part of a URL path with something else.
-
-  Also appends an optional list of query parameters.  Used for
-  replacing, for example, one link ID at the end of a relative
-  URL path with another.
-
-  Args:
-    path: HTTP request relative URL path (with no query arguments)
-    old_suffix: expected suffix at the end of request.path component;
-      if any False value (such as None), the empty string '' is used
-    new_suffix: if non-False, appended to request.path along with a
-      '/' separator (after removing old_suffix if necessary)
-    params: an optional dictionary of query parameters to append to
-      the redirect target; appended as ?<key1>=<value1>&<key2>=...
-      
-  Returns:
-    /path/with/new_suffix?a=1&b=2
-  """    
-  if not old_suffix:
-    old_suffix = ''
-
-  old_suffix = '/' + old_suffix
-
-  if path.endswith(old_suffix):
-    # also removes any trailing '/' if old_suffix was empty
-    path = path[:-len(old_suffix)]
-
-  if new_suffix:
-    # if present, appends new_suffix, after '/' separator
-    path = '%s/%s' % (path, new_suffix)
-
-  if params:
-    # appends any query parameters, after a '?' and separated by '&'
-    path = '%s?%s' % (path, '&'.join(
-        ['%s=%s' % (p,v) for p,v in params.iteritems()]))
-
-  return path
diff --git a/app/soc/views/oauth.py b/app/soc/views/oauth.py
index dd459c2..00614c0 100644
--- a/app/soc/views/oauth.py
+++ b/app/soc/views/oauth.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2011 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,20 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing views for Open Auth.
-"""
-
+"""Module containing views for Open Auth."""
 
 from django.conf.urls.defaults import url as django_url
 
 from soc.views.helper.gdata_apis import oauth as oauth_helper
 
-from soc.modules.gsoc.views.base import RequestHandler
+# TODO(nathaniel): modules-gsoc code being imported in non modules-gsoc code.
+from soc.modules.gsoc.views.base import GSoCRequestHandler
 
 
-class OAuthRedirectPage(RequestHandler):
-  """Redirect page to Google Documents.
-  """
+class OAuthRedirectPage(GSoCRequestHandler):
+  """Redirect page to Google Documents."""
 
   def djangoURLPatterns(self):
     patterns = [
@@ -57,9 +53,8 @@
     pass
 
 
-class OAuthVerifyToken(RequestHandler):
-  """Verify request token and redirect user.
-  """
+class OAuthVerifyToken(GSoCRequestHandler):
+  """Verify request token and redirect user."""
 
   def djangoURLPatterns(self):
     patterns = [
@@ -75,9 +70,8 @@
     return self.response
 
 
-class PopupOAuthRedirectPage(RequestHandler):
-  """Redirects popup page to Google Documents.
-  """
+class PopupOAuthRedirectPage(GSoCRequestHandler):
+  """Redirects popup page to Google Documents."""
 
   def djangoURLPatterns(self):
     patterns = [
@@ -104,9 +98,8 @@
     return self.response
 
 
-class PopupOAuthVerified(RequestHandler):
-  """ Calls parent window's methods to indicate successful login.
-  """
+class PopupOAuthVerified(GSoCRequestHandler):
+  """ Calls parent window's methods to indicate successful login."""
 
   def djangoURLPatterns(self):
     patterns = [
diff --git a/app/soc/views/org_home.py b/app/soc/views/org_home.py
index fb2df46..fd05387 100644
--- a/app/soc/views/org_home.py
+++ b/app/soc/views/org_home.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python
-#
 # Copyright 2012 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module containing the views for Organization Homepage.
-"""
-
+"""Module containing the views for Organization Homepage."""
 
 from google.appengine.ext import db
 
@@ -27,8 +23,7 @@
 
 
 class BanOrgPost(object):
-  """Handles banning/unbanning of organizations.
-  """
+  """Handles banning/unbanning of organizations."""
 
   def djangoURLPatterns(self):
     return [
@@ -43,7 +38,7 @@
 
   def post(self):
     assert isSet(self.data.organization)
-    
+
     value = self.data.POST.get('value')
     org_key = self.data.organization.key()
 
@@ -83,12 +78,14 @@
   def context(self):
     assert isSet(self.data.organization)
 
-    r = self.data.redirect.organization()
+    # TODO(nathaniel): make this .organization() call unnecessary.
+    self.data.redirect.organization()
+
     is_banned = self.data.organization.status == 'invalid'
 
     org_banned = ToggleButtonTemplate(
         self.data, 'on_off', 'Banned', 'organization-banned',
-        r.urlOf(self._getActionURLName()),
+        self.data.redirect.urlOf(self._getActionURLName()),
         checked=is_banned,
         help_text=self._getHelpText(),
         labels={
diff --git a/app/soc/views/profile_show.py b/app/soc/views/profile_show.py
index 255c850..7d618d4 100644
--- a/app/soc/views/profile_show.py
+++ b/app/soc/views/profile_show.py
@@ -1,5 +1,3 @@
-#!/usr/bin/env python2.5
-#
 # Copyright 2012 the Melange authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -14,9 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"""Module for displaying the Profile read-only page.
-"""
-
+"""Module for displaying the Profile read-only page."""
 
 from google.appengine.ext import db
 
@@ -27,8 +23,6 @@
 from soc.views.template import Template
 from soc.views.toggle_button import ToggleButtonTemplate
 
-from soc.modules.gsoc.views.base import RequestHandler
-
 
 class UserReadOnlyTemplate(readonly_template.ModelReadOnlyTemplate):
   """Template to construct readonly Profile data.
@@ -105,7 +99,7 @@
 
   def post(self):
     assert isSet(self.data.url_profile)
-    
+
     value = self.data.POST.get('value')
     profile_key = self.data.url_profile.key()
 
diff --git a/app/soc/views/site.py b/app/soc/views/site.py
index 7eb7c5d..9e923ef 100644
--- a/app/soc/views/site.py
+++ b/app/soc/views/site.py
@@ -18,6 +18,7 @@
 
 from google.appengine.api import users
 
+from django import http
 from django.conf.urls.defaults import url as django_url
 from django.forms import widgets as django_widgets
 from django.utils.functional import lazy
@@ -131,12 +132,11 @@
     ]
 
   def __call__(self, request, *args, **kwargs):
-    """Custom call implementation.
-
-    This avoids looking up unneeded data.
-    """
-    self.response = base.Response()
-
+    """Custom call implementation that avoids looking up unneeded data."""
+    # TODO(nathaniel): eliminate this - the RedirectHelper (self.redirect)
+    # should simply return a newly-crafted HttpResponse.
+    # TODO(nathaniel): this blocks (and is part of) issue 1665.
+    self.response = http.HttpResponse()
     try:
       self.init(request, args, kwargs)
 
@@ -150,10 +150,13 @@
         settings = site_logic.singleton()
         program = settings.active_program
         if program:
-          self.redirect.program(program).to(program.homepage_url_name)
+          # TODO(nathaniel): make this .program call unnecessary.
+          self.redirect.program(program=program)
+
+          self.redirect.to(program.homepage_url_name)
         else:
           self.redirect.to('edit_site_settings')
-    except exceptions.Error, e:
-      self.response = self.error(e.status, message=e.args[0])
 
-    return self.response
+      return self.response
+    except exceptions.Error, e:
+      return self.error(e.status, message=e.args[0])
diff --git a/app/soc/views/sitemap/__init__.py b/app/soc/views/sitemap/__init__.py
deleted file mode 100644
index 79b8182..0000000
--- a/app/soc/views/sitemap/__init__.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#   http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""This module contains sitemap and sidebar related submodules."""
\ No newline at end of file
diff --git a/app/soc/views/sitemap/sitemap.py b/app/soc/views/sitemap/sitemap.py
deleted file mode 100644
index 245ba1c..0000000
--- a/app/soc/views/sitemap/sitemap.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python2.5
-#
-# Copyright 2008 the Melange authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#   http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Module contains sidemap related functions.
-"""
-
-
-def getDjangoURLPatterns(params):
-  """Retrieves a list of sidebar entries for this View.
-
-  Params usage:
-    The params dictionary is passed to the getKeyFieldsPatterns
-    method, see it's docstring on how it is used.
-    
-    django_patterns: The django_patterns value is returned directly
-      if it is non-False.
-    django_patterns_defaults: The dajngo_patterns_defaults value is
-      used to construct the url patterns. It is expected to be a
-      list of tuples. The tuples should contain an url, a module
-      name, and the name of the url. The name is used as the
-      page_name passed as keyword argument, but also as the name
-      by which the url is known to Django internally.
-    url_name: The url_name argument is passed as argument to each
-      url, together with the link_id pattern, the link_id core
-      pattern, and the key fields for this View.
-
-  Args:
-    params: a dict with params for this View
-  """
-
-  # Return the found result
-  if params['django_patterns']:
-    return params['django_patterns']
-
-  # Construct defaults manualy
-  default_django_patterns = params['django_patterns_defaults']
-  default_patterns = default_django_patterns[:]
-  default_patterns += params['extra_django_patterns']
-
-  patterns = []
-
-  for url, module, name in default_patterns:
-    name = name % params
-    module = module % params
-
-    url = url % {
-        'url_name': params['url_name'],
-        'lnp': params['link_id_arg_pattern'],
-        'ulnp': params['link_id_pattern_core'],
-        'key_fields': params['key_fields_pattern'],
-        'scope': params['scope_path_pattern'],
-        'sans_link_id': params['sans_link_id_pattern'],
-        }
-
-    kwargs = {'page_name': name}
-
-    item = (url, module, kwargs, name)
-    patterns.append(item)
-
-  return patterns