Like :py:meth:`normalize.visitor.VisitorPattern.unpack` but called
        for ``cast`` operations.  Expects to work with dictionaries and lists
        instead of Record objects.

        Reverses the transform performed in
        :py:meth:`normalize.visitor.VisitorPattern.reduce` for collections with
        properties.

        If you pass tuples to ``isa`` of your Properties, then you might need
        to override this function and throw ``TypeError`` if the passed
        ``value_type`` is not appropriate for ``value``.

def grok(cls, value, value_type, visitor):
        """Like :py:meth:`normalize.visitor.VisitorPattern.unpack` but called
        for ``cast`` operations.  Expects to work with dictionaries and lists
        instead of Record objects.

        Reverses the transform performed in
        :py:meth:`normalize.visitor.VisitorPattern.reduce` for collections with
        properties.

        If you pass tuples to ``isa`` of your Properties, then you might need
        to override this function and throw ``TypeError`` if the passed
        ``value_type`` is not appropriate for ``value``.
        """
        is_coll = issubclass(value_type, Collection)
        is_record = issubclass(value_type, Record) and any(
            not visitor.is_filtered(prop) for prop in
            value_type.properties.values()
        )

        if is_record and not isinstance(value, cls.grok_mapping_types):
            raise exc.VisitorGrokRecordError(
                val=repr(value),
                record_type=value_type,
                record_type_name=value_type.__name__,
                field_selector=visitor.field_selector,
            )

        values = value
        if is_coll and is_record:
            try:
                if "values" in value:
                    values = value['values']
            except TypeError:
                pass

        generator = None
        if is_coll:
            if not isinstance(values, cls.grok_coll_types):
                raise exc.VisitorGrokCollectionError(
                    val=repr(values),
                    record_type=value_type,
                    record_type_name=value_type.__name__,
                    field_selector=visitor.field_selector,
                )
            generator = value_type.coll_to_tuples(values)

        propget = None
        if is_record:
            def propget(prop):
                return value[prop.name]

        return propget, generator