def build_ricecooker_json_tree(args, options, metadata_provider, json_tree_path):
    """
    Download all categories, subpages, modules, and resources from open.edu.
    """
    LOGGER.info('Starting to build the ricecooker_json_tree')

    channeldir = args['channeldir']
    if channeldir.endswith(os.path.sep):
        channeldir.rstrip(os.path.sep)
    channelparentdir, channeldirname = os.path.split(channeldir)
    channelparentdir, channeldirname = os.path.split(channeldir)

    # Ricecooker tree
    channel_info = metadata_provider.get_channel_info()
    thumbnail_chan_path =  channel_info.get('thumbnail_chan_path', None)
    if thumbnail_chan_path:
        thumbnail_rel_path = rel_path_from_chan_path(thumbnail_chan_path, metadata_provider.channeldir)
    else:
        thumbnail_rel_path = None

    ricecooker_json_tree = dict(
        dirname=channeldirname,
        title=channel_info['title'],
        description=channel_info['description'],
        source_domain=channel_info['source_domain'],
        source_id=channel_info['source_id'],
        language=channel_info['language'],
        thumbnail=thumbnail_rel_path,
        children=[],
    )
    channeldir = args['channeldir']
    content_folders = sorted(os.walk(channeldir))

    # MAIN PROCESSING OF os.walk OUTPUT
    ############################################################################
    # TODO(ivan): figure out all the implications of the
    # _ = content_folders.pop(0)  # Skip over channel folder because handled above
    for rel_path, _subfolders, filenames in content_folders:
        LOGGER.info('processing folder ' + str(rel_path))

        # IMPLEMENTATION DETAIL:
        #   - `filenames` contains real files in the `channeldir` folder
        #   - `exercises_filenames` contains virtual files whose sole purpse is to set the
        #     order of nodes within a given topic. Since alphabetical order is used to
        #     walk the files in the `channeldir`, we must "splice in" the exercises here
        if metadata_provider.has_exercises():
            dir_chan_path = chan_path_from_rel_path(rel_path, metadata_provider.channeldir)
            dir_path_tuple = path_to_tuple(dir_chan_path)
            exercises_filenames = metadata_provider.get_exercises_for_dir(dir_path_tuple)
            filenames.extend(exercises_filenames)

        sorted_filenames = sorted(filenames)
        process_folder(ricecooker_json_tree, rel_path, sorted_filenames, metadata_provider)

    # Write out ricecooker_json_tree.json
    write_tree_to_json_tree(json_tree_path, ricecooker_json_tree)
    LOGGER.info('Folder hierarchy walk result stored in ' + json_tree_path)
Download all categories, subpages, modules, and resources from open.edu.