def recurse(self, root_path, dir_cb, listing_cb, max_listing_size=<NUM_LIT:0>, <EOL>max_depth=MAX_REMOTE_RECURSION_DEPTH):
q = deque([(root_path, <NUM_LIT:0>)])<EOL>collected = []<EOL>def push_file(path, file_path, entry):<EOL><INDENT>collected.append((file_path, entry))<EOL>if max_listing_size > <NUM_LIT:0> andlen(collected) >= max_listing_size:<EOL><INDENT>listing_cb(path, collected)<EOL>del collected[:]<EOL><DEDENT><DEDENT>while q:<EOL><INDENT>(path, current_depth) = q.popleft()<EOL>entries = self.listdir(path)<EOL>for entry in entries:<EOL><INDENT>filename = stringify(entry.name)<EOL>file_path = ('<STR_LIT>' % (path, filename))<EOL>if entry.is_symlink:<EOL><INDENT>push_file(path, file_path, entry)<EOL><DEDENT>elif entry.is_directory:<EOL><INDENT>if filename == '<STR_LIT:.>' or filename == '<STR_LIT:..>':<EOL><INDENT>continue<EOL><DEDENT>if dir_cb is not None:<EOL><INDENT>dir_cb(path, file_path, entry)<EOL><DEDENT>new_depth = current_depth + <NUM_LIT:1><EOL>if max_depth is None or new_depth <= max_depth:<EOL><INDENT>q.append((file_path, new_depth))<EOL><DEDENT><DEDENT>elif entry.is_regular:<EOL><INDENT>if listing_cb is not None:<EOL><INDENT>push_file(path, file_path, entry)<EOL><DEDENT><DEDENT><DEDENT><DEDENT>if listing_cb is not None and (max_listing_size == <NUM_LIT:0> or <EOL>len(collected) > <NUM_LIT:0>):<EOL><INDENT>listing_cb(path, collected)<EOL><DEDENT>
Recursively iterate a directory. Invoke callbacks for directories 
        and entries (both are optional, but it doesn't make sense unless one is 
        provided). "max_listing_size" will allow for the file-listing to be 
        chunked into manageable pieces. "max_depth" limited how deep recursion 
        goes. This can be used to make it easy to simply read a single 
        directory in chunks.