docs: def _configure(
              self, target, conf=None, logger=None, callconf=None, keepstate=None,
              modules=None
      ):
          """Configure this class with input conf only if auto_conf or
          configure is true.
  
          This method should be overriden for specific conf
  
          :param target: object to configure. self targets by default.
          :param Configuration conf: configuration model to configure. Default is
              this conf.
          :param Logger logger: logger to use.
          :param bool callconf: if True, use conf in target __call__ parameters.
          :param bool keepstate: if True recreate sub objects if they already
              exist.
          :param list modules: modules to reload before.
          :return: configured target.
          """
  
          result = target
  
          self.loadmodules(modules=modules)
          modules = []
  
          if conf is None:
              conf = self.conf
  
          if logger is None:
              logger = self.logger
  
          if callconf is None:
              callconf = self.callparams
  
          if keepstate is None:
              keepstate = self.keepstate
  
          subcats = {}  # store sub configurable categories
          params = []  # self parameters
  
          sub_conf_prefix = Configurable.SUB_CONF_PREFIX
  
          for cat in conf.values():  # separate sub params and params
              cname = cat.name
  
              if cname.startswith(sub_conf_prefix):
  
                  subcnames = cname.split(sub_conf_prefix)
  
                  pname = subcnames[1]
                  fcname = cname[1 + len(pname):]
  
                  if not fcname:
                      fcname = str(random())
  
                  fcat = cat.copy(name=fcname)
  
                  if pname in subcats:
                      subcats[pname].append(fcat)
  
                  else:
                      subcats[pname] = [fcat]
  
              else:
                  cparams = cat.params
                  params += cparams.values()
  
          if callconf and callable(target):
  
              conf = self._toconf(params)
  
              args, kwargs = self.getcallparams(conf=conf, target=target)
  
              result = target = target(*args, **kwargs)
  
          for param in params:
  
              value, pname = param.value, param.name
  
              if pname in subcats:  # if sub param
  
                  subcallconf = True
  
                  if keepstate and hasattr(target, pname):
                      subcallconf = False
                      value = getattr(target, pname)
  
                  cats = subcats[pname]
  
                  subconf = configuration(*cats)
  
                  targets = applyconfiguration(
                      targets=[value], conf=subconf, callconf=subcallconf,
                      keepstate=keepstate, modules=modules
                  )
                  value = targets[0]
  
              if param.error:
                  continue
  
              elif self.foreigns or param.local:
                  try:
                      setattr(target, pname, value)
  
                  except Exception:
                      if logger is not None:
                          logger.error(
                              'Error while setting {0}({1}) on {2}: {3}'.format(
                                  pname, value, target, format_exc()
                              )
                          )
  
          return result