def _update_property(tree_to_update, xpath_root, xpaths, values):
    def update_element(elem, idx, root, path, vals):
        has_root = bool(root and len(path) > len(root) and path.startswith(root))
        path, attr = get_xpath_tuple(path)
        if attr:
            removed = [get_element(elem, path)]
            remove_element_attributes(removed[0], attr)
        elif not has_root:
            removed = wrap_value(remove_element(elem, path))
        else:
            path = get_xpath_branch(root, path)
            removed = [] if idx != 0 else [remove_element(e, path, True) for e in get_elements(elem, root)]
        if not vals:
            return removed
        items = []
        for i, val in enumerate(wrap_value(vals)):
            elem_to_update = elem
            if has_root:
                elem_to_update = insert_element(elem, (i + idx), root)
            val = val.decode('utf-8') if not isinstance(val, string_types) else val
            if not attr:
                items.append(insert_element(elem_to_update, i, path, val))
            elif path:
                items.append(insert_element(elem_to_update, i, path, **{attr: val}))
            else:
                set_element_attributes(elem_to_update, **{attr: val})
                items.append(elem_to_update)
        return items
    xpaths = reduce_value(xpaths)
    values = filter_empty(values)
    if isinstance(xpaths, string_types):
        return update_element(tree_to_update, 0, xpath_root, xpaths, values)
    else:
        each = []
        for index, xpath in enumerate(xpaths):
            value = values[index] if values else None
            each.extend(update_element(tree_to_update, index, xpath_root, xpath, value))
        return each