'Checks if the given block has unpublished changes
:param xblock: the block to check
:return: True if the draft and published versions differ'

def has_changes(self, xblock):

    def get_course(branch_name):
        return self._lookup_course(xblock.location.course_key.for_branch(branch_name)).structure
    def get_block(course_structure, block_key):
        return self._get_block_from_structure(course_structure, block_key)
    draft_course = get_course(ModuleStoreEnum.BranchName.draft)
    published_course = get_course(ModuleStoreEnum.BranchName.published)
    def has_changes_subtree(block_key):
        draft_block = get_block(draft_course, block_key)
        if (draft_block is None):
            return True
        published_block = get_block(published_course, block_key)
        if (published_block is None):
            return True
        if (self._get_version(draft_block) != self._get_version(published_block)):
            return True
        if ('children' in draft_block.fields):
            return any([has_changes_subtree(child_block_id) for child_block_id in draft_block.fields['children']])
        return False
    return has_changes_subtree(BlockKey.from_usage_key(xblock.location))
