diff --git a/features/hotlistissues.py b/features/hotlistissues.py
new file mode 100644
index 0000000..8743772
--- /dev/null
+++ b/features/hotlistissues.py
@@ -0,0 +1,349 @@
+# 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 that implement the hotlistissues page and related forms."""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import logging
+import ezt
+
+import settings
+import time
+import re
+
+from businesslogic import work_env
+from features import features_bizobj
+from features import features_constants
+from features import hotlist_helpers
+from framework import exceptions
+from framework import servlet
+from framework import sorting
+from framework import permissions
+from framework import framework_helpers
+from framework import paginate
+from framework import framework_constants
+from framework import framework_views
+from framework import grid_view_helpers
+from framework import template_helpers
+from framework import timestr
+from framework import urls
+from framework import xsrf
+from services import features_svc
+from tracker import tracker_bizobj
+
+_INITIAL_ADD_ISSUES_MESSAGE = 'projectname:localID, projectname:localID, etc.'
+_MSG_INVALID_ISSUES_INPUT = (
+    'Please follow project_name:issue_id, project_name:issue_id..')
+_MSG_ISSUES_NOT_FOUND = 'One or more of your issues were not found.'
+_MSG_ISSUES_NOT_VIEWABLE = 'You lack permission to view one or more issues.'
+
+
+class HotlistIssues(servlet.Servlet):
+  """HotlistIssues is a page that shows the issues of one hotlist."""
+
+  _PAGE_TEMPLATE = 'features/hotlist-issues-page.ezt'
+  _MAIN_TAB_MODE = servlet.Servlet.HOTLIST_TAB_ISSUES
+
+  def AssertBasePermission(self, mr):
+    """Check that the user has permission to even visit this page."""
+    super(HotlistIssues, self).AssertBasePermission(mr)
+    try:
+      hotlist = self._GetHotlist(mr)
+    except features_svc.NoSuchHotlistException:
+      return
+    permit_view = permissions.CanViewHotlist(
+        mr.auth.effective_ids, mr.perms, hotlist)
+    if not permit_view:
+      raise permissions.PermissionException(
+        'User is not allowed to view this hotlist')
+
+  def GatherPageData(self, mr):
+    """Build up a dictionary of data values to use when rendering the page.
+
+    Args:
+      mr: commonly usef info parsed from the request.
+
+    Returns:
+      Dict of values used by EZT for rendering the page.
+    """
+    with mr.profiler.Phase('getting hotlist'):
+      if mr.hotlist_id is None:
+        self.abort(404, 'no hotlist specified')
+    if mr.auth.user_id:
+      self.services.user.AddVisitedHotlist(
+          mr.cnxn, mr.auth.user_id, mr.hotlist_id)
+
+    if mr.mode == 'grid':
+      page_data = self.GetGridViewData(mr)
+    else:
+      page_data = self.GetTableViewData(mr)
+
+    with mr.profiler.Phase('making page perms'):
+      owner_permissions = permissions.CanAdministerHotlist(
+          mr.auth.effective_ids, mr.perms, mr.hotlist)
+      editor_permissions = permissions.CanEditHotlist(
+          mr.auth.effective_ids, mr.perms, mr.hotlist)
+      # TODO(jojwang): each issue should have an individual
+      # SetStar status based on its project to indicate whether or not
+      # the star icon should be shown to the user.
+      page_perms = template_helpers.EZTItem(
+          EditIssue=None, SetStar=mr.auth.user_id)
+
+    allow_rerank = (not mr.group_by_spec and mr.sort_spec.startswith(
+        'rank') and (owner_permissions or editor_permissions))
+
+    user_hotlists = self.services.features.GetHotlistsByUserID(
+        mr.cnxn, mr.auth.user_id)
+    try:
+      user_hotlists.remove(self.services.features.GetHotlist(
+          mr.cnxn, mr.hotlist_id))
+    except ValueError:
+      pass
+
+    new_ui_url = '%s/%s/issues' % (urls.HOTLISTS, mr.hotlist_id)
+
+    # Note: The HotlistView is created and returned in servlet.py
+    page_data.update(
+        {
+            'owner_permissions':
+                ezt.boolean(owner_permissions),
+            'editor_permissions':
+                ezt.boolean(editor_permissions),
+            'issue_tab_mode':
+                'issueList',
+            'grid_mode':
+                ezt.boolean(mr.mode == 'grid'),
+            'list_mode':
+                ezt.boolean(mr.mode == 'list'),
+            'chart_mode':
+                ezt.boolean(mr.mode == 'chart'),
+            'page_perms':
+                page_perms,
+            'colspec':
+                mr.col_spec,
+            # monorail:6336, used in <ezt-show-columns-connector>
+            'phasespec':
+                "",
+            'allow_rerank':
+                ezt.boolean(allow_rerank),
+            'csv_link':
+                framework_helpers.FormatURL(
+                    [
+                        (name, mr.GetParam(name))
+                        for name in framework_helpers.RECOGNIZED_PARAMS
+                    ],
+                    '%d/csv' % mr.hotlist_id,
+                    num=100),
+            'is_hotlist':
+                ezt.boolean(True),
+            'col_spec':
+                mr.col_spec.lower(),
+            'viewing_user_page':
+                ezt.boolean(True),
+            # for update-issues-hotlists-dialog in
+            # issue-list-controls-top.
+            'user_issue_hotlists': [],
+            'user_remaining_hotlists':
+                user_hotlists,
+            'new_ui_url':
+                new_ui_url,
+        })
+    return page_data
+  # TODO(jojwang): implement peek issue on hover, implement starring issues
+
+  def _GetHotlist(self, mr):
+    """Retrieve the current hotlist."""
+    if mr.hotlist_id is None:
+      return None
+    try:
+      hotlist = self.services.features.GetHotlist(mr.cnxn, mr.hotlist_id)
+    except features_svc.NoSuchHotlistException:
+      self.abort(404, 'hotlist not found')
+    return hotlist
+
+  def GetTableViewData(self, mr):
+    """EZT template values to render a Table View of issues.
+
+    Args:
+      mr: commonly used info parsed from the request.
+
+    Returns:
+      Dictionary of page data for rendering of the Table View.
+    """
+    table_data, table_related_dict = hotlist_helpers.CreateHotlistTableData(
+        mr, mr.hotlist.items, self.services)
+    columns = mr.col_spec.split()
+    ordered_columns = [template_helpers.EZTItem(col_index=i, name=col)
+                       for i, col in enumerate(columns)]
+    table_view_data = {
+        'table_data': table_data,
+        'panels': [template_helpers.EZTItem(ordered_columns=ordered_columns)],
+        'cursor': mr.cursor or mr.preview,
+        'preview': mr.preview,
+        'default_colspec': features_constants.DEFAULT_COL_SPEC,
+        'default_results_per_page': 10,
+        'preview_on_hover': (
+            settings.enable_quick_edit and mr.auth.user_pb.preview_on_hover),
+        # token must be generated using url with userid to accommodate
+        # multiple urls for one hotlist
+        'edit_hotlist_token': xsrf.GenerateToken(
+            mr.auth.user_id,
+            hotlist_helpers.GetURLOfHotlist(
+                mr.cnxn, mr.hotlist, self.services.user,
+                url_for_token=True) + '.do'),
+        'add_local_ids': '',
+        'placeholder': _INITIAL_ADD_ISSUES_MESSAGE,
+        'add_issues_selected': ezt.boolean(False),
+        'col_spec': ''
+        }
+    table_view_data.update(table_related_dict)
+
+    return table_view_data
+
+  def ProcessFormData(self, mr, post_data):
+    if not permissions.CanEditHotlist(
+        mr.auth.effective_ids, mr.perms, mr.hotlist):
+      raise permissions.PermissionException(
+          'User is not allowed to edit this hotlist.')
+
+    hotlist_view_url = hotlist_helpers.GetURLOfHotlist(
+        mr.cnxn, mr.hotlist, self.services.user)
+    current_col_spec = post_data.get('current_col_spec')
+    default_url = framework_helpers.FormatAbsoluteURL(
+        mr, hotlist_view_url,
+        include_project=False, colspec=current_col_spec)
+    sorting.InvalidateArtValuesKeys(
+        mr.cnxn,
+        [hotlist_item.issue_id for hotlist_item
+         in mr.hotlist.items])
+
+    if post_data.get('remove') == 'true':
+      project_and_local_ids = post_data.get('remove_local_ids')
+    else:
+      project_and_local_ids = post_data.get('add_local_ids')
+      if not project_and_local_ids:
+        return default_url
+
+    selected_iids = []
+    if project_and_local_ids:
+      pattern = re.compile(features_constants.ISSUE_INPUT_REGEX)
+      if pattern.match(project_and_local_ids):
+        issue_refs_tuples = [(pair.split(':')[0].strip(),
+                          int(pair.split(':')[1].strip()))
+                             for pair in project_and_local_ids.split(',')
+                             if pair.strip()]
+        project_names = {project_name for (project_name, _) in
+                         issue_refs_tuples}
+        projects_dict = self.services.project.GetProjectsByName(
+            mr.cnxn, project_names)
+        selected_iids, _misses = self.services.issue.ResolveIssueRefs(
+            mr.cnxn, projects_dict, mr.project_name, issue_refs_tuples)
+        if (not selected_iids) or len(issue_refs_tuples) > len(selected_iids):
+          mr.errors.issues = _MSG_ISSUES_NOT_FOUND
+          # TODO(jojwang): give issues that were not found.
+      else:
+        mr.errors.issues = _MSG_INVALID_ISSUES_INPUT
+
+    try:
+      with work_env.WorkEnv(mr, self.services) as we:
+        we.GetIssuesDict(selected_iids)
+    except exceptions.NoSuchIssueException:
+      mr.errors.issues = _MSG_ISSUES_NOT_FOUND
+    except permissions.PermissionException:
+      mr.errors.issues = _MSG_ISSUES_NOT_VIEWABLE
+
+    # TODO(jojwang): fix: when there are errors, hidden column come back on
+    # the .do page but go away once the errors are fixed and the form
+    # is submitted again
+    if mr.errors.AnyErrors():
+      self.PleaseCorrect(
+          mr, add_local_ids=project_and_local_ids,
+          add_issues_selected=ezt.boolean(True), col_spec=current_col_spec)
+
+    else:
+      with work_env.WorkEnv(mr, self.services) as we:
+        if post_data.get('remove') == 'true':
+          we.RemoveIssuesFromHotlists([mr.hotlist_id], selected_iids)
+        else:
+          we.AddIssuesToHotlists([mr.hotlist_id], selected_iids, '')
+      return framework_helpers.FormatAbsoluteURL(
+          mr, hotlist_view_url, saved=1, ts=int(time.time()),
+          include_project=False, colspec=current_col_spec)
+
+  def GetGridViewData(self, mr):
+    """EZT template values to render a Table View of issues.
+
+    Args:
+      mr: commonly used info parsed from the request.
+
+    Returns:
+      Dictionary of page data for rendering of the Table View.
+    """
+    mr.ComputeColSpec(mr.hotlist)
+    starred_iid_set = set(self.services.issue_star.LookupStarredItemIDs(
+        mr.cnxn, mr.auth.user_id))
+    issues_list = self.services.issue.GetIssues(
+        mr.cnxn,
+        [hotlist_issue.issue_id for hotlist_issue
+         in mr.hotlist.items])
+    allowed_issues = hotlist_helpers.FilterIssues(
+        mr.cnxn, mr.auth, mr.can, issues_list, self.services)
+    issue_and_hotlist_users = tracker_bizobj.UsersInvolvedInIssues(
+        allowed_issues or []).union(features_bizobj.UsersInvolvedInHotlists(
+            [mr.hotlist]))
+    users_by_id = framework_views.MakeAllUserViews(
+        mr.cnxn, self.services.user,
+        issue_and_hotlist_users)
+    hotlist_issues_project_ids = hotlist_helpers.GetAllProjectsOfIssues(
+        [issue for issue in issues_list])
+    config_list = hotlist_helpers.GetAllConfigsOfProjects(
+        mr.cnxn, hotlist_issues_project_ids, self.services)
+    harmonized_config = tracker_bizobj.HarmonizeConfigs(config_list)
+    limit = settings.max_issues_in_grid
+    grid_limited = len(allowed_issues) > limit
+    lower_cols = mr.col_spec.lower().split()
+    grid_x = (mr.x or harmonized_config.default_x_attr or '--').lower()
+    grid_y = (mr.y or harmonized_config.default_y_attr or '--').lower()
+    lower_cols.append(grid_x)
+    lower_cols.append(grid_y)
+    related_iids = set()
+    for issue in allowed_issues:
+      if 'blockedon' in lower_cols:
+        related_iids.update(issue.blocked_on_iids)
+      if 'blocking' in lower_cols:
+        related_iids.update(issue.blocking_iids)
+      if 'mergedinto' in lower_cols:
+        related_iids.add(issue.merged_into)
+    related_issues_list = self.services.issue.GetIssues(
+        mr.cnxn, list(related_iids))
+    related_issues = {issue.issue_id: issue for issue in related_issues_list}
+
+    hotlist_context_dict = {
+        hotlist_issue.issue_id: {'adder_id': hotlist_issue.adder_id,
+                                 'date_added': timestr.FormatRelativeDate(
+                                     hotlist_issue.date_added),
+                                 'note': hotlist_issue.note}
+        for hotlist_issue in mr.hotlist.items}
+
+    grid_view_data = grid_view_helpers.GetGridViewData(
+        mr, allowed_issues, harmonized_config,
+        users_by_id, starred_iid_set, grid_limited, related_issues,
+        hotlist_context_dict=hotlist_context_dict)
+
+    url_params = [(name, mr.GetParam(name)) for name in
+                  framework_helpers.RECOGNIZED_PARAMS]
+    # We are passing in None for the project_name in ArtifactPagination
+    # because we are not operating under any project.
+    grid_view_data.update({'pagination': paginate.ArtifactPagination(
+          allowed_issues,
+          mr.GetPositiveIntParam(
+              'num', features_constants.DEFAULT_RESULTS_PER_PAGE),
+          mr.GetPositiveIntParam('start'), None,
+          urls.HOTLIST_ISSUES, total_count=len(allowed_issues),
+          url_params=url_params)})
+
+    return grid_view_data
