code: def dois(self, key, value):
      
      def _get_first_non_curator_source(sources):
          sources_without_curator = [el for el in sources if el.upper() != 'CURATOR']
          return force_single_element(sources_without_curator)
  
      def _get_material(value):
          MATERIAL_MAP = {
              'ebook': 'publication',
          }
  
          q_value = force_single_element(value.get('q', ''))
          normalized_q_value = q_value.lower()
  
          return MATERIAL_MAP.get(normalized_q_value, normalized_q_value)
  
      def _is_doi(id_, type_):
          return (not type_ or type_.upper() == 'DOI') and is_doi(id_)
  
      def _is_handle(id_, type_):
          return (not type_ or type_.upper() == 'HDL') and is_handle(id_)
  
      dois = self.get('dois', [])
      persistent_identifiers = self.get('persistent_identifiers', [])
  
      values = force_list(value)
      for value in values:
          id_ = force_single_element(value.get('a', ''))
          material = _get_material(value)
          schema = force_single_element(value.get('2', ''))
  
          sources = force_list(value.get('9'))
          source = _get_first_non_curator_source(sources)
  
          if _is_doi(id_, schema):
              dois.append({
                  'material': material,
                  'source': source,
                  'value': normalize_doi(id_),
              })
          else:
              schema = 'HDL' if _is_handle(id_, schema) else schema
              persistent_identifiers.append({
                  'material': material,
                  'schema': schema,
                  'source': source,
                  'value': id_,
              })
  
      self['persistent_identifiers'] = persistent_identifiers
      return dois
docs: Populate the ``dois`` key.
  
      Also populates the ``persistent_identifiers`` key through side effects.