diff --git a/features/hotlistpeople.py b/features/hotlistpeople.py
new file mode 100644
index 0000000..1eb00ff
--- /dev/null
+++ b/features/hotlistpeople.py
@@ -0,0 +1,252 @@
+# Copyright 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file or at
+# https://developers.google.com/open-source/licenses/bsd
+
+"""Classes to implement the hotlistpeople page and related forms."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import logging
+import time
+
+import ezt
+
+from features import hotlist_helpers
+from features import hotlist_views
+from framework import framework_helpers
+from framework import framework_views
+from framework import paginate
+from framework import permissions
+from framework import servlet
+from framework import urls
+from project import project_helpers
+
+MEMBERS_PER_PAGE = 50
+
+
+class HotlistPeopleList(servlet.Servlet):
+  _PAGE_TEMPLATE = 'project/people-list-page.ezt'
+  # Note: using the project's peoplelist page template. minor edits were
+  # to make it compatible with HotlistPeopleList
+  _MAIN_TAB_MODE = servlet.Servlet.HOTLIST_TAB_PEOPLE
+
+  def AssertBasePermission(self, mr):
+    super(HotlistPeopleList, self).AssertBasePermission(mr)
+    if not permissions.CanViewHotlist(
+        mr.auth.effective_ids, mr.perms, mr.hotlist):
+      raise permissions.PermissionException(
+          'User is now allowed to view the hotlist people list')
+
+  def GatherPageData(self, mr):
+    """Build up a dictionary of data values to use when rendering the page."""
+    if mr.auth.user_id:
+      self.services.user.AddVisitedHotlist(
+          mr.cnxn, mr.auth.user_id, mr.hotlist_id)
+
+    all_members = (mr.hotlist.owner_ids +
+                   mr.hotlist.editor_ids + mr.hotlist.follower_ids)
+
+    hotlist_url = hotlist_helpers.GetURLOfHotlist(
+        mr.cnxn, mr.hotlist, self.services.user)
+
+    with mr.profiler.Phase('gathering members on this page'):
+      users_by_id = framework_views.MakeAllUserViews(
+          mr.cnxn, self.services.user, all_members)
+      framework_views.RevealAllEmailsToMembers(
+          mr.cnxn, self.services, mr.auth, users_by_id, mr.project)
+
+    untrusted_user_group_proxies = []
+    # TODO(jojwang): implement FindUntrustedGroups()
+
+    with mr.profiler.Phase('making member views'):
+      owner_views = self._MakeMemberViews(mr, mr.hotlist.owner_ids, users_by_id)
+      editor_views = self._MakeMemberViews(mr, mr.hotlist.editor_ids,
+                                           users_by_id)
+      follower_views = self._MakeMemberViews(mr, mr.hotlist.follower_ids,
+                                             users_by_id)
+      all_member_views = owner_views + editor_views + follower_views
+
+    url_params = [(name, mr.GetParam(name)) for name in
+                  framework_helpers.RECOGNIZED_PARAMS]
+    # We are passing in None for the project_name because we are not operating
+    # under any project.
+    pagination = paginate.ArtifactPagination(
+        all_member_views, mr.GetPositiveIntParam('num', MEMBERS_PER_PAGE),
+        mr.GetPositiveIntParam('start'), None,
+        '%s%s' % (hotlist_url, urls.HOTLIST_PEOPLE), url_params=url_params)
+
+    offer_membership_editing = permissions.CanAdministerHotlist(
+        mr.auth.effective_ids, mr.perms, mr.hotlist)
+
+    offer_remove_self = (
+        not offer_membership_editing and
+        mr.auth.user_id and
+        mr.auth.user_id in mr.hotlist.editor_ids)
+
+    newly_added_views = [mv for mv in all_member_views
+                         if str(mv.user.user_id) in mr.GetParam('new', [])]
+
+    return {
+        'is_hotlist': ezt.boolean(True),
+        'untrusted_user_groups': untrusted_user_group_proxies,
+        'pagination': pagination,
+        'initial_add_members': '',
+        'subtab_mode': None,
+        'initially_expand_form': ezt.boolean(False),
+        'newly_added_views': newly_added_views,
+        'offer_membership_editing': ezt.boolean(offer_membership_editing),
+        'offer_remove_self': ezt.boolean(offer_remove_self),
+        'total_num_owners': len(mr.hotlist.owner_ids),
+        'check_abandonment': ezt.boolean(True),
+        'initial_new_owner_username': '',
+        'placeholder': 'new-owner-username',
+        'open_dialog': ezt.boolean(False),
+        'viewing_user_page': ezt.boolean(True),
+        'new_ui_url': '%s/%s/people' % (urls.HOTLISTS, mr.hotlist_id),
+    }
+
+  def ProcessFormData(self, mr, post_data):
+    """Process the posted form."""
+    permit_edit = permissions.CanAdministerHotlist(
+        mr.auth.effective_ids, mr.perms, mr.hotlist)
+    can_remove_self = (
+        not permit_edit and
+        mr.auth.user_id and
+        mr.auth.user_id in mr.hotlist.editor_ids)
+    if not can_remove_self and not permit_edit:
+      raise permissions.PermissionException(
+          'User is not permitted to edit hotlist membership')
+    hotlist_url = hotlist_helpers.GetURLOfHotlist(
+        mr.cnxn, mr.hotlist, self.services.user)
+    if permit_edit:
+      if 'addbtn' in post_data:
+        return self.ProcessAddMembers(mr, post_data, hotlist_url)
+      elif 'removebtn' in post_data:
+        return self.ProcessRemoveMembers(mr, post_data, hotlist_url)
+      elif 'changeowners' in post_data:
+        return self.ProcessChangeOwnership(mr, post_data)
+    if can_remove_self:
+      if 'removeself' in post_data:
+        return self.ProcessRemoveSelf(mr, hotlist_url)
+
+  def _MakeMemberViews(self, mr, member_ids, users_by_id):
+    """Return a sorted list of MemberViews for display by EZT."""
+    member_views = [hotlist_views.MemberView(
+        mr.auth.user_id, member_id, users_by_id[member_id],
+        mr.hotlist) for member_id in member_ids]
+    member_views.sort(key=lambda mv: mv.user.email)
+    return member_views
+
+  def ProcessChangeOwnership(self, mr, post_data):
+    new_owner_id_set = project_helpers.ParseUsernames(
+        mr.cnxn, self.services.user, post_data.get('changeowners'))
+    remain_as_editor = post_data.get('becomeeditor') == 'on'
+    if len(new_owner_id_set) != 1:
+      mr.errors.transfer_ownership = (
+          'Please add one valid user email.')
+    else:
+      new_owner_id = new_owner_id_set.pop()
+      if self.services.features.LookupHotlistIDs(
+          mr.cnxn, [mr.hotlist.name], [new_owner_id]):
+        mr.errors.transfer_ownership = (
+            'This user already owns a hotlist with the same name')
+
+    if mr.errors.AnyErrors():
+      self.PleaseCorrect(
+          mr, initial_new_owner_username=post_data.get('changeowners'),
+          open_dialog=ezt.boolean(True))
+    else:
+      old_and_new_owner_ids = [new_owner_id] + mr.hotlist.owner_ids
+      (_, editor_ids, follower_ids) = hotlist_helpers.MembersWithoutGivenIDs(
+          mr.hotlist, old_and_new_owner_ids)
+      if remain_as_editor and mr.hotlist.owner_ids:
+        editor_ids.append(mr.hotlist.owner_ids[0])
+
+      self.services.features.UpdateHotlistRoles(
+          mr.cnxn, mr.hotlist_id, [new_owner_id], editor_ids, follower_ids)
+
+      hotlist = self.services.features.GetHotlist(mr.cnxn, mr.hotlist_id)
+      hotlist_url = hotlist_helpers.GetURLOfHotlist(
+        mr.cnxn, hotlist, self.services.user)
+      return framework_helpers.FormatAbsoluteURL(
+          mr,'%s%s' % (hotlist_url, urls.HOTLIST_PEOPLE),
+          saved=1, ts=int(time.time()),
+          include_project=False)
+
+  def ProcessAddMembers(self, mr, post_data, hotlist_url):
+    """Process the user's request to add members.
+
+    Args:
+      mr: common information parsed from the HTTP request.
+      post_data: dictionary of form data
+      hotlist_url: hotlist_url to return to after data has been processed.
+
+    Returns:
+      String URL to redirect the user to after processing
+    """
+    # NOTE: using project_helpers function
+    new_member_ids = project_helpers.ParseUsernames(
+        mr.cnxn, self.services.user, post_data.get('addmembers'))
+    if not new_member_ids or not post_data.get('addmembers'):
+      mr.errors.incorrect_email_input = (
+          'Please give full emails seperated by commas.')
+    role = post_data['role']
+
+    (owner_ids, editor_ids, follower_ids) = hotlist_helpers.MembersWithGivenIDs(
+        mr.hotlist, new_member_ids, role)
+    # TODO(jojwang): implement MAX_HOTLIST_PEOPLE
+
+    if not owner_ids:
+      mr.errors.addmembers = (
+          'Cannot have a hotlist without an owner; please leave at least one.')
+
+    if mr.errors.AnyErrors():
+      add_members_str = post_data.get('addmembers', '')
+      self.PleaseCorrect(
+          mr, initial_add_members=add_members_str, initially_expand_form=True)
+    else:
+      self.services.features.UpdateHotlistRoles(
+          mr.cnxn, mr.hotlist_id, owner_ids, editor_ids, follower_ids)
+      return framework_helpers.FormatAbsoluteURL(
+          mr, '%s%s' % (
+              hotlist_url, urls.HOTLIST_PEOPLE),
+          saved=1, ts=int(time.time()),
+          new=','.join([str(u) for u in new_member_ids]),
+          include_project=False)
+
+  def ProcessRemoveMembers(self, mr, post_data, hotlist_url):
+    """Process the user's request to remove members."""
+    remove_strs = post_data.getall('remove')
+    logging.info('remove_strs = %r', remove_strs)
+    remove_ids = set(
+        self.services.user.LookupUserIDs(mr.cnxn, remove_strs).values())
+    (owner_ids, editor_ids,
+     follower_ids) = hotlist_helpers.MembersWithoutGivenIDs(
+         mr.hotlist, remove_ids)
+
+    self.services.features.UpdateHotlistRoles(
+        mr.cnxn, mr.hotlist_id, owner_ids, editor_ids, follower_ids)
+
+    return framework_helpers.FormatAbsoluteURL(
+        mr, '%s%s' % (
+              hotlist_url, urls.HOTLIST_PEOPLE),
+          saved=1, ts=int(time.time()), include_project=False)
+
+  def ProcessRemoveSelf(self, mr, hotlist_url):
+    """Process the request to remove the logged-in user."""
+    remove_ids = [mr.auth.user_id]
+
+    # This function does no permission checking; that's done by the caller.
+    (owner_ids, editor_ids,
+        follower_ids) = hotlist_helpers.MembersWithoutGivenIDs(
+            mr.hotlist, remove_ids)
+
+    self.services.features.UpdateHotlistRoles(
+        mr.cnxn, mr.hotlist_id, owner_ids, editor_ids, follower_ids)
+
+    return framework_helpers.FormatAbsoluteURL(
+        mr, '%s%s' % (
+              hotlist_url, urls.HOTLIST_PEOPLE),
+          saved=1, ts=int(time.time()), include_project=False)
