diff --git a/services/usergroup_svc.py b/services/usergroup_svc.py
new file mode 100644
index 0000000..72797fc
--- /dev/null
+++ b/services/usergroup_svc.py
@@ -0,0 +1,616 @@
+# 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
+
+"""Persistence class for user groups.
+
+User groups are represented in the database by:
+- A row in the Users table giving an email address and user ID.
+  (A "group ID" is the user_id of the group in the User table.)
+- A row in the UserGroupSettings table giving user group settings.
+
+Membership of a user X in user group Y is represented as:
+- A row in the UserGroup table with user_id=X and group_id=Y.
+"""
+from __future__ import print_function
+from __future__ import division
+from __future__ import absolute_import
+
+import collections
+import logging
+import re
+
+from framework import exceptions
+from framework import permissions
+from framework import sql
+from proto import usergroup_pb2
+from services import caches
+
+
+USERGROUP_TABLE_NAME = 'UserGroup'
+USERGROUPSETTINGS_TABLE_NAME = 'UserGroupSettings'
+USERGROUPPROJECTS_TABLE_NAME = 'Group2Project'
+
+USERGROUP_COLS = ['user_id', 'group_id', 'role']
+USERGROUPSETTINGS_COLS = ['group_id', 'who_can_view_members',
+                          'external_group_type', 'last_sync_time',
+                          'notify_members', 'notify_group']
+USERGROUPPROJECTS_COLS = ['group_id', 'project_id']
+
+GROUP_TYPE_ENUM = (
+    'chrome_infra_auth', 'mdb', 'baggins', 'computed')
+
+
+class MembershipTwoLevelCache(caches.AbstractTwoLevelCache):
+  """Class to manage RAM and memcache for each user's memberships."""
+
+  def __init__(self, cache_manager, usergroup_service, group_dag):
+    super(MembershipTwoLevelCache, self).__init__(
+        cache_manager, 'user', 'memberships:', None)
+    self.usergroup_service = usergroup_service
+    self.group_dag = group_dag
+
+  def _DeserializeMemberships(self, memberships_rows):
+    """Reserialize the DB results into a {user_id: {group_id}}."""
+    result_dict = collections.defaultdict(set)
+    for user_id, group_id in memberships_rows:
+      result_dict[user_id].add(group_id)
+
+    return result_dict
+
+  def FetchItems(self, cnxn, keys):
+    """On RAM and memcache miss, hit the database to get memberships."""
+    direct_memberships_rows = self.usergroup_service.usergroup_tbl.Select(
+        cnxn, cols=['user_id', 'group_id'], distinct=True,
+        user_id=keys)
+    memberships_set = set()
+    self.group_dag.MarkObsolete()
+    logging.info('Rebuild group dag on RAM and memcache miss')
+    for c_id, p_id in direct_memberships_rows:
+      all_parents = self.group_dag.GetAllAncestors(cnxn, p_id, True)
+      all_parents.append(p_id)
+      memberships_set.update([(c_id, g_id) for g_id in all_parents])
+    retrieved_dict = self._DeserializeMemberships(list(memberships_set))
+
+    # Make sure that every requested user is in the result, and gets cached.
+    retrieved_dict.update(
+        (user_id, set()) for user_id in keys
+        if user_id not in retrieved_dict)
+    return retrieved_dict
+
+
+class UserGroupService(object):
+  """The persistence layer for user group data."""
+
+  def __init__(self, cache_manager):
+    """Initialize this service so that it is ready to use.
+
+    Args:
+      cache_manager: local cache with distributed invalidation.
+    """
+    self.usergroup_tbl = sql.SQLTableManager(USERGROUP_TABLE_NAME)
+    self.usergroupsettings_tbl = sql.SQLTableManager(
+        USERGROUPSETTINGS_TABLE_NAME)
+    self.usergroupprojects_tbl = sql.SQLTableManager(
+        USERGROUPPROJECTS_TABLE_NAME)
+
+    self.group_dag = UserGroupDAG(self)
+
+    # Like a dictionary {user_id: {group_id}}
+    self.memberships_2lc = MembershipTwoLevelCache(
+        cache_manager, self, self.group_dag)
+    # Like a dictionary {group_email: [group_id]}
+    self.group_id_cache = caches.ValueCentricRamCache(
+        cache_manager, 'usergroup')
+
+  ### Group creation
+
+  def CreateGroup(self, cnxn, services, group_name, who_can_view_members,
+                  ext_group_type=None, friend_projects=None):
+    """Create a new user group.
+
+    Args:
+      cnxn: connection to SQL database.
+      services: connections to backend services.
+      group_name: string email address of the group to create.
+      who_can_view_members: 'owners', 'members', or 'anyone'.
+      ext_group_type: The type of external group to import.
+      friend_projects: The project ids declared as group friends to view its
+        members.
+
+    Returns:
+      int group_id of the new group.
+    """
+    friend_projects = friend_projects or []
+    assert who_can_view_members in ('owners', 'members', 'anyone')
+    if ext_group_type:
+      ext_group_type = str(ext_group_type).lower()
+      assert ext_group_type in GROUP_TYPE_ENUM, ext_group_type
+      assert who_can_view_members == 'owners'
+    group_id = services.user.LookupUserID(
+        cnxn, group_name.lower(), autocreate=True, allowgroups=True)
+    group_settings = usergroup_pb2.MakeSettings(
+        who_can_view_members, ext_group_type, 0, friend_projects)
+    self.UpdateSettings(cnxn, group_id, group_settings)
+    self.group_id_cache.InvalidateAll(cnxn)
+    return group_id
+
+  def DeleteGroups(self, cnxn, group_ids):
+    """Delete groups' members and settings. It will NOT delete user entries.
+
+    Args:
+      cnxn: connection to SQL database.
+      group_ids: list of group ids to delete.
+    """
+    member_ids_dict, owner_ids_dict = self.LookupMembers(cnxn, group_ids)
+    citizens_id_dict = collections.defaultdict(list)
+    for g_id, user_ids in member_ids_dict.items():
+      citizens_id_dict[g_id].extend(user_ids)
+    for g_id, user_ids in owner_ids_dict.items():
+      citizens_id_dict[g_id].extend(user_ids)
+    for g_id, citizen_ids in citizens_id_dict.items():
+      logging.info('Deleting group %d', g_id)
+      # Remove group members, friend projects and settings
+      self.RemoveMembers(cnxn, g_id, citizen_ids)
+      self.usergroupprojects_tbl.Delete(cnxn, group_id=g_id)
+      self.usergroupsettings_tbl.Delete(cnxn, group_id=g_id)
+    self.group_id_cache.InvalidateAll(cnxn)
+
+  def DetermineWhichUserIDsAreGroups(self, cnxn, user_ids):
+    """From a list of user IDs, identify potential user groups.
+
+    Args:
+      cnxn: connection to SQL database.
+      user_ids: list of user IDs to examine.
+
+    Returns:
+      A list with a subset of the given user IDs that are user groups
+      rather than individual users.
+    """
+    # It is a group if there is any entry in the UserGroupSettings table.
+    group_id_rows = self.usergroupsettings_tbl.Select(
+        cnxn, cols=['group_id'], group_id=user_ids)
+    group_ids = [row[0] for row in group_id_rows]
+    return group_ids
+
+  ### User memberships in groups
+
+  def LookupComputedMemberships(self, cnxn, domain, use_cache=True):
+    """Look up the computed group memberships of a list of users.
+
+    Args:
+      cnxn: connection to SQL database.
+      domain: string with domain part of user's email address.
+      use_cache: set to False to ignore cached values.
+
+    Returns:
+      A list [group_id] of computed user groups that match the user.
+      For now, the length of this list will always be zero or one.
+    """
+    group_email = 'everyone@%s' % domain
+    group_id = self.LookupUserGroupID(cnxn, group_email, use_cache=use_cache)
+    if group_id:
+      return [group_id]
+
+    return []
+
+  def LookupUserGroupID(self, cnxn, group_email, use_cache=True):
+    """Lookup the group ID for the given user group email address.
+
+    Args:
+      cnxn: connection to SQL database.
+      group_email: string that identies the user group.
+      use_cache: set to False to ignore cached values.
+
+    Returns:
+      Int group_id if found, otherwise None.
+    """
+    if use_cache and self.group_id_cache.HasItem(group_email):
+      return self.group_id_cache.GetItem(group_email)
+
+    rows = self.usergroupsettings_tbl.Select(
+        cnxn, cols=['email', 'group_id'],
+        left_joins=[('User ON UserGroupSettings.group_id = User.user_id', [])],
+        email=group_email,
+        where=[('group_id IS NOT NULL', [])])
+    retrieved_dict = dict(rows)
+    # Cache a "not found" value for emails that are not user groups.
+    if group_email not in retrieved_dict:
+      retrieved_dict[group_email] = None
+    self.group_id_cache.CacheAll(retrieved_dict)
+
+    return retrieved_dict.get(group_email)
+
+  def LookupAllMemberships(self, cnxn, user_ids, use_cache=True):
+    """Lookup all the group memberships of a list of users.
+
+    Args:
+      cnxn: connection to SQL database.
+      user_ids: list of int user IDs to get memberships for.
+      use_cache: set to False to ignore cached values.
+
+    Returns:
+      A dict {user_id: {group_id}} for the given user_ids.
+    """
+    result_dict, missed_ids = self.memberships_2lc.GetAll(
+        cnxn, user_ids, use_cache=use_cache)
+    assert not missed_ids
+    return result_dict
+
+  def LookupMemberships(self, cnxn, user_id):
+    """Return a set of group_ids that this user is a member of."""
+    membership_dict = self.LookupAllMemberships(cnxn, [user_id])
+    return membership_dict[user_id]
+
+  ### Group member addition, removal, and retrieval
+
+  def RemoveMembers(self, cnxn, group_id, old_member_ids):
+    """Remove the given members/owners from the user group."""
+    self.usergroup_tbl.Delete(
+        cnxn, group_id=group_id, user_id=old_member_ids)
+
+    all_affected = self._GetAllMembersInList(cnxn, old_member_ids)
+
+    self.group_dag.MarkObsolete()
+    self.memberships_2lc.InvalidateAllKeys(cnxn, all_affected)
+
+  def UpdateMembers(self, cnxn, group_id, member_ids, new_role):
+    """Update role for given members/owners to the user group."""
+    # Circle detection
+    for mid in member_ids:
+      if self.group_dag.IsChild(cnxn, group_id, mid):
+        raise exceptions.CircularGroupException(
+            '%s is already an ancestor of group %s.' % (mid, group_id))
+
+    self.usergroup_tbl.Delete(
+        cnxn, group_id=group_id, user_id=member_ids)
+    rows = [(member_id, group_id, new_role) for member_id in member_ids]
+    self.usergroup_tbl.InsertRows(
+        cnxn, ['user_id', 'group_id', 'role'], rows)
+
+    all_affected = self._GetAllMembersInList(cnxn, member_ids)
+
+    self.group_dag.MarkObsolete()
+    self.memberships_2lc.InvalidateAllKeys(cnxn, all_affected)
+
+  def _GetAllMembersInList(self, cnxn, group_ids):
+    """Get all direct/indirect members/owners in a list."""
+    children_member_ids, children_owner_ids = self.LookupAllMembers(
+        cnxn, group_ids)
+    all_members_owners = set()
+    all_members_owners.update(group_ids)
+    for users in children_member_ids.values():
+      all_members_owners.update(users)
+    for users in children_owner_ids.values():
+      all_members_owners.update(users)
+    return list(all_members_owners)
+
+  def LookupAllMembers(self, cnxn, group_ids):
+    """Retrieve user IDs of members/owners of any of the given groups
+    transitively."""
+    member_ids_dict = {}
+    owner_ids_dict = {}
+    if not group_ids:
+      return member_ids_dict, owner_ids_dict
+    direct_member_rows = self.usergroup_tbl.Select(
+        cnxn, cols=['user_id', 'group_id', 'role'], distinct=True,
+        group_id=group_ids)
+    for gid in group_ids:
+      all_descendants = self.group_dag.GetAllDescendants(cnxn, gid, True)
+      indirect_member_rows = []
+      if all_descendants:
+        indirect_member_rows = self.usergroup_tbl.Select(
+            cnxn, cols=['user_id'], distinct=True,
+            group_id=all_descendants)
+
+      # Owners must have direct membership. All indirect users are members.
+      owner_ids_dict[gid] = [m[0] for m in direct_member_rows
+                             if m[1] == gid and m[2] == 'owner']
+      member_ids_list = [r[0] for r in indirect_member_rows]
+      member_ids_list.extend([m[0] for m in direct_member_rows
+                             if m[1] == gid and m[2] == 'member'])
+      member_ids_dict[gid] = list(set(member_ids_list))
+    return member_ids_dict, owner_ids_dict
+
+  def LookupMembers(self, cnxn, group_ids):
+    """"Retrieve user IDs of direct members/owners of any of the given groups.
+
+    Args:
+      cnxn: connection to SQL database.
+      group_ids: list of int user IDs for all user groups to be examined.
+
+    Returns:
+      A dict of member IDs, and a dict of owner IDs keyed by group id.
+    """
+    member_ids_dict = {}
+    owner_ids_dict = {}
+    if not group_ids:
+      return member_ids_dict, owner_ids_dict
+    member_rows = self.usergroup_tbl.Select(
+        cnxn, cols=['user_id', 'group_id', 'role'], distinct=True,
+        group_id=group_ids)
+    for gid in group_ids:
+      member_ids_dict[gid] = [row[0] for row in member_rows
+                               if row[1] == gid and row[2] == 'member']
+      owner_ids_dict[gid] = [row[0] for row in member_rows
+                              if row[1] == gid and row[2] == 'owner']
+    return member_ids_dict, owner_ids_dict
+
+  def ExpandAnyGroupEmailRecipients(self, cnxn, user_ids):
+    """Expand the list with members that are part of a group configured
+       to have notifications sent directly to members. Remove any groups
+       not configured to have notifications sent directly to the group.
+
+    Args:
+      cnxn: connection to SQL database.
+      user_ids: list of user IDs to check.
+
+    Returns:
+      A paire (individual user_ids, transitive_ids). individual_user_ids
+          is a list of user IDs that were in the given user_ids list and
+          that identify individual members or a group that has
+          settings.notify_group set to True. transitive_ids is a list of
+          user IDs of members of any user group in user_ids with
+          settings.notify_members set to True.
+    """
+    group_ids = self.DetermineWhichUserIDsAreGroups(cnxn, user_ids)
+    group_settings_dict = self.GetAllGroupSettings(cnxn, group_ids)
+    member_ids_dict, owner_ids_dict = self.LookupAllMembers(cnxn, group_ids)
+    indirect_ids = set()
+    direct_ids = {uid for uid in user_ids if uid not in group_ids}
+    for gid, settings in group_settings_dict.items():
+      if settings.notify_members:
+        indirect_ids.update(member_ids_dict.get(gid, set()))
+        indirect_ids.update(owner_ids_dict.get(gid, set()))
+      if settings.notify_group:
+        direct_ids.add(gid)
+
+    return list(direct_ids), list(indirect_ids)
+
+  def LookupVisibleMembers(
+      self, cnxn, group_id_list, perms, effective_ids, services):
+    """"Retrieve the list of user group direct member/owner IDs that the user
+    may see.
+
+    Args:
+      cnxn: connection to SQL database.
+      group_id_list: list of int user IDs for all user groups to be examined.
+      perms: optional PermissionSet for the user viewing this page.
+      effective_ids: set of int user IDs for that user and all
+          their group memberships.
+      services: backend services.
+
+    Returns:
+      A list of all the member IDs from any group that the user is allowed
+      to view.
+    """
+    settings_dict = self.GetAllGroupSettings(cnxn, group_id_list)
+    group_ids = list(settings_dict.keys())
+    (owned_project_ids, membered_project_ids,
+     contrib_project_ids) = services.project.GetUserRolesInAllProjects(
+         cnxn, effective_ids)
+    project_ids = owned_project_ids.union(
+        membered_project_ids).union(contrib_project_ids)
+    # We need to fetch all members/owners to determine whether the requester
+    # has permission to view.
+    direct_member_ids_dict, direct_owner_ids_dict = self.LookupMembers(
+        cnxn, group_ids)
+    all_member_ids_dict, all_owner_ids_dict = self.LookupAllMembers(
+        cnxn, group_ids)
+    visible_member_ids = {}
+    visible_owner_ids = {}
+    for gid in group_ids:
+      member_ids = all_member_ids_dict[gid]
+      owner_ids = all_owner_ids_dict[gid]
+
+      if permissions.CanViewGroupMembers(
+          perms, effective_ids, settings_dict[gid], member_ids, owner_ids,
+          project_ids):
+        visible_member_ids[gid] = direct_member_ids_dict[gid]
+        visible_owner_ids[gid] = direct_owner_ids_dict[gid]
+
+    return visible_member_ids, visible_owner_ids
+
+  ### Group settings
+
+  def GetAllUserGroupsInfo(self, cnxn):
+    """Fetch (addr, member_count, usergroup_settings) for all user groups."""
+    group_rows = self.usergroupsettings_tbl.Select(
+        cnxn, cols=['email'] + USERGROUPSETTINGS_COLS,
+        left_joins=[('User ON UserGroupSettings.group_id = User.user_id', [])])
+    count_rows = self.usergroup_tbl.Select(
+        cnxn, cols=['group_id', 'COUNT(*)'],
+        group_by=['group_id'])
+    count_dict = dict(count_rows)
+
+    group_ids = [g[1] for g in group_rows]
+    friends_dict = self.GetAllGroupFriendProjects(cnxn, group_ids)
+
+    user_group_info_tuples = [
+        (email, count_dict.get(group_id, 0),
+         usergroup_pb2.MakeSettings(visiblity, group_type, last_sync_time,
+                                    friends_dict.get(group_id, []),
+                                    bool(notify_members), bool(notify_group)),
+         group_id)
+        for (email, group_id, visiblity, group_type, last_sync_time,
+             notify_members, notify_group) in group_rows]
+    return user_group_info_tuples
+
+  def GetAllGroupSettings(self, cnxn, group_ids):
+    """Fetch {group_id: group_settings} for the specified groups."""
+    # TODO(jrobbins): add settings to control who can join, etc.
+    rows = self.usergroupsettings_tbl.Select(
+        cnxn, cols=USERGROUPSETTINGS_COLS, group_id=group_ids)
+    friends_dict = self.GetAllGroupFriendProjects(cnxn, group_ids)
+    settings_dict = {
+        group_id: usergroup_pb2.MakeSettings(
+            vis, group_type, last_sync_time, friends_dict.get(group_id, []),
+            notify_members=bool(notify_members),
+            notify_group=bool(notify_group))
+        for (group_id, vis, group_type, last_sync_time,
+             notify_members, notify_group) in rows}
+    return settings_dict
+
+  def GetGroupSettings(self, cnxn, group_id):
+    """Retrieve group settings for the specified user group.
+
+    Args:
+      cnxn: connection to SQL database.
+      group_id: int user ID of the user group.
+
+    Returns:
+      A UserGroupSettings object, or None if no such group exists.
+    """
+    return self.GetAllGroupSettings(cnxn, [group_id]).get(group_id)
+
+  def UpdateSettings(self, cnxn, group_id, group_settings):
+    """Update the visiblity settings of the specified group."""
+    who_can_view_members = str(group_settings.who_can_view_members).lower()
+    ext_group_type = group_settings.ext_group_type
+    assert who_can_view_members in ('owners', 'members', 'anyone')
+    if ext_group_type:
+      ext_group_type = str(group_settings.ext_group_type).lower()
+      assert ext_group_type in GROUP_TYPE_ENUM, ext_group_type
+      assert who_can_view_members == 'owners'
+    self.usergroupsettings_tbl.InsertRow(
+        cnxn, group_id=group_id, who_can_view_members=who_can_view_members,
+        external_group_type=ext_group_type,
+        last_sync_time=group_settings.last_sync_time,
+        notify_members=group_settings.notify_members,
+        notify_group=group_settings.notify_group,
+        replace=True)
+    self.usergroupprojects_tbl.Delete(
+        cnxn, group_id=group_id)
+    if group_settings.friend_projects:
+      rows = [(group_id, p_id) for p_id in group_settings.friend_projects]
+      self.usergroupprojects_tbl.InsertRows(
+        cnxn, ['group_id', 'project_id'], rows)
+
+  def GetAllGroupFriendProjects(self, cnxn, group_ids):
+    """Get {group_id: [project_ids]} for the specified user groups."""
+    rows = self.usergroupprojects_tbl.Select(
+        cnxn, cols=USERGROUPPROJECTS_COLS, group_id=group_ids)
+    friends_dict = {}
+    for group_id, project_id in rows:
+      friends_dict.setdefault(group_id, []).append(project_id)
+    return friends_dict
+
+  def GetGroupFriendProjects(self, cnxn, group_id):
+    """Get a list of friend projects for the specified user group."""
+    return self.GetAllGroupFriendProjects(cnxn, [group_id]).get(group_id)
+
+  def ValidateFriendProjects(self, cnxn, services, friend_projects):
+    """Validate friend projects.
+
+    Returns:
+      A list of project ids if no errors, or an error message.
+    """
+    project_names = list(filter(None, re.split('; |, | |;|,', friend_projects)))
+    id_dict = services.project.LookupProjectIDs(cnxn, project_names)
+    missed_projects = []
+    result = []
+    for p_name in project_names:
+      if p_name in id_dict:
+        result.append(id_dict[p_name])
+      else:
+        missed_projects.append(p_name)
+    error_msg = ''
+    if missed_projects:
+      error_msg = 'Project(s) %s do not exist' % ', '.join(missed_projects)
+      return None, error_msg
+    else:
+      return result, None
+
+  # TODO(jrobbins): re-implement FindUntrustedGroups()
+
+  def ExpungeUsersInGroups(self, cnxn, ids):
+    """Wipes the given user from the groups system.
+    The given user_ids may to members or groups, or groups themselves.
+    The groups and all their members will be deleted. The users will be
+    wiped from the groups they belong to.
+
+    It will NOT delete user entries. This method will not commit the
+    operations. This method will not make any changes to in-memory data.
+    """
+    # Delete any groups
+    self.usergroupprojects_tbl.Delete(cnxn, group_id=ids, commit=False)
+    self.usergroupsettings_tbl.Delete(cnxn, group_id=ids, commit=False)
+    self.usergroup_tbl.Delete(cnxn, group_id=ids, commit=False)
+
+    # Delete any group members
+    self.usergroup_tbl.Delete(cnxn, user_id=ids, commit=False)
+
+
+class UserGroupDAG(object):
+  """A directed-acyclic graph of potentially nested user groups."""
+
+  def __init__(self, usergroup_service):
+    self.usergroup_service = usergroup_service
+    self.user_group_parents = collections.defaultdict(list)
+    self.user_group_children = collections.defaultdict(list)
+    self.initialized = False
+
+  def Build(self, cnxn, circle_detection=False):
+    if not self.initialized:
+      self.user_group_parents.clear()
+      self.user_group_children.clear()
+      group_ids = self.usergroup_service.usergroupsettings_tbl.Select(
+          cnxn, cols=['group_id'])
+      usergroup_rows = self.usergroup_service.usergroup_tbl.Select(
+          cnxn, cols=['user_id', 'group_id'], distinct=True,
+          user_id=[r[0] for r in group_ids])
+      for user_id, group_id in usergroup_rows:
+        self.user_group_parents[user_id].append(group_id)
+        self.user_group_children[group_id].append(user_id)
+    self.initialized = True
+
+    if circle_detection:
+      for child_id, parent_ids in self.user_group_parents.items():
+        for parent_id in parent_ids:
+          if self.IsChild(cnxn, parent_id, child_id):
+            logging.error(
+                'Circle exists between group %d and %d.', child_id, parent_id)
+
+  def GetAllAncestors(self, cnxn, group_id, circle_detection=False):
+    """Return a list of distinct ancestor group IDs for the given group."""
+    self.Build(cnxn, circle_detection)
+    result = set()
+    child_ids = [group_id]
+    while child_ids:
+      parent_ids = set()
+      for c_id in child_ids:
+        group_ids = self.user_group_parents[c_id]
+        parent_ids.update(g_id for g_id in group_ids if g_id not in result)
+        result.update(parent_ids)
+      child_ids = list(parent_ids)
+    return list(result)
+
+  def GetAllDescendants(self, cnxn, group_id, circle_detection=False):
+    """Return a list of distinct descendant group IDs for the given group."""
+    self.Build(cnxn, circle_detection)
+    result = set()
+    parent_ids = [group_id]
+    while parent_ids:
+      child_ids = set()
+      for p_id in parent_ids:
+        group_ids = self.user_group_children[p_id]
+        child_ids.update(g_id for g_id in group_ids if g_id not in result)
+        result.update(child_ids)
+      parent_ids = list(child_ids)
+    return list(result)
+
+  def IsChild(self, cnxn, child_id, parent_id):
+    """Returns True if child_id is a direct/indirect child of parent_id."""
+    all_descendants = self.GetAllDescendants(cnxn, parent_id)
+    return child_id in all_descendants
+
+  def MarkObsolete(self):
+    """Mark the DAG as uninitialized so it'll be re-built."""
+    self.initialized = False
+
+  def __repr__(self):
+    result = {}
+    result['parents'] = self.user_group_parents
+    result['children'] = self.user_group_children
+    return str(result)
