Browse (get sub-elements from) a music library item.

        Args:
            ml_item (`DidlItem`): the item to browse, if left out or
                `None`, items at the root level will be searched.
            start (int): the starting index of the results.
            max_items (int): the maximum number of items to return.
            full_album_art_uri (bool): whether the album art URI should be
                fully qualified with the relevant IP address.
            search_term (str): A string that will be used to perform a fuzzy
                search among the search results. If used in combination with
                subcategories, the fuzzy search will be performed on the
                subcategory. Note: Searching will not work if ``ml_item`` is
                `None`.
            subcategories (list): A list of strings that indicate one or more
                subcategories to descend into. Note: Providing sub categories
                will not work if ``ml_item`` is `None`.

        Returns:
            A `SearchResult` instance.

        Raises:
            AttributeError: if ``ml_item`` has no ``item_id`` attribute.
            SoCoUPnPException: with ``error_code='701'`` if the item cannot be
                browsed.

def browse(self, ml_item=None, start=0, max_items=100,
               full_album_art_uri=False, search_term=None, subcategories=None):
        """Browse (get sub-elements from) a music library item.

        Args:
            ml_item (`DidlItem`): the item to browse, if left out or
                `None`, items at the root level will be searched.
            start (int): the starting index of the results.
            max_items (int): the maximum number of items to return.
            full_album_art_uri (bool): whether the album art URI should be
                fully qualified with the relevant IP address.
            search_term (str): A string that will be used to perform a fuzzy
                search among the search results. If used in combination with
                subcategories, the fuzzy search will be performed on the
                subcategory. Note: Searching will not work if ``ml_item`` is
                `None`.
            subcategories (list): A list of strings that indicate one or more
                subcategories to descend into. Note: Providing sub categories
                will not work if ``ml_item`` is `None`.

        Returns:
            A `SearchResult` instance.

        Raises:
            AttributeError: if ``ml_item`` has no ``item_id`` attribute.
            SoCoUPnPException: with ``error_code='701'`` if the item cannot be
                browsed.
        """
        if ml_item is None:
            search = 'A:'
        else:
            search = ml_item.item_id

        # Add sub categories
        if subcategories is not None:
            for category in subcategories:
                search += '/' + url_escape_path(really_unicode(category))
        # Add fuzzy search
        if search_term is not None:
            search += ':' + url_escape_path(really_unicode(search_term))

        try:
            response, metadata = \
                self._music_lib_search(search, start, max_items)
        except SoCoUPnPException as exception:
            # 'No such object' UPnP errors
            if exception.error_code == '701':
                return SearchResult([], 'browse', 0, 0, None)
            else:
                raise exception
        metadata['search_type'] = 'browse'

        # Parse the results
        containers = from_didl_string(response['Result'])
        item_list = []
        for container in containers:
            # Check if the album art URI should be fully qualified
            if full_album_art_uri:
                self._update_album_art_to_full_uri(container)
            item_list.append(container)

        # pylint: disable=star-args
        return SearchResult(item_list, **metadata)