code: def _map_agent_sites(self, agent):
          
          # If there are no modifications on this agent, then we can return the
          # copy of the agent
          if agent is None or not agent.mods:
              return [], agent
          new_agent = deepcopy(agent)
          mapped_sites = []
          # Now iterate over all the modifications and map each one
          for idx, mod_condition in enumerate(agent.mods):
              mapped_site = \
                  self._map_agent_mod(agent, mod_condition)
              # If we couldn't do the mapping or the mapped site isn't invalid
              # then we don't need to change the existing ModCondition
              if not mapped_site or mapped_site.not_invalid():
                  continue
              # Otherwise, if there is a mapping, we replace the old ModCondition
              # with the new one where only the residue and position are updated,
              # the mod type and the is modified flag are kept.
              if mapped_site.has_mapping():
                  mc = ModCondition(mod_condition.mod_type,
                                    mapped_site.mapped_res,
                                    mapped_site.mapped_pos,
                                    mod_condition.is_modified)
                  new_agent.mods[idx] = mc
              # Finally, whether or not we have a mapping, we keep track of mapped
              # sites and make them available to the caller
              mapped_sites.append(mapped_site)
          return mapped_sites, new_agent
docs: Check an agent for invalid sites and update if necessary.
  
          Parameters
          ----------
          agent : :py:class:`indra.statements.Agent`
              Agent to check for invalid modification sites.
  
          Returns
          -------
          tuple
              The first element is a list of MappedSite objects, the second
              element is either the original Agent, if unchanged, or a copy
              of it.