Recursively parses response according to configuration
        :param data: response or its part
        :param field_cfg: field configuration
        :param target: target object for parsed data
        :param is_optional: optional sign

def parse_field(data, field_cfg, target, is_optional=False):
        """
        Recursively parses response according to configuration
        :param data: response or its part
        :param field_cfg: field configuration
        :param target: target object for parsed data
        :param is_optional: optional sign
        """
        field_type = field_cfg[Field.FIELD_TYPE]
        field_key = field_cfg[Field.FIELD_KEY] if Field.FIELD_KEY in field_cfg else None
        field_ext_id = field_cfg[Field.FIELD_EXT_ID] if Field.FIELD_EXT_ID in field_cfg else field_key
        if field_type == Types.TYPE_ARRAY:
            if isinstance(target, dict):  # add to object
                target.update({field_ext_id: []})
                field_value = data[field_key]
            elif not field_key:  # add to array
                field_value = data
            else:
                raise NotImplementedError('Array of arrays is not supported')
            field_pattern = field_cfg[Field.FIELD_MATCH] if Field.FIELD_MATCH in field_cfg else None
            if Field.FIELD_SUBITEMS in field_cfg:
                subfield = next(iter(field_cfg[Field.FIELD_SUBITEMS].values()))  # only one field within array is allowed
                for item in field_value:
                    if Field.is_match(field_pattern, item):
                        Field.parse_field(item, subfield, target[field_ext_id] if field_ext_id else target)
            else:
                target[field_ext_id] = field_value
        elif field_type == Types.TYPE_OBJECT:
            is_explicit = bool(field_cfg[Field.FIELD_EXPLICIT]) if Field.FIELD_EXPLICIT in field_cfg else False
            is_optional = bool(field_cfg[Field.FIELD_OPTIONAL]) if Field.FIELD_OPTIONAL in field_cfg else False
            if field_key:
                try:
                    field_value = data[field_key]
                except KeyError:
                    if is_optional:
                        field_value = None
                    else:
                        raise
            else: # noname object
                field_value = data  # working with the same item
            if is_explicit:
                obj_exp = {}
                if isinstance(target, dict):  # add to object
                    target.update({field_ext_id: obj_exp})
                else:  # add to array
                    target.append(obj_exp)
            for subfield in field_cfg[Field.FIELD_SUBITEMS]:
                Field.parse_field(field_value, field_cfg[Field.FIELD_SUBITEMS][subfield],
                                  obj_exp if is_explicit else target, is_optional)
        else:  # other types
            try:
                field_value = data[field_key]
            except TypeError:
                if is_optional:
                    field_value = None
                else:
                    raise
            casted_value = Converter.convert(field_value, field_type)
            if isinstance(target, dict):  # add to object
                target.update({field_ext_id: casted_value})
            else:  # add to array
                target.append(casted_value)