docs: def create_extended_model(model, db_penalty=None, ex_penalty=None,
                            tp_penalty=None, penalties=None):
      """Create an extended model for gap-filling.
  
      Create a :class:`psamm.metabolicmodel.MetabolicModel` with
      all reactions added (the reaction database in the model is taken
      to be the universal database) and also with artificial exchange
      and transport reactions added. Return the extended
      :class:`psamm.metabolicmodel.MetabolicModel`
      and a weight dictionary for added reactions in that model.
  
      Args:
          model: :class:`psamm.datasource.native.NativeModel`.
          db_penalty: penalty score for database reactions, default is `None`.
          ex_penalty: penalty score for exchange reactions, default is `None`.
          tb_penalty: penalty score for transport reactions, default is `None`.
          penalties: a dictionary of penalty scores for database reactions.
      """
  
      # Create metabolic model
      model_extended = model.create_metabolic_model()
      extra_compartment = model.extracellular_compartment
  
      compartment_ids = set(c.id for c in model.compartments)
  
      # Add database reactions to extended model
      if len(compartment_ids) > 0:
          logger.info(
              'Using all database reactions in compartments: {}...'.format(
                  ', '.join('{}'.format(c) for c in compartment_ids)))
          db_added = add_all_database_reactions(model_extended, compartment_ids)
      else:
          logger.warning(
              'No compartments specified in the model; database reactions will'
              ' not be used! Add compartment specification to model to include'
              ' database reactions for those compartments.')
          db_added = set()
  
      # Add exchange reactions to extended model
      logger.info(
          'Using artificial exchange reactions for compartment: {}...'.format(
              extra_compartment))
      ex_added = add_all_exchange_reactions(
          model_extended, extra_compartment, allow_duplicates=True)
  
      # Add transport reactions to extended model
      boundaries = model.compartment_boundaries
      if len(boundaries) > 0:
          logger.info(
              'Using artificial transport reactions for the compartment'
              ' boundaries: {}...'.format(
                  '; '.join('{}<->{}'.format(c1, c2) for c1, c2 in boundaries)))
          tp_added = add_all_transport_reactions(
              model_extended, boundaries, allow_duplicates=True)
      else:
          logger.warning(
              'No compartment boundaries specified in the model;'
              ' artificial transport reactions will not be used!')
          tp_added = set()
  
      # Add penalty weights on reactions
      weights = {}
      if db_penalty is not None:
          weights.update((rxnid, db_penalty) for rxnid in db_added)
      if tp_penalty is not None:
          weights.update((rxnid, tp_penalty) for rxnid in tp_added)
      if ex_penalty is not None:
          weights.update((rxnid, ex_penalty) for rxnid in ex_added)
  
      if penalties is not None:
          for rxnid, penalty in iteritems(penalties):
              weights[rxnid] = penalty
      return model_extended, weights