def ExtractEvents(self, parser_mediator, registry_key, **kwargs):
    """Extracts events from a Windows Registry key.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.
    """
    dynamic_info_size_error_reported = False

    tasks_key = registry_key.GetSubkeyByName('Tasks')
    tree_key = registry_key.GetSubkeyByName('Tree')

    if not tasks_key or not tree_key:
      parser_mediator.ProduceExtractionWarning(
          'Task Cache is missing a Tasks or Tree sub key.')
      return

    task_guids = {}
    for sub_key in tree_key.GetSubkeys():
      for value_key, id_value in self._GetIdValue(sub_key):
        # TODO: improve this check to a regex.
        # The GUID is in the form {%GUID%} and stored an UTF-16 little-endian
        # string and should be 78 bytes in size.
        id_value_data_size = len(id_value.data)
        if id_value_data_size != 78:
          parser_mediator.ProduceExtractionWarning(
              'unsupported Id value data size: {0:d}.'.format(
                  id_value_data_size))
          continue

        guid_string = id_value.GetDataAsObject()
        task_guids[guid_string] = value_key.name

    dynamic_info_map = self._GetDataTypeMap('dynamic_info_record')
    dynamic_info2_map = self._GetDataTypeMap('dynamic_info2_record')

    dynamic_info_size = dynamic_info_map.GetByteSize()
    dynamic_info2_size = dynamic_info2_map.GetByteSize()

    for sub_key in tasks_key.GetSubkeys():
      dynamic_info_value = sub_key.GetValueByName('DynamicInfo')
      if not dynamic_info_value:
        continue

      dynamic_info_record_map = None
      dynamic_info_value_data_size = len(dynamic_info_value.data)
      if dynamic_info_value_data_size == dynamic_info_size:
        dynamic_info_record_map = dynamic_info_map
      elif dynamic_info_value_data_size == dynamic_info2_size:
        dynamic_info_record_map = dynamic_info2_map
      else:
        if not dynamic_info_size_error_reported:
          parser_mediator.ProduceExtractionWarning(
              'unsupported DynamicInfo value data size: {0:d}.'.format(
                  dynamic_info_value_data_size))
          dynamic_info_size_error_reported = True
        continue

      try:
        dynamic_info_record = self._ReadStructureFromByteStream(
            dynamic_info_value.data, 0, dynamic_info_record_map)
      except (ValueError, errors.ParseError) as exception:
        parser_mediator.ProduceExtractionWarning(
            'unable to parse DynamicInfo record with error: {0!s}.'.format(
                exception))

      name = task_guids.get(sub_key.name, sub_key.name)

      values_dict = {}
      values_dict['Task: {0:s}'.format(name)] = '[ID: {0:s}]'.format(
          sub_key.name)

      event_data = windows_events.WindowsRegistryEventData()
      event_data.key_path = registry_key.path
      event_data.offset = registry_key.offset
      event_data.regvalue = values_dict

      event = time_events.DateTimeValuesEvent(
          registry_key.last_written_time, definitions.TIME_DESCRIPTION_WRITTEN)
      parser_mediator.ProduceEventWithEventData(event, event_data)

      event_data = TaskCacheEventData()
      event_data.task_name = name
      event_data.task_identifier = sub_key.name

      last_registered_time = dynamic_info_record.last_registered_time
      if last_registered_time:
        # Note this is likely either the last registered time or
        # the update time.
        date_time = dfdatetime_filetime.Filetime(timestamp=last_registered_time)
        event = time_events.DateTimeValuesEvent(
            date_time, 'Last registered time')
        parser_mediator.ProduceEventWithEventData(event, event_data)

      launch_time = dynamic_info_record.launch_time
      if launch_time:
        # Note this is likely the launch time.
        date_time = dfdatetime_filetime.Filetime(timestamp=launch_time)
        event = time_events.DateTimeValuesEvent(
            date_time, 'Launch time')
        parser_mediator.ProduceEventWithEventData(event, event_data)

      unknown_time = getattr(dynamic_info_record, 'unknown_time', None)
      if unknown_time:
        date_time = dfdatetime_filetime.Filetime(timestamp=unknown_time)
        event = time_events.DateTimeValuesEvent(
            date_time, definitions.TIME_DESCRIPTION_UNKNOWN)
        parser_mediator.ProduceEventWithEventData(event, event_data)
Extracts events from a Windows Registry key.

    Args:
      parser_mediator (ParserMediator): mediates interactions between parsers
          and other components, such as storage and dfvfs.
      registry_key (dfwinreg.WinRegistryKey): Windows Registry key.