'Fetch all tasks in a folder
@param root: the root element of the data tree
@param folder_id: the ID of the folder to read from
@param deleted: mark the tasks as deleted in the data
tree (when reading tasks from a recycle bin)
@param msince: only retrieve tasks that have been modified
after this date/time (ISO-formatted string)'

def fetch_tasks(self, root, folder_id, deleted=False, msince=None):

    fields = json.dumps(['parentIds', 'description'])
    args = {'descendants': 'true', 'fields': json.dumps(['parentIds', 'description'])}
    if (msince is not None):
        args['updatedDate'] = ('%sZ,' % msince)
    (response, message) = self._send_request(path=('folders/%s/tasks' % folder_id), args=args)
    if (not response):
        return (None, message)
    details = {'title': 'title', 'description': 'description', 'status': 'status', 'importance': 'importance', 'permalink': 'permalink', 'createdDate': 'createdDate', 'updatedDate': 'updatedDate', 'dates': {'due': 'dueDate'}}
    tasks = {}
    data = response.get('data')
    if (data and (type(data) is list)):
        SubElement = etree.SubElement
        for task_data in data:
            scope = task_data.get('scope')
            if (scope not in ('WsTask', 'RbTask')):
                continue
            task_id = task_data.get('id')
            task = SubElement(root, 'task', id=str(task_id))
            tasks[task_id] = task
            deleted = (scope == 'RbTask')
            if deleted:
                task.set('deleted', str(True))
                continue
            parent_ids = task_data.get('parentIds')
            if parent_ids:
                for parent_id in parent_ids:
                    parent = SubElement(task, 'parentId')
                    parent.text = str(parent_id)
            self.add_details(task, task_data, details)
    return (tasks, None)
