docs: def apply_with(self, obj, val, ctx):
          """ recursively apply Schema object
  
          :param obj.Model obj: model object to instruct how to create this model
          :param dict val: things used to construct this model
          """
          for k, v in six.iteritems(val):
              if k in obj.properties:
                  pobj = obj.properties.get(k)
                  if pobj.readOnly == True and ctx['read'] == False:
                      raise Exception('read-only property is set in write context.')
  
                  self[k] = ctx['factory'].produce(pobj, v)
  
              # TODO: patternProperties here
              # TODO: fix bug, everything would not go into additionalProperties, instead of recursive
              elif obj.additionalProperties == True:
                  ctx['addp'] = True
              elif obj.additionalProperties not in (None, False):
                  ctx['addp_schema'] = obj
  
          in_obj = set(six.iterkeys(obj.properties))
          in_self = set(six.iterkeys(self))
  
          other_prop = in_obj - in_self
          for k in other_prop:
              p = obj.properties[k]
              if p.is_set("default"):
                  self[k] = ctx['factory'].produce(p, p.default)
  
          not_found = set(obj.required) - set(six.iterkeys(self))
          if len(not_found):
              raise ValueError('Model missing required key(s): {0}'.format(', '.join(not_found)))
  
          # remove assigned properties to avoid duplicated
          # primitive creation
          _val = {}
          for k in set(six.iterkeys(val)) - in_obj:
              _val[k] = val[k]
  
          if obj.discriminator:
              self[obj.discriminator] = ctx['name']
  
          return _val