'Create an instance of a Document (subclass) from a PyMongo
SON.'

@classmethod
def _from_son(cls, son, _auto_dereference=True, only_fields=None, created=False):

    if (not only_fields):
        only_fields = []
    if (son and (not isinstance(son, dict))):
        raise ValueError("The    source    SON    object    needs    to    be    of    type    'dict'")
    class_name = son.get('_cls', cls._class_name)
    data = {}
    for (key, value) in son.iteritems():
        key = str(key)
        key = cls._db_field_map.get(key, key)
        data[key] = value
    if (class_name != cls._class_name):
        cls = get_document(class_name)
    changed_fields = []
    errors_dict = {}
    fields = cls._fields
    if (not _auto_dereference):
        fields = copy.copy(fields)
    for (field_name, field) in fields.iteritems():
        field._auto_dereference = _auto_dereference
        if (field.db_field in data):
            value = data[field.db_field]
            try:
                data[field_name] = (value if (value is None) else field.to_python(value))
                if (field_name != field.db_field):
                    del data[field.db_field]
            except (AttributeError, ValueError) as e:
                errors_dict[field_name] = e
    if errors_dict:
        errors = '\n'.join([('%s    -    %s' % (k, v)) for (k, v) in errors_dict.items()])
        msg = ('Invalid    data    to    create    a    `%s`    instance.\n%s' % (cls._class_name, errors))
        raise InvalidDocumentError(msg)
    if cls.STRICT:
        data = {k: v for (k, v) in data.iteritems() if (k in cls._fields)}
    obj = cls(__auto_convert=False, _created=created, __only_fields=only_fields, **data)
    obj._changed_fields = changed_fields
    if (not _auto_dereference):
        obj._fields = fields
    return obj
