def _walk_tree(self, data, scheme, ancestors=None, property_name=None, prefix=None):
        if property_name is None:
            property_name = 'root'
            order = ['registries'] + [key for key in scheme.keys() if key not in ('registries',)]
            scheme = OrderedDict(sorted(scheme.items(), key=lambda x: order.index(x[0])))
        if data is None:
            return
        elif not isinstance(property_name, six.string_types):
            raise TypeError('property_name must be a string.')
        ancestors = self._update_ancestors(data, property_name, ancestors)
        if isinstance(ancestors, OrderedDict):
            if list(ancestors)[0] != 'root':
                raise LookupError('root must be the first item in ancestors.')
        else:
            raise TypeError('ancestors must be an OrderedDict. {0} was passed'.format(type(ancestors)))
        if not isinstance(scheme, dict):
            raise TypeError('scheme must be a dict. {0} was passed.'.format(type(scheme)))
        scheme = self._update_scheme(scheme, ancestors)
        if property_name is not None and data:
            data = self._get_cascading_attr(
                property_name, *list(ancestors)[1:]
            ) if scheme.get('cascading', False) else data
        for err in self.__execute_validations(scheme.get('is', {}), data, property_name, ancestors, prefix=prefix):
            if err:
                raise err
            else:
                self._create_attr(property_name, data, ancestors)
        self.__validate_unrecognized_values(scheme, data, ancestors, prefix)
        self.__populate_scheme_references(scheme, property_name)
        self.__validate_config_properties(scheme, data, ancestors, prefix)