def check_write_permission(self, url, depth, token_list, principal):
assert compat.is_native(url)<EOL>assert depth in ("<STR_LIT:0>", "<STR_LIT>")<EOL>_logger.debug(<EOL>"<STR_LIT>".format(<EOL>url, depth, token_list, principal<EOL>)<EOL>)<EOL>errcond = DAVErrorCondition(PRECONDITION_CODE_LockConflict)<EOL>self._lock.acquire_read()<EOL>try:<EOL><INDENT>u = url<EOL>while u:<EOL><INDENT>ll = self.get_url_lock_list(u)<EOL>_logger.debug("<STR_LIT>".format(u))<EOL>for l in ll:<EOL><INDENT>_logger.debug("<STR_LIT>".format(lock_string(l)))<EOL>if u != url and l["<STR_LIT>"] != "<STR_LIT>":<EOL><INDENT>continue<EOL><DEDENT>elif principal == l["<STR_LIT>"] and l["<STR_LIT>"] in token_list:<EOL><INDENT>continue<EOL><DEDENT>else:<EOL><INDENT>_logger.debug(<EOL>"<STR_LIT>".format(lock_string(l))<EOL>)<EOL>errcond.add_href(l["<STR_LIT:root>"])<EOL><DEDENT><DEDENT>u = util.get_uri_parent(u)<EOL><DEDENT>if depth == "<STR_LIT>":<EOL><INDENT>childLocks = self.storage.get_lock_list(<EOL>url, include_root=False, include_children=True, token_only=False<EOL>)<EOL>for l in childLocks:<EOL><INDENT>assert util.is_child_uri(url, l["<STR_LIT:root>"])<EOL>_logger.debug(<EOL>"<STR_LIT>".format(lock_string(l))<EOL>)<EOL>errcond.add_href(l["<STR_LIT:root>"])<EOL><DEDENT><DEDENT><DEDENT>finally:<EOL><INDENT>self._lock.release()<EOL><DEDENT>if len(errcond.hrefs) > <NUM_LIT:0>:<EOL><INDENT>raise DAVError(HTTP_LOCKED, err_condition=errcond)<EOL><DEDENT>return<EOL>
Check, if <principal> can modify <url>, otherwise raise HTTP_LOCKED.

        If modifying <url> is prevented by a lock, DAVError(HTTP_LOCKED) is
        raised. An embedded DAVErrorCondition contains the conflicting locks.

        <url> may be modified by <principal>, if it is not currently locked
        directly or indirectly (i.e. by a locked parent).
        For depth-infinity operations, <url> also must not have locked children.

        It is not enough to check whether a lock is owned by <principal>, but
        also the token must be passed with the request. Because <principal> may
        run two different applications.

        See http://www.webdav.org/specs/rfc4918.html#lock-model
            http://www.webdav.org/specs/rfc4918.html#rfc.section.7.4

        TODO: verify assumptions:
        - Parent locks WILL NOT be conflicting, if they are depth-0.
        - Exclusive child locks WILL be conflicting, even if they are owned by <principal>.

        @param url: URL that shall be modified, created, moved, or deleted
        @param depth: "0"|"infinity"
        @param token_list: list of lock tokens, that the principal submitted in If: header
        @param principal: name of the principal requesting a lock

        @return: None or raise error